diff --git a/scripts/admin-test-env-acceptance.mjs b/scripts/admin-test-env-acceptance.mjs index 05f1e7558..8ba0489d4 100644 --- a/scripts/admin-test-env-acceptance.mjs +++ b/scripts/admin-test-env-acceptance.mjs @@ -5,7 +5,7 @@ import { dirname, resolve } from 'node:path' import { pathToFileURL } from 'node:url' import process from 'node:process' -const CONFIGURED_MODULES = ['merchant-qualification-fixture', 'customers', 'overseas-storage-fees', 'system', 'notifications', 'master-data', 'suppliers', 'domestic-container', 'orders', 'fee-items', 'pricing', 'downloads', 'inbound-weight-ocr', 'inbound-measurement', 'inbound-fees', 'phase3-container-loading', 'phase3-container-overview', 'phase3-loading', 'phase3-loading-model-bridge', 'phase3-pda-convergence', 'phase3-evidence-gate', 'supplemental', 'supplemental-boundaries', 'ocean-bookings', 'truck-appointments', 'service-center-flow', 'phase3-loading-finalize', 'phase3-container-documents', 'phase3-customs', 'phase3-container-customs', 'phase3-port-schedules', 'phase3-carrier-schedule-queries', 'phase3-outbound-dispatch', 'phase3-outbound-aggregate', 'phase3-dispatch-gate', 'phase3-waiting-for-loading', 'phase3-warehouse-rbac', 'phase3-order-splitting', 'manual-state-matrix', 'phase4-overseas-warehouse', 'phase4-carrier-pickup-ready', 'phase4-overseas-pda', 'phase4-overseas-pda-operations', 'phase4-overseas-inbound-operations', 'phase4-overseas-client-services', 'phase4-overseas-dispatch', 'phase4-cross-region-events', 'phase4-overseas-business', 'phase4-overseas-master-data', 'phase4-carrier-nodes', 'finance', 'finance-full-fixtures', 'finance-reconciliation-full', 'finance-settlement-full', 'finance-downloads', 'firstleg-container-fee-allocation', 'finance-direct-paid-isolation', 'phase4-overseas-finance-cross-region', 'customer-operating-statistics'] +const CONFIGURED_MODULES = ['merchant-qualification-fixture', 'customers', 'overseas-storage-fees', 'system', 'notifications', 'master-data', 'suppliers', 'domestic-container', 'orders', 'fee-items', 'pricing', 'downloads', 'inbound-weight-ocr', 'inbound-measurement', 'inbound-fees', 'phase3-container-loading', 'phase3-container-overview', 'phase3-loading', 'phase3-loading-model-bridge', 'phase3-pda-convergence', 'phase3-evidence-gate', 'supplemental', 'supplemental-boundaries', 'ocean-bookings', 'truck-appointments', 'service-center-flow', 'phase3-loading-finalize', 'phase3-container-documents', 'phase3-customs', 'phase3-container-customs', 'phase3-port-schedules', 'phase3-carrier-schedule-queries', 'phase3-outbound-dispatch', 'phase3-outbound-aggregate', 'phase3-dispatch-gate', 'phase3-waiting-for-loading', 'phase3-warehouse-rbac', 'phase3-order-splitting', 'manual-state-matrix', 'phase4-overseas-warehouse', 'phase4-carrier-pickup-ready', 'phase4-overseas-pda', 'phase4-overseas-pda-operations', 'phase4-overseas-inbound-operations', 'phase4-overseas-client-services', 'phase4-overseas-dispatch', 'phase4-cross-region-events', 'phase4-overseas-business', 'phase4-overseas-master-data', 'phase4-carrier-nodes', 'finance', 'finance-full-fixtures', 'finance-reconciliation-full', 'finance-direct-paid-isolation', 'finance-settlement-full', 'finance-downloads', 'firstleg-container-fee-allocation', 'phase4-overseas-finance-cross-region', 'customer-operating-statistics'] const OPTIONAL_MODULES = ['manual-order-splitting-fixture', 'manual-order-splitting-verify', 'manual-preload-push-fixture', 'manual-preload-push-verify', 'manual-pda-ready-fixture', 'manual-pda-ready-verify', @@ -914,11 +914,26 @@ export class AcceptanceRun { async findAvailablePhone(module = 'customers') { this.phoneSequence = Number(this.phoneSequence || 0) + 1 - const markerDigits = this.marker.replace(/\D/g, '').slice(-8).padStart(8, '0') - const phone = `18${markerDigits}${String(this.phoneSequence % 10).padStart(1, '0')}` - this.addStep(module, '生成本轮隔离测试联系电话', null, /^1\d{10}$/.test(phone), - `sequence=${this.phoneSequence}`) - return phone + for (let attempt = 0; attempt < 100; attempt += 1) { + const seed = `${this.marker}:${this.phoneSequence}:${attempt}` + let hash = 2166136261 + for (const character of seed) { + hash ^= character.charCodeAt(0) + hash = Math.imul(hash, 16777619) >>> 0 + } + const phone = `18${String(hash).padStart(9, '0').slice(-9)}` + const response = await this.request('GET', + `/api/platform/v1/iam/tenants/administrator-phone-availability?phone=${encodeURIComponent(phone)}`) + const available = response?.http === 200 && String(response?.body?.code) === '200' + && response?.body?.data === true + if (!available) continue + this.addStep(module, '生成本轮隔离测试联系电话', response, true, + `sequence=${this.phoneSequence}, attempts=${attempt + 1}`) + return phone + } + this.addStep(module, '生成本轮隔离测试联系电话', null, false, + `sequence=${this.phoneSequence}, attempts=100;未找到可用手机号`, { deploymentBlocker: true }) + throw new Error('未找到可用的隔离测试手机号') } async runCustomerDimensionRules(tenantId) {