Merge branch 'release/test' of http://8.163.30.128:10082/html/client-web into release/test

This commit is contained in:
wujinliang
2026-09-17 14:26:54 +08:00
19 changed files with 454 additions and 102 deletions
@@ -3,6 +3,8 @@ import { readFileSync } from 'node:fs'
import test from 'node:test'
const source = readFileSync(new URL('./FirstLegOrdersView.vue', import.meta.url), 'utf8')
const tableSource = readFileSync(new URL('../../../components/common/DataTable.vue', import.meta.url), 'utf8')
const querySource = readFileSync(new URL('../../../components/common/QueryToolbar.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')
@@ -70,7 +72,7 @@ test('renders dynamic cargo lines and a responsive editor dialog', () => {
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; \}/)
assert.match(source, /\.prototype-order-table :deep\(> \.el-table\), \.prototype-order-table :deep\(> \.data-table__pagination\) \{ display: none; \}/)
})
test('uses the full editor dialog width for cargo details and cost estimates', () => {
@@ -89,11 +91,11 @@ 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<QueryModel>/)
assert.match(source, /<QueryToolbar v-model="filters" class="first-leg-query-toolbar" :fields="queryFields" ariaLabel="订单查询" @search="searchOrders" \/>/)
assert.match(source, /<QueryToolbar v-model="filters" class="first-leg-query-toolbar" layout="grid" :fields="queryFields" ariaLabel="订单查询" @search="searchOrders" \/>/)
assert.match(source, /async function searchOrders\(model: QueryModel\)/)
assert.match(source, /await store\.load\(\{/)
assert.match(source, /<DataTable v-model:page="tablePage" v-model:page-size="tablePageSize" :data="pagedOrders" :columns="visibleOrderColumns"/)
assert.match(source, /\{ key: 'actions', label: '操作', width: 216, fixed: 'left', align: 'center', headerAlign: 'center', slotName: 'actions' \}/)
assert.match(source, /\{ key: 'actions', label: '操作', width: 284, fixed: 'left', align: 'left', headerAlign: 'left', slotName: 'actions' \}/)
assert.doesNotMatch(source, /order-metrics|订单概览/)
})
@@ -188,7 +190,7 @@ test('keeps dense order identifiers on one line and aligns columns by content ty
assert.doesNotMatch(source, /<template #order="\{ row \}">[\s\S]{0,400}class="order-reference"/)
assert.match(source, /\.table-ellipsis, \.table-multivalue \{[^}]*text-overflow: ellipsis;[^}]*white-space: nowrap;/)
assert.match(source, /\.order-number-link \{[^}]*text-overflow: ellipsis;[^}]*white-space: nowrap;/)
assert.match(source, /\.prototype-order-table :deep\(\.el-table__body-wrapper td\.el-table__cell\) \{ height: 50px;/)
assert.match(tableSource, /height: var\(--client-table-row-height\)/)
})
test('shows one unified progress line and C02 business summaries without detail history', () => {
@@ -231,26 +233,26 @@ test('shows and searches the inbound code after a draft is submitted', () => {
assert.match(source, /<span v-else>—<\/span>/)
})
test('keeps the seven-stage progress and business summary usable on mobile', () => {
assert.match(progressSource, /grid-template-columns: repeat\(7, 82px\)/)
test('keeps all progress stages and business summary usable on mobile', () => {
assert.match(progressSource, /grid-auto-columns: 82px/)
assert.match(progressSource, /overflow-x: auto/)
assert.match(source, /\.fulfillment-summary \{ grid-template-columns: 1fr; \}/)
})
test('keeps the first viewport compact and moves create into the table toolbar', () => {
const tableToolbarSource = source.slice(source.indexOf('class="order-table-toolbar"'), source.indexOf('class="order-eligibility is-pending"'))
assert.match(source, /class="order-table-toolbar"/)
const tableToolbarSource = source.slice(source.indexOf('#toolbar-actions'), source.indexOf('class="order-eligibility is-pending"'))
assert.match(source, /#toolbar-actions/)
assert.match(source, /<strong>订单列表<\/strong><span>共 \{\{ filteredOrders\.length \}\} 条<\/span>/)
assert.match(source, /class="order-table-toolbar"[\s\S]*order:first-leg:create[\s\S]*创建订单[\s\S]*class="order-eligibility is-pending"/)
assert.match(source, /#toolbar-actions[\s\S]*order:first-leg:create[\s\S]*创建订单[\s\S]*class="order-eligibility is-pending"/)
assert.match(tableToolbarSource, /下载唛头[\s\S]*导出订单信息[\s\S]*批量提交草稿[\s\S]*创建订单/)
assert.doesNotMatch(source.slice(source.indexOf('<QueryToolbar'), source.indexOf('<div class="client-card order-table-card">')), /下载唛头|导出订单信息|创建订单/)
assert.match(source, /client-main:has\(> \.first-leg-page:not\(\.is-create-route\)\) > \.client-page-heading > div\) \{ position: absolute; width: 1px; height: 1px;/)
})
test('uses the prototype query grid and only shows the qualification notice before approval', () => {
assert.match(source, /\.first-leg-query-toolbar \{ display: block;/)
assert.match(source, /query-toolbar__filters\) \{ display: grid; min-width: 0; grid-template-columns: repeat\(4,/)
assert.match(source, /query-toolbar__actions\) \{ justify-content: flex-start; margin-top: 14px;/)
assert.match(querySource, /\.query-toolbar--grid \{ display: block;/)
assert.match(querySource, /query-toolbar__filters \{ display: grid; grid-template-columns: repeat\(4,/)
assert.match(querySource, /query-toolbar__actions \{ margin-top: 12px;/)
assert.match(source, /v-if="companySubmissionBlocked && !supportingDataErrors\.some/)
assert.doesNotMatch(source, /企业资料已审核,可正常提交订单/)
assert.doesNotMatch(source, /order-eligibility\.is-approved/)
@@ -399,6 +401,9 @@ test('loads only active server channels for the selected domestic warehouse', ()
assert.match(source, /availablePricingTaxModes/)
assert.match(source, /:loading="channelLoading"/)
assert.match(source, /:disabled="!form\.receivingWarehouseId \|\| channelLoading"/)
assert.match(source, /label="报价包税方式" prop="pricingTaxMode" required class="pricing-tax-mode-field"/)
assert.match(source, /\.compact-transport-grid > :deep\(\.pricing-tax-mode-field\) \{ display: none; \}/)
assert.doesNotMatch(source, /\.compact-transport-grid > :deep\(\.el-form-item:nth-child\(2\)\)/)
assert.match(source, /当前收货仓暂无可用渠道/)
assert.match(source, /渠道加载失败/)
assert.match(source, /@click="retryPricingChannels"/)
@@ -537,7 +542,9 @@ test('opens billing-weight confirmation independently from order details', () =>
test('shows billing-weight confirmation only when the backend marks it pending', () => {
const templateSource = source.slice(source.indexOf('<template>'), source.lastIndexOf('</template>'))
const entries = templateSource.match(/<el-button v-if="canConfirmInboundFee && [^"]*customerFeeConfirmationRequired" link type="primary" @click="openFeeConfirmation\([^)]*\)">确认计费重<\/el-button>/g) ?? []
assert.equal(entries.length, 2)
assert.equal(entries.length, 1)
assert.match(source, /if \(canConfirmInboundFee\.value && order\.businessSummary\.customerFeeConfirmationRequired\) \{\s*actions\.push\(\{ key: 'fee'/)
assert.match(source, /:row-actions="getOrderRowActions"/)
assert.match(orderStoreSource, /customerFeeConfirmationRequired: summary\?\.customerFeeConfirmationRequired \?\? false/)
})
@@ -595,7 +602,7 @@ test('opens customer customs documents only for server-confirmed loaded tax-refu
assert.match(source, /order\.status !== 'LOADED'/)
assert.match(source, /item\.orderId === order\.id && item\.taxMode === 'TAX_REFUND'/)
assert.match(source, /getMerchantCustomsForOrder\(order\.id\)/)
assert.match(source, /v-if="eligibleCustomsDetail\(row as FirstLegOrder\)"[\s\S]*?报关资料/)
assert.match(source, /if \(eligibleCustomsDetail\(order\)\) \{\s*actions\.push\(\{ key: 'customs', label: '报关资料'/)
assert.match(source, /class="mobile-order-card"[\s\S]*?v-if="eligibleCustomsDetail\(order\)"[\s\S]*?openCustomsDocuments\(order\)[\s\S]*?报关资料/)
assert.match(source, /<CustomsDocumentsDialog[\s\S]*?:can-edit="auth\.hasPermission\('order:first-leg:edit'\)"/)
assert.doesNotMatch(customsApiSource, /customs\/cases\//)