diff --git a/firstleg/src/main/java/com/baiyue/firstleg/mapper/LoadingListQueryMapper.java b/firstleg/src/main/java/com/baiyue/firstleg/mapper/LoadingListQueryMapper.java index 99f9d342a..bef28499c 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/mapper/LoadingListQueryMapper.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/mapper/LoadingListQueryMapper.java @@ -332,9 +332,6 @@ public interface LoadingListQueryMapper { @Select(""" SELECT CASE WHEN EXISTS (SELECT 1 FROM fl_loading_pick_task task - JOIN fl_loading_pick_assignment assignment ON assignment.pick_task_id=task.id - WHERE task.loading_plan_id=#{planId}) - OR EXISTS (SELECT 1 FROM fl_loading_pick_task task WHERE task.loading_plan_id=#{planId} AND task.task_status<>'LOADING') OR EXISTS (SELECT 1 FROM fl_loading_pick_task task JOIN fl_loading_pick_item item ON item.pick_task_id=task.id diff --git a/scripts/admin-test-env-acceptance.mjs b/scripts/admin-test-env-acceptance.mjs index e9a598f84..92e45847d 100644 --- a/scripts/admin-test-env-acceptance.mjs +++ b/scripts/admin-test-env-acceptance.mjs @@ -315,7 +315,7 @@ function usage() { 也可使用环境变量: ADMIN_TEST_GATEWAY, ADMIN_OVERSEAS_GATEWAY, ADMIN_TEST_USERNAME, ADMIN_TEST_PASSWORD, ADMIN_TEST_WEIGHT_IMAGE_PATH, ADMIN_TEST_CUSTOMER_NAME, MERCHANT_TEST_USERNAME, -MERCHANT_TEST_PASSWORD, ADMIN_WAIT_SPLIT_COUNT`) +MERCHANT_TEST_PASSWORD, ADMIN_PDA_USERNAME, ADMIN_PDA_PASSWORD, ADMIN_WAIT_SPLIT_COUNT`) } export function parseArguments(argv) { @@ -356,6 +356,8 @@ export function parseArguments(argv) { overseasGateway: (values.get('overseas-gateway') || process.env.ADMIN_OVERSEAS_GATEWAY || '').replace(/\/$/, ''), username: values.get('username') || process.env.ADMIN_TEST_USERNAME || '', password: values.get('password') || process.env.ADMIN_TEST_PASSWORD || '', + pdaUsername: values.get('pda-username') || process.env.ADMIN_PDA_USERNAME || '', + pdaPassword: values.get('pda-password') || process.env.ADMIN_PDA_PASSWORD || '', modules, requestedModules, customerName: values.get('customer-name') || process.env.ADMIN_TEST_CUSTOMER_NAME || '', @@ -551,6 +553,7 @@ export class AcceptanceRun { this.coverageGaps = [] this.context = {} this.token = '' + this.pdaToken = '' this.refreshToken = '' this.overseasToken = '' this.overseasExpiresAt = 0 @@ -559,6 +562,7 @@ export class AcceptanceRun { async request(method, path, body = undefined, token = this.token, extraHeaders = {}) { const headers = { Accept: 'application/json', ...extraHeaders } + if (this.pdaToken && /\/pda-loading\/tasks\/\d+/.test(String(path))) token = this.pdaToken if (token) headers.Authorization = `Bearer ${token}` if (body !== undefined) headers['Content-Type'] = 'application/json; charset=utf-8' const maxAttempts = ['GET', 'HEAD'].includes(String(method).toUpperCase()) ? 3 : 1 @@ -1756,6 +1760,15 @@ export class AcceptanceRun { if (!login?.accessToken) this.fatal = '平台管理员登录失败,未执行业务模块' else { this.token = login.accessToken + if (this.options.pdaUsername && this.options.pdaPassword) { + const pdaLoginResponse = await this.request('POST', '/api/auth/login', { + loginId: this.options.pdaUsername, password: this.options.pdaPassword, + }, '') + const pdaLogin = this.apiSuccess('authentication', '国内 PDA 作业员登录', pdaLoginResponse) + this.pdaToken = pdaLogin?.accessToken || '' + this.assert('authentication', 'PDA 作业员登录成功', pdaLoginResponse, Boolean(this.pdaToken), + `tokenPresent=${Boolean(this.pdaToken)}`, { deploymentBlocker: true, scenario: 'phase3-pda' }) + } this.refreshToken = login.refreshToken || '' this.overseasToken = login.overseasAccessToken || '' this.overseasExpiresAt = Number(login.overseasExpiresIn) > 0 diff --git a/scripts/admin-test-env-modules/manual-state-loading-pda.mjs b/scripts/admin-test-env-modules/manual-state-loading-pda.mjs index 1943e6fb1..5bf1f7b3a 100644 --- a/scripts/admin-test-env-modules/manual-state-loading-pda.mjs +++ b/scripts/admin-test-env-modules/manual-state-loading-pda.mjs @@ -222,7 +222,7 @@ async function createPlanTask(context, label) { if (!pdaOperator?.userId) throw new Error(`${label} 缺少可用 PDA 作业员`) const confirmPath = `${LOADING}/loading-plans/${planId}/confirm` - const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: Number(pdaOperator.userId) }) + const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: id(pdaOperator.userId) }) const confirmHeaders = Object.freeze({ 'Idempotency-Key': operationId(context, `${label}-plan-confirm`), }) diff --git a/scripts/admin-test-env-modules/phase3-container-loading.mjs b/scripts/admin-test-env-modules/phase3-container-loading.mjs index 3181c1931..437edd239 100644 --- a/scripts/admin-test-env-modules/phase3-container-loading.mjs +++ b/scripts/admin-test-env-modules/phase3-container-loading.mjs @@ -56,7 +56,7 @@ async function request(context, method, path, body, headers = {}) { const response = await fetch(`${context.options.gateway}${path}`, { method, headers: { - Accept: 'application/json', Authorization: `Bearer ${context.token}`, + Accept: 'application/json', Authorization: `Bearer ${context.pdaToken && /\/pda-loading\/tasks\/\d+/.test(path) ? context.pdaToken : context.token}`, ...(body === undefined ? {} : { 'Content-Type': 'application/json; charset=utf-8' }), ...headers, }, body: body === undefined ? undefined : JSON.stringify(body), signal: AbortSignal.timeout(60_000), @@ -568,7 +568,7 @@ export async function run(context) { Boolean(pdaOperator?.userId), `operatorId=${id(pdaOperator?.userId) || 'missing'}`, OPTIONS) if (!pdaOperator?.userId) return const confirmPath = `${FIRST_LEG}/loading-plans/${planId}/confirm` - const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: Number(pdaOperator.userId) }) + const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: id(pdaOperator.userId) }) const confirmHeaders = Object.freeze({ 'Idempotency-Key': `${context.marker}-container-plan-confirm`.slice(0, 128), }) @@ -590,7 +590,7 @@ export async function run(context) { && Number(confirmReplayResponse.body?.data?.version) === Number(confirmedPreload.version), responseEvidence(confirmReplayResponse), OPTIONS) const confirmSameKeyDifferentBody = await request(context, 'POST', confirmPath, - { expectedVersion: Number(confirmedPreload.version) }, confirmHeaders) + { expectedVersion: Number(confirmedPreload.version), assigneeId: id(pdaOperator.userId) }, confirmHeaders) context.addStep(MODULE, '计划级确认同 key 异参返回冲突', confirmSameKeyDifferentBody, confirmSameKeyDifferentBody.http === 200 && codeOf(confirmSameKeyDifferentBody) === 'A0409', responseEvidence(confirmSameKeyDifferentBody), OPTIONS) diff --git a/scripts/admin-test-env-modules/phase3-loading.mjs b/scripts/admin-test-env-modules/phase3-loading.mjs index 35326f75e..e34fef960 100644 --- a/scripts/admin-test-env-modules/phase3-loading.mjs +++ b/scripts/admin-test-env-modules/phase3-loading.mjs @@ -77,7 +77,7 @@ async function request(context, method, path, body, headers = {}) { try { const response = await fetch(`${context.options.gateway}${path}`, { method, - headers: { Accept: 'application/json', Authorization: `Bearer ${context.token}`, ...(body === undefined ? {} : { 'Content-Type': 'application/json; charset=utf-8' }), ...headers }, + headers: { Accept: 'application/json', Authorization: `Bearer ${context.pdaToken && /\/pda-loading\/tasks\/\d+/.test(path) ? context.pdaToken : context.token}`, ...(body === undefined ? {} : { 'Content-Type': 'application/json; charset=utf-8' }), ...headers }, body: body === undefined ? undefined : JSON.stringify(body), signal: AbortSignal.timeout(60_000), }) const raw = await response.text(); let payload = null @@ -672,7 +672,7 @@ export async function run(context) { Boolean(pdaOperator?.userId), `operatorId=${id(pdaOperator?.userId) || 'missing'}`, OPTIONS) if (!pdaOperator?.userId) return const confirmPath = `/api/platform/v1/first-leg/loading-plans/${loadingPlanId}/confirm` - const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: Number(pdaOperator.userId) }) + const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: id(pdaOperator.userId) }) const confirmHeaders = Object.freeze({ 'Idempotency-Key': `${context.marker}-p3-plan-confirm`.slice(0, 128) }) const confirm = await request(context, 'POST', confirmPath, confirmBody, confirmHeaders) const confirmed = context.apiSuccess(MODULE, '计划级原子确认整份预装并触发唯一 PDA 任务', confirm, '', OPTIONS) diff --git a/scripts/admin-test-env-modules/phase3-order-splitting.mjs b/scripts/admin-test-env-modules/phase3-order-splitting.mjs index fe93b8096..14069d148 100644 --- a/scripts/admin-test-env-modules/phase3-order-splitting.mjs +++ b/scripts/admin-test-env-modules/phase3-order-splitting.mjs @@ -345,7 +345,7 @@ async function loadOneFragment(context, state) { if (!pdaOperator?.userId) return null const confirmPath = `/api/platform/v1/first-leg/loading-plans/${encodeURIComponent(planId)}/confirm` - const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: Number(pdaOperator.userId) }) + const confirmBody = Object.freeze({ expectedVersion: confirmableVersion, assigneeId: id(pdaOperator.userId) }) const confirmHeaders = Object.freeze({ 'Idempotency-Key': `${operationBase}-plan-confirm`.slice(0, 128) }) const confirmResponse = await request(context, 'POST', confirmPath, confirmBody, confirmHeaders) const confirmed = context.apiSuccess(MODULE, `计划级确认 ${sourceOrderNo} 并生成唯一 PDA 任务`, confirmResponse, '', OPTIONS)