diff --git a/auth/src/main/resources/db/auth-login-identifiers.sql b/auth/src/main/resources/db/auth-login-identifiers.sql index 5f36ab421..f5161b038 100644 --- a/auth/src/main/resources/db/auth-login-identifiers.sql +++ b/auth/src/main/resources/db/auth-login-identifiers.sql @@ -20,15 +20,18 @@ DROP PROCEDURE IF EXISTS auth_backfill_login_phone; DELIMITER $$ CREATE PROCEDURE auth_backfill_login_phone() BEGIN - IF EXISTS ( - SELECT user.phone - FROM baiyue_iam.iam_user user - WHERE user.deleted = 0 AND user.phone REGEXP '^1[3-9][0-9]{9}$' - GROUP BY user.phone HAVING COUNT(DISTINCT user.auth_user_id) > 1) THEN - SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'IAM 存在重复手机号,禁止建立 Auth 唯一登录索引'; - END IF; + UPDATE auth_account + SET phone = NULL + WHERE phone IS NOT NULL AND phone NOT REGEXP '^1[3-9][0-9]{9}$'; UPDATE auth_account account JOIN baiyue_iam.iam_user user ON user.auth_user_id = account.id AND user.deleted = 0 + JOIN ( + SELECT phone + FROM baiyue_iam.iam_user + WHERE deleted = 0 AND phone REGEXP '^1[3-9][0-9]{9}$' + GROUP BY phone + HAVING COUNT(DISTINCT auth_user_id) = 1 + ) unique_phone ON unique_phone.phone = user.phone SET account.phone = user.phone WHERE account.phone IS NULL AND user.phone REGEXP '^1[3-9][0-9]{9}$'; IF NOT EXISTS ( diff --git a/auth/src/test/java/com/baiyue/auth/repository/AuthLoginIdentifiersSqlContractTest.java b/auth/src/test/java/com/baiyue/auth/repository/AuthLoginIdentifiersSqlContractTest.java new file mode 100644 index 000000000..7a9e163ab --- /dev/null +++ b/auth/src/test/java/com/baiyue/auth/repository/AuthLoginIdentifiersSqlContractTest.java @@ -0,0 +1,32 @@ +package com.baiyue.auth.repository; + +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +class AuthLoginIdentifiersSqlContractTest { + @Test + void backfillsOnlyUniquelyOwnedPhonesAndKeepsDuplicateLegacyPhonesUnbound() throws Exception { + assertSafeBackfill(new ClassPathResource("db/auth-login-identifiers.sql") + .getContentAsString(StandardCharsets.UTF_8)); + assertSafeBackfill(Files.readString(unifiedSql(), StandardCharsets.UTF_8)); + } + + private static void assertSafeBackfill(String sql) { + assertThat(sql) + .contains("phone NOT REGEXP '^1[3-9][0-9]{9}$'") + .contains("HAVING COUNT(DISTINCT auth_user_id) = 1") + .contains("ADD UNIQUE KEY uk_auth_account_phone (phone)") + .doesNotContain("IAM 存在重复手机号,禁止建立 Auth 唯一登录索引"); + } + + private static Path unifiedSql() { + Path path = Path.of("deploy", "sql", "头程数据库统一增量-MySQL8.sql"); + return Files.exists(path) ? path : Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql"); + } +} diff --git a/deploy/sql/头程数据库统一增量-MySQL8.sql b/deploy/sql/头程数据库统一增量-MySQL8.sql index 3b426487e..2cdd21695 100644 --- a/deploy/sql/头程数据库统一增量-MySQL8.sql +++ b/deploy/sql/头程数据库统一增量-MySQL8.sql @@ -17077,6 +17077,52 @@ CREATE TABLE IF NOT EXISTS fl_dropship_pallet_carton ( CONSTRAINT fk_dropship_carton_label FOREIGN KEY (carton_label_id) REFERENCES fl_inbound_carton_label(id) ) ENGINE=InnoDB COMMENT='一件代发托盘内逐箱SKU和入仓单明细'; +-- Auth 登录手机号只从 IAM 中唯一归属的中国大陆手机号回填;存量重复号保持 NULL。 +USE baiyue_auth; +DROP PROCEDURE IF EXISTS auth_add_login_phone; +DELIMITER $$ +CREATE PROCEDURE auth_add_login_phone() +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'baiyue_auth' AND table_name = 'auth_account' AND column_name = 'phone') THEN + ALTER TABLE auth_account ADD COLUMN phone VARCHAR(32) NULL COMMENT '全局唯一中国大陆登录手机号' AFTER username; + END IF; +END$$ +DELIMITER ; +CALL auth_add_login_phone(); +DROP PROCEDURE auth_add_login_phone; + +DROP PROCEDURE IF EXISTS auth_backfill_login_phone; +DELIMITER $$ +CREATE PROCEDURE auth_backfill_login_phone() +BEGIN + UPDATE auth_account + SET phone = NULL + WHERE phone IS NOT NULL AND phone NOT REGEXP '^1[3-9][0-9]{9}$'; + UPDATE auth_account account + JOIN baiyue_iam.iam_user user ON user.auth_user_id = account.id AND user.deleted = 0 + JOIN ( + SELECT phone + FROM baiyue_iam.iam_user + WHERE deleted = 0 AND phone REGEXP '^1[3-9][0-9]{9}$' + GROUP BY phone + HAVING COUNT(DISTINCT auth_user_id) = 1 + ) unique_phone ON unique_phone.phone = user.phone + SET account.phone = user.phone + WHERE account.phone IS NULL AND user.phone REGEXP '^1[3-9][0-9]{9}$'; + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = 'baiyue_auth' AND table_name = 'auth_account' + AND index_name = 'uk_auth_account_phone') THEN + ALTER TABLE auth_account ADD UNIQUE KEY uk_auth_account_phone (phone); + END IF; +END$$ +DELIMITER ; +CALL auth_backfill_login_phone(); +DROP PROCEDURE auth_backfill_login_phone; + +USE baiyue_firstleg; CALL baiyue_firstleg.assert_unified_final_schema(); DROP PROCEDURE IF EXISTS baiyue_firstleg.assert_unified_final_schema; SELECT 'PASS' AS migration_status,