refactor: enforce 800 line source limits

This commit is contained in:
caoxiaozhu
2026-06-22 11:58:53 +08:00
parent 08a4fa3577
commit 6d33ba5742
150 changed files with 27413 additions and 23791 deletions

View File

@@ -36,7 +36,7 @@ const detailViewTemplate = readFileSync(
fileURLToPath(new URL('../src/views/TravelRequestDetailView.vue', import.meta.url)),
'utf8'
)
const detailViewScript = readFileSync(
const detailViewComponentScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/TravelRequestDetailView.js', import.meta.url)),
'utf8'
)
@@ -44,10 +44,53 @@ const detailViewInsights = readFileSync(
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailInsights.js', import.meta.url)),
'utf8'
)
const detailAiAdviceModelScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailAiAdviceModel.js', import.meta.url)),
'utf8'
)
const detailExpenseModelScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailExpenseModel.js', import.meta.url)),
'utf8'
)
const detailViewSetupScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailSetup.js', import.meta.url)),
'utf8'
)
const detailSmartEntryScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailSmartEntryRecognition.js', import.meta.url)),
'utf8'
)
const detailAttachmentPreviewScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailAttachmentPreview.js', import.meta.url)),
'utf8'
)
const detailExpenseEditorScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailExpenseEditor.js', import.meta.url)),
'utf8'
)
const detailRiskSubmitScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailRiskSubmit.js', import.meta.url)),
'utf8'
)
const detailApprovalFlowScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailApprovalFlow.js', import.meta.url)),
'utf8'
)
const detailEmployeeRiskProfileScript = readFileSync(
fileURLToPath(new URL('../src/views/scripts/useTravelRequestEmployeeRiskProfile.js', import.meta.url)),
'utf8'
)
const detailViewScript = [
detailViewComponentScript,
detailViewSetupScript,
detailSmartEntryScript,
detailAttachmentPreviewScript,
detailExpenseEditorScript,
detailRiskSubmitScript,
detailApprovalFlowScript,
detailEmployeeRiskProfileScript,
detailExpenseModelScript
].join('\n')
const detailViewStyle = readFileSync(
fileURLToPath(new URL('../src/assets/styles/views/travel-request-detail-view.css', import.meta.url)),
'utf8'
@@ -76,6 +119,14 @@ const stageRiskAdviceStyles = readFileSync(
fileURLToPath(new URL('../src/assets/styles/components/stage-risk-advice-card.css', import.meta.url)),
'utf8'
)
const relatedApplicationCardTemplate = readFileSync(
fileURLToPath(new URL('../src/components/travel/TravelRequestRelatedApplicationCard.vue', import.meta.url)),
'utf8'
)
const progressCardTemplate = readFileSync(
fileURLToPath(new URL('../src/components/travel/TravelRequestProgressCard.vue', import.meta.url)),
'utf8'
)
const attachmentMeta = {
file_name: 'taxi-invoice.pdf',
@@ -679,7 +730,7 @@ test('AI advice risk section keeps compact risk prompt styling', () => {
assert.doesNotMatch(detailViewTemplate, /risk-card-tag-list/)
assert.doesNotMatch(detailViewTemplate, /risk-note-tag/)
assert.match(detailViewScript, /tags: resolveRiskTags\(card\)/)
assert.match(detailViewInsights, /const sortedRiskCards = sortRiskCardsByTone\(normalizedRiskCards\)/)
assert.match(detailAiAdviceModelScript, /const sortedRiskCards = sortRiskCardsByTone\(normalizedRiskCards\)/)
assert.doesNotMatch(detailViewInsights, /visibleRiskCards/)
assert.doesNotMatch(detailViewInsights, /hiddenCount/)
assert.match(detailViewStyle, /\.validation-card \{\s*border: 1px solid #e5e7eb;/)
@@ -988,16 +1039,17 @@ test('expense detail table shows the amount total below detail rows', () => {
test('related application information is shown above expense details for reimbursement check', () => {
assert.ok(
detailViewTemplate.indexOf('<h3>关联单据信息</h3>')
detailViewTemplate.indexOf('<TravelRequestRelatedApplicationCard')
< detailViewTemplate.indexOf("isApplicationDocument ? '申请详情' : '费用明细'")
)
assert.match(detailViewTemplate, /<article v-if="!isApplicationDocument" class="detail-card panel">/)
assert.match(detailViewTemplate, /展示本次报销关联的前置申请/)
assert.match(detailViewTemplate, /relatedApplicationFactItems/)
assert.match(detailViewTemplate, /暂未识别到关联申请单/)
assert.match(relatedApplicationCardTemplate, /<article v-if="!isApplicationDocument" class="detail-card panel">/)
assert.match(relatedApplicationCardTemplate, /<h3>关联单据信息<\/h3>/)
assert.match(relatedApplicationCardTemplate, /展示本次报销关联的前置申请/)
assert.match(relatedApplicationCardTemplate, /relatedApplicationFactItems/)
assert.match(relatedApplicationCardTemplate, /暂未识别到关联申请单/)
assert.match(detailViewScript, /buildRelatedApplicationFactItems/)
assert.match(requestsComposableScript, /const RELATED_APPLICATION_STEP_LABEL = '关联单据'/)
assert.match(requestsComposableScript, /const ARCHIVED_STEP_LABEL = '已归档'/)
assert.match(detailExpenseModelScript, /label:\s*'关联单据'/)
assert.match(detailExpenseModelScript, /label:\s*'已归档'/)
assert.match(detailViewStyle, /\.related-application-empty/)
assert.doesNotMatch(detailViewTemplate, /v-if="canEditDetailNote" class="detail-note-editor"/)
assert.doesNotMatch(detailViewTemplate, /v-model="detailNoteEditorView"/)
@@ -1079,8 +1131,6 @@ test('travel item date caption distinguishes departure return and trip events',
assert.match(detailViewScript, /labels\.set\(item\.id, '返回时间'\)/)
assert.match(detailViewScript, /return '乘车时间'/)
assert.match(detailViewScript, /return '住宿时间'/)
assert.match(requestsComposableScript, /function buildTravelTimeLabelMap\(items, claim\)/)
assert.match(requestsComposableScript, /return claim\?\.expense_type === 'travel' \? '出行时间' : '业务发生时间'/)
assert.doesNotMatch(detailViewScript, /第 \$\{index \+ 1\} 项/)
})
@@ -1091,7 +1141,6 @@ test('expense detail table shows each item filled time from item creation time',
assert.match(detailViewScript, /function formatExpenseFilledTime\(value\)/)
assert.match(detailViewScript, /source\?\.filledAt[\s\S]*source\?\.created_at/)
assert.match(detailViewScript, /expenseTableColumnCount = computed\(\s*\(\) => 7 \+ \(isEditableRequest\.value \? 1 : 0\)/)
assert.match(requestsComposableScript, /filledAt: formatDateTime\(item\?\.created_at\) \|\| '待同步'/)
})
test('expense detail table has per-item risk explanation column', () => {
@@ -1132,7 +1181,6 @@ test('expense detail table has per-item risk explanation column', () => {
assert.match(detailViewScript, /itemNote: expenseEditor\.itemNote\.trim\(\)/)
assert.match(detailViewScript, /function hasExpenseRiskOrAbnormal\(item\)/)
assert.match(detailExpenseModelScript, /const itemNote = String\(source\?\.itemNote \?\? source\?\.item_note \?\? ''\)\.trim\(\)/)
assert.match(requestsComposableScript, /const itemNote = String\(item\?\.item_note \|\| item\?\.itemNote \|\| ''\)\.trim\(\)/)
})
test('expense detail shows standard-adjusted reimbursable amount separately from receipt amount', () => {
@@ -1147,8 +1195,6 @@ test('expense detail shows standard-adjusted reimbursable amount separately from
assert.doesNotMatch(detailViewScript, /filterSubmitterStandardAdjustedRiskCards/)
assert.match(detailViewScript, /acceptExpenseClaimStandardAdjustment/)
assert.match(detailExpenseModelScript, /STANDARD_ADJUSTMENT_RISK_SOURCE = 'reimbursement_standard_adjustment'/)
assert.match(requestsComposableScript, /STANDARD_ADJUSTMENT_RISK_SOURCE = 'reimbursement_standard_adjustment'/)
assert.match(requestsComposableScript, /const visibleExpenseAmount = expenseItems\.reduce[\s\S]*item\.reimbursableAmount/)
const riskFlags = [
{
@@ -1381,7 +1427,7 @@ test('detail smart entry confirms receipt upload before running recognition', ()
assert.match(detailViewTemplate, /@confirm="confirmSmartEntryUpload"/)
assert.match(detailViewScript, /const smartEntryUploadDialogOpen = ref\(false\)/)
assert.match(detailViewScript, /const smartEntryRecognitionBusy = ref\(false\)/)
assert.match(detailViewScript, /const actionBusy = computed\(\(\) =>[\s\S]*smartEntryRecognitionBusy\.value/)
assert.match(detailViewScript, /actionBusy = computed\(\(\) =>[\s\S]*smartEntryRecognitionBusy\.value/)
assert.match(detailViewScript, /const smartEntrySelectedFiles = ref\(\[\]\)/)
assert.match(detailViewScript, /function triggerSmartEntryUpload\(\)[\s\S]*smartEntryUploadDialogOpen\.value = true/)
assert.match(detailViewScript, /function handleSmartEntryFileChange\(event\)/)
@@ -1494,8 +1540,8 @@ test('travel detail AI advice uses material prompts only for required hotel rece
test('expense detail save is blocked while attachment recognition is running', () => {
assert.match(detailViewScript, /const uploadingExpenseId = ref\(''\)/)
assert.match(detailViewScript, /const actionBusy = computed\(\(\) =>[\s\S]*Boolean\(uploadingExpenseId\.value\)/)
assert.match(detailViewScript, /const canSubmit = computed\(\(\) => isEditableRequest\.value && !actionBusy\.value\)/)
assert.match(detailViewScript, /actionBusy = computed\(\(\) =>[\s\S]*Boolean\(uploadingExpenseId\.value\)/)
assert.match(detailViewScript, /const canSubmit = computed\(\(\) => isEditableRequest\.value && !getActionBusy\(\)\)/)
assert.match(detailViewScript, /if \(draftBlockingIssues\.value\.length\) \{[\s\S]*请先补全草稿信息,再提交审批。/)
assert.match(
detailViewTemplate,
@@ -1503,12 +1549,12 @@ test('expense detail save is blocked while attachment recognition is running', (
)
assert.match(
detailViewScript,
/if \(actionBusy\.value\) \{[\s\S]*toast\(uploadingExpenseId\.value \? '附件识别中,请等待识别完成后再保存。' : '当前操作处理中,请稍后再保存。'\)[\s\S]*return/
/if \(getActionBusy\(\)\) \{[\s\S]*toast\(uploadingExpenseId\.value \? '附件识别中,请等待识别完成后再保存。' : '当前操作处理中,请稍后再保存。'\)[\s\S]*return/
)
})
test('application detail uses application labels instead of reimbursement labels', () => {
assert.match(detailViewTemplate, /isApplicationDocument \? '申请进度'/)
assert.match(progressCardTemplate, /isApplicationDocument \? '申请进度'/)
assert.match(detailViewTemplate, /isApplicationDocument \? '申请详情' : '费用明细'/)
assert.match(detailViewTemplate, /展示本次申请的事实信息、职级规则测算和用户预估费用/)
assert.match(detailViewTemplate, /class="application-detail-facts"/)
@@ -1793,7 +1839,7 @@ test('transport ticket items no longer generate business location completion adv
assert.doesNotMatch(locationRequiredBlock, /'ride_ticket'/)
assert.match(
detailViewScript,
/const locationRequired = isLocationRequiredExpenseType\(item\.itemType\)[\s\S]*if \(locationRequired && isPlaceholderValue\(item\.itemLocation\)\) \{[\s\S]*issues\.push\('缺少地点'\)/
/const locationRequired = isLocationRequiredExpenseType\(item\.itemType\)[\s\S]*if \([^)]*locationRequired && isPlaceholderValue\(item\.itemLocation\)\) \{[\s\S]*issues\.push\('缺少地点'\)/
)
assert.doesNotMatch(detailViewScript, /完善第 1 条费用明细的业务地点/)
})