feat(签署文书): 通用文本项按出现位置独立成项并插入文本框占位符
This commit is contained in:
@@ -18,11 +18,10 @@
|
||||
import type { SigningAnswers, SigningFieldDef, SigningFieldKind } from '@/api/workbench/types'
|
||||
|
||||
import {
|
||||
createFieldTokenPattern,
|
||||
FIELD_TOKEN_OPEN,
|
||||
PRIMARY_SIGNATURE_FIELD_ID,
|
||||
resolveAnswersFromSystem,
|
||||
resolveFieldByLabel,
|
||||
scanFieldTokens,
|
||||
SIGNING_DOCUMENT_HEADER,
|
||||
SIGNING_OPTION_MARKERS,
|
||||
type SigningSystemSnapshot,
|
||||
@@ -260,6 +259,11 @@ function buildFieldControl(
|
||||
* 占位符渲染:把 {患者姓名} 就地替换成填写项控件,保留同一文本节点内的前后文字。
|
||||
* 模板未收录的占位符按自定义文本项处理,仍可在文书上填写,
|
||||
* 避免出现"写了占位符但签署时既填不上也看不见"的情况。
|
||||
*
|
||||
* 解析统一走 scanFieldTokens,且计数器跨文本节点共用一个:
|
||||
* 自定义文本项靠"同名占位符第几次出现"编号,这里数出的序号必须和
|
||||
* 填写项统计(collectFieldDefs)数出来的完全一致,否则同一处内容
|
||||
* 在面板里是一个字段键、落到 DOM 上是另一个,取值就悄悄对不上了。
|
||||
*/
|
||||
function renderTokenFields(
|
||||
root: Element,
|
||||
@@ -270,6 +274,7 @@ function renderTokenFields(
|
||||
const doc = root.ownerDocument
|
||||
const walker = doc.createTreeWalker(root, NodeFilter.SHOW_TEXT)
|
||||
const targets: Text[] = []
|
||||
const counters = new Map<string, number>()
|
||||
let node = walker.nextNode()
|
||||
|
||||
while (node) {
|
||||
@@ -282,28 +287,18 @@ function renderTokenFields(
|
||||
|
||||
targets.forEach((textNode) => {
|
||||
const text = textNode.textContent ?? ''
|
||||
const pattern = createFieldTokenPattern()
|
||||
const fragment = doc.createDocumentFragment()
|
||||
let cursor = 0
|
||||
let match: RegExpExecArray | null
|
||||
|
||||
while ((match = pattern.exec(text)) !== null) {
|
||||
if (match.index > cursor) {
|
||||
fragment.appendChild(doc.createTextNode(text.slice(cursor, match.index)))
|
||||
scanFieldTokens(text, counters).forEach(({ start, end, field }) => {
|
||||
if (start > cursor) {
|
||||
fragment.appendChild(doc.createTextNode(text.slice(cursor, start)))
|
||||
}
|
||||
|
||||
fragment.appendChild(
|
||||
buildFieldWidget(
|
||||
doc,
|
||||
resolveFieldByLabel(match[1] ?? ''),
|
||||
answers,
|
||||
interactive,
|
||||
signatureActionable,
|
||||
),
|
||||
)
|
||||
fragment.appendChild(buildFieldWidget(doc, field, answers, interactive, signatureActionable))
|
||||
|
||||
cursor = pattern.lastIndex
|
||||
}
|
||||
cursor = end
|
||||
})
|
||||
|
||||
if (cursor < text.length) {
|
||||
fragment.appendChild(doc.createTextNode(text.slice(cursor)))
|
||||
|
||||
Reference in New Issue
Block a user