fix: 花名册合同风险统计与风险中心不一致

花名册快捷筛选标签基于当前页数据统计,改为后端返回全局RiskItem统计
- 后端roster API返回globalRiskStats(expiring/expired/unsigned)
- 前端优先使用全局统计,fallback到当前页统计
This commit is contained in:
selfrelease
2026-08-01 14:41:45 +08:00
parent e8690d4fbb
commit 31a25a7320
2 changed files with 17 additions and 2 deletions
+12
View File
@@ -210,6 +210,13 @@ router.get('/', authMiddleware, async (req: AuthRequest, res, next) => {
result = result.slice(skip, skip + pageSize) result = result.slice(skip, skip + pageSize)
} }
// 全局合同风险统计(基于 RiskItem,与风险中心同口径)
const [globalExpiring, globalExpired, globalUnsigned] = await Promise.all([
prisma.riskItem.count({ where: { orgId: req.user!.orgId, status: 'PENDING', type: 'CONTRACT', level: 'MEDIUM' } }),
prisma.riskItem.count({ where: { orgId: req.user!.orgId, status: 'PENDING', type: 'CONTRACT', level: 'HIGH' } }),
prisma.riskItem.count({ where: { orgId: req.user!.orgId, status: 'PENDING', type: 'ONBOARDING' } }),
])
res.json({ res.json({
success: true, success: true,
data: result, data: result,
@@ -219,6 +226,11 @@ router.get('/', authMiddleware, async (req: AuthRequest, res, next) => {
total: filteredTotal, total: filteredTotal,
totalPages: Math.ceil(filteredTotal / pageSize), totalPages: Math.ceil(filteredTotal / pageSize),
}, },
globalRiskStats: {
expiring: globalExpiring,
expired: globalExpired,
unsigned: globalUnsigned,
},
}) })
} catch (err) { } catch (err) {
next(err) next(err)
+5 -2
View File
@@ -235,14 +235,17 @@ export default function Roster() {
const hasActiveFilters = search || filterStatus || filterContractStatus || filterDepartment const hasActiveFilters = search || filterStatus || filterContractStatus || filterDepartment
/** 计算合同风险统计(基于当前页数据 */ /** 全局合同风险统计(来自后端,与风险中心同口径 */
const globalRiskStats = rosterData?.globalRiskStats
const riskStats = useMemo(() => { const riskStats = useMemo(() => {
if (globalRiskStats) return globalRiskStats
// fallback: 当前页统计
const expiring = employees.filter((e: any) => e.contractStatus === 'expiring').length const expiring = employees.filter((e: any) => e.contractStatus === 'expiring').length
const expired = employees.filter((e: any) => e.contractStatus === 'expired').length const expired = employees.filter((e: any) => e.contractStatus === 'expired').length
const unsigned = employees.filter((e: any) => ['unsigned', 'unsigned_over_30', 'unsigned_over_year'].includes(e.contractStatus)).length const unsigned = employees.filter((e: any) => ['unsigned', 'unsigned_over_30', 'unsigned_over_year'].includes(e.contractStatus)).length
const probation = employees.filter((e: any) => e.probationInfo?.isProbation && e.probationInfo?.isExpiring).length const probation = employees.filter((e: any) => e.probationInfo?.isProbation && e.probationInfo?.isExpiring).length
return { expiring, expired, unsigned, probation } return { expiring, expired, unsigned, probation }
}, [employees]) }, [globalRiskStats, employees])
/** 快捷筛选标签 */ /** 快捷筛选标签 */
const quickFilters = [ const quickFilters = [