From aced7929e168aa282778bc88d9b661cfa463e3ee Mon Sep 17 00:00:00 2001 From: selfrelease Date: Thu, 30 Jul 2026 19:17:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B9=B4=E5=BA=A6=E4=BB=B7=E5=80=BC?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E9=A3=8E=E9=99=A9=E9=87=8F=E5=8C=96=E6=8C=89?= =?UTF-8?q?=E5=8A=B3=E5=8A=A8=E6=B3=95=E8=AE=BE=E5=AE=9A=E6=B3=95=E5=AE=9A?= =?UTF-8?q?=E4=B8=8A=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 单条风险estimatedLoss封顶:双倍工资≤11个月(第82条)、经济补偿N≤12个月月薪≤社平3倍(第47条)、违法解除2N≤24个月(第87条) - 年度规避损失按30%规避率打折(非每项风险都演变为实际仲裁) - ROI上限9999% - 前端计算说明同步更新 --- backend/src/services/risk.service.ts | 37 ++++++++++++++----- .../src/pages/tools/AnnualValueReport.tsx | 10 +++-- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/backend/src/services/risk.service.ts b/backend/src/services/risk.service.ts index 0f3b1cf..7900a0a 100644 --- a/backend/src/services/risk.service.ts +++ b/backend/src/services/risk.service.ts @@ -15,8 +15,15 @@ function safeDecryptSalary(encrypted: string): number { } } +/** + * 社平工资3倍封顶(参照上海2024年度社平工资约12307元/月,3倍≈36921元) + * 《劳动合同法》第47条:月工资高于社平3倍的按3倍计,且补偿年限最高12年 + */ +const SOCIAL_AVG_SALARY_3X = 36921 + /** * 风险量化:根据风险类型和员工数据估算预估损失金额 + * 依据《劳动合同法》《劳动法》设定法定上限 * @returns { estimatedLoss, lossRange, deadline } */ function estimateRiskCost( @@ -24,21 +31,26 @@ function estimateRiskCost( employee?: { hireDate: Date; monthlySalary?: string } | null, ): { estimatedLoss: number; lossRange: [number, number]; deadline?: Date } { const today = new Date() - const salary = employee ? safeDecryptSalary(employee.monthlySalary || '0') : 0 + const rawSalary = employee ? safeDecryptSalary(employee.monthlySalary || '0') : 0 + // 第47条:高收入者月薪封顶为社平3倍 + const salary = Math.min(rawSalary, SOCIAL_AVG_SALARY_3X) const workYears = employee ? Math.max(0, (today.getFullYear() - employee.hireDate.getFullYear()) + (today.getMonth() - employee.hireDate.getMonth()) / 12) : 0 - const n = Math.max(0.5, Math.round(workYears * 2) / 2) // 经济补偿月数,不满半年算0.5 + // 经济补偿月数:每满1年1个月,不满半年算0.5个月,第47条上限12年 + const n = Math.min(12, Math.max(0.5, Math.round(workYears * 2) / 2)) // 根据风险标题关键词判断类型并估算 const title = risk.title // 未签合同(>30天):双倍工资 + // 《劳动合同法》第82条:超过1个月不满1年未签书面合同,每月支付2倍工资 + // 超过1年视为已订立无固定期限合同,不再适用双倍工资,故最多罚11个月 if (title.includes('未签合同') && title.includes('天')) { const daysMatch = title.match(/(\d+)天/) const days = daysMatch ? parseInt(daysMatch[1]) : 0 - const months = Math.ceil(days / 30) + const months = Math.min(11, Math.ceil(days / 30)) // 法定上限11个月 const loss = salary * months return { estimatedLoss: loss, @@ -48,8 +60,9 @@ function estimateRiskCost( } // 合同到期未续签:经济补偿 N × 月薪 + // 《劳动合同法》第47条:N≤12个月,月薪≤社平3倍 if (title.includes('到期') && title.includes('未续签')) { - const loss = salary * n + const loss = salary * n // n已封顶12 return { estimatedLoss: loss, lossRange: [loss, loss * 2], // 可能被认定为违法解除 2N @@ -79,8 +92,9 @@ function estimateRiskCost( } // 三期/工伤/医疗期:违法解除风险 2N + // 《劳动合同法》第87条:违法解除按第47条标准的2倍赔偿,2N≤24个月 if (title.includes('孕期') || title.includes('哺乳期') || title.includes('工伤') || title.includes('医疗期')) { - const loss = salary * n * 2 + const loss = salary * n * 2 // n已封顶12,故2N≤24 return { estimatedLoss: loss, lossRange: [loss, loss * 2], @@ -1609,9 +1623,11 @@ export async function getAnnualValueReport(orgId: string, year: number) { })) // 价值计算 - // 1. 规避损失 = 已解决风险的预估损失之和 + // 1. 规避损失 = 已解决风险的预估损失之和 × 0.3(规避率30%,非每项风险都会演变为实际仲裁) // 2. 节约工时 = AI 查询 * 0.5h + 合同审查 * 1h + 算薪批次 * 2h + 制度公示 * 1h // 3. 节约成本 = 节约工时 * 100 元/h(HR 平均时薪) + const RISK_AVOIDANCE_RATE = 0.3 // 规避率:约30%的未处理风险会演变为实际劳动争议 + const adjustedLossAvoided = Math.round(lossAvoided * RISK_AVOIDANCE_RATE) const aiTimeSaved = aiConversations * 0.5 + aiReviews * 1.0 const payrollTimeSaved = payrollBatches * 2.0 const policyTimeSaved = policiesPublished * 1.0 @@ -1619,12 +1635,13 @@ export async function getAnnualValueReport(orgId: string, year: number) { const timeSaved = Math.round(aiTimeSaved + payrollTimeSaved + policyTimeSaved + contractTimeSaved) const costSaved = timeSaved * 100 - // 总价值 = 规避损失 + 节约成本 - const totalValue = lossAvoided + costSaved + // 总价值 = 规避损失(打折后) + 节约成本 + const totalValue = adjustedLossAvoided + costSaved - // ROI = 总价值 / 系统成本(假设年费 12000 元) + // ROI = 总价值 / 系统成本(年费 12000 元),上限 9999% const systemCost = 12000 - const roi = systemCost > 0 ? Math.round((totalValue / systemCost) * 100) : 0 + const rawRoi = systemCost > 0 ? Math.round((totalValue / systemCost) * 100) : 0 + const roi = Math.min(rawRoi, 9999) const metrics = { risksResolved, diff --git a/frontend/src/pages/tools/AnnualValueReport.tsx b/frontend/src/pages/tools/AnnualValueReport.tsx index edc7286..cc3a4fa 100644 --- a/frontend/src/pages/tools/AnnualValueReport.tsx +++ b/frontend/src/pages/tools/AnnualValueReport.tsx @@ -226,7 +226,7 @@ export default function AnnualValueReport() {
- 规避损失:已解决风险的预估损失金额之和(基于风险量化模型) + 规避损失:已解决风险的预估损失之和 × 30%规避率(依据《劳动合同法》量化模型,单条上限按法定标准封顶)
@@ -238,11 +238,15 @@ export default function AnnualValueReport() {
- 总价值:规避损失 + 节约成本 + 总价值:规避损失(打折后) + 节约成本
- ROI:总价值 ÷ 系统年费(¥12,000)× 100% + ROI:总价值 ÷ 系统年费(¥12,000)× 100%,上限 9999% +
+
+ + 法定上限:双倍工资≤11个月(第82条)、经济补偿N≤12个月月薪≤社平3倍(第47条)、违法解除2N≤24个月(第87条)