Files
client-web/src/modules/overseas-warehouse/views/warehouseTransferForm.test.mjs
T
2026-09-17 16:34:51 +08:00

192 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
const view = readFileSync(new URL('./WarehouseServiceView.vue', import.meta.url), 'utf8')
const api = readFileSync(new URL('../api/warehouseServices.ts', import.meta.url), 'utf8')
test('仓储转运先选择入仓方式并按方式切换地址信息', () => {
assert.match(view, /value="WAREHOUSE_PICKUP">仓库上门提货/)
assert.match(view, /value="CUSTOMER_DELIVERY">客户送货到仓/)
assert.match(view, /form\.deliveryMethod === 'WAREHOUSE_PICKUP'.*提货地址/s)
assert.match(view, /form\.deliveryMethod === 'CUSTOMER_DELIVERY'.*送货地址.*收货联系人.*联系电话/s)
assert.match(view, /getMerchantWarehouseDetail\(form\.warehouse\)/)
})
test('仓储转运支持无目的地、FBA 仓和私人仓并显式选择是否换标', () => {
assert.match(view, /是否有目的去向/)
assert.match(view, /value="NONE">暂未确定/)
assert.match(view, /value="FBA">FBA 仓/)
assert.match(view, /value="PRIVATE">私人仓/)
assert.match(view, /transferDestinationType === 'PRIVATE'.*私人仓地址.*邮编.*私人仓联系人.*联系电话/s)
assert.match(view, /是否需要换标/)
assert.match(view, /:value="false">不需要换标/)
assert.match(view, /:value="true">需要换标/)
assert.match(api, /fbaWarehouseCode\?: string/)
assert.match(api, /privateDestinationAddress\?: string; privateDestinationPostalCode\?: string/)
assert.match(api, /fbaShipmentNo\?: string/)
assert.doesNotMatch(view, /换标费用(CNY)/)
assert.doesNotMatch(view, /relabelChargeAmount:/)
})
test('仓储转运换标整票只允许一个目的仓', () => {
assert.match(view, /props\.service === 'transfer' && transferDestinationType === 'FBA'[^\n]+未换标货物目的 FBA 仓/)
assert.match(view, /此处只表示不换标箱子的去向/)
assert.match(view, /FBA 货件编号<\/span><el-input v-model="form\.fbaShipmentNo" placeholder="选填,可后续补充"/)
assert.match(view, /transferDestinationType\.value === 'FBA' && !form\.destination/)
assert.match(view, /transferDestinationType\.value === 'PRIVATE'.*!form\.privateDestinationPostalCode/)
assert.match(view, /整票换标货物目的 FBA 仓/)
assert.match(view, /暂不支持一票多个目的仓/)
assert.match(view, /if \(!transferRelabelDefaultDestination\.value\) \{ ElMessage\.warning\('请选择整票换标货物的 FBA 目的仓'\)/)
assert.match(view, /destinationWarehouseCode: transferRelabelDefaultDestination\.value \|\| undefined/)
const transferRelabelSection = view.split('warehouse-transfer-relabel">')[1]?.split('warehouse-transfer-submit-bar')[0] || ''
assert.doesNotMatch(transferRelabelSection, /v-model="row\.destinationWarehouseId"/)
assert.doesNotMatch(transferRelabelSection, /<th>FBA 目的仓 \*<\/th>/)
assert.doesNotMatch(view, /applyTransferRelabelDestination/)
assert.match(view, /destinationWarehouseId: binding\.destinationWarehouseCode \|\| ''/)
assert.match(view, /props\.service === 'transfer' \? '客户箱唛号' : '仓库唛头'/)
assert.match(view, /已导入 \$\{importedRows\.length\} 条仓储转运换标明细/)
assert.doesNotMatch(transferRelabelSection, /新 FBA 箱唛<\/th><th>FBA 目的仓<\/th>/)
assert.match(view, /const includeDestination = false/)
})
test('仓储转运不要求客户填写内部入仓号和我方箱唛,但换标时填写客户箱唛', () => {
const transferConfig = view.match(/transfer:\s*\{[^\n]+/)?.[0] || ''
const transferSubmit = view.match(/const payload: TransferCreate = \{[^\n]+/)?.[0] || ''
assert.doesNotMatch(transferConfig, /进仓编号/)
assert.doesNotMatch(transferSubmit, /inboundCode|sourceLastlegOrderIds/)
assert.match(view, /货物明细/)
assert.match(view, /客户只填写自己的箱唛,我方箱唛由系统生成/)
assert.match(view, /downloadTransferCartonMarkTemplate/)
assert.match(view, /importTransferCartonMarks/)
assert.match(view, /下载 SKU 关联模板/)
assert.match(view, /上传 SKU 关联/)
assert.match(view, /下载箱号关联模板/)
assert.match(view, /上传箱号关联/)
assert.match(view, /下载 SKU 混箱模板/)
assert.match(view, /上传 SKU 混箱/)
assert.match(view, /换标类型/)
assert.match(view, /v-if="labelingMode === 'carton'"/)
assert.match(view, /v-else-if="labelingMode === 'sku'"/)
assert.match(view, /v-else class="warehouse-table-scroll"/)
assert.match(view, /添加 SKU 明细/)
assert.match(view, /绑定明细/)
assert.match(view, /旧 SKU \*.*新 SKU \*.*换标数量(件)\*.*新 FBA 箱唛 \*.*备注/)
assert.match(transferSubmit, /fbaBoxNos: customerCartonMarks/)
assert.match(transferSubmit, /shippingMark: transferCustomerMarks\(item\)/)
assert.match(transferSubmit, /relabelItems: form\.relabel/)
assert.match(view, /props\.service === 'disposal' \? '本次废弃箱数' : '预计箱数'/)
assert.match(view, /<th v-if="props\.service === 'relabel'">FNSKU \/ 箱唛<\/th>/)
assert.doesNotMatch(view, /<th v-if="props\.service === 'transfer'">FNSKU \/ 箱唛<\/th>/)
})
test('上门提货不提交物流号,需要换标时随转运单登记申请', () => {
assert.match(view, /trackingNo:\s*form\.deliveryMethod === 'CUSTOMER_DELIVERY'\s*\?[^:]+:\s*undefined/)
assert.match(view, /本次提交将同时登记换标申请/)
assert.match(view, /form\.deliveryMethod === 'CUSTOMER_DELIVERY'.*物流跟踪号/s)
assert.match(view, /提货联系人/)
assert.match(view, /联系人电话/)
assert.match(view, /换标联系人/)
assert.match(view, /form\.pickupContact/)
assert.match(view, /form\.pickupPhone/)
assert.match(view, /form\.relabelContact/)
assert.match(view, /form\.relabelPhone/)
assert.match(view, /选择海外仓后自动带出,也可手动填写/)
assert.match(view, /pickupContactName: form\.deliveryMethod === 'WAREHOUSE_PICKUP' \? form\.pickupContact : undefined/)
assert.match(view, /pickupContactPhone: form\.deliveryMethod === 'WAREHOUSE_PICKUP' \? form\.pickupPhone : undefined/)
assert.match(view, /relabelContactName: form\.relabel \? form\.relabelContact/)
assert.match(api, /pickupContactName\?: string; pickupContactPhone\?: string/)
})
test('仓储转运列表操作仓使用海外仓接口数据', () => {
assert.match(view, /loadAllWarehouseRecords\('OVERSEAS', getMerchantWarehouses\)/)
assert.match(view, /warehouseDisplay\(item\.operatingWarehouseId\)/)
assert.match(view, /\['OVERSEAS', 'OVERSEAS_PARTNER'\]/)
assert.match(view, /v-for="warehouse in \(props\.service === 'relabel' \? fbaWarehouses : operationWarehouses\)"/)
assert.doesNotMatch(view, /美西洛杉矶仓/)
})
test('仓储转运预计发货时间可选并只读展示实际发货时间', () => {
assert.match(view, /预计发货时间/)
assert.match(view, /v-model="form\.estimatedShipAt"/)
assert.match(view, /选填,可线下确认后补充/)
assert.doesNotMatch(view, /!form\.estimatedShipAt && '预计发货时间'/)
assert.match(view, /estimatedShipAt: form\.estimatedShipAt/)
assert.match(view, /实际发货时间由仓库出库或 PDA 完成后回填/)
assert.match(api, /estimatedShipAt\?: string/)
})
test('客户仓储转运展示每个实际流转状态的中文名称', () => {
assert.match(view, /label: '草稿', value: 'DRAFT'/)
assert.match(view, /label: '待审核', value: 'PENDING_REVIEW'/)
assert.match(view, /label: '入库测量中', value: 'INBOUND_MEASURING'/)
assert.match(view, /label: '待客户确认实测', value: 'WAIT_CUSTOMER_CONFIRMATION'/)
assert.match(view, /label: '待确认目的地', value: 'WAIT_FBA_DESTINATION'/)
assert.match(view, /label: '待排车', value: 'READY_FOR_DISPATCH'/)
assert.match(view, /WAIT_OUTBOUND: '待出库'/)
assert.match(view, /OUTBOUNDED: '已出库'/)
})
test('PDA 打托完成后客户可从列表或详情确认并查看实测数据', () => {
assert.match(view, /row\.__status === 'WAIT_CUSTOMER_CONFIRMATION'/)
assert.match(view, /confirmTransferFromList\(row\['0'\]\)/)
assert.match(view, /selectedDetail\?\.status === 'WAIT_CUSTOMER_CONFIRMATION'/)
assert.match(view, /PDA 打托实测数据/)
for (const label of ['托盘号', '库位', '箱数', '长 × 宽 × 高(cm)', '毛重(kg)', '体积(m³)', '完成时间']) assert.equal(view.includes(label), true)
assert.match(view, /pallet\.warehouseLocationCode/)
assert.match(view, /pallet\.cartonCount/)
assert.match(view, /pallet\.grossWeightKg/)
assert.match(view, /pallet\.volumeCbm/)
assert.doesNotMatch(view, /pallet\.items/)
})
test('仓储转运详情自动加载 PDA 测量照片并释放 Blob URL', () => {
assert.match(api, /downloadTransferMeasurementPhoto/)
assert.match(api, /measurement-photos\/files\/\$\{encodeURIComponent\(fileId\)\}\/download/)
assert.match(view, /measurementPhotos\?: TransferMeasurementPhoto\[\]/)
assert.match(view, /fileId: string \| number/)
assert.match(view, /if \(props\.service === 'transfer'\) void loadMeasurementPhotos\(\)/)
assert.match(view, /测量打托现场照片/)
assert.match(view, /:preview-src-list="measurementPhotoPreviewUrls"/)
assert.match(view, /加载失败,点击重试/)
assert.match(view, /URL\.createObjectURL\(blob\)/)
assert.match(view, /URL\.revokeObjectURL\(url\)/)
assert.match(view, /onBeforeUnmount\(\(\) => \{ clearCompletionPhotos\(\); clearMeasurementPhotos\(\) \}\)/)
})
test('PDA 完成后主单显示入库完成并保留客户确认测量入口', () => {
assert.match(view, /row\.__status === 'WAIT_CUSTOMER_CONFIRMATION'.*确认测量数据/s)
assert.match(view, /selectedDetail\?\.status === 'WAIT_CUSTOMER_CONFIRMATION'.*确认测量数据/s)
assert.doesNotMatch(view, /确认实测并入库/)
})
test('仓储转运可在新建页直接提交,也可保存草稿后编辑提交', () => {
assert.match(api, /function submitTransfer\(transferNo: string\)/)
assert.match(api, /function updateTransfer\(transferNo: string, payload: TransferCreate\)/)
assert.match(api, /warehouse-transfers\/\$\{encodeURIComponent\(transferNo\)\}\/save-draft/)
assert.match(api, /warehouse-transfers\/\$\{encodeURIComponent\(transferNo\)\}\/submit/)
assert.match(view, /submit\('draft'\).*保存草稿/s)
assert.match(view, /async function openEdit\(transferNo: string\)/)
assert.match(view, /row\.__status === 'DRAFT'[^>]*[\s\S]*?@click="openEdit\(row\['0'\]\)"[^>]*>编辑/)
assert.match(view, /v-if="props\.service === 'transfer'"[^>]*type="primary"[^>]*native-type="submit"[^>]*>提交订单/)
assert.match(view, /await updateTransfer\(editingTransferNo\.value, payload\)/)
assert.match(view, /await submitTransfer\(transferNo\)/)
assert.match(view, /<form [^>]*@submit\.prevent="submit\('submit'\)"/)
assert.match(view, /selectedDetail\?\.status !== 'DRAFT'[^>]*[\s\S]*?printTransferCartons[^>]*[\s\S]*?打印箱唛/)
assert.doesNotMatch(view, /row\.__status !== 'DRAFT'.*printTransferCartons\(row\['0'\]\)/s)
assert.doesNotMatch(view, /selectedDetail\?\.status === 'DRAFT'[^>]*[\s\S]*?>提交订单/)
assert.match(view, /native-type="button"[^>]*:loading="saving"[^>]*@click="submit\('draft'\)"/)
assert.match(view, /DRAFT: '草稿'/)
assert.doesNotMatch(view, /<h3>箱唛明细<\/h3>/)
})
test('仓储转运基础货物不强制 SKU 和中文品名,只换箱唛不强制旧 SKU', () => {
assert.match(view, /商品 SKU\{\{ props\.service === 'transfer' \? '' : ' \*' \}\}/)
assert.match(view, /中文品名\{\{ props\.service === 'transfer' \? '' : ' \*' \}\}/)
assert.match(view, /props\.service === 'transfer' \? '选填' : '请输入商品 SKU'/)
assert.match(view, /v-if="labelingMode === 'carton'"[^\n]+<th>旧 SKU<\/th>/)
assert.match(view, /labelingMode\.value !== 'carton' && \(!row\.sku\.trim\(\) \|\| !row\.newSkuCode\.trim\(\)\)/)
assert.match(api, /skuCode\?: string; productNameZh\?: string/)
assert.match(api, /originalSku\?: string/)
})