feat: 待办事项显示损失金额理由

后端 estimateRiskCost 返回 lossReason 字段,说明法律依据和计算方式
前端在损失金额下方显示理由,如'逾期缴纳社保/公积金将产生滞纳金,每日万分之五'
This commit is contained in:
freedakgmail
2026-08-17 20:57:45 +08:00
parent a1a0b22e95
commit 03e9e83483
2 changed files with 18 additions and 1 deletions
+12 -1
View File
@@ -30,7 +30,7 @@ const SOCIAL_AVG_SALARY_3X = 36921
function estimateRiskCost(
risk: { type: RiskType; level: RiskLevel; title: string; description: string },
employee?: { hireDate: Date; monthlySalary?: string } | null,
): { estimatedLoss: number; lossRange: [number, number]; deadline?: Date } {
): { estimatedLoss: number; lossRange: [number, number]; deadline?: Date; lossReason?: string } {
const today = new Date()
const rawSalary = employee ? safeDecryptSalary(employee.monthlySalary || '0') : 0
// 第47条:高收入者月薪封顶为社平3倍
@@ -57,6 +57,7 @@ function estimateRiskCost(
estimatedLoss: loss,
lossRange: [loss * 0.5, loss],
deadline: new Date(today.getTime() + 7 * 86400000), // 7天内处理
lossReason: `《劳动合同法》第82条:未签书面合同,每月支付2倍工资。${months}个月×月薪${salary.toFixed(0)}`,
}
}
@@ -68,6 +69,7 @@ function estimateRiskCost(
estimatedLoss: loss,
lossRange: [loss, loss * 2], // 可能被认定为违法解除 2N
deadline: new Date(today.getTime() + 3 * 86400000), // 3天内处理
lossReason: `《劳动合同法》第47条:经济补偿N×月薪。N=${n}个月×月薪${salary.toFixed(0)}元,违法解除可能2N`,
}
}
@@ -79,6 +81,7 @@ function estimateRiskCost(
estimatedLoss: 0,
lossRange: [0, salary * n],
deadline: new Date(today.getTime() + days * 86400000),
lossReason: `到期未续签可能需支付经济补偿,最高N=${n}个月×月薪${salary.toFixed(0)}`,
}
}
@@ -89,6 +92,7 @@ function estimateRiskCost(
estimatedLoss: loss,
lossRange: [loss, loss * 3],
deadline: new Date(today.getTime() + 14 * 86400000), // 14天内处理
lossReason: `试用期工资差额约20%:月薪${salary.toFixed(0)}元×20%`,
}
}
@@ -100,6 +104,7 @@ function estimateRiskCost(
estimatedLoss: loss,
lossRange: [loss, loss * 2],
deadline: new Date(today.getTime() + 1 * 86400000), // 1天内处理
lossReason: `《劳动合同法》第87条:违法解除按2N赔偿。2N=${(n * 2).toFixed(1)}个月×月薪${salary.toFixed(0)}`,
}
}
@@ -109,6 +114,7 @@ function estimateRiskCost(
estimatedLoss: 500,
lossRange: [100, 2000],
deadline: new Date(today.getTime() + 3 * 86400000),
lossReason: '逾期缴纳社保/公积金将产生滞纳金,每日万分之五',
}
}
@@ -117,6 +123,7 @@ function estimateRiskCost(
estimatedLoss: 1000,
lossRange: [500, 5000],
deadline: new Date(today.getTime() + 1 * 86400000),
lossReason: '逾期发放工资/申报个税可能面临行政处罚及赔偿,《劳动法》第91条',
}
}
@@ -128,6 +135,7 @@ function estimateRiskCost(
estimatedLoss: days > 0 ? salary * (days / 30) : salary,
lossRange: [500, salary * 6],
deadline: new Date(today.getTime() + (days > 0 ? days : 7) * 86400000),
lossReason: `未及时办理退休可能导致多缴社保公积金,约${(days / 30).toFixed(1)}个月×月薪${salary.toFixed(0)}`,
}
}
@@ -916,6 +924,8 @@ export async function getDashboardData(orgId: string) {
const estimatedLoss = r.estimatedLoss || 0
const priority = calcPriority(r.level, estimatedLoss, r.deadline || undefined)
const daysUntilDeadline = r.deadline ? daysBetween(r.deadline, new Date()) : null
// 动态计算损失理由
const costInfo = estimateRiskCost({ type: r.type, level: r.level, title: r.title, description: r.description }, null)
return {
id: r.id,
type: r.type as 'CONTRACT' | 'SALARY' | 'TERMINATION' | 'MONTHLY' | 'ONBOARDING' | 'RETIREMENT',
@@ -926,6 +936,7 @@ export async function getDashboardData(orgId: string) {
actionUrl: r.actionUrl || '/',
estimatedLoss,
lossRange: r.lossRange as [number, number] | null,
lossReason: costInfo.lossReason || null,
deadline: r.deadline?.toISOString().slice(0, 10) || null,
daysUntilDeadline,
employeeName: r.employee?.name || null,