diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index ffa0cb239..3ffecbda1 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -16533,8 +16533,6 @@ BEGIN END IF; END$$ DELIMITER ; -CALL assert_finance_permissions(); -DROP PROCEDURE IF EXISTS assert_finance_permissions; -- IAM 跨区安全事件可靠发送箱。来源:iam/src/main/resources/db/security-event-outbox.sql USE baiyue_iam; @@ -17604,12 +17602,6 @@ DELIMITER ; CALL baiyue_firstleg.ensure_smart_loading_candidate_indexes(); DROP PROCEDURE IF EXISTS baiyue_firstleg.ensure_smart_loading_candidate_indexes; -CALL baiyue_firstleg.assert_unified_final_schema(); -DROP PROCEDURE IF EXISTS baiyue_firstleg.assert_unified_final_schema; -SELECT 'PASS' AS migration_status, - '统一增量全部执行完成;父子订单、履约分片、装柜门禁、订舱拖车、报关船期、船司查询、仓库角色、费用、Finance人工财务、公共资源、可靠审计及IAM安全事件结构校验通过' AS message; - - -- 一件代发客户资金账户:实际余额优先,授信额度补足;冻结后结算或解冻。 USE baiyue_finance; CREATE TABLE IF NOT EXISTS fin_wallet_account ( @@ -17875,7 +17867,9 @@ DELIMITER ; CALL migrate_wallet_permissions(); DROP PROCEDURE IF EXISTS migrate_wallet_permissions; -SELECT '统一增量全部执行完成;父子订单、履约分片、装柜门禁、订舱拖车、报关船期、船司查询、仓库角色、费用、Finance人工财务、客户资金账户、公共资源、可靠审计及IAM安全事件结构校验通过' AS message; +-- 钱包写权限属于 Finance 权限总数的一部分,必须先完成钱包权限迁移再做总量断言。 +CALL assert_finance_permissions(); +DROP PROCEDURE IF EXISTS assert_finance_permissions; USE baiyue_finance; @@ -17920,3 +17914,26 @@ SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE tab PREPARE lx_inbound_ddl FROM @ddl; EXECUTE lx_inbound_ddl; DEALLOCATE PREPARE lx_inbound_ddl; SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='baiyue_lastleg' AND table_name='ll_outbound_order' AND column_name='lx_codes'), 'SELECT 1', 'ALTER TABLE baiyue_lastleg.ll_outbound_order ADD COLUMN lx_codes VARCHAR(1000) NULL COMMENT ''关联一件代发领星入库单代码汇总'' AFTER outbound_type')); PREPARE lx_outbound_ddl FROM @ddl; EXECUTE lx_outbound_ddl; DEALLOCATE PREPARE lx_outbound_ddl; +DROP PROCEDURE IF EXISTS assert_wallet_event_schema; +DELIMITER $$ +CREATE PROCEDURE assert_wallet_event_schema() +BEGIN + IF (SELECT COUNT(*) FROM information_schema.TABLES + WHERE TABLE_SCHEMA='baiyue_finance' + AND TABLE_NAME IN ('fin_wallet_command_inbox','fin_wallet_event_outbox')) <> 2 THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='统一迁移失败:客户资金跨区事件表不完整'; + END IF; + IF (SELECT COUNT(*) FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA='baiyue_finance' AND TABLE_NAME='fin_wallet_event_outbox' + AND INDEX_NAME='uk_fin_wallet_event_key' AND NON_UNIQUE=0) <> 1 THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='统一迁移失败:客户资金结果事件幂等索引不完整'; + END IF; +END$$ +DELIMITER ; +CALL assert_wallet_event_schema(); +DROP PROCEDURE IF EXISTS assert_wallet_event_schema; + +CALL baiyue_firstleg.assert_unified_final_schema(); +DROP PROCEDURE IF EXISTS baiyue_firstleg.assert_unified_final_schema; +SELECT 'PASS' AS migration_status, + '统一增量全部执行完成;父子订单、履约分片、装柜门禁、订舱拖车、报关船期、船司查询、仓库角色、费用、Finance人工财务、客户资金账户、公共资源、可靠审计及IAM安全事件结构校验通过' AS message; diff --git a/finance/src/test/java/com/baiyue/finance/FinanceContractTest.java b/finance/src/test/java/com/baiyue/finance/FinanceContractTest.java index 7f2695f70..a7d673357 100644 --- a/finance/src/test/java/com/baiyue/finance/FinanceContractTest.java +++ b/finance/src/test/java/com/baiyue/finance/FinanceContractTest.java @@ -45,5 +45,10 @@ class FinanceContractTest { assertTrue(unified.contains("CREATE DATABASE IF NOT EXISTS baiyue_finance")); assertTrue(unified.contains("assert_finance_permissions")); assertTrue(unified.contains("merchant:finance:statement:view")); + int walletEventSchema = unified.indexOf("CREATE TABLE IF NOT EXISTS fin_wallet_event_outbox"); + int finalPass = unified.lastIndexOf("SELECT 'PASS' AS migration_status"); + assertTrue(walletEventSchema >= 0); + assertTrue(finalPass > walletEventSchema); + assertTrue(unified.contains("CREATE PROCEDURE assert_wallet_event_schema()")); } } diff --git a/iam/src/test/java/com/baiyue/iam/repository/AdminPrototypeMenuPermissionSqlContractTest.java b/iam/src/test/java/com/baiyue/iam/repository/AdminPrototypeMenuPermissionSqlContractTest.java index 2a0616e1e..2075ae94c 100644 --- a/iam/src/test/java/com/baiyue/iam/repository/AdminPrototypeMenuPermissionSqlContractTest.java +++ b/iam/src/test/java/com/baiyue/iam/repository/AdminPrototypeMenuPermissionSqlContractTest.java @@ -66,7 +66,9 @@ class AdminPrototypeMenuPermissionSqlContractTest { .contains("客户全局 Finance 权限模板不完整") .contains("客户全局管理员 Finance 模板授权不完整") .satisfies(content -> assertThat(content.indexOf("(5105050,0,'PLATFORM','BUTTON'")) - .isLessThan(content.indexOf("CREATE PROCEDURE assert_finance_permissions()"))); + .isLessThan(content.indexOf("CREATE PROCEDURE assert_finance_permissions()"))) + .satisfies(content -> assertThat(content.indexOf("CALL migrate_wallet_permissions();")) + .isLessThan(content.indexOf("CALL assert_finance_permissions();"))); } @Test diff --git a/scripts/admin-test-env-modules/phase4-overseas-client-services-contract.test.mjs b/scripts/admin-test-env-modules/phase4-overseas-client-services-contract.test.mjs index 821664d07..7c1e3fb22 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-client-services-contract.test.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-client-services-contract.test.mjs @@ -29,6 +29,7 @@ test('module never borrows historical order or inventory candidates', () => { }) test('relabel transfer and discard cover create replay conflict list detail and legal initial states', () => { + assert.match(source, /chargeAmount: 0\.01/) for (const token of [ '客户创建贴标申请', '客户贴标申请幂等重放', '贴标同幂等键异载荷返回A0409', '客户查询自身贴标申请列表', '客户查询自身贴标申请详情', 'PENDING_PROCESSING', diff --git a/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs b/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs index 830e9b614..3b01ca857 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs @@ -93,6 +93,7 @@ async function verifyRelabel(context, token, order) { customerOrderNo: order.row.orderNo, overseasWarehouseId: order.row.overseasWarehouseId, labelDeadline: future(7), contactName: '客户贴标验收联系人', contactPhone: '13800000006', + chargeAmount: 0.01, remark: context.marker, idempotencyKey: `${context.marker}-CLIENT-RELABEL`.slice(0, 255), items: [{ skuCode: cargo.skuCode, productImageFileId: null, productImageFileName: null, productImageUrl: null,