/** * 员工特殊状态台账路由 * 管理三期/工伤/医疗期等特殊状态的 CRUD 和提醒 */ import { Router, Response, NextFunction } from 'express' import { authMiddleware, AuthRequest } from '../middleware/auth' import prisma from '../lib/prisma' import { parsePagination } from '../lib/pagination' import { createSpecialStatus, updateSpecialStatus, deleteSpecialStatus, getPendingReminders, STATUS_TYPES, getAlertLevel, } from '../services/special-status.service' import { createSpecialStatusSchema, updateSpecialStatusSchema } from '../schemas/special-status.schema' const router = Router() /** * 获取特殊状态列表(分页 + 筛选) */ router.get('/', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { const orgId = req.user!.orgId const { page, pageSize } = parsePagination(req.query) const type = (req.query.type as string) || '' const status = (req.query.status as string) || '' const search = (req.query.search as string) || '' const where: any = { orgId } if (type) where.type = type if (status) where.status = status if (search) { where.employee = { OR: [ { name: { contains: search, mode: 'insensitive' } }, { phone: { contains: search } }, ], } } const [list, total] = await Promise.all([ (prisma as any).employeeSpecialStatus.findMany({ where, orderBy: { createdAt: 'desc' }, skip: (page - 1) * pageSize, take: pageSize, include: { employee: { select: { id: true, name: true, department: true, phone: true, gender: true, status: true }, }, }, }), (prisma as any).employeeSpecialStatus.count({ where }), ]) // 附加预警级别 const listWithAlert = list.map((item: any) => ({ ...item, alertLevel: getAlertLevel(item.reminderDate, item.status), })) res.json({ success: true, data: { list: listWithAlert, total, page, pageSize }, }) } catch (err) { next(err) } }) /** * 获取单条详情 */ router.get('/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { const record = await (prisma as any).employeeSpecialStatus.findFirst({ where: { id: req.params.id, orgId: req.user!.orgId }, include: { employee: { select: { id: true, name: true, department: true, phone: true, gender: true, hireDate: true }, }, }, }) if (!record) { return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '记录不存在' } }) } res.json({ success: true, data: record }) } catch (err) { next(err) } }) /** * 创建特殊状态 */ router.post('/', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { const data = createSpecialStatusSchema.parse(req.body) const record = await createSpecialStatus(req.user!.orgId, req.user!.id, data) res.json({ success: true, data: record }) } catch (err: any) { if (err.code) { return res.status(400).json({ success: false, error: { code: err.code, message: err.message } }) } next(err) } }) /** * 更新特殊状态 */ router.put('/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { const data = updateSpecialStatusSchema.parse(req.body) const record = await updateSpecialStatus(req.user!.orgId, req.user!.id, req.params.id, data) res.json({ success: true, data: record }) } catch (err: any) { if (err.code) { return res.status(400).json({ success: false, error: { code: err.code, message: err.message } }) } next(err) } }) /** * 删除特殊状态 */ router.delete('/:id', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { await deleteSpecialStatus(req.user!.orgId, req.params.id) res.json({ success: true, data: { message: '已删除' } }) } catch (err: any) { if (err.code) { return res.status(400).json({ success: false, error: { code: err.code, message: err.message } }) } next(err) } }) /** * 获取待提醒列表 */ router.get('/reminders/pending', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { const reminders = await getPendingReminders(req.user!.orgId) res.json({ success: true, data: reminders }) } catch (err) { next(err) } }) /** * 获取统计概览 */ router.get('/stats/overview', authMiddleware, async (req: AuthRequest, res: Response, next: NextFunction) => { try { const orgId = req.user!.orgId const [total, active, pending, byType] = await Promise.all([ (prisma as any).employeeSpecialStatus.count({ where: { orgId } }), (prisma as any).employeeSpecialStatus.count({ where: { orgId, status: 'ACTIVE' } }), (prisma as any).employeeSpecialStatus.count({ where: { orgId, status: 'PENDING' } }), (prisma as any).employeeSpecialStatus.groupBy({ by: ['type'], where: { orgId, status: 'ACTIVE' }, _count: true, }), ]) // 预警统计 const soon7 = new Date() soon7.setDate(soon7.getDate() + 7) const soon30 = new Date() soon30.setDate(soon30.getDate() + 30) const [redCount, yellowCount] = await Promise.all([ (prisma as any).employeeSpecialStatus.count({ where: { orgId, status: 'ACTIVE', reminderDate: { lte: soon7 } }, }), (prisma as any).employeeSpecialStatus.count({ where: { orgId, status: 'ACTIVE', reminderDate: { gt: soon7, lte: soon30 } }, }), ]) res.json({ success: true, data: { total, active, pending, redAlert: redCount, yellowAlert: yellowCount, byType: byType.map((t: any) => ({ type: t.type, label: STATUS_TYPES[t.type]?.label || t.type, count: t._count })), }, }) } catch (err) { next(err) } }) export default router