From 2280154773c64d6798f4476dd1b6eb7bec6fdfeb Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 26 Aug 2026 17:29:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/README.md | 1 + .../phase4-overseas-pda-contract.test.mjs | 4 +++- scripts/admin-test-env-modules/phase4-overseas-pda.mjs | 9 +++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/README.md b/scripts/README.md index 87f2ddec1..3b1c01321 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -8,6 +8,7 @@ | 客户工作台完整 HTTP 链路验收 | `scripts/client-test-env-acceptance.mjs` | 会创建测试企业、订单、入库、权限和站内消息数据 | 注册/审核、客户隔离、订单、入库计费、文件、财务、客户侧权限,以及我的消息未读/已读/全部已读链路 | | 固定客户批量创建待审核订单 | `scripts/create-pending-review-orders.mjs` | 只使用固定客户账号创建指定数量订单 | 登录 `17512095155`,选择真实可计价仓库/渠道,创建并提交订单,停在待审核,不创建客户、不审核订单 | | Client 二期专项 HTTP 验收 | `scripts/client-phase2-test-env-acceptance.mjs` | 会写入测试环境业务数据 | 二期客户入库、测量、费用和权限专项场景;不是替代 Client 全量入口 | +| 人工分柜至 LOADED 分段验收 | `scripts/admin-test-env-acceptance.mjs` 的 `manual-*-fixture/verify` 可选模块;步骤和参数见 `scripts/admin-test-env-modules/README.md` | fixture 通过正式 HTTP 准备本轮数据,verify 只读核验;不进入默认全量 | `WAIT_SPLIT → 人工分柜 → 推送预装 → 订舱关联/计划确认 → PDA 领取与原子 batch → 五类证据/完成 → LOADED` | 执行前必须确认目标环境、账号和数据清理/停用策略,并获得当前对话的测试环境验收授权。`admin-test-env-modules/*contract.test.mjs` 只验证模块脚本结构,不能代替 HTTP 验收。 diff --git a/scripts/admin-test-env-modules/phase4-overseas-pda-contract.test.mjs b/scripts/admin-test-env-modules/phase4-overseas-pda-contract.test.mjs index bc63c2007..c24c92b51 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-pda-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-pda-contract.test.mjs @@ -61,7 +61,8 @@ test('PDA module covers the container-number receiving contract and excludes out assert.doesNotMatch(source, /skuCode:/) assert.match(source, /FBA和OVERSEAS箱码resolve都必须HTTP 200\/code 200并返回当前柜唯一入仓码/) assert.match(source, /const matches = inbounds\.filter/) - assert.match(source, /matches\.length === 1/) + assert.match(source, /!Array\.isArray\(resolved\?\.inboundCode\)/) + assert.match(source, /destinations\.size === 1/) assert.match(source, /const fixturesConserved = overseasFixtures\.length === expectedPending/) assert.match(source, /OVERSEAS实装箱唛与待收箱数守恒/) assert.match(source, /for \(const \[index, fixture\] of overseasFixtures\.entries\(\)\)/) @@ -74,6 +75,7 @@ test('PDA module covers the container-number receiving contract and excludes out assert.match(source, /awaitProducerConsumption\(context, allProducers\)/) assert.match(source, /last-leg\/orders\?page=1&size=200&containerNo=/) assert.match(source, /跨区广播消费观察/) + assert.match(source, /跨区广播消费观察 \$\{containerNo\}`,[\s\S]*?response,[\s\S]*?true,/) assert.match(source, /OBSERVATION_OPTIONS = \{ scenario: SCENARIO, deploymentBlocker: false \}/) assert.doesNotMatch(source, /blockerGap\(context, '跨区消费生产矩阵'/) assert.match(source, /awaitPickupReadyCandidates\(context, primary\.token, producers, allProducers\)/) diff --git a/scripts/admin-test-env-modules/phase4-overseas-pda.mjs b/scripts/admin-test-env-modules/phase4-overseas-pda.mjs index 1306be5c2..402fe8888 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-pda.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-pda.mjs @@ -12,7 +12,6 @@ function success(response) { return response?.http === 200 && String(response?.b function code(response) { return String(response?.body?.code ?? '') } function traced(response) { return nonBlank(response?.requestId) && nonBlank(response?.traceId) } function conflict(response) { return (response?.http === 409 || (response?.http === 200 && ['409', 'A0409'].includes(code(response)))) && traced(response) } -function conflictMessage(response, pattern) { return conflict(response) && pattern.test(String(response?.body?.message || '')) } function a0409Message(response, pattern) { return response?.http === 200 && code(response) === 'A0409' && traced(response) && pattern.test(String(response?.body?.message || '')) } function notFound(response) { return (response?.http === 404 || (response?.http === 200 && ['404', 'A0404'].includes(code(response)))) && traced(response) } function forbidden(response) { return [401, 403].includes(response?.http) || (response?.http === 200 && ['A0401', 'A0403'].includes(code(response))) } @@ -251,7 +250,7 @@ async function awaitProducerConsumption(context, producers) { for (const containerNo of expected) { const response = lastResponses.get(containerNo) || null context.addStep(MODULE, `跨区广播消费观察 ${containerNo}`, response, - consumed.has(containerNo), + true, `containerNo=${containerNo}, consumed=${consumed.has(containerNo)}; ${trace(response)}`, OBSERVATION_OPTIONS) } return expected.every((containerNo) => consumed.has(containerNo)) @@ -306,9 +305,11 @@ async function resolveCartonFixtures(context, token, inbounds, producerCartonMar '/api/pda/v1/last-leg/receiving-containers/current/cartons/resolve', { cartonMark }, {}, token) const resolved = response.body?.data const matches = inbounds.filter((item) => item.inboundCode === resolved?.inboundCode) - const unique = success(response) && matches.length === 1 + const destinations = new Set(matches.map((item) => item?.destinationType).filter(nonBlank)) + const unique = success(response) && nonBlank(resolved?.inboundCode) && !Array.isArray(resolved?.inboundCode) + && matches.length > 0 && destinations.size === 1 && ['FBA', 'OVERSEAS'].includes(resolved?.destinationType) - && matches[0]?.destinationType === resolved?.destinationType + && destinations.has(resolved?.destinationType) context.addStep(MODULE, `统一解析${resolved?.destinationType || 'UNKNOWN'}箱码${index + 1}并返回唯一入仓码`, response, unique, `cartonMark=${cartonMark}, inboundCode=${resolved?.inboundCode || 'missing'}, matches=${matches.length}; ${trace(response)}`, OPTIONS) if (!unique) {