feat: 区分待解聘/待离职+撤回功能

1. 花名册列表区分「待解聘」(amber)和「待离职」(blue)
2. 未到日期的解聘/离职记录可撤回,撤回后删除记录并恢复在职状态
3. 后端新增 DELETE /termination/:id/revoke 接口
4. 花名册列表返回 latestTerminationType 和 latestTerminationId
This commit is contained in:
freedakgmail
2026-07-23 18:07:37 +08:00
parent 29ba3a98bc
commit 2896ba77aa
4 changed files with 69 additions and 2 deletions
+24 -1
View File
@@ -51,6 +51,14 @@ export default function Roster() {
},
})
const revokeMutation = useMutation({
mutationFn: (recordId: string) => api.delete(`/termination/${recordId}/revoke`),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['roster'] })
queryClient.invalidateQueries({ queryKey: ['dashboard'] })
},
})
const filtered = employees?.filter((e: any) =>
!search || e.name.includes(search) || e.department.includes(search)
) || []
@@ -156,7 +164,22 @@ export default function Roster() {
</button>
)}
{e.hasTermination && e.status === 'ACTIVE' && (
<span className="text-xs text-gray-400"></span>
<div className="flex items-center justify-center gap-2">
<span className={`text-xs ${e.latestTerminationType === 'RESIGNATION' ? 'text-blue-600' : 'text-amber-600'}`}>
{e.latestTerminationType === 'RESIGNATION' ? '待离职' : '待解聘'}
</span>
<button
className="text-xs text-gray-400 hover:text-danger"
onClick={(ev) => {
ev.stopPropagation()
if (e.latestTerminationId && confirm(`确认撤回${e.latestTerminationType === 'RESIGNATION' ? '离职' : '解聘'}记录?`)) {
revokeMutation.mutate(e.latestTerminationId)
}
}}
>
</button>
</div>
)}
</td>
</tr>