feat: 移除ROI,新增待处理风险列表
- 移除ROI横幅和说明,改为年度总价值概览 - 后端新增 pendingRisks 查询,返回PENDING状态风险 - 前端新增待处理风险表格,按员工去重展示 - summary 改为包含待处理风险数量
This commit is contained in:
@@ -117,7 +117,7 @@ export default function AnnualValueReport() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ROI 横幅 */}
|
||||
{/* 年度总价值概览 */}
|
||||
<Card className="bg-gradient-to-r from-primary/10 to-amber-50 border-primary/20">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
@@ -125,13 +125,13 @@ export default function AnnualValueReport() {
|
||||
<TrendingUp className="w-8 h-8 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs text-gray-500">投资回报率 (ROI)</div>
|
||||
<div className="text-3xl font-bold text-primary">{report.roi}%</div>
|
||||
<div className="text-xs text-gray-500">年度总价值</div>
|
||||
<div className="text-3xl font-bold text-primary">{fmtMoney(report.totalValue)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<div className="text-xs text-gray-500">年度总价值</div>
|
||||
<div className="text-2xl font-bold text-amber-600">{fmtMoney(report.totalValue)}</div>
|
||||
<div className="text-xs text-gray-500">规避损失</div>
|
||||
<div className="text-2xl font-bold text-safe">{fmtMoney(report.adjustedLossAvoided || 0)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-3 text-sm text-gray-700">{report.summary}</p>
|
||||
@@ -168,7 +168,7 @@ export default function AnnualValueReport() {
|
||||
<div key={r.id} className="flex items-center justify-between p-2 rounded-md bg-gray-50 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium">{r.year} 年</span>
|
||||
<span className="font-bold text-primary">ROI {r.roi}%</span>
|
||||
<span className="font-bold text-primary">总价值 {fmtMoney(r.totalValue)}</span>
|
||||
<span className="text-gray-500">{r.summary}</span>
|
||||
</div>
|
||||
<span className="text-gray-400">{new Date(r.createdAt).toLocaleDateString('zh-CN')}</span>
|
||||
@@ -270,6 +270,61 @@ export default function AnnualValueReport() {
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 未解决风险列表 */}
|
||||
{report.pendingRiskDetails && report.pendingRiskDetails.length > 0 && (
|
||||
<Card>
|
||||
<h2 className="text-sm font-medium mb-3 flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-danger" />
|
||||
待处理风险 ({report.pendingRiskDetails.length} 人)
|
||||
</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-xs">
|
||||
<thead>
|
||||
<tr className="border-b border-gray-200 text-gray-500">
|
||||
<th className="text-left py-2 px-2 font-medium">员工</th>
|
||||
<th className="text-left py-2 px-2 font-medium">部门</th>
|
||||
<th className="text-center py-2 px-2 font-medium">风险数</th>
|
||||
<th className="text-right py-2 px-2 font-medium">潜在损失</th>
|
||||
<th className="text-left py-2 px-2 font-medium">风险明细</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{report.pendingRiskDetails.map((emp: any, idx: number) => (
|
||||
<tr key={idx} className="border-b border-gray-50">
|
||||
<td className="py-2 px-2 font-medium">{emp.name}</td>
|
||||
<td className="py-2 px-2 text-gray-600">{emp.department}</td>
|
||||
<td className="py-2 px-2 text-center">{emp.riskCount}</td>
|
||||
<td className="py-2 px-2 text-right font-bold text-danger">¥{emp.totalLoss.toLocaleString()}</td>
|
||||
<td className="py-2 px-2">
|
||||
<div className="space-y-0.5">
|
||||
{emp.details.map((d: any, i: number) => (
|
||||
<div key={i} className="flex items-center gap-1.5">
|
||||
<span className="text-gray-700">{d.title}</span>
|
||||
<span className="text-gray-400">·</span>
|
||||
<span className="text-gray-500">{d.legalBasis}</span>
|
||||
<span className="text-gray-400">·</span>
|
||||
<span className="text-gray-600">¥{d.estimatedLoss.toLocaleString()}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr className="border-t-2 border-gray-200 font-bold">
|
||||
<td className="py-2 px-2" colSpan={3}>合计</td>
|
||||
<td className="py-2 px-2 text-right text-danger">
|
||||
¥{report.pendingRiskDetails.reduce((s: number, e: any) => s + e.totalLoss, 0).toLocaleString()}
|
||||
</td>
|
||||
<td className="py-2 px-2"></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 价值计算说明 */}
|
||||
<Card className="bg-gray-50">
|
||||
<h2 className="text-sm font-medium mb-2">价值计算说明</h2>
|
||||
@@ -290,10 +345,6 @@ export default function AnnualValueReport() {
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-amber-500 mt-1 flex-shrink-0" />
|
||||
<span><b>总价值</b>:规避损失 + 节约成本</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-1.5">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-gray-400 mt-1 flex-shrink-0" />
|
||||
<span><b>ROI</b>:总价值 ÷ 系统年费(¥12,000)× 100%,上限 9999%</span>
|
||||
</div>
|
||||
<div className="flex items-start gap-1.5">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-gray-300 mt-1 flex-shrink-0" />
|
||||
<span><b>法定上限</b>:双倍工资≤11个月(第82条)、经济补偿N≤12个月月薪≤社平3倍(第47条)、违法解除2N≤24个月(第87条)</span>
|
||||
|
||||
Reference in New Issue
Block a user