feat: 完成前端业务闭环与后端联调

This commit is contained in:
2026-08-24 23:37:56 +08:00
parent c59e36f933
commit 9ad572907b
175 changed files with 10711 additions and 1740 deletions
+83 -1
View File
@@ -1,6 +1,7 @@
import { normalizeOptionalSafeInteger } from './request-normalizers.js'
import { createRequestError } from './request-client.js'
import { LINEAGE_PERSON_OPTIONS } from './lineage-person-options.js'
import { normalizeBusinessOptionProjection } from './business-dictionary-contract.js'
const optionLabels = (options) => Object.freeze(
Object.fromEntries(options.map(({ value, label }) => [value, label]))
@@ -89,14 +90,47 @@ export const normalizeLineagePersonDetail = (value, expectedGenealogyId, expecte
}
const personNo = normalizeLineagePersonText(value.personNo, '人物编号')
const generationName = normalizeLineagePersonText(value.generationName, '字辈')
const aliasName = normalizeLineagePersonText(value.aliasName, '别名或曾用名')
const courtesyName = normalizeLineagePersonText(value.courtesyName, '表字')
const aliasName = normalizeLineagePersonText(value.aliasName, '别号或曾用名')
const avatarOssId = normalizeOptionalLineagePersonIdentity(value.avatarOssId, '头像文件标识')
const birthDate = normalizeLineagePersonDate(value.birthDate, '出生日期')
const deathDate = normalizeLineagePersonDate(value.deathDate, '逝世日期')
const birthLunar = normalizeLineagePersonText(value.birthLunar, '出生农历')
const deathLunar = normalizeLineagePersonText(value.deathLunar, '逝世农历')
const birthPlace = normalizeLineagePersonText(value.birthPlace, '出生地')
const zodiacOption = normalizeBusinessOptionProjection(
value.zodiacCode,
value.zodiacLabel,
value.zodiacOptionState,
'成员生肖',
'LINEAGE_PERSON_RESPONSE_INVALID'
)
const currentAddress = normalizeLineagePersonText(value.currentAddress, '现居地')
const mobile = normalizeLineagePersonText(value.mobile, '联系电话')
const email = normalizeLineagePersonText(value.email, '电子邮箱')
const educationOption = normalizeBusinessOptionProjection(
value.educationCode,
value.educationLabel,
value.educationOptionState,
'成员学历分类',
'LINEAGE_PERSON_RESPONSE_INVALID'
)
const occupation = normalizeLineagePersonText(value.occupation, '职业')
const deathAge = value.deathAge === undefined || value.deathAge === null
? null
: normalizeOptionalSafeInteger(value.deathAge, '人物享年')
if (deathAge !== null && (deathAge < 0 || deathAge > 200)) {
throw lineagePersonError('成员详情享年无效')
}
const deathPlace = normalizeLineagePersonText(value.deathPlace, '逝世地')
const deathExpressionOption = normalizeBusinessOptionProjection(
value.deathExpressionCode,
value.deathExpressionLabel,
value.deathExpressionOptionState,
'成员逝世表述',
'LINEAGE_PERSON_RESPONSE_INVALID'
)
const burialDate = normalizeLineagePersonDate(value.burialDate, '安葬日期')
const burialPlace = normalizeLineagePersonText(value.burialPlace, '安葬地')
const spouseNames = normalizeLineageSpouseNames(value.spouseNames)
const personStatus = normalizeLineagePersonText(value.personStatus, '人物状态')
@@ -107,6 +141,10 @@ export const normalizeLineagePersonDetail = (value, expectedGenealogyId, expecte
const deathLunarLabel = normalizeLineagePersonDictionaryLabel(deathLunar, '逝世农历', LINEAGE_BOOLEAN_LABELS)
const biography = normalizeLineagePersonText(value.biography, '生平')
const remark = normalizeLineagePersonText(value.remark, '备注')
const canManageSensitiveMedicalHistory = value.canManageSensitiveMedicalHistory === true
if (value.canManageSensitiveMedicalHistory !== undefined && typeof value.canManageSensitiveMedicalHistory !== 'boolean') {
throw lineagePersonError('成员详情敏感病史权限无效')
}
const relationName = normalizeLineagePersonText(value.relationName, '关系显示名称')
for (const field of ['canDisable', 'canCreateDocument', 'canManageDocuments']) {
if (value[field] !== undefined && typeof value[field] !== 'boolean') {
@@ -140,6 +178,7 @@ export const normalizeLineagePersonDetail = (value, expectedGenealogyId, expecte
appUserId,
bindingMode,
personNo,
courtesyName,
aliasName,
generation: value.generation,
generationName,
@@ -158,13 +197,29 @@ export const normalizeLineagePersonDetail = (value, expectedGenealogyId, expecte
deathLunarLabel,
years: birthDate || deathDate ? `${birthDate}${deathDate}` : '生卒待补',
birthplace: birthPlace,
zodiac: zodiacOption.label,
zodiacCode: zodiacOption.value,
zodiacOptionState: zodiacOption.state,
currentAddress,
mobile,
email,
education: educationOption.label,
educationCode: educationOption.value,
educationOptionState: educationOption.state,
occupation,
deathAge,
deathPlace,
deathType: deathExpressionOption.label,
deathExpressionCode: deathExpressionOption.value,
deathExpressionOptionState: deathExpressionOption.state,
burialDate,
burialPlace,
spouseNames,
personStatus,
personStatusLabel,
biography,
remark,
canManageSensitiveMedicalHistory,
relationName,
sortOrder,
status: personStatus === '1' ? 'deceased' : 'normal',
@@ -176,6 +231,33 @@ export const normalizeLineagePersonDetail = (value, expectedGenealogyId, expecte
}
}
export const normalizeLineageSensitiveProfile = (value, expectedPersonId) => {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw lineagePersonError('成员敏感健康资料响应不是对象')
}
const personId = normalizeLineagePersonIdentity(value.personId, '敏感健康资料人物标识')
if (personId !== expectedPersonId) {
throw lineagePersonError('成员敏感健康资料响应标识与请求不匹配')
}
if (typeof value.present !== 'boolean' || typeof value.canManage !== 'boolean') {
throw lineagePersonError('成员敏感健康资料状态无效')
}
const hereditaryMedicalHistory = normalizeLineagePersonText(
value.hereditaryMedicalHistory,
'遗传病史'
)
if (!value.present && hereditaryMedicalHistory) {
throw lineagePersonError('成员敏感健康资料状态与正文不一致')
}
return {
personId,
hereditaryMedicalHistory,
present: value.present,
canManage: value.canManage,
updatedAt: normalizeLineagePersonText(value.updatedAt, '敏感健康资料更新时间')
}
}
export const normalizeLineagePersonPage = (value, expectedGenealogyId) => {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw lineagePersonError('成员分页响应不是对象')