diff --git a/services/user-service/migrations/001_init.sql b/services/user-service/migrations/001_init.sql index 1d6de3b..5e59ffc 100644 --- a/services/user-service/migrations/001_init.sql +++ b/services/user-service/migrations/001_init.sql @@ -1,6 +1,6 @@ -- 用户主表 CREATE TABLE IF NOT EXISTS user_main ( - id BIGSERIAL PRIMARY KEY, + id UUID PRIMARY KEY, deleted BOOLEAN NOT NULL DEFAULT FALSE, createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, modifydate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP @@ -8,8 +8,8 @@ CREATE TABLE IF NOT EXISTS user_main ( -- 用户登录账号表 CREATE TABLE IF NOT EXISTS user_login_account ( - id BIGSERIAL PRIMARY KEY, - user_id BIGINT NOT NULL, + id UUID PRIMARY KEY, + user_id UUID NOT NULL, account VARCHAR(100) NOT NULL, deleted BOOLEAN NOT NULL DEFAULT FALSE, createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -23,8 +23,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_user_login_account_active -- 用户密码表 CREATE TABLE IF NOT EXISTS user_login_password ( - id BIGSERIAL PRIMARY KEY, - user_id BIGINT NOT NULL, + id UUID PRIMARY KEY, + user_id UUID NOT NULL, password VARCHAR(255) NOT NULL, deleted BOOLEAN NOT NULL DEFAULT FALSE, createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -39,13 +39,13 @@ CREATE INDEX IF NOT EXISTS idx_user_login_password_user_id -- bcrypt hash: $2b$12$REwMlLDCbzR4UpL6MWnzE.AacihwpFvQhGs7vDKTwwyNMb1qBWOTm DO $$ DECLARE - v_user_id BIGINT; + v_user_id UUID := '018fa3e0-7e5c-7aaa-8b1d-9f6e4c3b2a10'::UUID; BEGIN - INSERT INTO user_main DEFAULT VALUES RETURNING id INTO v_user_id; + INSERT INTO user_main (id) VALUES (v_user_id); - INSERT INTO user_login_account (user_id, account) - VALUES (v_user_id, 'admin'); + INSERT INTO user_login_account (id, user_id, account) + VALUES ('018fa3e0-7e5c-7bbb-8b1d-9f6e4c3b2a10'::UUID, v_user_id, 'admin'); - INSERT INTO user_login_password (user_id, password) - VALUES (v_user_id, '$2b$12$REwMlLDCbzR4UpL6MWnzE.AacihwpFvQhGs7vDKTwwyNMb1qBWOTm'); + INSERT INTO user_login_password (id, user_id, password) + VALUES ('018fa3e0-7e5c-7ccc-8b1d-9f6e4c3b2a10'::UUID, v_user_id, '$2b$12$REwMlLDCbzR4UpL6MWnzE.AacihwpFvQhGs7vDKTwwyNMb1qBWOTm'); END $$; diff --git a/services/user-service/user-login/Cargo.toml b/services/user-service/user-login/Cargo.toml index c9c4a35..1bc1662 100644 --- a/services/user-service/user-login/Cargo.toml +++ b/services/user-service/user-login/Cargo.toml @@ -14,7 +14,10 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # 数据库 -sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "postgres", "chrono"] } +sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "postgres", "chrono", "uuid"] } + +# UUID +uuid = { version = "1", features = ["v7", "serde"] } # Redis redis = { version = "0.29", features = ["tokio-comp"] } diff --git a/services/user-service/user-register/Cargo.toml b/services/user-service/user-register/Cargo.toml index bad26bb..5149c1f 100644 --- a/services/user-service/user-register/Cargo.toml +++ b/services/user-service/user-register/Cargo.toml @@ -11,7 +11,10 @@ tower = "0.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "postgres", "chrono"] } +sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "postgres", "chrono", "uuid"] } + +# UUID +uuid = { version = "1", features = ["v7", "serde"] } redis = { version = "0.29", features = ["tokio-comp"] } bcrypt = "0.17" diff --git a/services/user-service/user-register/src/main.rs b/services/user-service/user-register/src/main.rs index e5f3699..436a294 100644 --- a/services/user-service/user-register/src/main.rs +++ b/services/user-service/user-register/src/main.rs @@ -11,6 +11,7 @@ use sqlx::PgPool; use std::env; use std::sync::Arc; use tracing::{info, warn}; +use uuid::Uuid; use validator::Validate; #[derive(Clone)] @@ -31,7 +32,7 @@ struct RegisterRequest { #[derive(Serialize)] struct RegisterResponse { success: bool, - user_id: Option, + user_id: Option, message: String, } @@ -89,7 +90,7 @@ async fn register_handler( } // 检查账号是否已存在 - let existing: Option<(i64,)> = sqlx::query_as( + let existing: Option<(Uuid,)> = sqlx::query_as( "SELECT id FROM user_login_account WHERE account = $1 AND deleted = FALSE" ) .bind(&payload.username) @@ -140,32 +141,33 @@ async fn register_handler( } }; - let result: Result<(i64,), sqlx::Error> = sqlx::query_as( - "INSERT INTO user_main DEFAULT VALUES RETURNING id" - ) - .fetch_one(&mut *tx) - .await; - - let user_id = match result { - Ok((id,)) => id, - Err(e) => { - warn!("Insert user_main failed: {}", e); - let _ = tx.rollback().await; - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(RegisterResponse { - success: false, - user_id: None, - message: "Registration failed".to_string(), - }), - ); - } - }; + let user_id = Uuid::now_v7(); if let Err(e) = sqlx::query( - "INSERT INTO user_login_account (user_id, account) VALUES ($1, $2)" + "INSERT INTO user_main (id) VALUES ($1)" ) .bind(user_id) + .execute(&mut *tx) + .await + { + warn!("Insert user_main failed: {}", e); + let _ = tx.rollback().await; + return ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(RegisterResponse { + success: false, + user_id: None, + message: "Registration failed".to_string(), + }), + ); + } + + let account_id = Uuid::now_v7(); + if let Err(e) = sqlx::query( + "INSERT INTO user_login_account (id, user_id, account) VALUES ($1, $2, $3)" + ) + .bind(account_id) + .bind(user_id) .bind(&payload.username) .execute(&mut *tx) .await @@ -182,9 +184,11 @@ async fn register_handler( ); } + let password_id = Uuid::now_v7(); if let Err(e) = sqlx::query( - "INSERT INTO user_login_password (user_id, password) VALUES ($1, $2)" + "INSERT INTO user_login_password (id, user_id, password) VALUES ($1, $2, $3)" ) + .bind(password_id) .bind(user_id) .bind(&password_hash) .execute(&mut *tx)