- ReceiptFolderView 删除票据后提示已关联附件副本保留,接入 useToast;fetchReceiptFolderAsset 加 no-store 避免预览缓存 - PersonalWorkbenchAiMode 附件区/对话气泡适配资产缓存,personal-workbench-ai-mode.css 调整布局 - usePersonalWorkbenchAiMode/useWorkbenchAiApplicationPreviewFlow/useWorkbenchAiAttachmentAssociationFlow/useWorkbenchAiStewardFlow 完善附件草稿选择与关联流程 - travelRequestDetailSmartEntryRecognition 智能识别增强,AppShellRouteView/PersonalWorkbenchView/useApplicationPreviewEditor/useTravelReimbursementSubmitComposer 等配套适配 - 新增 expense-attachment-draft-selection、receipt-folder-asset-cache、travel-request-detail-smart-entry-recognition 测试,更新 attachment-association-confirmation、expense-application-fast-preview、workbench-ai-mode-switch 测试
91 lines
3.2 KiB
JavaScript
91 lines
3.2 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import test from 'node:test'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
import { useTravelReimbursementCreateViewControls } from '../src/views/scripts/useTravelReimbursementCreateViewControls.js'
|
|
|
|
function ref(value) {
|
|
return { value }
|
|
}
|
|
|
|
const submitComposerScript = readFileSync(
|
|
fileURLToPath(new URL('../src/views/scripts/useTravelReimbursementSubmitComposer.js', import.meta.url)),
|
|
'utf8'
|
|
)
|
|
|
|
test('选择候选草稿时直接确认归集并带入附件原件', async () => {
|
|
const submitCalls = []
|
|
const attachedFiles = [{ name: '2月20 武汉-上海.pdf' }]
|
|
const message = {
|
|
queryPayload: {
|
|
selectionMode: 'draft_association'
|
|
}
|
|
}
|
|
|
|
const controls = useTravelReimbursementCreateViewControls({
|
|
activeSessionType: ref('expense'),
|
|
attachedFiles: ref(attachedFiles),
|
|
clearAssistantSessionSnapshot: () => {},
|
|
closeAfterBusy: ref(false),
|
|
conversationId: ref('conversation-1'),
|
|
deleteConversation: async () => {},
|
|
deleteSessionBusy: ref(false),
|
|
deleteSessionDialogOpen: ref(false),
|
|
draftClaimId: ref(''),
|
|
emitClose: () => {},
|
|
getExpenseQueryActivePage: () => 1,
|
|
getExpenseQueryTotalPages: () => 1,
|
|
persistSessionState: () => {},
|
|
resetCurrentSessionState: () => {},
|
|
reviewActionBusy: ref(false),
|
|
router: { push: () => {} },
|
|
resolveCurrentUserId: () => 'user-1',
|
|
sessionSwitchBusy: ref(false),
|
|
submitComposer: async (options) => {
|
|
submitCalls.push(options)
|
|
return { ok: true }
|
|
},
|
|
submitting: ref(false),
|
|
toast: () => {},
|
|
workbenchVisible: ref(true)
|
|
})
|
|
|
|
await controls.handleExpenseQueryRecordClick(message, {
|
|
claimId: 'claim-1',
|
|
claimNo: 'R74CB7C2R'
|
|
})
|
|
|
|
assert.equal(submitCalls.length, 1)
|
|
assert.equal(submitCalls[0].associationConfirmed, true)
|
|
assert.equal(submitCalls[0].skipDraftAssociationPrompt, true)
|
|
assert.equal(submitCalls[0].uploadDisposition, 'continue_existing')
|
|
assert.deepEqual(submitCalls[0].files, attachedFiles)
|
|
assert.equal(submitCalls[0].files[0], attachedFiles[0])
|
|
assert.equal(submitCalls[0].extraContext.review_action, 'link_to_existing_draft')
|
|
assert.equal(submitCalls[0].extraContext.attachment_association_confirmed, true)
|
|
assert.equal(submitCalls[0].extraContext.draft_claim_id, 'claim-1')
|
|
assert.equal(message.queryPayload.selectionLocked, true)
|
|
assert.equal(message.queryPayload.selectedClaimId, 'claim-1')
|
|
})
|
|
|
|
test('确认归集到现有草稿时先同步附件再渲染最终结果', () => {
|
|
assert.match(
|
|
submitComposerScript,
|
|
/let attachmentSyncCompleted = false/
|
|
)
|
|
assert.match(
|
|
submitComposerScript,
|
|
/if \(\s*reviewActionResult === 'link_to_existing_draft'[\s\S]*await persistComposerFilesToDraft\(\)[\s\S]*attachmentSyncCompleted = true[\s\S]*\}/
|
|
)
|
|
assert.ok(
|
|
submitComposerScript.indexOf('await persistComposerFilesToDraft()') <
|
|
submitComposerScript.indexOf('const assistantMessage = createMessage('),
|
|
'附件同步应先于最终助手消息,避免详情页先展示空明细和旧风险'
|
|
)
|
|
assert.match(
|
|
submitComposerScript,
|
|
/if \(!attachmentSyncCompleted\) \{\s*const persistTask = persistComposerFilesToDraft\(\)/
|
|
)
|
|
})
|