chore: align db spec with migrations
This commit is contained in:
448
specs/DB.sql
448
specs/DB.sql
@@ -1,151 +1,339 @@
|
|||||||
-- 新项目数据库 DDL(PostgreSQL)
|
-- QuyUn v2 数据库 DDL(PostgreSQL)
|
||||||
-- 目标:多租户(tenant_id 全表隔离)+ tenant_uuid 用于 OSS Key:quyun/<tenant_uuid>/<md5>.<ext>
|
-- 说明:本文件用于规格参考,需与 backend/database/migrations 保持一致。
|
||||||
-- 注意:tenant_uuid 由业务代码生成写入(不使用 DB 扩展默认值)
|
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
-- 1) 租户
|
-- Users
|
||||||
CREATE TABLE IF NOT EXISTS tenants (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
tenant_code VARCHAR(64) NOT NULL,
|
|
||||||
tenant_uuid UUID NOT NULL,
|
|
||||||
name VARCHAR(128) NOT NULL DEFAULT '',
|
|
||||||
status INT2 NOT NULL DEFAULT 0,
|
|
||||||
config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
||||||
);
|
|
||||||
|
|
||||||
-- tenant_code:不区分大小写(写入/查询均 lower),并限制字符集 a-z0-9_-
|
|
||||||
ALTER TABLE tenants
|
|
||||||
ADD CONSTRAINT tenants_tenant_code_format
|
|
||||||
CHECK (tenant_code ~ '^[A-Za-z0-9_-]+$');
|
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_tenants_tenant_code_lower
|
|
||||||
ON tenants (lower(tenant_code));
|
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_tenants_tenant_uuid
|
|
||||||
ON tenants (tenant_uuid);
|
|
||||||
|
|
||||||
-- 2) 租户后台账号
|
|
||||||
CREATE TABLE IF NOT EXISTS admin_users (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
||||||
username VARCHAR(64) NOT NULL,
|
|
||||||
password_hash TEXT NOT NULL,
|
|
||||||
role VARCHAR(32) NOT NULL DEFAULT 'admin',
|
|
||||||
status INT2 NOT NULL DEFAULT 0,
|
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_admin_users_tenant_username
|
|
||||||
ON admin_users (tenant_id, lower(username));
|
|
||||||
|
|
||||||
-- 3) 用户(微信 openid 用户)
|
|
||||||
CREATE TABLE IF NOT EXISTS users(
|
CREATE TABLE IF NOT EXISTS users(
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
username varchar(255) NOT NULL UNIQUE, -- 用户名:唯一,用于登录
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
password varchar(255) NOT NULL, -- 密码:加密存储
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
roles text[] DEFAULT '{user}', -- 角色:用户角色列表,如 {user, super_admin}
|
||||||
deleted_at TIMESTAMPTZ,
|
status varchar(50) DEFAULT 'active', -- 状态:active/inactive/banned
|
||||||
status INT2 NOT NULL DEFAULT 0,
|
metas jsonb DEFAULT '{}', -- 元数据:额外扩展信息
|
||||||
open_id VARCHAR(128) NOT NULL,
|
balance bigint DEFAULT 0, -- 全局可用余额:分/最小货币单位
|
||||||
username VARCHAR(128) NOT NULL DEFAULT '',
|
balance_frozen bigint DEFAULT 0, -- 全局冻结余额:分/最小货币单位
|
||||||
avatar TEXT,
|
verified_at timestamp with time zone, -- 实名认证时间
|
||||||
metas JSONB NOT NULL DEFAULT '{}'::jsonb,
|
nickname varchar(255) DEFAULT '', -- 昵称:用户显示名称
|
||||||
auth_token JSONB NOT NULL DEFAULT '{}'::jsonb,
|
avatar varchar(512) DEFAULT '', -- 头像:URL地址
|
||||||
balance BIGINT NOT NULL DEFAULT 0
|
gender varchar(32) DEFAULT 'secret', -- 性别:male/female/secret
|
||||||
|
bio varchar(512) DEFAULT '', -- 简介:用户个人简介
|
||||||
|
birthday date, -- 生日:YYYY-MM-DD
|
||||||
|
location jsonb DEFAULT '{}', -- 位置:省市区信息 {province: "...", city: "..."}
|
||||||
|
points bigint DEFAULT 0, -- 积分:用户积分
|
||||||
|
phone varchar(32) DEFAULT '', -- 手机号:用于登录/验证
|
||||||
|
is_real_name_verified boolean DEFAULT FALSE, -- 是否实名认证:true/false
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:默认 now()
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:默认 now()
|
||||||
|
deleted_at timestamp with time zone -- 删除时间:软删除
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_users_tenant_openid
|
-- Tenants
|
||||||
ON users (tenant_id, open_id);
|
CREATE TABLE IF NOT EXISTS tenants(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
CREATE INDEX IF NOT EXISTS ix_users_tenant_id
|
user_id bigint NOT NULL, -- 创建者ID:关联 users.id
|
||||||
ON users (tenant_id, id);
|
code varchar(64) NOT NULL UNIQUE, -- 租户代码:唯一标识,用于 URL 等
|
||||||
|
uuid uuid NOT NULL, -- UUID:全局唯一标识
|
||||||
-- 4) 媒体
|
name varchar(128) NOT NULL, -- 租户名称
|
||||||
CREATE TABLE IF NOT EXISTS medias (
|
status varchar(64) NOT NULL, -- 状态:pending_verify/verified/banned
|
||||||
id BIGSERIAL PRIMARY KEY,
|
config jsonb DEFAULT '{}', -- 配置:租户配置信息
|
||||||
tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
expired_at timestamp with time zone, -- 过期时间:租户有效期
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:默认 now()
|
||||||
name VARCHAR(255) NOT NULL DEFAULT '',
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:默认 now()
|
||||||
mime_type VARCHAR(128) NOT NULL DEFAULT '',
|
|
||||||
size BIGINT NOT NULL DEFAULT 0,
|
|
||||||
path VARCHAR(512) NOT NULL DEFAULT '',
|
|
||||||
metas JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
||||||
hash VARCHAR(64) NOT NULL DEFAULT ''
|
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 租户内按 md5 去重
|
CREATE INDEX IF NOT EXISTS idx_tenants_user_id ON tenants(user_id);
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_medias_tenant_hash
|
|
||||||
ON medias (tenant_id, hash);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS ix_medias_tenant_id
|
-- TenantUsers
|
||||||
ON medias (tenant_id, id);
|
CREATE TABLE IF NOT EXISTS tenant_users(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
-- 5) 曲谱/内容
|
tenant_id bigint NOT NULL, -- 租户ID:关联 tenants.id
|
||||||
CREATE TABLE IF NOT EXISTS posts (
|
user_id bigint NOT NULL, -- 用户ID:关联 users.id
|
||||||
id BIGSERIAL PRIMARY KEY,
|
role text[] DEFAULT '{member}', -- 角色:member/tenant_admin
|
||||||
tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
status varchar(50) DEFAULT 'verified', -- 状态:pending_verify/verified/banned
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:默认 now()
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:默认 now()
|
||||||
deleted_at TIMESTAMPTZ,
|
UNIQUE (tenant_id, user_id)
|
||||||
status INT2 NOT NULL DEFAULT 0,
|
|
||||||
title VARCHAR(128) NOT NULL,
|
|
||||||
head_images JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
||||||
description VARCHAR(256) NOT NULL DEFAULT '',
|
|
||||||
content TEXT NOT NULL DEFAULT '',
|
|
||||||
price BIGINT NOT NULL DEFAULT 0,
|
|
||||||
discount INT2 NOT NULL DEFAULT 100,
|
|
||||||
views BIGINT NOT NULL DEFAULT 0,
|
|
||||||
likes BIGINT NOT NULL DEFAULT 0,
|
|
||||||
tags JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
||||||
assets JSONB NOT NULL DEFAULT '[]'::jsonb
|
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS ix_posts_tenant_status_deleted
|
-- Contents
|
||||||
ON posts (tenant_id, status, deleted_at);
|
CREATE TABLE IF NOT EXISTS contents(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增;用于内容引用
|
||||||
-- 6) 授权关系(购买/赠送)
|
tenant_id bigint NOT NULL, -- 租户ID:多租户隔离关键字段
|
||||||
CREATE TABLE IF NOT EXISTS user_posts (
|
user_id bigint NOT NULL, -- 用户ID:内容创建者/发布者
|
||||||
id BIGSERIAL PRIMARY KEY,
|
title varchar(255) NOT NULL, -- 标题:用于列表展示与搜索
|
||||||
tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
description text NOT NULL, -- 描述:用于详情页展示
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
status varchar(32) DEFAULT 'draft', -- 状态:draft/reviewing/published/unpublished/blocked
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
visibility varchar(32) DEFAULT 'tenant_only', -- 可见性:public/tenant_only/private
|
||||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
preview_seconds int DEFAULT 60, -- 试看秒数:默认 60
|
||||||
post_id BIGINT NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
preview_downloadable boolean DEFAULT FALSE, -- 试看是否允许下载
|
||||||
price BIGINT NOT NULL DEFAULT 0
|
published_at timestamp with time zone, -- 发布时间
|
||||||
|
summary varchar(256) DEFAULT '', -- 简介:用于列表/卡片展示
|
||||||
|
tags jsonb DEFAULT '[]', -- 标签:JSON 数组
|
||||||
|
body text DEFAULT '', -- 内容主体:文章内容/详细介绍
|
||||||
|
genre varchar(64) DEFAULT '', -- 类型/流派
|
||||||
|
views int DEFAULT 0, -- 浏览量
|
||||||
|
likes int DEFAULT 0, -- 点赞数
|
||||||
|
key varchar(32) DEFAULT '', -- 音乐调性/主音
|
||||||
|
is_pinned boolean DEFAULT FALSE, -- 是否置顶
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
|
||||||
|
deleted_at timestamp with time zone -- 软删除时间
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_user_posts_tenant_user_post
|
CREATE INDEX IF NOT EXISTS idx_contents_tenant_id ON contents(tenant_id);
|
||||||
ON user_posts (tenant_id, user_id, post_id);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS ix_user_posts_tenant_user
|
-- MediaAssets
|
||||||
ON user_posts (tenant_id, user_id, id);
|
CREATE TABLE IF NOT EXISTS media_assets(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID:多租户隔离关键字段
|
||||||
|
user_id bigint NOT NULL, -- 用户ID:资源上传者
|
||||||
|
type varchar(32) DEFAULT 'video', -- 资源类型:video/audio/image
|
||||||
|
status varchar(32) DEFAULT 'uploaded', -- 处理状态:uploaded/processing/ready/failed/deleted
|
||||||
|
provider varchar(64) NOT NULL, -- 存储提供方:s3/minio/oss/local
|
||||||
|
bucket varchar(128) NOT NULL, -- 存储桶
|
||||||
|
object_key varchar(512) NOT NULL, -- 对象键
|
||||||
|
meta jsonb DEFAULT '{}', -- 元数据:JSON
|
||||||
|
variant varchar(32) DEFAULT 'main', -- 产物类型:main/preview
|
||||||
|
source_asset_id bigint DEFAULT 0, -- 派生来源资源ID
|
||||||
|
hash varchar(64) DEFAULT '', -- 文件 MD5 哈希
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
|
||||||
|
deleted_at timestamp with time zone -- 软删除时间
|
||||||
|
);
|
||||||
|
|
||||||
-- 7) 订单(仅余额)
|
CREATE INDEX IF NOT EXISTS idx_media_assets_hash ON media_assets (hash);
|
||||||
|
|
||||||
|
-- ContentAssets
|
||||||
|
CREATE TABLE IF NOT EXISTS content_assets(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
content_id bigint NOT NULL, -- 内容ID
|
||||||
|
asset_id bigint NOT NULL, -- 资源ID
|
||||||
|
role varchar(32) DEFAULT 'main', -- 资源角色:main/cover/preview
|
||||||
|
sort int DEFAULT 0, -- 排序
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ContentPrices
|
||||||
|
CREATE TABLE IF NOT EXISTS content_prices(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
content_id bigint NOT NULL, -- 内容ID
|
||||||
|
currency varchar(16) DEFAULT 'CNY', -- 币种
|
||||||
|
price_amount bigint NOT NULL, -- 基础价格:分
|
||||||
|
discount_type varchar(16) DEFAULT 'none', -- 折扣类型:none/percent/amount
|
||||||
|
discount_value bigint DEFAULT 0, -- 折扣值
|
||||||
|
discount_start_at timestamp with time zone, -- 折扣开始时间
|
||||||
|
discount_end_at timestamp with time zone, -- 折扣结束时间
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
|
||||||
|
UNIQUE (tenant_id, content_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ContentAccess
|
||||||
|
CREATE TABLE IF NOT EXISTS content_access(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
content_id bigint NOT NULL, -- 内容ID
|
||||||
|
order_id bigint DEFAULT 0, -- 订单ID
|
||||||
|
status varchar(16) DEFAULT 'active', -- 权益状态
|
||||||
|
revoked_at timestamp with time zone, -- 撤销时间
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
|
||||||
|
UNIQUE (tenant_id, user_id, content_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Orders
|
||||||
CREATE TABLE IF NOT EXISTS orders(
|
CREATE TABLE IF NOT EXISTS orders(
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
type varchar(32) DEFAULT 'content_purchase', -- 订单类型
|
||||||
order_no VARCHAR(64) NOT NULL,
|
status varchar(32) DEFAULT 'created', -- 订单状态
|
||||||
price BIGINT NOT NULL DEFAULT 0,
|
currency varchar(16) DEFAULT 'CNY', -- 币种
|
||||||
discount INT2 NOT NULL DEFAULT 100,
|
amount_original bigint NOT NULL, -- 原价金额
|
||||||
currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
|
amount_discount bigint NOT NULL, -- 优惠金额
|
||||||
payment_method VARCHAR(50) NOT NULL DEFAULT 'balance',
|
amount_paid bigint NOT NULL, -- 实付金额
|
||||||
post_id BIGINT NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
|
snapshot jsonb DEFAULT '{}', -- 订单快照
|
||||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
idempotency_key varchar(128) NOT NULL, -- 幂等键
|
||||||
status INT2 NOT NULL DEFAULT 0,
|
paid_at timestamp with time zone, -- 支付时间
|
||||||
meta JSONB NOT NULL DEFAULT '{}'::jsonb
|
refunded_at timestamp with time zone, -- 退款时间
|
||||||
|
refund_forced boolean DEFAULT FALSE, -- 是否强制退款
|
||||||
|
refund_operator_user_id bigint DEFAULT 0, -- 退款操作人
|
||||||
|
refund_reason varchar(255) DEFAULT '', -- 退款原因
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
|
||||||
|
coupon_id bigint DEFAULT 0 -- 关联优惠券ID (0表示未使用)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_orders_tenant_order_no
|
-- OrderItems
|
||||||
ON orders (tenant_id, order_no);
|
CREATE TABLE IF NOT EXISTS order_items(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
order_id bigint NOT NULL, -- 订单ID
|
||||||
|
content_id bigint NOT NULL, -- 内容ID
|
||||||
|
content_user_id bigint NOT NULL, -- 内容作者用户ID
|
||||||
|
amount_paid bigint NOT NULL, -- 该行实付金额
|
||||||
|
snapshot jsonb DEFAULT '{}', -- 内容快照
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
|
||||||
|
);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS ix_orders_tenant_user
|
-- TenantLedgers
|
||||||
ON orders (tenant_id, user_id, id);
|
CREATE TABLE IF NOT EXISTS tenant_ledgers(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
order_id bigint DEFAULT 0, -- 关联订单ID
|
||||||
|
type varchar(32) NOT NULL, -- 流水类型
|
||||||
|
amount bigint NOT NULL, -- 流水金额
|
||||||
|
balance_before bigint NOT NULL, -- 变更前可用余额
|
||||||
|
balance_after bigint NOT NULL, -- 变更后可用余额
|
||||||
|
frozen_before bigint NOT NULL, -- 变更前冻结余额
|
||||||
|
frozen_after bigint NOT NULL, -- 变更后冻结余额
|
||||||
|
idempotency_key varchar(128) NOT NULL, -- 幂等键
|
||||||
|
remark varchar(255) NOT NULL, -- 备注
|
||||||
|
operator_user_id bigint DEFAULT 0, -- 操作者用户ID
|
||||||
|
biz_ref_type varchar(32) DEFAULT '', -- 业务引用类型
|
||||||
|
biz_ref_id bigint DEFAULT 0, -- 业务引用ID
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
|
||||||
|
);
|
||||||
|
|
||||||
|
-- TenantInvites
|
||||||
|
CREATE TABLE IF NOT EXISTS tenant_invites(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 创建人用户ID
|
||||||
|
code varchar(64) NOT NULL, -- 邀请码
|
||||||
|
status varchar(32) DEFAULT 'active', -- 邀请状态
|
||||||
|
max_uses int NOT NULL, -- 最大可使用次数
|
||||||
|
used_count int DEFAULT 0, -- 已使用次数
|
||||||
|
expires_at timestamp with time zone, -- 过期时间
|
||||||
|
disabled_at timestamp with time zone, -- 禁用时间
|
||||||
|
disabled_operator_user_id bigint DEFAULT 0, -- 禁用操作人用户ID
|
||||||
|
remark varchar(255) DEFAULT '', -- 备注
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
|
||||||
|
);
|
||||||
|
|
||||||
|
-- TenantJoinRequests
|
||||||
|
CREATE TABLE IF NOT EXISTS tenant_join_requests(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 申请人用户ID
|
||||||
|
status varchar(32) DEFAULT 'pending', -- 申请状态
|
||||||
|
reason varchar(255) NOT NULL, -- 申请原因
|
||||||
|
decided_at timestamp with time zone, -- 处理时间
|
||||||
|
decided_operator_user_id bigint DEFAULT 0, -- 处理人用户ID
|
||||||
|
decided_reason varchar(255) DEFAULT '', -- 处理说明
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Comments
|
||||||
|
CREATE TABLE IF NOT EXISTS comments(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
content_id bigint NOT NULL, -- 内容ID
|
||||||
|
reply_to bigint DEFAULT 0, -- 回复评论ID:0表示一级评论
|
||||||
|
content text NOT NULL, -- 评论内容
|
||||||
|
likes int DEFAULT 0, -- 点赞数
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间
|
||||||
|
deleted_at timestamp with time zone -- 软删除时间
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_comments_content_id ON comments(content_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_comments_user_id ON comments(user_id);
|
||||||
|
|
||||||
|
-- User Content Actions (Like, Favorite)
|
||||||
|
CREATE TABLE IF NOT EXISTS user_content_actions(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
content_id bigint NOT NULL, -- 内容ID
|
||||||
|
type varchar(32) NOT NULL, -- 类型:like, favorite
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
UNIQUE (user_id, content_id, type)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- User Comment Actions (Like)
|
||||||
|
CREATE TABLE IF NOT EXISTS user_comment_actions(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
comment_id bigint NOT NULL, -- 评论ID
|
||||||
|
type varchar(32) NOT NULL, -- 类型:like
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
UNIQUE (user_id, comment_id, type)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Payout Accounts
|
||||||
|
CREATE TABLE IF NOT EXISTS payout_accounts(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
tenant_id bigint NOT NULL, -- 租户ID
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
type varchar(32) NOT NULL, -- 类型:bank, alipay
|
||||||
|
name varchar(128) NOT NULL, -- 账户名称/开户行
|
||||||
|
account varchar(128) NOT NULL, -- 账号
|
||||||
|
realname varchar(128) NOT NULL, -- 真实姓名
|
||||||
|
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间
|
||||||
|
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_payout_accounts_tenant_id ON payout_accounts(tenant_id);
|
||||||
|
|
||||||
|
-- Notifications
|
||||||
|
CREATE TABLE IF NOT EXISTS notifications(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||||||
|
user_id bigint NOT NULL, -- 接收用户ID
|
||||||
|
tenant_id bigint DEFAULT 0, -- 来源租户ID
|
||||||
|
type varchar(32) NOT NULL, -- 类型:system, order, audit, interaction
|
||||||
|
title varchar(255) NOT NULL, -- 标题
|
||||||
|
content text NOT NULL, -- 内容
|
||||||
|
is_read boolean DEFAULT FALSE, -- 是否已读
|
||||||
|
created_at timestamp with time zone DEFAULT NOW() -- 创建时间
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);
|
||||||
|
|
||||||
|
-- Coupons
|
||||||
|
CREATE TABLE IF NOT EXISTS coupons(
|
||||||
|
id bigserial PRIMARY KEY, -- 主键ID
|
||||||
|
tenant_id bigint NOT NULL DEFAULT 0, -- 租户ID
|
||||||
|
title varchar(255) NOT NULL, -- 优惠券标题
|
||||||
|
description text, -- 优惠券描述
|
||||||
|
type varchar(32) NOT NULL, -- 优惠券类型: fix_amount/discount
|
||||||
|
value bigint NOT NULL, -- 优惠券面值
|
||||||
|
min_order_amount bigint NOT NULL DEFAULT 0, -- 最低订单金额门槛
|
||||||
|
max_discount bigint, -- 最高抵扣金额
|
||||||
|
total_quantity integer NOT NULL DEFAULT 0, -- 发行总量
|
||||||
|
used_quantity integer NOT NULL DEFAULT 0, -- 已使用数量
|
||||||
|
start_at timestamptz, -- 开始生效时间
|
||||||
|
end_at timestamptz, -- 过期失效时间
|
||||||
|
created_at timestamptz NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at timestamptz NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_coupons_tenant_id ON coupons(tenant_id);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS user_coupons(
|
||||||
|
id bigserial PRIMARY KEY,
|
||||||
|
user_id bigint NOT NULL, -- 用户ID
|
||||||
|
coupon_id bigint NOT NULL, -- 优惠券ID
|
||||||
|
order_id bigint, -- 使用该优惠券的订单ID
|
||||||
|
status varchar(32) NOT NULL DEFAULT 'unused', -- 状态: unused/used/expired
|
||||||
|
used_at timestamptz, -- 使用时间
|
||||||
|
created_at timestamptz NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_coupons_user_id ON user_coupons(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_coupons_coupon_id ON user_coupons(coupon_id);
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user