146 lines
4.3 KiB
TypeScript
146 lines
4.3 KiB
TypeScript
import { query } from '../../utils/db'
|
|
|
|
/**
|
|
* 유지보수 업무 통계
|
|
* GET /api/maintenance/stats
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const params = getQuery(event)
|
|
const projectId = params.projectId ? Number(params.projectId) : null
|
|
const year = params.year ? Number(params.year) : new Date().getFullYear()
|
|
const month = params.month ? Number(params.month) : null
|
|
|
|
const conditions: string[] = ['EXTRACT(YEAR FROM m.request_date) = $1']
|
|
const values: any[] = [year]
|
|
let paramIndex = 2
|
|
|
|
if (projectId) {
|
|
conditions.push(`m.project_id = $${paramIndex++}`)
|
|
values.push(projectId)
|
|
}
|
|
|
|
if (month) {
|
|
conditions.push(`EXTRACT(MONTH FROM m.request_date) = $${paramIndex++}`)
|
|
values.push(month)
|
|
}
|
|
|
|
const whereClause = conditions.join(' AND ')
|
|
|
|
// 상태별 통계
|
|
const statusStats = await query(`
|
|
SELECT
|
|
m.status,
|
|
COUNT(*) as count
|
|
FROM wr_maintenance_task m
|
|
WHERE ${whereClause}
|
|
GROUP BY m.status
|
|
`, values)
|
|
|
|
// 유형별 통계
|
|
const typeStats = await query(`
|
|
SELECT
|
|
m.task_type,
|
|
COUNT(*) as count
|
|
FROM wr_maintenance_task m
|
|
WHERE ${whereClause}
|
|
GROUP BY m.task_type
|
|
`, values)
|
|
|
|
// 우선순위별 통계
|
|
const priorityStats = await query(`
|
|
SELECT
|
|
m.priority,
|
|
COUNT(*) as count
|
|
FROM wr_maintenance_task m
|
|
WHERE ${whereClause}
|
|
GROUP BY m.priority
|
|
`, values)
|
|
|
|
// 월별 추이 (연간)
|
|
const monthlyTrend = await query(`
|
|
SELECT
|
|
EXTRACT(MONTH FROM m.request_date) as month,
|
|
COUNT(*) as total,
|
|
COUNT(CASE WHEN m.status = 'COMPLETED' THEN 1 END) as completed
|
|
FROM wr_maintenance_task m
|
|
WHERE EXTRACT(YEAR FROM m.request_date) = $1
|
|
${projectId ? 'AND m.project_id = $2' : ''}
|
|
GROUP BY EXTRACT(MONTH FROM m.request_date)
|
|
ORDER BY month
|
|
`, projectId ? [year, projectId] : [year])
|
|
|
|
// 담당자별 통계
|
|
const assigneeStats = await query(`
|
|
SELECT
|
|
e.employee_id,
|
|
e.employee_name,
|
|
COUNT(*) as total,
|
|
COUNT(CASE WHEN m.status = 'COMPLETED' THEN 1 END) as completed
|
|
FROM wr_maintenance_task m
|
|
JOIN wr_employee_info e ON m.assignee_id = e.employee_id
|
|
WHERE ${whereClause}
|
|
GROUP BY e.employee_id, e.employee_name
|
|
ORDER BY total DESC
|
|
LIMIT 10
|
|
`, values)
|
|
|
|
// 프로젝트별 통계
|
|
const projectStats = await query(`
|
|
SELECT
|
|
p.project_id,
|
|
p.project_name,
|
|
COUNT(*) as total,
|
|
COUNT(CASE WHEN m.status = 'COMPLETED' THEN 1 END) as completed
|
|
FROM wr_maintenance_task m
|
|
JOIN wr_project_info p ON m.project_id = p.project_id
|
|
WHERE EXTRACT(YEAR FROM m.request_date) = $1
|
|
${month ? 'AND EXTRACT(MONTH FROM m.request_date) = $2' : ''}
|
|
GROUP BY p.project_id, p.project_name
|
|
ORDER BY total DESC
|
|
LIMIT 10
|
|
`, month ? [year, month] : [year])
|
|
|
|
// 전체 합계
|
|
const totalResult = await query(`
|
|
SELECT
|
|
COUNT(*) as total,
|
|
COUNT(CASE WHEN m.status = 'COMPLETED' THEN 1 END) as completed,
|
|
COUNT(CASE WHEN m.status = 'PENDING' THEN 1 END) as pending,
|
|
COUNT(CASE WHEN m.status = 'IN_PROGRESS' THEN 1 END) as in_progress
|
|
FROM wr_maintenance_task m
|
|
WHERE ${whereClause}
|
|
`, values)
|
|
|
|
return {
|
|
year,
|
|
month,
|
|
projectId,
|
|
summary: {
|
|
total: Number(totalResult[0]?.total || 0),
|
|
completed: Number(totalResult[0]?.completed || 0),
|
|
pending: Number(totalResult[0]?.pending || 0),
|
|
inProgress: Number(totalResult[0]?.in_progress || 0)
|
|
},
|
|
byStatus: statusStats.map((s: any) => ({ status: s.status, count: Number(s.count) })),
|
|
byType: typeStats.map((t: any) => ({ taskType: t.task_type, count: Number(t.count) })),
|
|
byPriority: priorityStats.map((p: any) => ({ priority: p.priority, count: Number(p.count) })),
|
|
monthlyTrend: monthlyTrend.map((m: any) => ({
|
|
month: Number(m.month),
|
|
total: Number(m.total),
|
|
completed: Number(m.completed)
|
|
})),
|
|
byAssignee: assigneeStats.map((a: any) => ({
|
|
employeeId: a.employee_id,
|
|
employeeName: a.employee_name,
|
|
total: Number(a.total),
|
|
completed: Number(a.completed)
|
|
})),
|
|
byProject: projectStats.map((p: any) => ({
|
|
projectId: p.project_id,
|
|
projectName: p.project_name,
|
|
total: Number(p.total),
|
|
completed: Number(p.completed)
|
|
}))
|
|
}
|
|
})
|