fix: 修复已撤销解聘记录(CANCELLED)在各模块中未正确过滤的问题
- 花名册API新增latestTerminationStatus字段,前端列表/操作按钮/离职日期列过滤CANCELLED/COMPLETED - 证据链后端过滤CANCELLED状态的解聘记录,不再产生无效证据和风险提醒 - 重新入职判断增加status=COMPLETED条件,避免已撤销记录被误判为已离职 - 薪酬警告过滤CANCELLED状态,不再对已撤销记录触发结算提醒 - 风险扫描查询条件增加status=COMPLETED,避免已撤销记录导致员工被跳过 - 解聘向导canProceed和警告提示过滤CANCELLED/COMPLETED状态 - 档案解聘记录列表过滤CANCELLED状态,新增流程状态标签 - 重新生成Prisma Client以同步femaleWorkerType字段
This commit is contained in:
@@ -346,7 +346,7 @@ export default function Roster() {
|
||||
</td>
|
||||
<td className="hidden px-4 py-3 text-gray-500">{e.hireDate?.toString().slice(0, 10)}</td>
|
||||
<td className="hidden px-4 py-3 text-gray-500">
|
||||
{e.hasTermination && e.latestTerminationDate ? (
|
||||
{e.hasTermination && e.latestTerminationDate && e.latestTerminationStatus !== 'CANCELLED' && e.latestTerminationStatus !== 'COMPLETED' ? (
|
||||
<span className={e.status === 'RESIGNED' ? 'text-gray-500' : 'text-amber-600'}>
|
||||
{e.latestTerminationDate.toString().slice(0, 10)}
|
||||
{e.status === 'ACTIVE' && ' (预计)'}
|
||||
@@ -425,7 +425,7 @@ export default function Roster() {
|
||||
<td className="px-4 py-3 text-center text-gray-500">{e.counts?.performanceRecords || 0}</td>
|
||||
<td className="px-4 py-3 text-center text-gray-500">{e.counts?.payslips || 0}</td>
|
||||
<td className="px-4 py-3 text-center">
|
||||
{e.status === 'ACTIVE' && !e.hasTermination && (
|
||||
{e.status === 'ACTIVE' && (!e.hasTermination || e.latestTerminationStatus === 'CANCELLED' || e.latestTerminationStatus === 'COMPLETED') && (
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
@@ -468,7 +468,7 @@ export default function Roster() {
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{e.hasTermination && e.status === 'ACTIVE' && (
|
||||
{e.hasTermination && e.status === 'ACTIVE' && e.latestTerminationStatus !== 'CANCELLED' && e.latestTerminationStatus !== 'COMPLETED' && (
|
||||
<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' ? '待离职' : '待解聘'}
|
||||
@@ -2294,7 +2294,8 @@ function TerminationInfo({ employeeId, profile, records }: { employeeId: string;
|
||||
enabled: !!printRecord,
|
||||
})
|
||||
|
||||
if (!records?.length) return <Card><div className="text-center py-8 text-gray-400">暂无离职/解聘记录</div></Card>
|
||||
const validRecords = (records || []).filter((t: any) => t.status !== 'CANCELLED')
|
||||
if (!validRecords.length) return <Card><div className="text-center py-8 text-gray-400">暂无离职/解聘记录</div></Card>
|
||||
|
||||
if (printRecord) {
|
||||
return (
|
||||
@@ -2412,7 +2413,7 @@ function TerminationInfo({ employeeId, profile, records }: { employeeId: string;
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
{records.map((t) => (
|
||||
{validRecords.map((t) => (
|
||||
<Card key={t.id} className="p-4">
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
@@ -2424,6 +2425,11 @@ function TerminationInfo({ employeeId, profile, records }: { employeeId: string;
|
||||
{t.riskLevel === 'SAFE' ? '风险低' : t.riskLevel === 'WARNING' ? '注意' : '高风险'}
|
||||
</span>
|
||||
)}
|
||||
{t.status && (
|
||||
<span className={`px-2 py-0.5 rounded text-xs ${t.status === 'COMPLETED' ? 'bg-green-50 text-safe' : t.status === 'PENDING_APPROVAL' ? 'bg-amber-50 text-amber-700' : t.status === 'APPROVED' ? 'bg-blue-50 text-blue-700' : 'bg-gray-100 text-gray-600'}`}>
|
||||
{t.status === 'DRAFT' ? '草稿' : t.status === 'PENDING_APPROVAL' ? '待审批' : t.status === 'APPROVED' ? '已审批' : t.status === 'COMPLETED' ? '已完成' : t.status === 'REJECTED' ? '已驳回' : t.status === 'EXECUTING' ? '执行中' : t.status}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-3 text-xs">
|
||||
{t.type === 'RESIGNATION' ? (
|
||||
|
||||
@@ -49,6 +49,7 @@ interface RosterEmployee {
|
||||
department: string
|
||||
status: string
|
||||
hasTermination?: boolean
|
||||
latestTerminationStatus?: string
|
||||
hireDate: string
|
||||
monthlySalary: number
|
||||
latestContract: any
|
||||
@@ -417,7 +418,7 @@ export default function Termination() {
|
||||
}, [selectedEmployee, terminationDate, socialAvgWage, reason])
|
||||
|
||||
const canProceed = () => {
|
||||
if (step === 0) return !!employeeId && (!!draftId || !selectedEmployee?.hasTermination)
|
||||
if (step === 0) return !!employeeId && (!!draftId || !selectedEmployee?.hasTermination || selectedEmployee?.latestTerminationStatus === 'CANCELLED' || selectedEmployee?.latestTerminationStatus === 'COMPLETED')
|
||||
if (step === 1) return !!reason && !!terminationDate && (!riskAssessment?.warnings.length || acknowledgeRisk)
|
||||
if (step === 2) return true
|
||||
if (step === 3) return true
|
||||
@@ -921,7 +922,7 @@ export default function Termination() {
|
||||
<div className="font-medium">{selectedEmployee.name}({selectedEmployee.department})</div>
|
||||
<div>入职日期:{selectedEmployee.hireDate?.toString().slice(0, 10)}</div>
|
||||
<div>月工资:¥{fmt(selectedEmployee.monthlySalary)}</div>
|
||||
{selectedEmployee.hasTermination && (
|
||||
{selectedEmployee.hasTermination && selectedEmployee.latestTerminationStatus !== 'CANCELLED' && selectedEmployee.latestTerminationStatus !== 'COMPLETED' && (
|
||||
<div className="text-danger font-medium mt-1">⚠️ 该员工已有离职/解聘记录,如需再次解聘请先办理重新雇佣</div>
|
||||
)}
|
||||
{selectedEmployee.latestContract ? (
|
||||
|
||||
Reference in New Issue
Block a user