feat: 20260815 系统优化 - 全部31项问题修复(P0×6+P1×14+P2×9+P3×2)

P0紧急修复(6项):
- 草稿保存完整恢复所有字段(含socialAvgWage)
- 补偿金批次从compensationBreakdown读取
- 违法解除风险确认UI
- 合同结束日期前后校验(前后端双保险)

P1高优先级(14项):
- 离职日期联动社保/公积金截止月(15号规则)
- 合规检查+工作交接改为软阻断(生成待办)
- 补偿月数(N/N+1/2N/自定义)+计算基数(近12月/合同/自定义)
- 解聘并入花名册操作栏(类型选择跳转向导)
- 合同续签开始日期自动推导(原合同结束日+1天)
- 年龄合规筛查(童工阻断/未成年工/退休警告)
- 编辑入职日期后状态联动(待入职↔在职)
- 转正移植到花名册操作栏+薪资回写
- 男职工无法选择三期

P2体验优化(9项):
- "劳动合同"调整为"用工关系"
- 费用结算新增剩余年假折算(300%日工资)
- 身份证号全域改为"证件号码"(前后端18个文件)
- 手机号查重
- 开具证明+合同续签移植到花名册操作栏
- 批量转正+批量开具证明
- 去掉用工办理模块

P3规划(2项):
- 组织架构+审批流(Department/Position/ApprovalFlow/ApprovalInstance)
- 客服工作台(Ticket/ChatSession+SUPPORT角色)

新增模型: Department/Position/ApprovalFlow/ApprovalInstance/Ticket/TicketMessage/ChatSession/ChatMessage
新增字段: Employee.departmentId/supervisorId
新增角色: SUPPORT

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
selfrelease
2026-08-15 12:37:27 +08:00
parent 8cfdd566af
commit e1b5ae9aab
46 changed files with 3455 additions and 206 deletions
+4 -4
View File
@@ -94,7 +94,7 @@ router.get('/', authMiddleware, async (req: AuthRequest, res, next) => {
whereBase.contracts = { none: {} }
}
// 当有 contractStatus(非 unsigned)筛选或身份证号搜索时,需要先查全部再过滤后分页
// 当有 contractStatus(非 unsigned)筛选或证件号码搜索时,需要先查全部再过滤后分页
const needPostFilter = (!!contractStatus && contractStatus !== 'unsigned') || isIdCardSearch
const [dbTotal, employees] = await Promise.all([
@@ -170,7 +170,7 @@ router.get('/', authMiddleware, async (req: AuthRequest, res, next) => {
const isResigned = e.terminations.some((t) => t.status === 'COMPLETED' && t.terminationDate <= today)
const isPreHire = !isResigned && e.hireDate > todayEnd
const dynamicStatus = isResigned ? 'RESIGNED' : (isPreHire ? 'PRE_HIRE' : 'ACTIVE')
// 身份证号脱敏显示
// 证件号码脱敏显示
let idCardMasked: string | null = null
if (e.idCardNumber) {
try {
@@ -250,7 +250,7 @@ router.get('/', authMiddleware, async (req: AuthRequest, res, next) => {
result = result.filter((e) => e.contractStatus === contractStatus)
}
// 身份证号后N位搜索:在内存中过滤(idCardNumber 已解密为明文)
// 证件号码后N位搜索:在内存中过滤(idCardNumber 已解密为明文)
if (isIdCardSearch) {
result = result.filter((e: any) => {
if (!e.idCardNumber) return false
@@ -1025,7 +1025,7 @@ router.get('/:employeeId/disciplinary/:recordId/certificate', authMiddleware, as
const content = `违纪确认证明
兹证明 ${record.employee.name}身份证号${idCard || '___'})系我单位员工,于 ${record.violationDate.toISOString().slice(0, 10)} 发生以下违纪行为:
兹证明 ${record.employee.name}证件号码${idCard || '___'})系我单位员工,于 ${record.violationDate.toISOString().slice(0, 10)} 发生以下违纪行为:
违纪类型:${typeMap[record.violationType] || record.violationType}
严重程度:${severityMap[record.severity] || record.severity}