1ㅊㅏ완료
This commit is contained in:
@@ -1,8 +1,22 @@
|
||||
import { query } from '../../../utils/db'
|
||||
|
||||
const ADMIN_EMAIL = 'coziny@gmail.com'
|
||||
|
||||
/**
|
||||
* 주간보고 목록 조회
|
||||
* 주간보고 목록 조회 (필터링 지원)
|
||||
* GET /api/report/weekly/list
|
||||
*
|
||||
* Query params:
|
||||
* - authorId: 작성자 ID
|
||||
* - projectId: 프로젝트 ID
|
||||
* - year: 연도
|
||||
* - weekFrom: 시작 주차
|
||||
* - weekTo: 종료 주차
|
||||
* - startDate: 시작일 (YYYY-MM-DD)
|
||||
* - endDate: 종료일 (YYYY-MM-DD)
|
||||
* - status: 상태 (DRAFT, SUBMITTED, AGGREGATED)
|
||||
* - viewAll: 전체 조회 (관리자만)
|
||||
* - limit: 조회 개수 (기본 100)
|
||||
*/
|
||||
export default defineEventHandler(async (event) => {
|
||||
const userId = getCookie(event, 'user_id')
|
||||
@@ -10,14 +24,89 @@ export default defineEventHandler(async (event) => {
|
||||
throw createError({ statusCode: 401, message: '로그인이 필요합니다.' })
|
||||
}
|
||||
|
||||
const queryParams = getQuery(event)
|
||||
const limit = parseInt(queryParams.limit as string) || 20
|
||||
// 현재 사용자 정보 조회 (관리자 여부 확인)
|
||||
const currentUser = await query<any>(`
|
||||
SELECT employee_email FROM wr_employee_info WHERE employee_id = $1
|
||||
`, [userId])
|
||||
const isAdmin = currentUser[0]?.employee_email === ADMIN_EMAIL
|
||||
|
||||
const q = getQuery(event)
|
||||
const limit = parseInt(q.limit as string) || 100
|
||||
const viewAll = q.viewAll === 'true'
|
||||
|
||||
// 필터 조건 구성
|
||||
const conditions: string[] = []
|
||||
const params: any[] = []
|
||||
let paramIndex = 1
|
||||
|
||||
// 관리자가 viewAll이면 전체 조회, 아니면 본인 것만
|
||||
if (!isAdmin || !viewAll) {
|
||||
// 작성자 필터 (본인 또는 지정된 작성자)
|
||||
if (q.authorId) {
|
||||
conditions.push(`r.author_id = $${paramIndex++}`)
|
||||
params.push(q.authorId)
|
||||
} else if (!isAdmin) {
|
||||
// 관리자가 아니면 본인 것만
|
||||
conditions.push(`r.author_id = $${paramIndex++}`)
|
||||
params.push(userId)
|
||||
}
|
||||
} else if (q.authorId) {
|
||||
// 관리자가 viewAll이어도 작성자 필터가 있으면 적용
|
||||
conditions.push(`r.author_id = $${paramIndex++}`)
|
||||
params.push(q.authorId)
|
||||
}
|
||||
|
||||
// 프로젝트 필터
|
||||
if (q.projectId) {
|
||||
conditions.push(`EXISTS (
|
||||
SELECT 1 FROM wr_weekly_report_project wrp
|
||||
WHERE wrp.report_id = r.report_id AND wrp.project_id = $${paramIndex++}
|
||||
)`)
|
||||
params.push(q.projectId)
|
||||
}
|
||||
|
||||
// 연도 필터
|
||||
if (q.year) {
|
||||
conditions.push(`r.report_year = $${paramIndex++}`)
|
||||
params.push(q.year)
|
||||
}
|
||||
|
||||
// 주차 범위 필터
|
||||
if (q.weekFrom) {
|
||||
conditions.push(`r.report_week >= $${paramIndex++}`)
|
||||
params.push(q.weekFrom)
|
||||
}
|
||||
if (q.weekTo) {
|
||||
conditions.push(`r.report_week <= $${paramIndex++}`)
|
||||
params.push(q.weekTo)
|
||||
}
|
||||
|
||||
// 날짜 범위 필터
|
||||
if (q.startDate) {
|
||||
conditions.push(`r.week_start_date >= $${paramIndex++}`)
|
||||
params.push(q.startDate)
|
||||
}
|
||||
if (q.endDate) {
|
||||
conditions.push(`r.week_end_date <= $${paramIndex++}`)
|
||||
params.push(q.endDate)
|
||||
}
|
||||
|
||||
// 상태 필터
|
||||
if (q.status) {
|
||||
conditions.push(`r.report_status = $${paramIndex++}`)
|
||||
params.push(q.status)
|
||||
}
|
||||
|
||||
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''
|
||||
|
||||
params.push(limit)
|
||||
|
||||
const reports = await query<any>(`
|
||||
SELECT
|
||||
r.report_id,
|
||||
r.author_id,
|
||||
e.employee_name as author_name,
|
||||
e.employee_email as author_email,
|
||||
r.report_year,
|
||||
r.report_week,
|
||||
r.week_start_date,
|
||||
@@ -27,29 +116,50 @@ export default defineEventHandler(async (event) => {
|
||||
r.report_status,
|
||||
r.submitted_at,
|
||||
r.created_at,
|
||||
(SELECT COUNT(*) FROM wr_weekly_report_project WHERE report_id = r.report_id) as project_count
|
||||
(SELECT COUNT(DISTINCT project_id) FROM wr_weekly_report_task WHERE report_id = r.report_id) as project_count,
|
||||
(SELECT string_agg(DISTINCT p.project_name, ', ')
|
||||
FROM wr_weekly_report_task t
|
||||
JOIN wr_project_info p ON t.project_id = p.project_id
|
||||
WHERE t.report_id = r.report_id) as project_names,
|
||||
(SELECT COALESCE(SUM(task_hours), 0) FROM wr_weekly_report_task WHERE report_id = r.report_id AND task_type = 'WORK') as total_work_hours,
|
||||
(SELECT COALESCE(SUM(task_hours), 0) FROM wr_weekly_report_task WHERE report_id = r.report_id AND task_type = 'PLAN') as total_plan_hours
|
||||
FROM wr_weekly_report r
|
||||
JOIN wr_employee_info e ON r.author_id = e.employee_id
|
||||
WHERE r.author_id = $1
|
||||
ORDER BY r.report_year DESC, r.report_week DESC
|
||||
LIMIT $2
|
||||
`, [userId, limit])
|
||||
${whereClause}
|
||||
ORDER BY r.report_year DESC, r.report_week DESC, e.employee_name
|
||||
LIMIT $${paramIndex}
|
||||
`, params)
|
||||
|
||||
return {
|
||||
isAdmin,
|
||||
reports: reports.map((r: any) => ({
|
||||
reportId: r.report_id,
|
||||
authorId: r.author_id,
|
||||
authorName: r.author_name,
|
||||
authorEmail: r.author_email,
|
||||
reportYear: r.report_year,
|
||||
reportWeek: r.report_week,
|
||||
weekStartDate: r.week_start_date,
|
||||
weekEndDate: r.week_end_date,
|
||||
weekStartDate: formatDateOnly(r.week_start_date),
|
||||
weekEndDate: formatDateOnly(r.week_end_date),
|
||||
issueDescription: r.issue_description,
|
||||
vacationDescription: r.vacation_description,
|
||||
reportStatus: r.report_status,
|
||||
submittedAt: r.submitted_at,
|
||||
createdAt: r.created_at,
|
||||
projectCount: parseInt(r.project_count)
|
||||
projectCount: parseInt(r.project_count),
|
||||
projectNames: r.project_names,
|
||||
totalWorkHours: parseFloat(r.total_work_hours) || 0,
|
||||
totalPlanHours: parseFloat(r.total_plan_hours) || 0
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
// 날짜를 YYYY-MM-DD 형식으로 변환 (타임존 보정)
|
||||
function formatDateOnly(date: Date | string | null): string {
|
||||
if (!date) return ''
|
||||
const d = new Date(date)
|
||||
// 한국 시간 기준으로 날짜만 추출
|
||||
const kstOffset = 9 * 60 * 60 * 1000
|
||||
const kstDate = new Date(d.getTime() + kstOffset)
|
||||
return kstDate.toISOString().split('T')[0]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user