Files
juwan-backend/desc/sql/users/user_verifications.sql
T
2026-02-27 19:17:01 +08:00

52 lines
3.1 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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) -- 每个角色只有一条最新的认证记录
);
-- NoteAuto 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();
-- | 字段名 | 类型 | 技术含义 | 业务目的与设计思考 |
-- | :--- | :--- | :--- | :--- |
-- | **`id`** | BIGINT | **主键 (Primary Key)** | **这张认证申请单的唯一编号**。<br>后端代码在处理“审核通过”这个动作时,操作的是这个 ID(例如:`Approve(verificationId)`)。 |
-- | **`user_id`** | BIGINT | **外键 (Foreign Key)** | **谁在申请?**<br>关联到 `users` 表。通过这个字段,我们可以查到申请人的昵称、手机号等信息。 |
-- | **`role`** | VARCHAR | 普通字段 | **申请什么身份?**<br>枚举值:`player` (打手), `owner` (店长)。<br>因为一个用户可以同时是打手和店长,所以需要区分这条记录是申请哪个身份的。 |
-- | **`status`** | VARCHAR | 状态字段 | **当前进度如何?**<br>枚举值:`pending` (待审核), `approved` (已通过), `rejected` (已驳回)。 |
-- | **`materials`** | **JSONB** | **非结构化数据** | **提交了什么证明材料?**<br>**精华设计**:这里不使用多张表或多个字段,而是用 JSON 存。因为打手需要传“身份证+段位图”,店长需要传“营业执照”。不同角色的材料结构不同,用 JSONB 最灵活,以后改规则不需要改表结构。 |
-- | **`reject_reason`** | TEXT | 文本 | **驳回理由**。<br>只有当 `status` = 'rejected' 时才有值,告诉用户哪里填错了。 |
-- | **`reviewed_by`** | BIGINT | 审计字段 | **谁审核的?**<br>记录是哪个管理员(Admin ID)点击了通过或拒绝。用于内部追责和审计。 |
-- | **`reviewed_at`** | TIMESTAMPTZ | 时间字段 | **什么时候审核的?**<br>用于统计管理员的工作效率,或者展示给用户“审核耗时”。 |
-- | **`created_at`** | TIMESTAMPTZ | 时间字段 | **申请提交时间**。 |
-- | **`updated_at`** | TIMESTAMPTZ | 时间字段 | **最后更新时间**。<br>比如用户重新上传了图片,这个时间会变。 |