feat: 系统优化Phase2 - 面包屑导航/侧边栏间距/制度公示阅读签收/模板变量中文化/通知类型补全

- 面包屑导航组件,集成至TopNav header
- 侧边栏菜单分组间距增大,分组间分隔线
- 制度公示员工阅读签收:PolicyReadRecord模型、portal路由、管理端阅读统计
- 修复Policies.tsx民主程序推进bug(字段名/API路径/参数)
- 用工文本模板变量名英文转中文显示
- 通知类型TYPE_LABELS补全(RISK_ALERT/SOCIAL_INS/OVERTIME_ALERT/PAYSLIP_READY)
- 通知示例数据补充
- h2标题统一为text-sm font-medium
- 新增run.md
This commit is contained in:
selfrelease
2026-07-26 20:32:38 +08:00
parent 9cb0d1f63b
commit d79e3baa34
71 changed files with 18561 additions and 3230 deletions
+158 -17
View File
@@ -159,6 +159,12 @@ model Organization {
performanceRecords PerformanceRecord[]
retirementPolicies RetirementPolicy[]
socialMonthlyProcesses SocialMonthlyProcess[]
evidenceChains EvidenceChain[]
attendanceConfirmations AttendanceConfirmation[]
policyDocuments PolicyDocument[]
policyReadRecords PolicyReadRecord[]
healthCheckReports HealthCheckReport[]
annualValueReports AnnualValueReport[]
}
model User {
@@ -231,6 +237,9 @@ model Employee {
housingFundRecords EmployeeHousingFundRecord[]
departmentRecords EmployeeDepartmentRecord[]
aiReviewRecords AIReviewRecord[]
evidenceChains EvidenceChain[]
attendanceConfirmations AttendanceConfirmation[]
policyReadRecords PolicyReadRecord[]
@@unique([orgId, idCardHash])
}
@@ -320,22 +329,28 @@ model TerminationRecord {
}
model RiskItem {
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
employeeId String?
employee Employee? @relation(fields: [employeeId], references: [id], onDelete: SetNull)
type RiskType
level RiskLevel
status RiskStatus @default(PENDING)
title String
description String
actionUrl String?
resolvedAt DateTime?
resolvedBy String?
remark String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
employeeId String?
employee Employee? @relation(fields: [employeeId], references: [id], onDelete: SetNull)
type RiskType
level RiskLevel
status RiskStatus @default(PENDING)
title String
description String
actionUrl String?
// 风险量化:预估损失金额(元)
estimatedLoss Float?
// 风险量化:损失区间 [最低, 最高]
lossRange Json?
// 建议处理截止日期
deadline DateTime?
resolvedAt DateTime?
resolvedBy String?
remark String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([orgId, status])
@@index([orgId, type])
@@ -460,13 +475,16 @@ model EmployeeAttachment {
employeeId String
employee Employee @relation(fields: [employeeId], references: [id], onDelete: Cascade)
fileName String
fileType String // ID_CARD / BANK_CARD / CONTRACT_SCAN / EDUCATION / OTHER
fileType String // ID_CARD / BANK_CARD / CONTRACT_SCAN / EDUCATION / DISCIPLINARY / OTHER
fileUrl String
fileSize Int @default(0)
// 关联违纪记录(可选)
disciplinaryRecordId String?
uploadedBy String
createdAt DateTime @default(now())
@@index([orgId, employeeId])
@@index([disciplinaryRecordId])
}
// ========== 仲裁证据链 ==========
@@ -876,3 +894,126 @@ model RetirementPolicy {
@@index([orgId, createdAt])
}
// ========== 证据链管理 ==========
model EvidenceChain {
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
category String // CONTRACT_SIGN / ONBOARD / PAYSLIP_CONFIRM / DISCIPLINARY / ATTENDANCE / TERMINATION
refId String? // 关联记录 ID(合同ID/工资条ID等)
employeeId String?
employee Employee? @relation(fields: [employeeId], references: [id], onDelete: SetNull)
events Json // [{ action, timestamp, ip, userAgent, smsCode?, location? }]
hash String // 全链路 SHA-256 哈希(防篡改)
createdBy String
createdAt DateTime @default(now())
@@index([orgId, category, refId])
@@index([orgId, employeeId])
}
// ========== 考勤确认 ==========
model AttendanceConfirmation {
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
employeeId String
employee Employee @relation(fields: [employeeId], references: [id], onDelete: Cascade)
month String // YYYY-MM
workDays Int @default(0)
weekdayHours Float @default(0)
weekendHours Float @default(0)
holidayHours Float @default(0)
overtimePay Float @default(0)
confirmedAt DateTime?
confirmIp String?
status String @default("PENDING") // PENDING / CONFIRMED / DISPUTED
disputeNote String? // 员工有异议时的说明
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([orgId, employeeId, month])
@@index([orgId, month])
@@index([orgId, status])
}
// ========== 规章制度民主程序 ==========
model PolicyDocument {
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
title String
content String
type String @default("RULES") // RULES=规章制度 / NOTICE=通知
status String @default("DRAFT") // DRAFT / DISCUSSING / CONSULTING / PUBLISHED
democracyProgress Json? // { currentStep: 1-4, steps: [{ name, status, date, note }] }
publishedAt DateTime?
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
readRecords PolicyReadRecord[]
@@index([orgId, status])
}
// ========== 规章制度阅读签收 ==========
model PolicyReadRecord {
id String @id @default(cuid())
policyId String
policy PolicyDocument @relation(fields: [policyId], references: [id], onDelete: Cascade)
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
employeeId String
employee Employee @relation(fields: [employeeId], references: [id], onDelete: Cascade)
readAt DateTime @default(now())
ip String?
userAgent String?
@@unique([policyId, employeeId])
@@index([orgId, employeeId])
}
// ========== 用工体检诊断报告 ==========
model HealthCheckReport {
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
year Int // 诊断年度
totalScore Int // 综合评分 0-100
level String // safe / warning / danger
dimensions Json // [{ key, name, score, findings: [], recommendations: [] }]
summary String // 诊断总结
createdBy String
createdAt DateTime @default(now())
@@index([orgId, year])
@@index([orgId, createdAt])
}
// ========== 年度价值报告 ==========
model AnnualValueReport {
id String @id @default(cuid())
orgId String
org Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
year Int // 报告年度
totalValue Int // 总价值(元)
roi Float // ROI 百分比
metrics Json // { risksResolved, lossAvoided, aiQueries, contractsReviewed, payrollProcessed, employeesManaged }
timeline Json // [{ month, event, value }] 月度事件时间轴
costSaved Int // 节约成本(元)
timeSaved Int // 节约工时(小时)
summary String // 年度总结
createdBy String
createdAt DateTime @default(now())
@@index([orgId, year])
@@index([orgId, createdAt])
}