fix: AI身份证不脱敏+优化员工端登录页UI

- AI读取身份证改为解密明文,不再脱敏,确保生日等信息正确
- 员工端登录页优化:渐变背景、图标输入框、圆角Tab、loading动画、回车登录
This commit is contained in:
freedakgmail
2026-08-17 18:40:27 +08:00
parent c6e2dbf5b7
commit f2a8f9a97c
2 changed files with 106 additions and 47 deletions
+10 -11
View File
@@ -78,15 +78,14 @@ function daysFromNow(date: Date): number {
}
/**
* 脱敏身份证号:保留前6位和后4位,中间用 * 代替
* 例:310101199001011234 → 310101********1234
* 解密身份证号(不脱敏,AI 需要完整身份证号来正确读取生日等信息)
*/
function maskIdCard(encrypted: string | null): string {
function decryptIdCard(encrypted: string | null): string {
if (!encrypted) return '未登记'
try {
const plain = decrypt(encrypted)
if (plain && plain.length >= 10) {
return plain.slice(0, 6) + '********' + plain.slice(-4)
return plain
}
return '未登记'
} catch {
@@ -115,7 +114,7 @@ async function buildOrgContext(orgId: string): Promise<string> {
if (e.isPregnant) specialStatus.push('孕期/哺乳期')
if (e.isInMedicalPeriod) specialStatus.push('医疗期')
if (e.isWorkInjured) specialStatus.push('工伤')
return `- ${e.name}(身份证:${maskIdCard(e.idCardNumber)}${e.department}),入职${e.hireDate.toISOString().slice(0, 10)}(已工作${tenure}),${contract ? `合同:${contract.contractType}${contract.endDate ? `到期${contract.endDate.toISOString().slice(0, 10)}(剩余${daysToExpire}天)` : '无固定期限'}` : '未签合同'}${specialStatus.length > 0 ? `,特殊状态:${specialStatus.join('/')}` : ''}`
return `- ${e.name}(身份证:${decryptIdCard(e.idCardNumber)}${e.department}),入职${e.hireDate.toISOString().slice(0, 10)}(已工作${tenure}),${contract ? `合同:${contract.contractType}${contract.endDate ? `到期${contract.endDate.toISOString().slice(0, 10)}(剩余${daysToExpire}天)` : '无固定期限'}` : '未签合同'}${specialStatus.length > 0 ? `,特殊状态:${specialStatus.join('/')}` : ''}`
}).join('\n')
const riskSummary = risks.map((r) => `- ${r.title}${r.level}):${r.description || '无详细描述'}`).join('\n')
@@ -265,17 +264,17 @@ router.get('/predict', authMiddleware, async (req: AuthRequest, res, next) => {
orgContext = `当前日期:${new Date().toISOString().slice(0, 10)}
员工详情:
- 姓名:${emp.name}
- 身份证号:${maskIdCard(emp.idCardNumber)}
- 身份证号:${decryptIdCard(emp.idCardNumber)}
- 部门:${emp.department}
- 入职日期:${emp.hireDate.toISOString().slice(0, 10)}(已工作${tenure}
- 状态:${emp.status}
- 特殊状态:${[emp.isPregnant && '孕期/哺乳期', emp.isInMedicalPeriod && '医疗期', emp.isWorkInjured && '工伤'].filter(Boolean).join('、') || '无'}
- 合同:${contract ? `${contract.contractType}${contract.startDate.toISOString().slice(0, 10)}${contract.endDate ? contract.endDate.toISOString().slice(0, 10) : '无固定期限'}${contractDaysLeft !== null ? `(距到期${contractDaysLeft}天)` : ''}` : '未签合同'}${term ? `\n- 离职/解聘记录:${typeMap[term.type] || term.type},原因:${reasonMap[term.reason] || term.reason},离职日期:${term.terminationDate.toISOString().slice(0, 10)},流程状态:${statusMap[term.status] || term.status},经济补偿金:¥${term.compensation.toFixed(2)}${term.resignationReason ? `,离职原因说明:${term.resignationReason}` : ''}${socialInsEnd}${housingFundEnd}${handoverDone ? '工作交接已完成' : '工作交接未完成'}${agreementSigned ? '已签署解除协议' : '未签署解除协议'}` : ''}`
scopeHint = `请只针对员工【${emp.name}(身份证:${maskIdCard(emp.idCardNumber)})】进行风险预测,不要分析其他员工。以上数据中的工龄、天数等均已由系统计算,请直接使用,不要重新计算。`
scopeHint = `请只针对员工【${emp.name}(身份证:${decryptIdCard(emp.idCardNumber)})】进行风险预测,不要分析其他员工。以上数据中的工龄、天数等均已由系统计算,请直接使用,不要重新计算。`
}
} else if (department) {
const employees = await prisma.employee.findMany({ where: { orgId: req.user!.orgId, department, status: 'ACTIVE' }, include: { contracts: { orderBy: { createdAt: 'desc' }, take: 1 } } })
const empSummary = employees.map(e => `- ${e.name}(身份证:${maskIdCard(e.idCardNumber)}),入职${e.hireDate.toISOString().slice(0, 10)}${e.contracts[0] ? e.contracts[0].contractType : '未签合同'}`).join('\n')
const empSummary = employees.map(e => `- ${e.name}(身份证:${decryptIdCard(e.idCardNumber)}),入职${e.hireDate.toISOString().slice(0, 10)}${e.contracts[0] ? e.contracts[0].contractType : '未签合同'}`).join('\n')
orgContext = `部门【${department}】员工列表(${employees.length}人):\n${empSummary}`
scopeHint = `请只针对【${department}】部门的员工进行风险预测,不要分析其他部门的员工。`
}
@@ -324,17 +323,17 @@ router.get('/predict-stream', authMiddleware, async (req: AuthRequest, res, next
orgContext = `当前日期:${new Date().toISOString().slice(0, 10)}
员工详情:
- 姓名:${emp.name}
- 身份证号:${maskIdCard(emp.idCardNumber)}
- 身份证号:${decryptIdCard(emp.idCardNumber)}
- 部门:${emp.department}
- 入职日期:${emp.hireDate.toISOString().slice(0, 10)}(已工作${tenure}
- 状态:${emp.status}
- 特殊状态:${[emp.isPregnant && '孕期/哺乳期', emp.isInMedicalPeriod && '医疗期', emp.isWorkInjured && '工伤'].filter(Boolean).join('、') || '无'}
- 合同:${contract ? `${contract.contractType}${contract.startDate.toISOString().slice(0, 10)}${contract.endDate ? contract.endDate.toISOString().slice(0, 10) : '无固定期限'}${contractDaysLeft !== null ? `(距到期${contractDaysLeft}天)` : ''}` : '未签合同'}${term ? `\n- 离职/解聘记录:${typeMap[term.type] || term.type},原因:${reasonMap[term.reason] || term.reason},离职日期:${term.terminationDate.toISOString().slice(0, 10)},流程状态:${statusMap[term.status] || term.status},经济补偿金:¥${term.compensation.toFixed(2)}${term.resignationReason ? `,离职原因说明:${term.resignationReason}` : ''}${socialInsEnd}${housingFundEnd}${handoverDone ? '工作交接已完成' : '工作交接未完成'}${agreementSigned ? '已签署解除协议' : '未签署解除协议'}` : ''}`
scopeHint = `请只针对员工【${emp.name}(身份证:${maskIdCard(emp.idCardNumber)})】进行风险预测,不要分析其他员工。以上数据中的工龄、天数等均已由系统计算,请直接使用,不要重新计算。`
scopeHint = `请只针对员工【${emp.name}(身份证:${decryptIdCard(emp.idCardNumber)})】进行风险预测,不要分析其他员工。以上数据中的工龄、天数等均已由系统计算,请直接使用,不要重新计算。`
}
} else if (department) {
const employees = await prisma.employee.findMany({ where: { orgId: req.user!.orgId, department, status: 'ACTIVE' }, include: { contracts: { orderBy: { createdAt: 'desc' }, take: 1 } } })
const empSummary = employees.map(e => `- ${e.name}(身份证:${maskIdCard(e.idCardNumber)}),入职${e.hireDate.toISOString().slice(0, 10)}${e.contracts[0] ? e.contracts[0].contractType : '未签合同'}`).join('\n')
const empSummary = employees.map(e => `- ${e.name}(身份证:${decryptIdCard(e.idCardNumber)}),入职${e.hireDate.toISOString().slice(0, 10)}${e.contracts[0] ? e.contracts[0].contractType : '未签合同'}`).join('\n')
orgContext = `部门【${department}】员工列表(${employees.length}人):\n${empSummary}`
scopeHint = `请只针对【${department}】部门的员工进行风险预测,不要分析其他部门的员工。`
}