From 601ae835047d2a77a5365afaec66d8f2d93b9e04 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 2 Sep 2026 16:01:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E6=95=9B=E6=B5=B7=E5=A4=96PDA?= =?UTF-8?q?=E5=9B=9E=E5=BD=92=E5=A4=B9=E5=85=B7=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin-test-env-modules/phase3-loading.mjs | 35 +++++++++++-------- .../phase3-producer-chain-contract.test.mjs | 9 +++-- .../phase4-overseas-pda.mjs | 2 +- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/scripts/admin-test-env-modules/phase3-loading.mjs b/scripts/admin-test-env-modules/phase3-loading.mjs index 10fd5475b..0c6973665 100644 --- a/scripts/admin-test-env-modules/phase3-loading.mjs +++ b/scripts/admin-test-env-modules/phase3-loading.mjs @@ -48,22 +48,27 @@ async function ensureMatsonSupplier(context, records) { } export function stableLoadedCartonMarks(items) { - const used = new Set() - return [...(Array.isArray(items) ? items : [])] + const groups = new Map() + for (const item of [...(Array.isArray(items) ? items : [])] .sort((left, right) => id(left?.loadingPlanItemId).localeCompare(id(right?.loadingPlanItemId))) - .flatMap((item) => { - const count = Math.max(0, Number(item?.pickedPackageCount) || 0) - const labels = [...new Set((item?.boxCodes || []) - .map((value) => String(value || '').trim()).filter((value) => value && !used.has(value)))] - // Partial loading keeps the lowest carton indexes on the loaded source inbound and - // transfers the highest indexes to the remainder child. Mirror that settlement rule - // instead of sampling labels, otherwise downstream PDA fixtures may reference cartons - // that were deliberately moved out of this container. - .sort((left, right) => left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' })) - .slice(0, count) - labels.forEach((value) => used.add(value)) - return labels - }) + ) { + const groupKey = id(item?.inboundId) || `item:${id(item?.loadingPlanItemId)}` + const group = groups.get(groupKey) || { count: 0, labels: new Set() } + group.count += Math.max(0, Number(item?.pickedPackageCount) || 0) + for (const value of item?.boxCodes || []) { + const label = String(value || '').trim() + if (label) group.labels.add(label) + } + groups.set(groupKey, group) + } + // Settlement transfers the highest carton indexes to the remainder child for the whole + // inbound, not per cargo line. Aggregate task rows by inbound before selecting the retained + // low indexes so the downstream fixture mirrors the persisted container manifest. + return [...groups.entries()] + .sort(([left], [right]) => left.localeCompare(right)) + .flatMap(([, group]) => [...group.labels] + .sort((left, right) => left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' })) + .slice(0, group.count)) } async function request(context, method, path, body, headers = {}) { diff --git a/scripts/admin-test-env-modules/phase3-producer-chain-contract.test.mjs b/scripts/admin-test-env-modules/phase3-producer-chain-contract.test.mjs index 14226516e..0352d3a6e 100644 --- a/scripts/admin-test-env-modules/phase3-producer-chain-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase3-producer-chain-contract.test.mjs @@ -447,9 +447,12 @@ test('preload and loading versions use immediate operation baselines and exact p test('loaded carton fixture mirrors partial settlement and keeps the lowest carton indexes', () => { const marks = stableLoadedCartonMarks([ - { loadingPlanItemId: '20', pickedPackageCount: 3, - boxCodes: ['NYEXX2609020358#8-5', 'NYEXX2609020358#8-2', 'NYEXX2609020358#8-1', 'NYEXX2609020358#8-3'] }, - { loadingPlanItemId: '10', pickedPackageCount: 1, boxCodes: ['NYEXX2609020357#4-4', 'NYEXX2609020357#4-1'] }, + { loadingPlanItemId: '30', inboundId: '200', pickedPackageCount: 1, + boxCodes: ['NYEXX2609020358#8-5'] }, + { loadingPlanItemId: '20', inboundId: '200', pickedPackageCount: 2, + boxCodes: ['NYEXX2609020358#8-2', 'NYEXX2609020358#8-1', 'NYEXX2609020358#8-3'] }, + { loadingPlanItemId: '10', inboundId: '100', pickedPackageCount: 1, + boxCodes: ['NYEXX2609020357#4-4', 'NYEXX2609020357#4-1'] }, ]) assert.deepEqual(marks, [ 'NYEXX2609020357#4-1', diff --git a/scripts/admin-test-env-modules/phase4-overseas-pda.mjs b/scripts/admin-test-env-modules/phase4-overseas-pda.mjs index b01062fb3..7f4ebbd84 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-pda.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-pda.mjs @@ -529,7 +529,7 @@ async function runReceiving(context, token, secondaryToken, merchantToken, prefe `/api/pda/v1/last-leg/receiving-containers/${encodeURIComponent(containerNo)}/prepare`, { idempotencyKey: key(context, 'secondary-prepare') }, conflict) } - const other = candidates.data.find((item) => item.containerNo !== containerNo) + const other = candidates.data.find((item) => item.containerNo !== containerNo && item.operable === true) if (other) await expected(context, token, 'GET', '当前账号跨柜切换锁返回409', `/api/pda/v1/last-leg/receiving-containers/${encodeURIComponent(other.containerNo)}`, undefined, conflict) else blockerGap(context, '跨柜锁409', '当前客户只有一个待收柜,无法在不伪造柜数据的前提下验证跨柜锁')