import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' const source = readFileSync(new URL('./FirstLegOrdersView.vue', import.meta.url), 'utf8') const routerSource = readFileSync(new URL('../routes.ts', import.meta.url), 'utf8') const editorShellSource = readFileSync(new URL('../components/FirstLegOrderEditorShell.vue', import.meta.url), 'utf8') const progressSource = readFileSync(new URL('../components/OrderProgressPanel.vue', import.meta.url), 'utf8') const customsDialogSource = readFileSync(new URL('../components/CustomsDocumentsDialog.vue', import.meta.url), 'utf8') const customsApiSource = readFileSync(new URL('../api/customs.ts', import.meta.url), 'utf8') test('routes the confirmed first-leg path to the implemented order view', () => { assert.match(routerSource, /path: 'orders\/first-leg'[\s\S]*?component: \(\) => import\('\.\/views\/FirstLegOrdersView\.vue'\)[\s\S]*?release: 'active'/) }) test('opens order creation as a dedicated protected page while keeping draft editing in a large dialog', () => { assert.match(routerSource, /path: 'orders\/first-leg\/create'[\s\S]*?name: 'first-leg-order-create'[\s\S]*?release: 'active'[\s\S]*?permission: 'order:first-leg:create'/) assert.match(routerSource, /name: 'first-leg-order-create'[\s\S]*?props: \{ createPage: true \}/) assert.match(source, /router\.push\(\{ name: 'first-leg-order-create' \}\)/) assert.match(source, /defineProps<\{ createPage\?: boolean \}>/) assert.match(source, /const isCreatePage = computed\(\(\) => props\.createPage\)/) assert.match(source, /]*:page="isCreatePage"/) assert.match(editorShellSource, /
/) assert.match(editorShellSource, / { assert.match(source, /function openCreate\(\)/) assert.match(source, /async function saveDraft\(\)/) assert.match(source, /function submitOrder\(\)/) assert.match(source, /async function openDetail\(order: FirstLegOrder\)/) assert.match(source, /Promise\.allSettled\(\[/) assert.match(source, /const orderPageRequest = isCreatePage\.value\s*\? store\.loadWarehouseType\('DOMESTIC', true\)\s*:\s*store\.load\(\{ includeDrafts: true \}\)/) assert.match(source, /Promise\.allSettled\(\[\s*orderPageRequest,\s*companyRequest/) assert.match(source, /tenantStore\.loadCompanyContext\(\)/) assert.match(source, /await store\.loadDetail\(order\.id\)/) assert.doesNotMatch(source, /cancelOrder|取消订单/) }) test('keeps create-page support errors scoped to create-page requests', () => { assert.match(source, /if \(!isCreatePage\.value && store\.draftLoadError\)/) }) test('blocks order submission before company approval while preserving draft actions', () => { assert.match(source, /companySubmissionBlocked/) assert.match(source, /companyAuditLoaded\.value = true/) assert.match(source, /企业资料待审核,当前仅可保存订单草稿/) assert.match(source, /暂时无法提交订单/) assert.match(source, /router\.push\('\/company\/profile'\)/) assert.match(source, /auth\.hasPermission\('order:first-leg:submit'\)/) }) test('defers approval checks to the server when the member cannot read the company profile', () => { assert.match(source, /const canViewCompanyProfile = computed/) assert.match(source, /const companySubmissionBlocked = computed\(\(\) => companyAuditLoaded\.value/) assert.match(source, /const knownCompanyAuditStatus = companyAuditLoaded\.value \? tenantStore\.company\.auditStatus : undefined/) assert.match(source, /store\.submitSaved\(savedOrder\.id, knownCompanyAuditStatus\)/) }) test('renders dynamic cargo lines and a responsive editor dialog', () => { assert.match(source, /v-for="\(item, index\) in form\.items"/) assert.match(source, /function addCargoItem\(\)/) assert.match(source, /function removeCargoItem\(index: number\)/) assert.match(editorShellSource, /first-leg-editor-dialog\.el-dialog\) \{[^}]*height: 94vh;/) assert.match(editorShellSource, /width: 100vw !important; height: 100vh;/) assert.match(source, /class="mobile-order-list"/) assert.match(source, /\.desktop-order-table \{ display: none; \}/) }) test('uses the full editor dialog width for cargo details and cost estimates', () => { assert.match(source, /:class="\{ 'is-dialog-order-form': !isCreatePage \}"/) assert.match(source, /\.order-form\.is-dialog-order-form \{ width: 100%; max-width: none; \}/) assert.match(source, /\.is-dialog-order-form > \.cargo-section, \.is-dialog-order-form > \.cost-estimate-section \{ width: 100%; max-width: none; \}/) assert.match(source, /\.price-estimate__result \{ display: grid; grid-template-columns:/) assert.match(source, /\.cargo-table-wrap \{ width: 100%;/) }) test('keeps primary mobile order actions touch sized', () => { assert.match(source, /\.editor-actions :deep\(\.el-button\) \{ min-height: 44px;/) }) test('uses the shared query toolbar and data table without metric cards', () => { assert.match(source, /import QueryToolbar, \{ type QueryField, type QueryModel \}/) assert.match(source, /import DataTable, \{ type DataTableColumn \}/) assert.match(source, /const filters = ref/) assert.match(source, //) assert.match(source, /async function searchOrders\(model: QueryModel\)/) assert.match(source, /await store\.load\(\{/) assert.match(source, / { assert.match(source, /下载唛头/) assert.match(source, /导出订单信息/) assert.match(source, /function downloadShippingMarks\(\)/) assert.match(source, /downloadMerchantOrderCartonLabelsBatch\(orders\.map\(\(order\) => order\.id\)\)/) assert.match(source, /error\.traceId \? `,追踪号 \$\{error\.traceId\}`/) assert.doesNotMatch(source, /order\.businessSummary\.inboundId/) assert.match(source, /批量箱唛-\$\{orders\.length\}单\.pdf/) assert.match(source, /function exportOrderInformation\(\)/) assert.match(source, /selectedOrders\.value\.map/) assert.match(source, /订单信息\.csv/) assert.doesNotMatch(source, /exportOrderInformation[\s\S]{0,1200}loadDetail/) }) test('selects orders before downloading marks or exporting last-mile data', () => { assert.match(source, /\{ key: 'selection', type: 'selection', width: 48, fixed: 'left', reserveSelection: true \}/) assert.match(source, /const selectedOrders = ref\(\[\]\)/) assert.match(source, /const selectedOrderCount = computed\(\(\) => selectedOrders\.value\.length\)/) assert.match(source, /@selection-change="handleOrderSelectionChange"/) assert.match(source, /:disabled="selectedOrderCount === 0" @click="downloadShippingMarks"/) assert.match(source, /:disabled="selectedOrderCount === 0" @click="exportOrderInformation"/) assert.match(source, /const orders = selectedOrders\.value\s*$/m) assert.match(source, /const rows = selectedOrders\.value\.map/) assert.doesNotMatch(source, /const orders = filteredOrders\.value\.filter/) assert.doesNotMatch(source, /const rows = filteredOrders\.value\.map/) }) test('downloads selected carton labels with one array request', () => { const downloadStart = source.indexOf('async function downloadShippingMarks()') const downloadEnd = source.indexOf('function formatExportDateTime', downloadStart) const downloadSource = source.slice(downloadStart, downloadEnd) assert.match(downloadSource, /await downloadMerchantOrderCartonLabelsBatch\(orders\.map\(\(order\) => order\.id\)\)/) assert.match(downloadSource, /saveBlob\(result\.blob/) assert.match(downloadSource, /result\.failureCount/) assert.doesNotMatch(downloadSource, /for \(const order of orders\)/) assert.doesNotMatch(downloadSource, /Promise\.all\(/) assert.doesNotMatch(downloadSource, /businessSummary\.inboundId\)/) assert.doesNotMatch(downloadSource, /没有已生成的入库单|未生成入库单/) }) test('exports every visible order field with normalized dates', () => { assert.match(source, /function formatExportDateTime\(value: string \| null \| undefined\)/) assert.match(source, /return `\$\{date\.getFullYear\(\)\}-\$\{pad\(date\.getMonth\(\) \+ 1\)\}-\$\{pad\(date\.getDate\(\)\)\} \$\{pad\(date\.getHours\(\)\)\}:\$\{pad\(date\.getMinutes\(\)\)\}:\$\{pad\(date\.getSeconds\(\)\)\}`/) for (const label of ['订单号', '入仓码', '渠道', '运输方式', '交货方式', '预约提货时间', '目的仓', '目的仓类型', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS', '总毛重', '总净重', '总体积', '总数量', '计费单价', '计费体积', '计费重量', '备注', '货件编号', '跟踪编号', '国内仓入库时间', '创建时间']) { assert.match(source, new RegExp(`'${label}'`)) } assert.match(source, /formatExportDateTime\(order\.inboundedAt\)/) assert.match(source, /order\.pickupMethod === 'PICKUP' \? formatExportDateTime\(order\.requestedPickupAt\) : '-'/) assert.match(source, /formatListMetric\(order\.chargeableVolumeCbm, 'm³'\)/) assert.doesNotMatch(source, /formatExportDateTime\(order\.businessDate\)/) assert.match(source, /formatExportDateTime\(order\.createdAt\)/) }) test('matches the prototype with selectable dense order-list columns', () => { assert.match(source, /aria-label="设置订单列表显示列"/) assert.match(source, /-<\/template>/) assert.match(source, /