diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index b0f01e3..ff57145 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -140,6 +140,7 @@ model Organization { esignTrainingEnabled Boolean @default(false) // 培训记录电子签 esignPerformanceEnabled Boolean @default(false) // 绩效考核电子签 esignDisciplinaryEnabled Boolean @default(false) // 违纪记录电子签 + socialInsCutoffDay Int @default(15) // 社保/公积金截止日:每月该日前离职→截止月=离职月-1,该日后→截止月=离职月 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/backend/src/schemas/termination.schema.ts b/backend/src/schemas/termination.schema.ts index 826cf00..66ffd01 100644 --- a/backend/src/schemas/termination.schema.ts +++ b/backend/src/schemas/termination.schema.ts @@ -44,7 +44,9 @@ export const createTerminationDraftSchema = z.object({ reason: z.string().max(200).optional(), terminationDate: z.string().optional(), compensation: z.number().min(0).optional(), + compensationBreakdown: z.any().optional(), handoverItems: z.array(z.any()).optional(), + checklistOverrides: z.any().optional(), remark: z.string().max(500).optional(), }) @@ -52,6 +54,8 @@ export const updateTerminationDraftSchema = z.object({ reason: z.string().max(200).optional(), terminationDate: z.string().optional(), compensation: z.number().min(0).optional(), + compensationBreakdown: z.any().optional(), handoverItems: z.array(z.any()).optional(), + checklistOverrides: z.any().optional(), remark: z.string().max(500).optional(), }) diff --git a/backend/src/services/termination.service.ts b/backend/src/services/termination.service.ts index b5508eb..3845dfc 100644 --- a/backend/src/services/termination.service.ts +++ b/backend/src/services/termination.service.ts @@ -8,6 +8,13 @@ function dateToMonth(date: Date): string { return `${y}-${m}` } +/** 计算上一个月,格式 YYYY-MM */ +function prevMonth(month: string): string { + const [y, m] = month.split('-').map(Number) + if (m === 1) return `${y - 1}-12` + return `${y}-${String(m - 1).padStart(2, '0')}` +} + export interface ChecklistItem { key: string label: string @@ -572,6 +579,26 @@ export async function createDraft(orgId: string, userId: string, data: any) { const { level } = assessRisk(employee, data.reason || 'NEGOTIATED') + // 自动推导社保/公积金截止月(基于组织 socialInsCutoffDay 配置) + let socialInsEndMonth = data.socialInsEndMonth || null + let housingFundEndMonth = data.housingFundEndMonth || null + if (data.terminationDate && !socialInsEndMonth) { + const org = await prisma.organization.findUnique({ where: { id: orgId }, select: { socialInsCutoffDay: true } }) + const cutoffDay = org?.socialInsCutoffDay ?? 15 + const termDate = new Date(data.terminationDate) + const termDay = termDate.getDate() + const termMonth = dateToMonth(termDate) + // cutoffDay 日前离职 → 截止月 = 离职月 - 1;cutoffDay 日后离职 → 截止月 = 离职月 + if (termDay <= cutoffDay) { + const prevMon = prevMonth(termMonth) + socialInsEndMonth = prevMon + housingFundEndMonth = prevMon + } else { + socialInsEndMonth = termMonth + housingFundEndMonth = termMonth + } + } + const record = await prisma.terminationRecord.create({ data: { orgId, @@ -581,8 +608,8 @@ export async function createDraft(orgId: string, userId: string, data: any) { terminationDate: data.terminationDate ? new Date(data.terminationDate) : new Date(), resignationReason: data.resignationReason || null, compensation: data.compensation || 0, - socialInsEndMonth: data.socialInsEndMonth || null, - housingFundEndMonth: data.housingFundEndMonth || null, + socialInsEndMonth, + housingFundEndMonth, riskLevel: level, checklist: data.checklist || {}, remark: data.remark || null, diff --git a/frontend/src/components/layout/Breadcrumb.tsx b/frontend/src/components/layout/Breadcrumb.tsx index cf45252..705f5a9 100644 --- a/frontend/src/components/layout/Breadcrumb.tsx +++ b/frontend/src/components/layout/Breadcrumb.tsx @@ -15,7 +15,7 @@ const ROUTE_MAP: Record = { '/': { group: '工作台', label: '总览' }, '/calendar': { group: '工作台', label: '工作日历' }, '/roster': { group: '员工管理', label: '花名册' }, - '/work-process': { group: '员工管理', label: '用工办理' }, + '/work-process': { group: '员工管理', label: '批量流程' }, '/attendance': { group: '员工管理', label: '考勤确认' }, '/leave-approval': { group: '员工管理', label: '休假审批' }, '/termination': { group: '员工管理', label: '解聘补偿' },