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
+94
View File
@@ -521,6 +521,100 @@ export async function updateEmployee(orgId: string, id: string, data: any) {
if (data.specialDeduction !== undefined) updateData.specialDeduction = data.specialDeduction
if (data.city !== undefined) updateData.city = data.city
// 参保城市变更:关闭旧城市在保记录,创建新城市记录
if (data.city !== undefined && data.city !== employee.city) {
const nowMonth = new Date().toISOString().slice(0, 7)
const cityChangeReason = data.cityChangeReason || '未填写原因'
const changeRemark = `城市变更:${employee.city || '未设置'}${data.city}${cityChangeReason}`
// 社保:关闭旧在保记录,创建新城市记录
const activeSocial = await prisma.employeeSocialInsRecord.findFirst({
where: { employeeId: id, endMonth: null },
})
if (activeSocial) {
await prisma.employeeSocialInsRecord.update({
where: { id: activeSocial.id },
data: { endMonth: nowMonth, changeType: 'CITY_CHANGE', remark: changeRemark },
})
await prisma.employeeSocialInsRecord.create({
data: {
orgId,
employeeId: id,
city: data.city,
startMonth: nowMonth,
endMonth: null,
base: activeSocial.base,
changeType: 'CITY_CHANGE',
remark: changeRemark,
createdBy: '',
},
})
} else {
// 兜底:没有在保记录也创建一条,保留变更历史
await prisma.employeeSocialInsRecord.create({
data: {
orgId,
employeeId: id,
city: data.city,
startMonth: nowMonth,
endMonth: null,
base: employee.socialInsBase || 0,
changeType: 'CITY_CHANGE',
remark: changeRemark,
createdBy: '',
},
})
}
// 公积金:同上
const activeHousing = await prisma.employeeHousingFundRecord.findFirst({
where: { employeeId: id, endMonth: null },
})
if (activeHousing) {
await prisma.employeeHousingFundRecord.update({
where: { id: activeHousing.id },
data: { endMonth: nowMonth, changeType: 'CITY_CHANGE', remark: changeRemark },
})
await prisma.employeeHousingFundRecord.create({
data: {
orgId,
employeeId: id,
city: data.city,
startMonth: nowMonth,
endMonth: null,
base: activeHousing.base,
changeType: 'CITY_CHANGE',
remark: changeRemark,
createdBy: '',
},
})
} else {
// 兜底:没有在保记录也创建一条
await prisma.employeeHousingFundRecord.create({
data: {
orgId,
employeeId: id,
city: data.city,
startMonth: nowMonth,
endMonth: null,
base: employee.housingFundBase || 0,
changeType: 'CITY_CHANGE',
remark: changeRemark,
createdBy: '',
},
})
}
// 写审计日志
await prisma.auditLog.create({
data: {
orgId,
userId: '',
action: 'CITY_CHANGE',
entity: 'Employee',
entityId: id,
detail: { oldCity: employee.city, newCity: data.city, reason: cityChangeReason, remark: changeRemark },
},
})
}
await prisma.employee.update({ where: { id }, data: updateData })
await runRiskDetection(orgId)