From 4eb882b1e2d1d74a8baba0ea011d3a86e86695d6 Mon Sep 17 00:00:00 2001 From: freedakgmail Date: Mon, 17 Aug 2026 19:04:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=88=9B=E5=BB=BA=E5=91=98=E5=B7=A5?= =?UTF-8?q?=E6=97=B6=E4=BB=8E=E8=BA=AB=E4=BB=BD=E8=AF=81=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E6=80=A7=E5=88=AB=E5=92=8C=E5=87=BA=E7=94=9F=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - contract.service.ts createEmployee: gender 为空时从身份证第17位解析,birthDate 从第7-14位提取 - portal.routes.ts GET /profile: gender/birthDate 为空时从身份证 fallback 解析 - gender 统一使用中文 男/女(与数据库和其他服务一致) - 前端 MyProfile.tsx 性别显示适配中文 --- backend/src/routes/portal.routes.ts | 22 ++++++++++++++++++++-- backend/src/services/contract.service.ts | 3 ++- frontend/src/pages/portal/MyProfile.tsx | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/backend/src/routes/portal.routes.ts b/backend/src/routes/portal.routes.ts index c61b87d..f9b0bcd 100644 --- a/backend/src/routes/portal.routes.ts +++ b/backend/src/routes/portal.routes.ts @@ -885,11 +885,29 @@ router.get('/profile', portalAuth, async (req: any, res, next) => { try { if (emp.idCardNumber) idCardNo = decrypt(emp.idCardNumber) } catch {} try { if (emp.bankAccount) bankAccount = decrypt(emp.bankAccount) } catch {} + // 从身份证号解析性别和出生日期(数据库字段为空时) + let gender = emp.gender || '' + let birthDate = emp.birthDate ? emp.birthDate.toISOString().slice(0, 10) : '' + if (idCardNo && idCardNo.length === 18) { + // 第17位:奇数=男,偶数=女 + if (!gender) { + const genderDigit = parseInt(idCardNo[16], 10) + gender = genderDigit % 2 === 1 ? '男' : '女' + } + // 第7-14位:出生日期 YYYYMMDD + if (!birthDate) { + const y = idCardNo.slice(6, 10) + const m = idCardNo.slice(10, 12) + const d = idCardNo.slice(12, 14) + birthDate = `${y}-${m}-${d}` + } + } + res.json({ success: true, data: { name: emp.name, - gender: emp.gender || '', + gender, phone: emp.phone || '', idCardNo, idType: emp.idType || 'ID_CARD', @@ -903,7 +921,7 @@ router.get('/profile', portalAuth, async (req: any, res, next) => { bankName: emp.bankName || '', education: emp.education || '', city: emp.city || '', - birthDate: emp.birthDate ? emp.birthDate.toISOString().slice(0, 10) : '', + birthDate, }, }) } catch (err) { next(err) } diff --git a/backend/src/services/contract.service.ts b/backend/src/services/contract.service.ts index b8bf995..742325f 100644 --- a/backend/src/services/contract.service.ts +++ b/backend/src/services/contract.service.ts @@ -410,12 +410,13 @@ export async function createEmployee(orgId: string, userId: string, data: any) { monthlySalary: encrypt(data.monthlySalary), baseSalary: encrypt(String(baseSalaryNum)), performanceSalary: encrypt(String(performanceSalaryNum)), - gender: data.gender, + gender: data.gender || (data.idCardNumber ? extractGenderFromIdCard(data.idCardNumber) : null), femaleWorkerType: data.femaleWorkerType, phone: data.phone, passwordHash, idCardNumber: data.idCardNumber ? encrypt(data.idCardNumber) : null, idCardHash: data.idCardNumber ? sha256(data.idCardNumber) : null, + birthDate: data.idCardNumber ? extractBirthDateFromIdCard(data.idCardNumber) : null, isPregnant: data.isPregnant || false, isInMedicalPeriod: data.isInMedicalPeriod || false, isWorkInjured: data.isWorkInjured || false, diff --git a/frontend/src/pages/portal/MyProfile.tsx b/frontend/src/pages/portal/MyProfile.tsx index 694bc76..3aba523 100644 --- a/frontend/src/pages/portal/MyProfile.tsx +++ b/frontend/src/pages/portal/MyProfile.tsx @@ -75,7 +75,7 @@ export default function MyProfile() { const readOnlyFields = [ { label: '姓名', value: profile.name, icon: User }, - { label: '性别', value: profile.gender === 'M' ? '男' : profile.gender === 'F' ? '女' : '未填写', icon: User }, + { label: '性别', value: profile.gender === '男' ? '男' : profile.gender === '女' ? '女' : '未填写', icon: User }, { label: '手机号', value: profile.phone || '未填写', icon: Phone }, { label: '证件号码', value: profile.idCardNo || '未填写', icon: IdCard }, { label: '部门', value: profile.department || '未填写', icon: User },