fix(pda): prepare 0.1.0 package and refresh counting retry keys

This commit is contained in:
2026-11-06 13:53:33 +08:00
parent 7e793b1d1b
commit 9c17ec2779
4 changed files with 17 additions and 12 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
"name" : "柏悦物流 PDA 海外版",
"appid" : "__UNI__936D079",
"description" : "柏悦物流海外仓 PDA 作业端",
"versionName" : "0.0.5",
"versionCode" : 5,
"versionName" : "0.1.0",
"versionCode" : 10,
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
@@ -362,7 +362,10 @@ export default {
const detail = await countWarehouseTransferCartons(this.selected.transferNo, { idempotencyKey: this.cartonRequestKey, boxes, discrepancyReason: this.countDiscrepancyReason, forecastPackageCount: Number(this.selected.packageCount) });
if (!detail.cartons?.length || !detail.cartons.every(box => box.countedAt)) throw new Error('清点结果未确认,请刷新核实');
uni.setStorageSync(this.cartonDraftKey(), { deletedBoxes: this.deletedCartonBoxes }); this.selected = detail; this.pallets = detail.pallets.map(restoredPallet); this.restoreCartons();
} catch (error) { this.error = error } finally { this.countingCartons = false }
} catch (error) { this.error = error } finally {
this.countingCartons = false;
this.cartonRequestKey = ''; this.cartonSignature = '';
}
},
openPalletOperations() { uni.navigateTo({ url: '/pages/pallet/pallet' }) },
destinationLabel(value, fallback = {}) { const code = String(value?.fbaWarehouseCode || fallback?.fbaWarehouseCode || '').trim(); if (code) return code; const type = value?.destinationType || fallback?.destinationType; return type === 'PRIVATE' ? '私人仓' : '目的仓待定' },
+5 -3
View File
@@ -25,9 +25,9 @@ const read = (path) => readFile(new URL(path, import.meta.url), 'utf8')
test('outbound list and detail lead with the outbound number and label the task number separately', async () => {
const page = await read('../src/pages/outbound/outbound.vue')
assert.match(page, /class="business-code">\{\{ task\.outboundNo \|\| '—' \}\}/)
assert.match(page, /class="pda-task-no">\{\{ task\.outboundNo \|\| '—' \}\}/)
assert.match(page, /class="business-code">\{\{ current\.outboundNo \|\| '—' \}\}/)
assert.match(page, /任务号 \{\{ task\.taskNo \|\| '—' \}\}/)
assert.match(page, /任务号 \{\{ task\.taskNo \}\}/)
assert.match(page, /任务号 \{\{ current\.taskNo \|\| '—' \}\}/)
assert.match(page, /@tap="openTask\(task\.taskNo\)"/)
})
@@ -248,10 +248,12 @@ test('native action gates reject strings and retain server block reasons', () =>
async function dispatchScanHarness(items) {
const source = (await read('../src/pages/dispatch/dispatch.vue')).match(/<script>([\s\S]*?)<\/script>/)[1]
const draft={palletCode:'OLD',dispatchItemId:'old',cartonCode:''};let sounds=0
const deps={PortalHeader:{},ScanTargetInput:{},DispatchHandoverStatus:{},DispatchLoadingDocuments:{},fulfillment:{dispatch:draft},updateFulfillmentDraft:(_,value)=>Object.assign(draft,value),playSuccessSound:()=>{sounds++}}
const deps={PortalHeader:{},ScanTargetInput:{},DispatchHandoverStatus:{},DispatchLoadingDocuments:{},fulfillment:{dispatch:draft},updateFulfillmentDraft:(_,value)=>Object.assign(draft,value),playSuccessSound:()=>{sounds++},clearTimeout:()=>{},setTimeout:()=>0}
const definition=new Function(...Object.keys(deps),source.replace(/^\s*import .*$/gm,'').replace('export default','return'))(...Object.values(deps))
const state={activeTab:'picking',current:{dispatchNo:'DS-TEST',stage:'LOADING',actions:{PICK:{allowed:true}},items:items.map(item=>({sourceKey:`source-${item.dispatchItemId}`,sourceBusinessType:'RELABEL_ORDER',sourceBusinessNo:`RL-${item.dispatchItemId}`,positions:[],...item,returnCartons:item.returnCartons||[]}))},error:{message:'previous error'},successMessage:'',setError(error){this.error={message:error.message}}}
state.gate=definition.methods.gate.bind(state);state.selectPallet=definition.methods.selectPallet.bind(state);state.chooseSource=definition.methods.chooseSource.bind(state)
state.clearScanNotice = definition.methods.clearScanNotice.bind(state)
state.showScanNotice = definition.methods.showScanNotice.bind(state)
return {state,draft,scan:definition.methods.handleScan.bind(state),sounds:()=>sounds}
}
+6 -6
View File
@@ -52,8 +52,8 @@ test('login has no committed demo credentials and inbound operation implements t
assert.match(runtime, /#ifdef H5[\s\S]*?VITE_H5_API_BASE_URL/)
assert.match(runtime, /#ifdef H5[\s\S]*?VITE_H5_API_BASE_URL/)
assert.match(operation, /startScanBroadcast/)
assert.match(operation, /palletWorkflowActive = Boolean\(this\.activeInbound \|\| this\.resolvedPallet\)/)
assert.match(operation, /queuedTarget: scan\.target/)
assert.match(operation, /this\.current === current && this\.activeInbound === inbound && this\.activeInbound\.inboundCode === inboundCode/)
assert.match(operation, /dispatchHardwareScan\(scan\)[\s\S]*this\.activeInbound && this\.activeTarget === 'pallet'[\s\S]*this\.resolvePallet\(scan\.value\)/)
for (const action of ['prepareReceivingContainer', 'getCurrentReceiving', 'resolveCurrentCarton', 'resolveCurrentPallet', 'receiveCurrentBulk', 'receiveCurrentCarton', 'receiveCurrentWholePallet', 'completeCurrentReceiving']) assert.match(operation, new RegExp(action))
for (const path of ['/candidates', '/prepare', '/unload-photos/files', '/sign', '/cartons/resolve', '/pallets/resolve', '/receipts/bulk', '/receipts/carton', '/receipts/pallet', '/complete']) assert.match(inbound, new RegExp(path.replaceAll('/', '\\/')))
assert.match(inbound, /current\('\/pallets\/resolve'\)/)
@@ -70,7 +70,7 @@ test('login has no committed demo credentials and inbound operation implements t
assert.match(operation, /clearReceiptContext\(\)[\s\S]*activeScanTarget = 'carton'[\s\S]*scheduleScanDrain/)
assert.match(operation, /name="pallet"[\s\S]*@activate="activeTarget = 'pallet'"/)
assert.match(operation, /receiving\.activeScanTarget = 'pallet'/, '普通FBA或中转解析后直接进入托盘扫码以减少操作')
assert.match(operation, /\[Overseas PDA scan\] dispatch/)
assert.match(operation, /this\.scanQueue\.push\(scan\)[\s\S]*this\.dispatchHardwareScan\(scan\)/)
assert.match(operation, /\[Overseas PDA cargo\] failed[\s\S]*requestId[\s\S]*traceId/)
for (const role of ['LICENSE_PLATE', 'CONTAINER_SEAL', 'DOOR_OPEN']) assert.match(adapter, new RegExp(role))
for (const forbidden of ['customerId', 'planNo', 'allocationId', 'warehouseId', 'locationId']) assert.doesNotMatch(inbound, new RegExp(forbidden))
@@ -125,8 +125,8 @@ test('candidate containers use compact card navigation and a small refresh actio
assert.match(operation, /class="container-card container-card-compact"[\s\S]*container-card-disabled[\s\S]*@tap="openContainer\(item\)"/)
assert.match(operation, /class="container-detail-link"/)
assert.doesNotMatch(operation, /<button class="primary-button"[^>]*openContainer\(item\.containerNo\)/)
assert.match(operation, /class="list-toolbar"><text>共 \{\{ candidates\.length \}\} 柜<\/text>/)
assert.match(operation, /\.list-toolbar button\{[^}]*height:28px[^}]*min-height:28px/)
assert.match(operation, /class="list-toolbar">\s*<text>共 \{\{ candidates\.length \}\} 柜<\/text>/)
assert.match(operation, /\.list-toolbar button\{[^}]*height:36px[^}]*min-height:36px/)
assert.match(operation, /class="candidate-facts"[\s\S]*总订单[\s\S]*入仓码[\s\S]*已生成计划[\s\S]*未操作/)
assert.match(operation, /class="candidate-destinations"/)
assert.match(operation, /计划到仓:\{\{ formatPlannedArrival\(item\.plannedArrivalAt\) \}\}/)
@@ -189,7 +189,7 @@ test('return packing is a separate same-customer inventory operation', async ()
test('home reuses the persisted warehouse profile instead of requesting it on every show', async () => {
const [home, inbound, operation] = await Promise.all([read('../src/pages/home/home.vue'), read('../src/api/inbound.js'), read('../src/pages/operation/operation.vue')])
assert.match(home, /if \(!this\.user\?\.warehouseCode \|\| !this\.user\?\.warehouseName\) this\.loadWarehouseProfile\(\)/)
assert.match(home, /if \(!this\.user\?\.warehouseCode \|\| !this\.user\?\.warehouseName\) await this\.loadWarehouseProfile\(\)/)
assert.match(inbound, /let warehouseProfileRequest = null/)
assert.match(inbound, /if \(!warehouseProfileRequest\)[\s\S]*\.finally\(\(\) => \{ warehouseProfileRequest = null \}\)/)
assert.match(operation, /await this\.refreshBoundWarehouse\(\)[\s\S]*await this\.loadCandidates\(false, false\)/)