fix: 修复首页数据不一致 — 1)风险分布用去重数据 2)无工资数据时不估算社保 3)TaskCenter显示全部待办不再截取10条 4)修复dedupedTodos引用顺序

This commit is contained in:
selfrelease
2026-08-01 07:53:30 +08:00
parent aef45c066e
commit d64f9c41a6
3 changed files with 12 additions and 12 deletions
+1 -2
View File
@@ -246,11 +246,10 @@ router.get('/workspace/next-actions', authMiddleware, async (req: AuthRequest, r
const now = new Date() const now = new Date()
const in30Days = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000) const in30Days = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)
// 1. 待办风险项 // 1. 待办风险项(全部)
const riskItems = await prisma.riskItem.findMany({ const riskItems = await prisma.riskItem.findMany({
where: { orgId, status: 'PENDING' }, where: { orgId, status: 'PENDING' },
orderBy: { createdAt: 'desc' }, orderBy: { createdAt: 'desc' },
take: 10,
select: { id: true, title: true, type: true, level: true, deadline: true, actionUrl: true, employeeId: true }, select: { id: true, title: true, type: true, level: true, deadline: true, actionUrl: true, employeeId: true },
}) })
+9 -8
View File
@@ -692,8 +692,8 @@ export async function getDashboardData(orgId: string) {
socialEmpTotal = totalSocialEmp socialEmpTotal = totalSocialEmp
housingOrgTotal = totalHousingOrg housingOrgTotal = totalHousingOrg
housingEmpTotal = totalHousingEmp housingEmpTotal = totalHousingEmp
} else if (socialConfig && employeeCount > 0) { } else if (socialConfig && employeeCount > 0 && payslips.length > 0) {
// 用平均工资作为估算基数 // 用平均工资作为估算基数(仅当有工资条数据时才估算)
const avgBase = employeeCount > 0 ? Math.max(socialConfig.baseMin, Math.min(socialConfig.baseMax, totalBaseSalary / Math.max(employeeCount, 1))) : socialConfig.baseMin const avgBase = employeeCount > 0 ? Math.max(socialConfig.baseMin, Math.min(socialConfig.baseMax, totalBaseSalary / Math.max(employeeCount, 1))) : socialConfig.baseMin
socialOrgTotal = avgBase * (socialConfig.pensionOrg + socialConfig.medicalOrg + socialConfig.unemploymentOrg + socialConfig.injuryOrg + socialConfig.maternityOrg) / 100 * employeeCount socialOrgTotal = avgBase * (socialConfig.pensionOrg + socialConfig.medicalOrg + socialConfig.unemploymentOrg + socialConfig.injuryOrg + socialConfig.maternityOrg) / 100 * employeeCount
socialEmpTotal = avgBase * (socialConfig.pensionEmp + socialConfig.medicalEmp + socialConfig.unemploymentEmp) / 100 * employeeCount socialEmpTotal = avgBase * (socialConfig.pensionEmp + socialConfig.medicalEmp + socialConfig.unemploymentEmp) / 100 * employeeCount
@@ -773,12 +773,6 @@ export async function getDashboardData(orgId: string) {
orgTotalCost: yearTotalPay + yearSocialOrg + yearHousingOrg + yearOvertimePay + yearSeverance, orgTotalCost: yearTotalPay + yearSocialOrg + yearHousingOrg + yearOvertimePay + yearSeverance,
} }
const riskDistribution = {
contract: riskItems.filter((r: typeof riskItems[number]) => r.type === 'CONTRACT').length,
salary: riskItems.filter((r: typeof riskItems[number]) => r.type === 'SALARY').length,
termination: riskItems.filter((r: typeof riskItems[number]) => r.type === 'TERMINATION').length,
}
// 为所有风险项计算优先级和量化信息 // 为所有风险项计算优先级和量化信息
const todosWithCost = riskItems.map((r: typeof riskItems[number]) => { const todosWithCost = riskItems.map((r: typeof riskItems[number]) => {
const estimatedLoss = r.estimatedLoss || 0 const estimatedLoss = r.estimatedLoss || 0
@@ -832,6 +826,13 @@ export async function getDashboardData(orgId: string) {
} }
const dedupedTodos = Array.from(dedupedTodoMap.values()) const dedupedTodos = Array.from(dedupedTodoMap.values())
// 风险分布:使用去重后的数据,与待办列表一致
const riskDistribution = {
contract: dedupedTodos.filter((t) => t.type === 'CONTRACT').length,
salary: dedupedTodos.filter((t) => t.type === 'SALARY').length,
termination: dedupedTodos.filter((t) => t.type === 'TERMINATION').length,
}
// 按优先级排序:URGENT > HIGH > MEDIUM > LOW // 按优先级排序:URGENT > HIGH > MEDIUM > LOW
const priorityOrder = { URGENT: 0, HIGH: 1, MEDIUM: 2, LOW: 3 } const priorityOrder = { URGENT: 0, HIGH: 1, MEDIUM: 2, LOW: 3 }
todosWithCost.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]) todosWithCost.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority])
+2 -2
View File
@@ -102,8 +102,8 @@ export function TaskCenter() {
<span className="text-xs text-ink-400">({group.items.length})</span> <span className="text-xs text-ink-400">({group.items.length})</span>
</div> </div>
{/* 行动项列表 */} {/* 行动项列表 */}
<div className="space-y-1 ml-5"> <div className="space-y-1 ml-5 max-h-60 overflow-y-auto">
{group.items.slice(0, 5).map((item) => ( {group.items.map((item) => (
<Link <Link
key={item.id} key={item.id}
to={item.link} to={item.link}