feat: 城市变更功能完善及跨页面缓存刷新修复

- 城市变更使用CITY_CHANGE类型替代ADJUST,月度办理显示减员/新增(城市变更)
- 在保人员查询排除本月已关闭记录(gte→gt)和本月新增记录(lte→lt)
- 社保/公积金减员查询包含CITY_CHANGE类型
- 缴纳记录表格添加城市列显示
- 后端profile API从快照提取city字段
- 修复旧快照缺失city字段的数据
- 修复旧记录changeType为CITY_CHANGE,endMonth与新记录startMonth一致
- 城市变更必填原因,写入备注和审计日志
- 员工详情页添加变更历史Tab
- 移除薪酬社保Tab下重复的参保城市变更子Tab
- 全局修复跨页面mutation缓存刷新:调薪/调部门/离职/重新入职/批量续签/批量解聘/社保公积金调基/月度办理/撤销解聘均刷新roster-profile
This commit is contained in:
selfrelease
2026-07-25 22:40:39 +08:00
parent 7ca2ada0d4
commit f74b2808a3
9 changed files with 1988 additions and 380 deletions
+36
View File
@@ -172,11 +172,46 @@ router.get('/:id/profile', authMiddleware, async (req: AuthRequest, res, next) =
performanceRecords: { orderBy: { period: 'desc' } },
terminations: { orderBy: { createdAt: 'desc' } },
attachments: true,
socialInsRecords: { orderBy: { startMonth: 'desc' } },
housingFundRecords: { orderBy: { startMonth: 'desc' } },
salaryChanges: { orderBy: { effectiveDate: 'desc' } },
departmentRecords: { orderBy: { effectiveMonth: 'desc' } },
},
})
if (!employee) {
return res.status(404).json({ success: false, error: { code: 'NOT_FOUND', message: '员工不存在' } })
}
// 查询该员工相关的月度办理记录(从快照中筛选该员工)
const allProcesses = await prisma.socialMonthlyProcess.findMany({
where: { orgId: req.user!.orgId },
orderBy: { month: 'desc' },
})
const employeeId = req.params.id
const monthlyProcessRecords: any[] = []
for (const p of allProcesses) {
const snap = p.snapshot as any
// 从增减员快照中筛选
const changes = snap.changes
const active = snap.active
const type = p.type
let found = false
let recordData: any = { month: p.month, type, processedAt: p.processedAt, status: p.status }
if (changes?.additions) {
const item = changes.additions.find((a: any) => a.employeeId === employeeId)
if (item) { recordData.changeType = '新增'; recordData.detail = item.detail; recordData.base = item.base; recordData.city = item.city; found = true }
}
if (!found && changes?.reductions) {
const item = changes.reductions.find((a: any) => a.employeeId === employeeId)
if (item) { recordData.changeType = '减少'; recordData.detail = item.detail; recordData.base = item.base; recordData.city = item.city; found = true }
}
if (!found && active?.items) {
const item = active.items.find((a: any) => a.employeeId === employeeId)
if (item) { recordData.changeType = '正常在保'; recordData.detail = item.detail; recordData.base = item.base; recordData.city = item.city; found = true }
}
if (found) monthlyProcessRecords.push(recordData)
}
const { monthlySalary, bankAccount, idCardNumber, ...rest } = employee
const today = new Date()
today.setHours(0, 0, 0, 0)
@@ -189,6 +224,7 @@ router.get('/:id/profile', authMiddleware, async (req: AuthRequest, res, next) =
monthlySalary: safeDecrypt(monthlySalary),
bankAccount: bankAccount ? safeDecrypt(bankAccount).toString() : null,
idCardNumber: idCardNumber ? safeDecrypt(idCardNumber).toString() : null,
monthlyProcessRecords,
},
})
} catch (err) {