feat: 同步报销流程与工作台改动

This commit is contained in:
caoxiaozhu
2026-06-09 08:32:00 +00:00
parent e124e4bbcb
commit 25724c354f
64 changed files with 6518 additions and 687 deletions

View File

@@ -27,6 +27,10 @@ const appShellComposable = readFileSync(
fileURLToPath(new URL('../src/composables/useAppShell.js', import.meta.url)),
'utf8'
)
const requestsComposable = readFileSync(
fileURLToPath(new URL('../src/composables/useRequests.js', import.meta.url)),
'utf8'
)
const assistantScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/TravelReimbursementCreateView.js', import.meta.url)),
'utf8'
@@ -70,6 +74,47 @@ test('documents center reloads immediately when entered or clicked again', () =>
assert.match(appShellComposable, /reloadDocumentCenterRequests,/)
})
test('documents center uses the full request list instead of the global date-filtered list', () => {
assert.match(
appShellRouteView,
/<DocumentsCenterView[\s\S]*:filtered-requests="requests"[\s\S]*:has-data="requests\.length > 0"/
)
assert.doesNotMatch(
appShellRouteView,
/<DocumentsCenterView[\s\S]*:filtered-requests="filteredRequests"/
)
})
test('workbench summary merges approval inbox requests without polluting document center rows', () => {
assert.match(appShellComposable, /import \{ fetchAllApprovalExpenseClaims, fetchExpenseClaimDetail \} from '\.\.\/services\/reimbursements\.js'/)
assert.match(appShellComposable, /const workbenchApprovalRequests = ref\(\[\]\)/)
assert.match(appShellComposable, /async function reloadWorkbenchApprovalRequests\(\)/)
assert.match(appShellComposable, /async function reloadWorkbenchRequests\(\)/)
assert.match(appShellComposable, /fetchAllApprovalExpenseClaims\(\)/)
assert.match(appShellComposable, /payload\.map\(\(item\) => mapExpenseClaimToRequest\(item\)\)/)
assert.match(appShellComposable, /Promise\.all\(\[[\s\S]*reloadRequests\(\{ silent: true \}\),[\s\S]*reloadWorkbenchApprovalRequests\(\)[\s\S]*\]\)/)
assert.match(appShellComposable, /if \(view === 'workbench'\) \{[\s\S]*void reloadWorkbenchRequests\(\)/)
assert.match(appShellComposable, /const workbenchRequests = computed\(\(\) =>[\s\S]*mergeWorkbenchRequests\(requests\.value, workbenchApprovalRequests\.value\)/)
assert.match(appShellComposable, /buildWorkbenchSummary\(workbenchRequests\.value, currentUser\.value\)/)
assert.match(appShellRouteView, /<DocumentsCenterView[\s\S]*:filtered-requests="requests"/)
assert.doesNotMatch(appShellRouteView, /<DocumentsCenterView[\s\S]*workbenchRequests/)
})
test('workbench progress refreshes after homepage create or detail updates', () => {
assert.match(appShellComposable, /async function handleDraftSaved\(payload = \{\}\) \{[\s\S]*await reloadWorkbenchRequests\(\)/)
assert.match(appShellComposable, /async function handleRequestUpdated\(\) \{[\s\S]*await reloadWorkbenchRequests\(\)[\s\S]*await refreshSelectedRequestDetail\(String\(route\.params\.requestId \|\| ''\)\)/)
assert.doesNotMatch(appShellComposable, /async function handleRequestUpdated\(\) \{[\s\S]*await reloadRequests\(\)[\s\S]*await refreshSelectedRequestDetail/)
})
test('workbench progress refresh is silent to avoid homepage flashing', () => {
assert.match(requestsComposable, /async function reload\(options = \{\}\) \{[\s\S]*const silent = Boolean\(options\?\.silent\)/)
assert.match(requestsComposable, /if \(!silent\) \{[\s\S]*loading\.value = true[\s\S]*error\.value = ''[\s\S]*\}/)
assert.match(requestsComposable, /catch \(nextError\) \{[\s\S]*if \(!silent\) \{[\s\S]*requests\.value = \[\][\s\S]*\}/)
assert.match(requestsComposable, /finally \{[\s\S]*if \(!silent\) \{[\s\S]*loading\.value = false[\s\S]*\}/)
assert.match(appShellComposable, /async function reloadWorkbenchRequests\(\) \{[\s\S]*reloadRequests\(\{ silent: true \}\)/)
assert.match(appShellComposable, /async function reloadDocumentCenterRequests\(\) \{[\s\S]*return reloadRequests\(\)/)
})
test('document detail navigation preserves document center list query', () => {
assert.match(
appShellComposable,
@@ -86,12 +131,12 @@ test('document detail navigation preserves document center list query', () => {
})
test('document detail refreshes claim detail instead of relying on stale list cache', () => {
assert.match(appShellComposable, /import \{ fetchExpenseClaimDetail \} from '\.\.\/services\/reimbursements\.js'/)
assert.match(appShellComposable, /import \{ fetchAllApprovalExpenseClaims, fetchExpenseClaimDetail \} from '\.\.\/services\/reimbursements\.js'/)
assert.match(appShellComposable, /import \{ mapExpenseClaimToRequest, useRequests \} from '\.\/useRequests\.js'/)
assert.match(appShellComposable, /const snapshot = normalizeRequestForUi\(selectedRequestSnapshot\.value\)[\s\S]*if \(isSameRequestIdentity\(snapshot, requestId\)\) \{[\s\S]*return snapshot/)
assert.match(appShellComposable, /async function refreshSelectedRequestDetail\(requestOrId = selectedRequestSnapshot\.value\) \{[\s\S]*fetchExpenseClaimDetail\(lookupId\)[\s\S]*mapExpenseClaimToRequest\(payload\)[\s\S]*upsertRequestSnapshot\(mappedRequest\)/)
assert.match(appShellComposable, /function openRequestDetail\(request, options = \{\}\) \{[\s\S]*void refreshSelectedRequestDetail\(request\)/)
assert.match(appShellComposable, /async function handleRequestUpdated\(\) \{[\s\S]*await reloadRequests\(\)[\s\S]*await refreshSelectedRequestDetail\(String\(route\.params\.requestId \|\| ''\)\)/)
assert.match(appShellComposable, /async function handleRequestUpdated\(\) \{[\s\S]*await reloadWorkbenchRequests\(\)[\s\S]*await refreshSelectedRequestDetail\(String\(route\.params\.requestId \|\| ''\)\)/)
assert.match(appShellComposable, /route\.name === 'app-document-detail'[\s\S]*void refreshSelectedRequestDetail\(String\(route\.params\.requestId \|\| ''\)\)/)
})