From 849fa77df0f2858596d3851cc12738eb6496731c Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 11 Jan 2026 08:37:02 -0800 Subject: [PATCH] =?UTF-8?q?fix(auth-service):=20=E5=85=81=E8=AE=B8synced?= =?UTF-8?q?=5Flegacy=5Fusers=E7=9A=84phone=E5=92=8Cpassword=5Fhash?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改schema让phone和passwordHash字段可为空 - 添加migration: 20260111083500_allow_nullable_phone_password - CDC consumer使用null替代空字符串 - 支持同步没有手机号/密码的系统账户 Co-Authored-By: Claude Opus 4.5 --- .claude/settings.local.json | 5 ++++- .../migration.sql | 3 +++ .../auth-service/prisma/schema.prisma | 4 ++-- .../messaging/cdc/legacy-user-cdc.consumer.ts | 20 ++++-------------- .../public/drawable-xhdpi/background_1.png | Bin 0 -> 536 bytes .../public/drawable-xhdpi/button1.png | Bin 0 -> 210 bytes .../public/drawable-xxhdpi/background_1.png | Bin 0 -> 1211 bytes .../public/drawable-xxhdpi/button1.png | Bin 0 -> 344 bytes .../public/drawable-xxxhdpi/background_1.png | Bin 0 -> 1406 bytes .../public/drawable-xxxhdpi/button1.png | Bin 0 -> 390 bytes .../admin-web/public/drawable/background.xml | 13 ++++++++++++ frontend/admin-web/public/drawable/button.xml | 10 +++++++++ .../admin-web/public/drawable/container.xml | 10 +++++++++ .../admin-web/public/drawable/container_1.xml | 10 +++++++++ .../admin-web/public/drawable/container_2.xml | 10 +++++++++ .../admin-web/public/drawable/container_3.xml | 10 +++++++++ .../admin-web/public/drawable/container_4.xml | 10 +++++++++ .../admin-web/public/drawable/container_5.xml | 10 +++++++++ .../admin-web/public/drawable/container_6.xml | 10 +++++++++ .../admin-web/public/drawable/container_7.xml | 10 +++++++++ .../admin-web/public/drawable/overlay.xml | 13 ++++++++++++ 21 files changed, 129 insertions(+), 19 deletions(-) create mode 100644 backend/services/auth-service/prisma/migrations/20260111083500_allow_nullable_phone_password/migration.sql create mode 100644 frontend/admin-web/public/drawable-xhdpi/background_1.png create mode 100644 frontend/admin-web/public/drawable-xhdpi/button1.png create mode 100644 frontend/admin-web/public/drawable-xxhdpi/background_1.png create mode 100644 frontend/admin-web/public/drawable-xxhdpi/button1.png create mode 100644 frontend/admin-web/public/drawable-xxxhdpi/background_1.png create mode 100644 frontend/admin-web/public/drawable-xxxhdpi/button1.png create mode 100644 frontend/admin-web/public/drawable/background.xml create mode 100644 frontend/admin-web/public/drawable/button.xml create mode 100644 frontend/admin-web/public/drawable/container.xml create mode 100644 frontend/admin-web/public/drawable/container_1.xml create mode 100644 frontend/admin-web/public/drawable/container_2.xml create mode 100644 frontend/admin-web/public/drawable/container_3.xml create mode 100644 frontend/admin-web/public/drawable/container_4.xml create mode 100644 frontend/admin-web/public/drawable/container_5.xml create mode 100644 frontend/admin-web/public/drawable/container_6.xml create mode 100644 frontend/admin-web/public/drawable/container_7.xml create mode 100644 frontend/admin-web/public/drawable/overlay.xml diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 843e9494..3abdb4a3 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -701,7 +701,10 @@ "Bash(ssh ceshi@103.39.231.231 \"docker ps | grep -i kong\")", "Bash(ssh ceshi@103.39.231.231 \"curl -s http://localhost:8000/api/v2/mining-admin/auth/login -X POST -H ''Content-Type: application/json'' -d ''{\"\"username\"\":\"\"admin\"\",\"\"password\"\":\"\"admin123\"\"}''\")", "Bash(ssh ceshi@103.39.231.231 \"curl -s http://localhost:8000/api/v2/mining-admin/auth/profile -H ''Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI3ODRlNTA0MS1hYTM2LTQ0ZTctYTM1NS0yY2I2ZjYwYmY1YmIiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6IlNVUEVSX0FETUlOIiwiaWF0IjoxNzY4MTIyMjc3LCJleHAiOjE3NjgyMDg2Nzd9.XL0i0_tQlybkT9ktLIP90WQZDujPbbARL20h6fLmeRE''\")", - "Bash(user \")" + "Bash(user \")", + "mcp__UIPro__getCodeFromUIProPlugin", + "Bash(flutter create:*)", + "Bash(DATABASE_URL=\"postgresql://postgres:postgres@localhost:5432/rwa_auth?schema=public\" npx prisma migrate dev:*)" ], "deny": [], "ask": [] diff --git a/backend/services/auth-service/prisma/migrations/20260111083500_allow_nullable_phone_password/migration.sql b/backend/services/auth-service/prisma/migrations/20260111083500_allow_nullable_phone_password/migration.sql new file mode 100644 index 00000000..83238cd0 --- /dev/null +++ b/backend/services/auth-service/prisma/migrations/20260111083500_allow_nullable_phone_password/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable: 允许 phone 和 password_hash 为空(支持系统账户同步) +ALTER TABLE "synced_legacy_users" ALTER COLUMN "phone" DROP NOT NULL; +ALTER TABLE "synced_legacy_users" ALTER COLUMN "password_hash" DROP NOT NULL; diff --git a/backend/services/auth-service/prisma/schema.prisma b/backend/services/auth-service/prisma/schema.prisma index 3fe72f47..0a194f5f 100644 --- a/backend/services/auth-service/prisma/schema.prisma +++ b/backend/services/auth-service/prisma/schema.prisma @@ -84,8 +84,8 @@ model SyncedLegacyUser { // 1.0 用户数据 legacyId BigInt @unique @map("legacy_id") // 1.0 的 user.id accountSequence String @unique @map("account_sequence") - phone String - passwordHash String @map("password_hash") + phone String? // 系统账户可能没有手机号 + passwordHash String? @map("password_hash") // 系统账户可能没有密码 status String legacyCreatedAt DateTime @map("legacy_created_at") diff --git a/backend/services/auth-service/src/infrastructure/messaging/cdc/legacy-user-cdc.consumer.ts b/backend/services/auth-service/src/infrastructure/messaging/cdc/legacy-user-cdc.consumer.ts index 53b33bf3..eeed68c7 100644 --- a/backend/services/auth-service/src/infrastructure/messaging/cdc/legacy-user-cdc.consumer.ts +++ b/backend/services/auth-service/src/infrastructure/messaging/cdc/legacy-user-cdc.consumer.ts @@ -124,24 +124,12 @@ export class LegacyUserCdcConsumer implements OnModuleInit, OnModuleDestroy { } private async upsertLegacyUser(user: UnwrappedCdcUser, sequenceNum: bigint) { - // 跳过没有手机号的系统账户(user_id 1-5 通常是系统/测试账户) - if (!user.phone_number) { - this.logger.debug(`Skipped user ${user.user_id} (no phone number)`); - return; - } - - // 跳过没有密码的账户 - if (!user.password_hash) { - this.logger.debug(`Skipped user ${user.user_id} (no password)`); - return; - } - try { await this.prisma.syncedLegacyUser.upsert({ where: { legacyId: BigInt(user.user_id) }, update: { - phone: user.phone_number, - passwordHash: user.password_hash, + phone: user.phone_number || null, + passwordHash: user.password_hash || null, accountSequence: user.account_sequence, status: user.status, sourceSequenceNum: sequenceNum, @@ -149,8 +137,8 @@ export class LegacyUserCdcConsumer implements OnModuleInit, OnModuleDestroy { }, create: { legacyId: BigInt(user.user_id), - phone: user.phone_number, - passwordHash: user.password_hash, + phone: user.phone_number || null, + passwordHash: user.password_hash || null, accountSequence: user.account_sequence, status: user.status, legacyCreatedAt: new Date(user.registered_at), diff --git a/frontend/admin-web/public/drawable-xhdpi/background_1.png b/frontend/admin-web/public/drawable-xhdpi/background_1.png new file mode 100644 index 0000000000000000000000000000000000000000..bc62067f7450a3f4027b10bae17ae4a7eafdfe15 GIT binary patch literal 536 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 literal 0 HcmV?d00001 diff --git a/frontend/admin-web/public/drawable-xxxhdpi/button1.png b/frontend/admin-web/public/drawable-xxxhdpi/button1.png new file mode 100644 index 0000000000000000000000000000000000000000..b6328fdef6bb4570c6a514234b54bb15c8803e93 GIT binary patch literal 390 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-1!HlL zyA#8@b22Z19F}xPUq=Rpjs4tz5?O(A(w;7kAr*{or|kD*auhhW|NXl!>mCc~_NY~q zU5HiQxaZQOOMdqq?lX9M%O7odoyS4T!V?yUMN zAAm1>4MV*VV;vG zJk%HAX;aJnU!%8I__?f%a*ji%zuk@;KgQeX8VlR25*ZzJ6;vXe6O?6G%0dqOOAt9C z`dGhkOYmn=)`>HG(t_>mXNzeYg!p>4d-dfyuYH`l^_uW^&(gK~-#?qG=J&U&=ip>t ho>_M!KKJZRWckryKAX$Bu@V?;44$rjF6*2UngBCOnN + + + + diff --git a/frontend/admin-web/public/drawable/button.xml b/frontend/admin-web/public/drawable/button.xml new file mode 100644 index 00000000..05df329a --- /dev/null +++ b/frontend/admin-web/public/drawable/button.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container.xml b/frontend/admin-web/public/drawable/container.xml new file mode 100644 index 00000000..58818132 --- /dev/null +++ b/frontend/admin-web/public/drawable/container.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_1.xml b/frontend/admin-web/public/drawable/container_1.xml new file mode 100644 index 00000000..d7a14353 --- /dev/null +++ b/frontend/admin-web/public/drawable/container_1.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_2.xml b/frontend/admin-web/public/drawable/container_2.xml new file mode 100644 index 00000000..2e61b46e --- /dev/null +++ b/frontend/admin-web/public/drawable/container_2.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_3.xml b/frontend/admin-web/public/drawable/container_3.xml new file mode 100644 index 00000000..8506b426 --- /dev/null +++ b/frontend/admin-web/public/drawable/container_3.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_4.xml b/frontend/admin-web/public/drawable/container_4.xml new file mode 100644 index 00000000..81588103 --- /dev/null +++ b/frontend/admin-web/public/drawable/container_4.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_5.xml b/frontend/admin-web/public/drawable/container_5.xml new file mode 100644 index 00000000..98773d7f --- /dev/null +++ b/frontend/admin-web/public/drawable/container_5.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_6.xml b/frontend/admin-web/public/drawable/container_6.xml new file mode 100644 index 00000000..89f51a10 --- /dev/null +++ b/frontend/admin-web/public/drawable/container_6.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_7.xml b/frontend/admin-web/public/drawable/container_7.xml new file mode 100644 index 00000000..feee424c --- /dev/null +++ b/frontend/admin-web/public/drawable/container_7.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/overlay.xml b/frontend/admin-web/public/drawable/overlay.xml new file mode 100644 index 00000000..40ead997 --- /dev/null +++ b/frontend/admin-web/public/drawable/overlay.xml @@ -0,0 +1,13 @@ + + + + +