fix(signing): 回写阶段同样归一性别展示避免覆盖

This commit is contained in:
yelan
2026-10-07 20:00:56 +08:00
parent d835c869e2
commit 2458624491
3 changed files with 30 additions and 12 deletions
@@ -34,6 +34,7 @@ import {
type SigningSignatureRequest, type SigningSignatureRequest,
} from '@/utils/signing-document' } from '@/utils/signing-document'
import { ensureDocumentPaperStyle } from '@/utils/document-paper' import { ensureDocumentPaperStyle } from '@/utils/document-paper'
import { normalizeDisplayAnswers } from '@/utils/signing-fields'
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@@ -181,7 +182,9 @@ function applyStoredValues() {
applySelectedItemsToRoot(container, props.selectedItems ?? []) applySelectedItemsToRoot(container, props.selectedItems ?? [])
const answers: SigningAnswers = { ...(props.fieldAnswers ?? {}) } // 回写同样要过展示归一:这一步会把已固化的 fieldAnswers 同步进 DOM,
// 拿原始值(HIS 的 MALE)写就等于把渲染阶段的归一又盖回去了
const answers: SigningAnswers = normalizeDisplayAnswers({ ...(props.fieldAnswers ?? {}) })
if (props.signatureDataUrl && !answers.signature) { if (props.signatureDataUrl && !answers.signature) {
answers.signature = props.signatureDataUrl answers.signature = props.signatureDataUrl
+6 -11
View File
@@ -27,7 +27,7 @@ import {
collectStructuredFieldIds, collectStructuredFieldIds,
FIELD_ELEMENT_SELECTOR, FIELD_ELEMENT_SELECTOR,
FIELD_TOKEN_OPEN, FIELD_TOKEN_OPEN,
normalizeSexLabel, normalizeDisplayAnswers,
PRIMARY_SIGNATURE_FIELD_ID, PRIMARY_SIGNATURE_FIELD_ID,
readFieldFromElement, readFieldFromElement,
resolveAnswersFromSystem, resolveAnswersFromSystem,
@@ -770,18 +770,13 @@ export function buildSigningDocumentHtml(
// 「编辑器里撑满版心、预览/签署里按内容收缩」。详见 utils/rich-text 的 unlockTableLayout。 // 「编辑器里撑满版心、预览/签署里按内容收缩」。详见 utils/rich-text 的 unlockTableLayout。
unlockTableLayout(root) unlockTableLayout(root)
// 已填写的取值优先于系统快照:签署后被固化的填写项要保持原样回显 // 已填写的取值优先于系统快照:签署后被固化的填写项要保持原样回显。
const answers: SigningAnswers = { // 合并之后再按展示口径归一(性别:HIS 的 MALE / FEMALE → 男 / 女)——
// 后端的填写结果会盖掉患者快照那一路的归一值,所以只能在这里收口一次。
const answers: SigningAnswers = normalizeDisplayAnswers({
...resolveAnswersFromSystem(data), ...resolveAnswersFromSystem(data),
...(data.fieldAnswers ?? {}), ...(data.fieldAnswers ?? {}),
} })
// 性别在文书上必须落成中文:后端的填写结果里可能是 HIS 的英文枚举(MALE / FEMALE),
// 它会盖掉患者快照那一路的归一值,所以只在两路合并之后收口一次 ——
// 不这样做的话,工作台列表显示「男」、点开文书却是「MALE」。
if (typeof answers.sex === 'string') {
answers.sex = normalizeSexLabel(answers.sex)
}
if (data.signatureDataUrl && !answers.signature) { if (data.signatureDataUrl && !answers.signature) {
answers.signature = data.signatureDataUrl answers.signature = data.signatureDataUrl
+20
View File
@@ -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。 */ /** 把患者/就诊快照映射成填写项初值,字段键即 SIGNING_FIELD_PRESETS 的 id。 */
export function resolveAnswersFromSystem(snapshot: SigningSystemSnapshot): SigningAnswers { export function resolveAnswersFromSystem(snapshot: SigningSystemSnapshot): SigningAnswers {
return { return {