用户表 ID 改为 UUID V7 并由业务层生成

This commit is contained in:
fish
2026-04-13 20:26:29 +08:00
parent 49af914f9b
commit e95bc4d196
4 changed files with 48 additions and 38 deletions

View File

@@ -1,6 +1,6 @@
-- 用户主表 -- 用户主表
CREATE TABLE IF NOT EXISTS user_main ( CREATE TABLE IF NOT EXISTS user_main (
id BIGSERIAL PRIMARY KEY, id UUID PRIMARY KEY,
deleted BOOLEAN NOT NULL DEFAULT FALSE, deleted BOOLEAN NOT NULL DEFAULT FALSE,
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
modifydate 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 ( CREATE TABLE IF NOT EXISTS user_login_account (
id BIGSERIAL PRIMARY KEY, id UUID PRIMARY KEY,
user_id BIGINT NOT NULL, user_id UUID NOT NULL,
account VARCHAR(100) NOT NULL, account VARCHAR(100) NOT NULL,
deleted BOOLEAN NOT NULL DEFAULT FALSE, deleted BOOLEAN NOT NULL DEFAULT FALSE,
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, 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 ( CREATE TABLE IF NOT EXISTS user_login_password (
id BIGSERIAL PRIMARY KEY, id UUID PRIMARY KEY,
user_id BIGINT NOT NULL, user_id UUID NOT NULL,
password VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL,
deleted BOOLEAN NOT NULL DEFAULT FALSE, deleted BOOLEAN NOT NULL DEFAULT FALSE,
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, 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 -- bcrypt hash: $2b$12$REwMlLDCbzR4UpL6MWnzE.AacihwpFvQhGs7vDKTwwyNMb1qBWOTm
DO $$ DO $$
DECLARE DECLARE
v_user_id BIGINT; v_user_id UUID := '018fa3e0-7e5c-7aaa-8b1d-9f6e4c3b2a10'::UUID;
BEGIN 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) INSERT INTO user_login_account (id, user_id, account)
VALUES (v_user_id, 'admin'); VALUES ('018fa3e0-7e5c-7bbb-8b1d-9f6e4c3b2a10'::UUID, v_user_id, 'admin');
INSERT INTO user_login_password (user_id, password) INSERT INTO user_login_password (id, user_id, password)
VALUES (v_user_id, '$2b$12$REwMlLDCbzR4UpL6MWnzE.AacihwpFvQhGs7vDKTwwyNMb1qBWOTm'); VALUES ('018fa3e0-7e5c-7ccc-8b1d-9f6e4c3b2a10'::UUID, v_user_id, '$2b$12$REwMlLDCbzR4UpL6MWnzE.AacihwpFvQhGs7vDKTwwyNMb1qBWOTm');
END $$; END $$;

View File

@@ -14,7 +14,10 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" 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
redis = { version = "0.29", features = ["tokio-comp"] } redis = { version = "0.29", features = ["tokio-comp"] }

View File

@@ -11,7 +11,10 @@ tower = "0.5"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" 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"] } redis = { version = "0.29", features = ["tokio-comp"] }
bcrypt = "0.17" bcrypt = "0.17"

View File

@@ -11,6 +11,7 @@ use sqlx::PgPool;
use std::env; use std::env;
use std::sync::Arc; use std::sync::Arc;
use tracing::{info, warn}; use tracing::{info, warn};
use uuid::Uuid;
use validator::Validate; use validator::Validate;
#[derive(Clone)] #[derive(Clone)]
@@ -31,7 +32,7 @@ struct RegisterRequest {
#[derive(Serialize)] #[derive(Serialize)]
struct RegisterResponse { struct RegisterResponse {
success: bool, success: bool,
user_id: Option<i64>, user_id: Option<Uuid>,
message: String, 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" "SELECT id FROM user_login_account WHERE account = $1 AND deleted = FALSE"
) )
.bind(&payload.username) .bind(&payload.username)
@@ -140,32 +141,33 @@ async fn register_handler(
} }
}; };
let result: Result<(i64,), sqlx::Error> = sqlx::query_as( let user_id = Uuid::now_v7();
"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(),
}),
);
}
};
if let Err(e) = sqlx::query( 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) .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) .bind(&payload.username)
.execute(&mut *tx) .execute(&mut *tx)
.await .await
@@ -182,9 +184,11 @@ async fn register_handler(
); );
} }
let password_id = Uuid::now_v7();
if let Err(e) = sqlx::query( 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(user_id)
.bind(&password_hash) .bind(&password_hash)
.execute(&mut *tx) .execute(&mut *tx)