add: user accomplished
This commit is contained in:
@@ -7,6 +7,10 @@ info (
|
||||
)
|
||||
|
||||
type (
|
||||
EmptyResp {}
|
||||
ForgotPasswordReq {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
SendVerificationCodeReq {
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Scene string `json:"scene" binding:"required,oneof=register login reset_password bind_email"`
|
||||
@@ -30,5 +34,18 @@ service email-api {
|
||||
)
|
||||
@handler SendVerificationCode
|
||||
post /verification-code/send (SendVerificationCodeReq) returns (SendVerificationCodeResp)
|
||||
|
||||
|
||||
}
|
||||
|
||||
@server (
|
||||
group: user
|
||||
prefix: /api/v1/auth
|
||||
|
||||
)
|
||||
service email-api {
|
||||
@doc "忘记密码-发送验证码"
|
||||
@handler ForgotPassword
|
||||
post /forgot-password/send (ForgotPasswordReq) returns (EmptyResp)
|
||||
}
|
||||
|
||||
|
||||
+149
-111
@@ -1,126 +1,164 @@
|
||||
syntax = "v1"
|
||||
|
||||
info (
|
||||
author: "Asadz"
|
||||
date: "2024-06-19"
|
||||
version: "1.0"
|
||||
info(
|
||||
author: "Asadz"
|
||||
date: "2024-06-19"
|
||||
version: "1.0"
|
||||
)
|
||||
|
||||
type (
|
||||
RegisterReq {
|
||||
Username string `json:"username" binding:"required,min=3,max=50"`
|
||||
Password string `json:"password" binding:"required,min=6,max=128"`
|
||||
Email string `json:"email,omitempty" binding:"omitempty,email"`
|
||||
Phone string `json:"phone,omitempty" binding:"omitempty,len=11"`
|
||||
Vcode int32 `json:"vcode"`
|
||||
}
|
||||
RegisterResp {
|
||||
UserId int64 `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
LoginReq {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
LoginResp {
|
||||
UserId int64 `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Token string `json:"token"`
|
||||
Expires int64 `json:"expires"`
|
||||
}
|
||||
GetUserInfoReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
}
|
||||
UserInfo {
|
||||
UserId int64 `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Status int `json:"status"`
|
||||
CreateAt int64 `json:"createAt"`
|
||||
UpdateAt int64 `json:"updateAt"`
|
||||
}
|
||||
UpdateUserInfoReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
Email string `json:"email" binding:"omitempty,email"`
|
||||
Phone string `json:"phone" binding:"omitempty,len=11"`
|
||||
Avatar string `json:"avatar" binding:"omitempty,url"`
|
||||
}
|
||||
UpdateUserInfoResp {
|
||||
UserId int64 `json:"userId"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
UpdatePasswordReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
OldPassword string `json:"oldPassword" binding:"required"`
|
||||
NewPassword string `json:"newPassword" binding:"required,min=6,max=128"`
|
||||
}
|
||||
UpdatePasswordResp {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
LogoutReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
Token string `header:"Authorization" binding:"required"`
|
||||
}
|
||||
LogoutResp {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
ErrorResp {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
EmptyResp {
|
||||
}
|
||||
SearchUserResp {
|
||||
Username string `json:"username"`
|
||||
UserId int64 `json:"userId"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
Bio string `json:"bio"`
|
||||
Page int64 `json:"page"`
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
ResetPasswordByVcode {
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Vcode string `json:"vcode"`
|
||||
}
|
||||
RegisterReq {
|
||||
Username string `json:"username" binding:"required,min=3,max=50"`
|
||||
Password string `json:"password" binding:"required,min=6,max=128"`
|
||||
Email string `json:"email,omitempty" binding:"omitempty,email"`
|
||||
Phone string `json:"phone,omitempty" binding:"omitempty,len=11"`
|
||||
Vcode int32 `json:"vcode"`
|
||||
}
|
||||
RegisterResp {
|
||||
UserId int64 `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
LoginReq {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
LoginResp {
|
||||
UserId int64 `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Token string `json:"token"`
|
||||
Expires int64 `json:"expires"`
|
||||
}
|
||||
GetUserInfoReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
}
|
||||
UserInfo {
|
||||
UserId int64 `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Avatar string `json:"avatar"`
|
||||
Status int `json:"status"`
|
||||
CreateAt int64 `json:"createAt"`
|
||||
UpdateAt int64 `json:"updateAt"`
|
||||
}
|
||||
UpdateUserInfoReq {
|
||||
Nickname *string `json:"nickname,omitempty"`
|
||||
Avatar *string `json:"avatar,omitempty"`
|
||||
Bio *string `json:"bio,omitempty"`
|
||||
}
|
||||
UpdateUserInfoResp {
|
||||
UserId int64 `json:"userId"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
UpdatePasswordReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
OldPassword string `json:"oldPassword" binding:"required"`
|
||||
NewPassword string `json:"newPassword" binding:"required,min=6,max=128"`
|
||||
}
|
||||
UpdatePasswordResp {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
LogoutReq {
|
||||
UserId int64 `path:"userId" binding:"required,gt=0"`
|
||||
Token string `header:"Authorization" binding:"required"`
|
||||
}
|
||||
LogoutResp {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
ErrorResp {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: user
|
||||
prefix: /api/users
|
||||
middleware: Logger
|
||||
@server(
|
||||
group: user
|
||||
prefix: /api/v1/auth
|
||||
middleware: Logger
|
||||
)
|
||||
service user-api {
|
||||
@doc (
|
||||
summary: "用户注册接口"
|
||||
description: "通过用户名、密码、邮箱、电话号码注册新用户账户"
|
||||
)
|
||||
@handler Register
|
||||
post /register (RegisterReq) returns (RegisterResp)
|
||||
@doc(
|
||||
summary: "用户注册接口"
|
||||
description: "通过用户名、密码、邮箱、电话号码注册新用户账户"
|
||||
)
|
||||
@handler Register
|
||||
post /register (RegisterReq) returns (RegisterResp)
|
||||
|
||||
@doc (
|
||||
summary: "用户登录接口"
|
||||
description: "使用用户名和密码进行登录,返回访问令牌和用户信息"
|
||||
)
|
||||
@handler Login
|
||||
post /login (LoginReq) returns (LoginResp)
|
||||
@doc(
|
||||
summary: "用户登录接口"
|
||||
description: "使用用户名和密码进行登录,返回访问令牌和用户信息"
|
||||
)
|
||||
@handler Login
|
||||
post /login (LoginReq) returns (LoginResp)
|
||||
|
||||
@doc (
|
||||
summary: "获取用户信息"
|
||||
description: "根据用户ID获取用户的详细信息,包含个人资料和账户状态"
|
||||
)
|
||||
@handler GetUserInfo
|
||||
get /:userId (GetUserInfoReq) returns (UserInfo)
|
||||
@doc(
|
||||
summary: "修改用户密码"
|
||||
description: "验证旧密码后修改为新密码,需要提供原密码"
|
||||
)
|
||||
@handler UpdatePassword
|
||||
put /:userId/password (UpdatePasswordReq) returns (UpdatePasswordResp)
|
||||
|
||||
@doc (
|
||||
summary: "修改用户信息"
|
||||
description: "修改用户的邮箱、电话号码、头像等信息"
|
||||
)
|
||||
@handler UpdateUserInfo
|
||||
put /:userId (UpdateUserInfoReq) returns (UpdateUserInfoResp)
|
||||
@doc(
|
||||
summary: "用户登出"
|
||||
description: "需要携带 Authorization 令牌,清除用户会话并使令牌失效"
|
||||
)
|
||||
@handler Logout
|
||||
post /:userId/logout (LogoutReq) returns (LogoutResp)
|
||||
|
||||
@doc (
|
||||
summary: "修改用户密码"
|
||||
description: "验证旧密码后修改为新密码,需要提供原密码"
|
||||
)
|
||||
@handler UpdatePassword
|
||||
put /:userId/password (UpdatePasswordReq) returns (UpdatePasswordResp)
|
||||
|
||||
@doc (
|
||||
summary: "用户登出"
|
||||
description: "需要携带 Authorization 令牌,清除用户会话并使令牌失效"
|
||||
)
|
||||
@handler Logout
|
||||
post /:userId/logout (LogoutReq) returns (LogoutResp)
|
||||
@doc "修改密码-使用验证码"
|
||||
@handler UpdatePasswordByVcode
|
||||
put /forgot-password/reset (ResetPasswordByVcode) returns (EmptyResp)
|
||||
}
|
||||
|
||||
@server(
|
||||
group: user
|
||||
prefix: /api/v1/user
|
||||
middleware: Logger
|
||||
)
|
||||
service user-api {
|
||||
@doc "获取当前登录用户信息"
|
||||
@handler GetMe
|
||||
get /me returns (UserInfo)
|
||||
|
||||
@doc "通过用户名搜索用户"
|
||||
@handler SearchUsersByUsername
|
||||
get /search () returns ([]UserInfo)
|
||||
|
||||
@doc "更改当前登录用户信息"
|
||||
@handler UpdateMe
|
||||
put /me (UpdateUserInfoReq) returns (UserInfo)
|
||||
|
||||
@doc(
|
||||
summary: "获取用户信息"
|
||||
description: "根据用户ID获取用户的详细信息,包含个人资料和账户状态"
|
||||
)
|
||||
@handler GetUserInfo
|
||||
get /:userId (GetUserInfoReq) returns (UserInfo)
|
||||
|
||||
@doc(
|
||||
summary: "修改用户信息"
|
||||
description: "修改用户的邮箱、电话号码、头像等信息"
|
||||
)
|
||||
@handler UpdateUserInfo
|
||||
put /:userId (UpdateUserInfoReq) returns (UpdateUserInfoResp)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package ="./pb";
|
||||
|
||||
package pb;
|
||||
|
||||
// ------------------------------------
|
||||
// Messages
|
||||
// ------------------------------------
|
||||
|
||||
//--------------------------------userVerifications--------------------------------
|
||||
message UserVerifications {
|
||||
int64 id = 1; //id
|
||||
int64 userId = 2; //userId
|
||||
string role = 3; //role
|
||||
string status = 4; //status
|
||||
string materials = 5; //materials
|
||||
string rejectReason = 6; //rejectReason
|
||||
int64 reviewedBy = 7; //reviewedBy
|
||||
int64 reviewedAt = 8; //reviewedAt
|
||||
int64 createdAt = 9; //createdAt
|
||||
int64 updatedAt = 10; //updatedAt
|
||||
}
|
||||
|
||||
message AddUserVerificationsReq {
|
||||
int64 userId = 1; //userId
|
||||
string role = 2; //role
|
||||
string status = 3; //status
|
||||
string materials = 4; //materials
|
||||
string rejectReason = 5; //rejectReason
|
||||
int64 reviewedBy = 6; //reviewedBy
|
||||
int64 reviewedAt = 7; //reviewedAt
|
||||
int64 createdAt = 8; //createdAt
|
||||
int64 updatedAt = 9; //updatedAt
|
||||
}
|
||||
|
||||
message AddUserVerificationsResp {
|
||||
}
|
||||
|
||||
message UpdateUserVerificationsReq {
|
||||
int64 id = 1; //id
|
||||
int64 userId = 2; //userId
|
||||
string role = 3; //role
|
||||
string status = 4; //status
|
||||
string materials = 5; //materials
|
||||
string rejectReason = 6; //rejectReason
|
||||
int64 reviewedBy = 7; //reviewedBy
|
||||
int64 reviewedAt = 8; //reviewedAt
|
||||
int64 createdAt = 9; //createdAt
|
||||
int64 updatedAt = 10; //updatedAt
|
||||
}
|
||||
|
||||
message UpdateUserVerificationsResp {
|
||||
}
|
||||
|
||||
message DelUserVerificationsReq {
|
||||
int64 id = 1; //id
|
||||
}
|
||||
|
||||
message DelUserVerificationsResp {
|
||||
}
|
||||
|
||||
message GetUserVerificationsByIdReq {
|
||||
int64 id = 1; //id
|
||||
}
|
||||
|
||||
message GetUserVerificationsByIdResp {
|
||||
UserVerifications userVerifications = 1; //userVerifications
|
||||
}
|
||||
|
||||
message SearchUserVerificationsReq {
|
||||
int64 page = 1; //page
|
||||
int64 limit = 2; //limit
|
||||
int64 id = 3; //id
|
||||
int64 userId = 4; //userId
|
||||
string role = 5; //role
|
||||
string status = 6; //status
|
||||
string materials = 7; //materials
|
||||
string rejectReason = 8; //rejectReason
|
||||
int64 reviewedBy = 9; //reviewedBy
|
||||
int64 reviewedAt = 10; //reviewedAt
|
||||
int64 createdAt = 11; //createdAt
|
||||
int64 updatedAt = 12; //updatedAt
|
||||
}
|
||||
|
||||
message SearchUserVerificationsResp {
|
||||
repeated UserVerifications userVerifications = 1; //userVerifications
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------
|
||||
// Rpc Func
|
||||
// ------------------------------------
|
||||
|
||||
service user_verifications{
|
||||
|
||||
//-----------------------userVerifications-----------------------
|
||||
rpc AddUserVerifications(AddUserVerificationsReq) returns (AddUserVerificationsResp);
|
||||
rpc UpdateUserVerifications(UpdateUserVerificationsReq) returns (UpdateUserVerificationsResp);
|
||||
rpc DelUserVerifications(DelUserVerificationsReq) returns (DelUserVerificationsResp);
|
||||
rpc GetUserVerificationsById(GetUserVerificationsByIdReq) returns (GetUserVerificationsByIdResp);
|
||||
rpc SearchUserVerifications(SearchUserVerificationsReq) returns (SearchUserVerificationsResp);
|
||||
|
||||
}
|
||||
+75
-48
@@ -8,50 +8,62 @@ package pb;
|
||||
// Messages
|
||||
// ------------------------------------
|
||||
|
||||
//--------------------------------users--------------------------------
|
||||
//--------------------------------users--------------------------------
|
||||
message Users {
|
||||
int64 userId = 1; //userId
|
||||
int64 id = 1; //id
|
||||
string username = 2; //username
|
||||
string passwd = 3; //passwd
|
||||
string nickname = 4; //nickname
|
||||
string phone = 5; //phone
|
||||
int64 roleType = 6; //roleType
|
||||
bool isVerified = 7; //isVerified
|
||||
bool state = 8; //state
|
||||
int64 createdAt = 9; //createdAt
|
||||
int64 updatedAt = 10; //updatedAt
|
||||
int64 deletedAt = 11; //deletedAt
|
||||
string passwordHash = 3; //passwordHash
|
||||
string phone = 4; //phone
|
||||
string email = 5; //email
|
||||
string nickname = 6; //nickname
|
||||
string avatar = 7; //avatar
|
||||
string bio = 8; //bio
|
||||
string currentRole = 9; //currentRole
|
||||
repeated string verifiedRoles = 10; //verifiedRoles
|
||||
string verificationStatus = 11; //verificationStatus
|
||||
bool isAdmin = 12; //isAdmin
|
||||
int64 createdAt = 13; //createdAt
|
||||
int64 updatedAt = 14; //updatedAt
|
||||
int64 deletedAt = 15; //deletedAt
|
||||
}
|
||||
|
||||
message AddUsersReq {
|
||||
int64 userId = 1; //userId
|
||||
string username = 2; //username
|
||||
string passwd = 3; //passwd
|
||||
string nickname = 4; //nickname
|
||||
string phone = 5; //phone
|
||||
int64 roleType = 6; //roleType
|
||||
bool isVerified = 7; //isVerified
|
||||
bool state = 8; //state
|
||||
int64 createdAt = 9; //createdAt
|
||||
int64 updatedAt = 10; //updatedAt
|
||||
int64 deletedAt = 11; //deletedAt
|
||||
string username = 1; //username
|
||||
string passwordHash = 2; //passwordHash
|
||||
string phone = 3; //phone
|
||||
string email = 4; //email
|
||||
string nickname = 5; //nickname
|
||||
string avatar = 6; //avatar
|
||||
string bio = 7; //bio
|
||||
string currentRole = 8; //currentRole
|
||||
repeated string verifiedRoles = 9; //verifiedRoles
|
||||
string verificationStatus = 10; //verificationStatus
|
||||
bool isAdmin = 11; //isAdmin
|
||||
int64 createdAt = 12; //createdAt
|
||||
int64 updatedAt = 13; //updatedAt
|
||||
int64 deletedAt = 14; //deletedAt
|
||||
}
|
||||
|
||||
message AddUsersResp {
|
||||
}
|
||||
|
||||
message UpdateUsersReq {
|
||||
int64 userId = 1; //userId
|
||||
string username = 2; //username
|
||||
string passwd = 3; //passwd
|
||||
string nickname = 4; //nickname
|
||||
string phone = 5; //phone
|
||||
int64 roleType = 6; //roleType
|
||||
bool isVerified = 7; //isVerified
|
||||
bool state = 8; //state
|
||||
int64 createdAt = 9; //createdAt
|
||||
int64 updatedAt = 10; //updatedAt
|
||||
int64 deletedAt = 11; //deletedAt
|
||||
int64 id = 1; //id
|
||||
optional string username = 2; //username
|
||||
optional string passwordHash = 3; //passwordHash
|
||||
optional string phone = 4; //phone
|
||||
optional string email = 5; //email
|
||||
optional string nickname = 6; //nickname
|
||||
optional string avatar = 7; //avatar
|
||||
optional string bio = 8; //bio
|
||||
optional string currentRole = 9; //currentRole
|
||||
repeated string verifiedRoles = 10; //verifiedRoles
|
||||
optional string verificationStatus = 11; //verificationStatus
|
||||
optional bool isAdmin = 12; //isAdmin
|
||||
optional int64 createdAt = 13; //createdAt
|
||||
optional int64 updatedAt = 14; //updatedAt
|
||||
optional int64 deletedAt = 15; //deletedAt
|
||||
}
|
||||
|
||||
message UpdateUsersResp {
|
||||
@@ -73,19 +85,23 @@ message GetUsersByIdResp {
|
||||
}
|
||||
|
||||
message SearchUsersReq {
|
||||
int64 page = 1; //page
|
||||
int64 limit = 2; //limit
|
||||
int64 userId = 3; //userId
|
||||
string username = 4; //username
|
||||
string passwd = 5; //passwd
|
||||
string nickname = 6; //nickname
|
||||
string phone = 7; //phone
|
||||
int64 roleType = 8; //roleType
|
||||
bool isVerified = 9; //isVerified
|
||||
bool state = 10; //state
|
||||
int64 createdAt = 11; //createdAt
|
||||
int64 updatedAt = 12; //updatedAt
|
||||
int64 deletedAt = 13; //deletedAt
|
||||
optional int64 page = 1; //page
|
||||
optional int64 limit = 2; //limit
|
||||
optional int64 id = 3; //id
|
||||
optional string username = 4; //username
|
||||
optional string passwordHash = 5; //passwordHash
|
||||
optional string phone = 6; //phone
|
||||
optional string email = 7; //email
|
||||
optional string nickname = 8; //nickname
|
||||
optional string avatar = 9; //avatar
|
||||
optional string bio = 10; //bio
|
||||
optional string currentRole = 11; //currentRole
|
||||
repeated string verifiedRoles = 12; //verifiedRoles
|
||||
optional string verificationStatus = 13; //verificationStatus
|
||||
optional bool isAdmin = 14; //isAdmin
|
||||
optional int64 createdAt = 15; //createdAt
|
||||
optional int64 updatedAt = 16; //updatedAt
|
||||
optional int64 deletedAt = 17; //deletedAt
|
||||
}
|
||||
|
||||
message SearchUsersResp {
|
||||
@@ -121,7 +137,7 @@ message ValidateTokenResp {
|
||||
bool valid = 1; // token 是否有效(不在黑名单中)
|
||||
string message = 2; // 验证失败原因
|
||||
int64 userId = 3; // 用户ID
|
||||
int64 roleType = 4; // 用户角色
|
||||
string roleType = 4; // 用户角色
|
||||
}
|
||||
|
||||
message CheckPermissionReq {
|
||||
@@ -156,7 +172,17 @@ message LogoutResp {
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
message ResetPasswordReq {
|
||||
string newPassword = 1;
|
||||
string email = 2;
|
||||
string requestId = 3;
|
||||
string vcode = 4;
|
||||
}
|
||||
|
||||
message ResetPasswordResp {
|
||||
|
||||
}
|
||||
// ------------------------------------
|
||||
// Rpc Func
|
||||
// ------------------------------------
|
||||
|
||||
@@ -174,4 +200,5 @@ service usercenter {
|
||||
rpc ValidateToken(ValidateTokenReq) returns (ValidateTokenResp);
|
||||
rpc CheckPermission(CheckPermissionReq) returns (CheckPermissionResp);
|
||||
rpc Logout(LogoutReq) returns (LogoutResp);
|
||||
}
|
||||
rpc ResetPassword(ResetPasswordReq) returns (ResetPasswordResp);
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
-- create
|
||||
-- extension if not exists "uuid-ossp";
|
||||
create
|
||||
extension if not exists "pg_trgm";
|
||||
|
||||
create table users
|
||||
(
|
||||
user_id BIGINT primary key not null,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
passwd VARCHAR(255) NOT NULL,
|
||||
nickname VARCHAR(50) NOT NULL DEFAULT ('user_' || substr(md5(random()::text), 1, 10)),
|
||||
phone VARCHAR(20) UNIQUE NOT NULL default '',
|
||||
email varchar(50) unique not null default '',
|
||||
role_type SMALLINT NOT NULL default 1, -- 1:玩家, 2:打手, 3:店长
|
||||
is_verified BOOLEAN DEFAULT false,
|
||||
state BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at timestamp with time zone default current_timestamp,
|
||||
deleted_at timestamp with time zone
|
||||
);
|
||||
@@ -0,0 +1,35 @@
|
||||
CREATE TABLE user_verifications (
|
||||
id BIGINT PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id),
|
||||
role VARCHAR(20) NOT NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
materials JSONB NOT NULL,
|
||||
reject_reason TEXT,
|
||||
reviewed_by BIGINT,
|
||||
reviewed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
|
||||
CONSTRAINT chk_verification_status CHECK (status IN ('pending', 'approved', 'rejected')),
|
||||
UNIQUE(user_id, role) -- 每个角色只有一条最新的认证记录
|
||||
);
|
||||
|
||||
-- Note:Auto update verification_status of users table
|
||||
CREATE OR REPLACE FUNCTION sync_user_verification_status()
|
||||
RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
status_json JSONB;
|
||||
BEGIN
|
||||
SELECT jsonb_object_agg(role, status)
|
||||
INTO status_json
|
||||
FROM user_verifications
|
||||
WHERE user_id = NEW.user_id;
|
||||
|
||||
UPDATE users SET verification_status = status_json WHERE id = NEW.user_id;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER trigger_sync_verifications
|
||||
AFTER INSERT OR UPDATE ON user_verifications
|
||||
FOR EACH ROW EXECUTE FUNCTION sync_user_verification_status();
|
||||
@@ -0,0 +1,29 @@
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm; -- 三元组模糊搜索
|
||||
CREATE EXTENSION IF NOT EXISTS btree_gin; -- 复合 GIN 索引
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto; -- 加密函数
|
||||
|
||||
CREATE TABLE users
|
||||
(
|
||||
id BIGINT PRIMARY KEY,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(20) UNIQUE,
|
||||
email VARCHAR(100) UNIQUE,
|
||||
nickname VARCHAR(100) NOT NULL,
|
||||
avatar TEXT,
|
||||
bio TEXT,
|
||||
"current_role" VARCHAR(20) NOT NULL DEFAULT 'consumer',
|
||||
verified_roles TEXT[] DEFAULT ARRAY ['consumer']::TEXT[],
|
||||
-- 结构: {"player": "pending", "owner": "rejected", "consumer": "approved"}
|
||||
verification_status JSONB DEFAULT '{"consumer": "approved"}'::JSONB,
|
||||
is_admin BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ,
|
||||
|
||||
CONSTRAINT chk_current_role CHECK (current_role IN ('consumer', 'player', 'owner', 'admin'))
|
||||
);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX idx_users_phone ON users (phone) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX idx_users_username_trgm ON users USING gin (username gin_trgm_ops) WHERE deleted_at IS NULL;
|
||||
Reference in New Issue
Block a user