feat(web): AI 文档详情引用解析与查询卡片增强

- 新增 aiDocumentDetailReference,统一解析 #ai-open-document-detail / #ai-open-application-detail 引用,兼容 A/R/D 短格式与 AP-/RE-/AD- 旧格式单号,提供 isBusinessDocumentReference 判定
- aiDocumentQueryModel 文档卡片接入详情引用,按申请单/报销单生成对应 href,HTML 渲染器识别单据记录表格并生成卡片链接
- PersonalWorkbenchAiMode 处理文档详情点击跳转,卡片样式重构为结构化布局并更新背景资源
- expenseApplicationPreview 补充事由字段,同步新增/更新 ai-document-detail-reference、document-query-model、html-renderer、workbench-ai-mode 等测试
- 更新公司通信费报销规则表
This commit is contained in:
caoxiaozhu
2026-06-21 22:49:53 +08:00
parent 3b74a330a3
commit 8b3495455b
15 changed files with 832 additions and 318 deletions

View File

@@ -84,7 +84,10 @@ test('AI mode handles document query prompts locally before steward planning', (
assert.match(aiMode, /async function handleAiDocumentQueryIntent/)
assert.match(aiMode, /buildAiDocumentQueryConditionSummary/)
assert.match(aiMode, /filterAiDocumentQueryRecords\(payload, intent\)/)
assert.match(aiMode, /mergeAiDocumentQueryPayloads/)
assert.match(aiMode, /fetchApprovalExpenseClaims/)
assert.match(aiMode, /Promise\.all\(\[/)
assert.match(aiMode, /fetchAiDocumentQueryPayload\(intent\)/)
assert.match(aiMode, /buildAiDocumentQueryMessage/)
assert.match(aiMode, /AI_DOCUMENT_QUERY_STEP_DELAY_MS/)
assert.match(aiMode, /async function updateAiDocumentQueryThinking/)
@@ -149,6 +152,16 @@ test('AI mode handles application preview save and submit through buttons or tex
assert.match(aiMode, /#ai-open-application-detail:/)
})
test('AI mode keeps missing application fields editable in the preview table without quick template action', () => {
assert.match(aiMode, /function buildInlineApplicationPreviewSuggestedActions\(applicationPreview = \{\}, draftPayload = null\)/)
assert.match(aiMode, /label:\s*'保存草稿'/)
assert.match(aiMode, /function handleInlineApplicationPreviewTextAction\(prompt\)/)
assert.doesNotMatch(aiMode, /label:\s*'快速模板'/)
assert.doesNotMatch(aiMode, /action_type:\s*'prefill_composer'/)
assert.doesNotMatch(aiMode, /buildInlineApplicationPreviewTemplatePrefill/)
assert.doesNotMatch(aiMode, /applyInlineApplicationPreviewTemplateText/)
})
test('AI mode waits for submit confirmation before adding submit action to the conversation', () => {
const executeStart = aiMode.indexOf('async function executeInlineApplicationPreviewAction')
const executeEnd = aiMode.indexOf('\nfunction handleInlineApplicationPreviewTextAction', executeStart)
@@ -179,8 +192,14 @@ test('AI mode waits for submit confirmation before adding submit action to the c
test('AI mode formats saved application draft as a detail table without continuing submit flow', () => {
assert.match(aiMode, /function buildInlineApplicationResultTable\(draftPayload = \{\}, options = \{\}\)/)
assert.match(aiMode, /\| 单据类型 \| 单据编号 \| 单据状态 \| 当前节点 \| 操作 \|/)
assert.match(aiMode, /function normalizeInlineApplicationStatusLabel\(value, fallback = ''\)/)
assert.match(aiMode, /submitted:\s*'审批中'/)
assert.match(aiMode, /const statusLabel = normalizeInlineApplicationStatusLabel\(info\.statusLabel, options\.statusLabel\)/)
assert.match(aiMode, /\| 单据类型 \| 单据编号 \| 单据状态 \| 当前节点 \| 日期 \| 地点 \| 事由 \| 金额 \| 操作 \|/)
assert.match(aiMode, /\[查看\]\(\$\{href\}\)/)
assert.match(aiMode, /dateLabel:\s*rangeText \|\| dateText \|\| resolveBodyField\(\['时间', '日期', '申请时间'\]\) \|\| '待补充'/)
assert.match(aiMode, /locationLabel:[\s\S]*resolveBodyField\(\['地点', '目的地'\]\) \|\| '待补充'/)
assert.match(aiMode, /reasonLabel:[\s\S]*resolveBodyField\(\['事由', '事件', '申请事由'\]\) \|\| '待补充'/)
assert.match(aiMode, /buildInlineApplicationActionDetailHref\(info\)/)
assert.match(aiMode, /params\.set\('claim_id', claimId\)/)
assert.match(aiMode, /params\.set\('claim_no', claimNo\)/)