diff --git a/clinical-web/src/components/document/DocumentPaper.vue b/clinical-web/src/components/document/DocumentPaper.vue index a106b8a..b45051c 100644 --- a/clinical-web/src/components/document/DocumentPaper.vue +++ b/clinical-web/src/components/document/DocumentPaper.vue @@ -34,6 +34,7 @@ import { type SigningSignatureRequest, } from '@/utils/signing-document' import { ensureDocumentPaperStyle } from '@/utils/document-paper' +import { normalizeDisplayAnswers } from '@/utils/signing-fields' const props = withDefaults( defineProps<{ @@ -181,7 +182,9 @@ function applyStoredValues() { applySelectedItemsToRoot(container, props.selectedItems ?? []) - const answers: SigningAnswers = { ...(props.fieldAnswers ?? {}) } + // 回写同样要过展示归一:这一步会把已固化的 fieldAnswers 同步进 DOM, + // 拿原始值(HIS 的 MALE)写就等于把渲染阶段的归一又盖回去了 + const answers: SigningAnswers = normalizeDisplayAnswers({ ...(props.fieldAnswers ?? {}) }) if (props.signatureDataUrl && !answers.signature) { answers.signature = props.signatureDataUrl diff --git a/clinical-web/src/utils/signing-document.ts b/clinical-web/src/utils/signing-document.ts index 7c359e2..7ad40fc 100644 --- a/clinical-web/src/utils/signing-document.ts +++ b/clinical-web/src/utils/signing-document.ts @@ -27,7 +27,7 @@ import { collectStructuredFieldIds, FIELD_ELEMENT_SELECTOR, FIELD_TOKEN_OPEN, - normalizeSexLabel, + normalizeDisplayAnswers, PRIMARY_SIGNATURE_FIELD_ID, readFieldFromElement, resolveAnswersFromSystem, @@ -770,18 +770,13 @@ export function buildSigningDocumentHtml( // 「编辑器里撑满版心、预览/签署里按内容收缩」。详见 utils/rich-text 的 unlockTableLayout。 unlockTableLayout(root) - // 已填写的取值优先于系统快照:签署后被固化的填写项要保持原样回显 - const answers: SigningAnswers = { + // 已填写的取值优先于系统快照:签署后被固化的填写项要保持原样回显。 + // 合并之后再按展示口径归一(性别:HIS 的 MALE / FEMALE → 男 / 女)—— + // 后端的填写结果会盖掉患者快照那一路的归一值,所以只能在这里收口一次。 + const answers: SigningAnswers = normalizeDisplayAnswers({ ...resolveAnswersFromSystem(data), ...(data.fieldAnswers ?? {}), - } - - // 性别在文书上必须落成中文:后端的填写结果里可能是 HIS 的英文枚举(MALE / FEMALE), - // 它会盖掉患者快照那一路的归一值,所以只在两路合并之后收口一次 —— - // 不这样做的话,工作台列表显示「男」、点开文书却是「MALE」。 - if (typeof answers.sex === 'string') { - answers.sex = normalizeSexLabel(answers.sex) - } + }) if (data.signatureDataUrl && !answers.signature) { answers.signature = data.signatureDataUrl diff --git a/clinical-web/src/utils/signing-fields.ts b/clinical-web/src/utils/signing-fields.ts index 859bad2..99a6ce9 100644 --- a/clinical-web/src/utils/signing-fields.ts +++ b/clinical-web/src/utils/signing-fields.ts @@ -1077,6 +1077,26 @@ export function normalizeSexLabel(value: string): string { } } +/** + * 文书展示前归一「有固定来源的系统取值」(目前只有性别:HIS 给 MALE / FEMALE,纸上要印男 / 女)。 + * + * 渲染与回写**两条路都必须过这一道**,只用在一处等于没改: + * ① 渲染:buildSigningDocumentHtml 把取值写进生成的 HTML; + * ② 回写:DocumentPaper 的 applyStoredValues 紧接着把已固化的 fieldAnswers 同步进 DOM。 + * 只归一 ① 的话,② 会拿原始值(MALE)把它盖回去 —— 现象就是「代码改了,纸面没变」。 + * + * 取值没变化时返回原对象,避免无谓的对象替换引发重渲染。 + */ +export function normalizeDisplayAnswers(answers: SigningAnswers): SigningAnswers { + if (typeof answers.sex !== 'string') { + return answers + } + + const label = normalizeSexLabel(answers.sex) + + return label === answers.sex ? answers : { ...answers, sex: label } +} + /** 把患者/就诊快照映射成填写项初值,字段键即 SIGNING_FIELD_PRESETS 的 id。 */ export function resolveAnswersFromSystem(snapshot: SigningSystemSnapshot): SigningAnswers { return {