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') const warehouseApi = readFileSync(new URL('../../first-leg/api/firstLeg.ts', import.meta.url), 'utf8') test('总文件可以独立清除并重选同名文件,提交时禁止清除', () => { assert.match(view, /@click="clearCreateTotalFile\('CARTON_TOTAL'\)"/) assert.match(view, /@click="clearCreateTotalFile\('SKU_TOTAL'\)"/) const clear = view.slice(view.indexOf('function clearCreateTotalFile'), view.indexOf('function chooseCreateTotalFile')) assert.match(clear, /if \(saving.value\) return/) assert.match(clear, /file.value = null/) assert.match(clear, /input.value.value = ''/) assert.match(view, /aria-label="清除箱唛总文件" :disabled="saving"/) assert.match(view, /aria-label="清除 SKU 总文件" :disabled="saving"/) }) test('贴标申请从当前客户仍有库存的历史入仓单选择来源', () => { assert.match(view, /海外操作仓(中转仓)/) assert.match(view, /选择有库存的历史入仓单/) assert.match(view, /曾经下单且当前仍有库存的入仓单/) assert.match(view, /当前中转仓暂无已入库可用库存/) assert.match(view, /relabelInboundOptions/) assert.match(view, /listRelabelInventoryCandidates\(form\.warehouse\)/) assert.match(api, /relabel-applications\/inventory-candidates/) assert.match(api, /params: \{ operationWarehouseId/) }) test('客户贴标表单不展示客户单号、托盘和内部库存来源列', () => { assert.doesNotMatch(view, /\*<\/i>客户单号/) assert.doesNotMatch(view, /原入仓单<\/th>/) assert.doesNotMatch(view, /托盘<\/th>/) assert.doesNotMatch(view, /中转仓<\/th>/) assert.doesNotMatch(view, /已选托盘组成/) }) test('贴标申请保留关联模板下载和上传入口', () => { assert.match(view, /downloadRelabelTemplate/) 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, /skuTemplateInput\?\.click\(\)/) assert.match(view, /cartonTemplateInput\?\.click\(\)/) assert.match(view, /importRelabelTemplate/) assert.match(view, /明细行标识/) assert.match(view, /'明细行标识', '旧箱唛', '旧SKU标签', '新SKU标签'/) assert.match(view, /const includeDestination = false/) assert.doesNotMatch(view, /const includeDestination = props\.service !== 'transfer'/) assert.match(view, /SKU 与箱号关联通过仓库唛头合并/) assert.match(view, /仓库唛头 \*<\/th>/) assert.doesNotMatch(view, /库存位置ID/) }) test('贴标货物明细支持手动添加和编辑', () => { assert.match(view, /手动添加行/) assert.match(view, /addRelabelCargoRow/) assert.match(view, /所选入仓单没有更多可添加的库存箱/) assert.match(view, / { assert.match(view, /interface ImportedRelabelBinding/) assert.match(view, /待导入绑定关系/) assert.match(view, /全选/) assert.match(view, /导入到明细/) assert.match(view, /importSelectedBindingsToDetails/) assert.match(view, /item\.selected/) assert.match(view, /cartonDetailRows/) assert.match(view, /included: false/) assert.match(view, /cargoRows\.value\[0\]\.included = true/) }) test('箱唛换标一行固定代表一箱', () => { const cartonTable = view.match(/
.+?(?=
)/s)?.[0] assert.ok(cartonTable) assert.match(cartonTable, /箱数<\/th>/) assert.match(cartonTable, /1 箱<\/strong><\/td>/) assert.doesNotMatch(cartonTable, /v-model="row\.quantity"/) assert.doesNotMatch(view, /'本次箱数'/) assert.match(view, /totalPackageCount: 1, notifiedPackageCount: 1/) }) test('贴标货物明细通过单一换标类型选择三种模式', () => { assert.match(view, //) assert.match(view, /只换箱唛<\/el-radio-button>/) assert.match(view, /只换 SKU 标签<\/el-radio-button>/) assert.match(view, /SKU 和箱唛都换<\/el-radio-button>/) assert.doesNotMatch(view, /el-tab-pane label="(?:箱唛换标|SKU 换标)"/) assert.match(view, /interface SkuRelabelRow/) assert.match(view, /旧 SKU \*/) assert.match(view, /仓库唛头 \*/) assert.match(view, /换标数量(件)\*/) assert.match(view, /旧SKU标签/) assert.match(view, /新SKU标签/) assert.match(view, /已读取 \$\{rows\.length\} 条绑定关系/) assert.match(view, /applyExistingSkuBinding/) assert.match(view, /applyExistingCartonBinding/) assert.match(view, /buildSkuRelabelItems/) assert.match(view, /CARTON_AND_SKU/) assert.match(view, /changeCarton/) assert.doesNotMatch(view, /SKU 换标提交待接口接入/) }) test('箱唛相关换标必须选择四选一派送方式', () => { assert.match(view, /label="卡车派送" value="TRUCK"/) assert.match(view, /label="快递派送" value="EXPRESS"/) assert.match(view, /label="卡车自提" value="TRUCK_PICKUP"/) assert.match(view, /label="快递自提" value="EXPRESS_PICKUP"/) assert.match(api, /RelabelDeliveryMethod = 'TRUCK' \| 'EXPRESS' \| 'TRUCK_PICKUP' \| 'EXPRESS_PICKUP'/) assert.match(view, /labelingMode\.value !== 'sku' && !form\.deliveryMethod/) }) test('一次申请单选库存来源且保留普通入仓或退货合箱归属', () => { assert.doesNotMatch(view, /multiple filterable collapse-tags/) assert.match(view, /RETURN_CARTON:\$\{item\.returnCartonId\}/) assert.match(view, /sourceInventoryBalanceId: String\(candidate\.inventoryBalanceId\)/) assert.match(view, /sourceInventoryPositionId: String\(position\.positionId\)/) assert.match(view, /sourceInboundOrderId: String\(candidate\.inboundOrderId\)/) assert.match(view, /returnCartonId: String\(candidate\.returnCartonId\)/) assert.match(api, /sourceInventoryBalanceId\?: string; sourceInventoryPositionId\?: string; sourceInboundOrderId\?: string; returnCartonId\?: string/) }) test('海外操作仓和FBA目的仓使用独立字段', () => { assert.match(api, /operationWarehouseId: string/) assert.match(api, /destinationFbaWarehouseCode\?: string/) assert.match(view, /operationWarehouseId: form\.warehouse/) assert.match(view, /destinationFbaWarehouseCode: form\.destination/) assert.match(view, /整张贴标申请只能选择一个目的仓/) assert.doesNotMatch(view, /v-model="row\.destinationWarehouseId"[^\n]+请选择 FBA 目的仓/) }) test('操作仓和FBA仓均从商户仓库目录按类型加载', () => { assert.match(view, /loadAllWarehouseRecords\('FBA', getMerchantWarehouses\)/) assert.match(view, /\['OVERSEAS', 'OVERSEAS_PARTNER'\]/) assert.match(view, /v-for="warehouse in operationWarehouses"/) assert.match(view, /v-for="warehouse in fbaWarehouses"/) assert.doesNotMatch(view, /美西海外仓-ONT8/) }) test('选择海外操作仓后自动带出仓库签收联系方式', () => { assert.match(warehouseApi, /contactName: string \| null/) assert.match(warehouseApi, /contactPhone: string \| null/) assert.match(view, /form\.contact = warehouse\?\.contactName \|\| ''/) assert.match(view, /form\.phone = warehouse\?\.contactPhone \|\| ''/) assert.match(view, /海外仓签收联系人/) assert.match(view, /海外仓联系电话/) assert.doesNotMatch(view, /ElMessage\.warning\('该海外仓主数据未完整维护/) assert.match(view, /form\.warehouse && !form\.contact[^\n]+warehouse-unmaintained[^\n]+未维护/) assert.match(view, /form\.warehouse && !form\.phone[^\n]+warehouse-unmaintained[^\n]+未维护/) }) test('贴标详情展示箱唛、SKU 子明细和独立FBA目的仓', () => { assert.match(api, /export interface RelabelDetail/) assert.match(view, /item\.cartonMark \|\| '—'/) assert.match(view, /item\.fbaCartonMark \|\| '—'/) assert.match(view, /item\.destinationFbaWarehouseCode/) assert.match(view, /item\.operationType === 'CARTON_AND_SKU'/) assert.match(view, /item\.skuItems\?\.length/) }) test('客户在换标列表确认完工且照片使用二进制下载', () => { assert.match(view, /row\.__status === 'CUSTOMER_CONFIRM_PENDING'/) assert.match(view, /confirmRelabelFromList\(row\['0'\]\)/) assert.doesNotMatch(view, /selectedRelabelDetail\?\.application\.status === 'CUSTOMER_CONFIRM_PENDING'/) assert.match(api, /overseasBlobRequest/) }) test('客户详情进入页面后直接回显完工照片并支持大图预览', () => { assert.match(view, /void loadCompletionPhotos\(\)/) assert.match(view, /class="warehouse-photo-grid"/) assert.match(view, /照片 \{\{ index \+ 1 \}\}<\/el-button>/) }) test('进入复核后客户订单回显换标完成状态', () => { assert.match(view, /\['CUSTOMER_CONFIRM_PENDING', 'READY_FOR_OUTBOUND', 'COMPLETED'\]\.includes\(value\) \? '换标完成'/) })