340 lines
16 KiB
PL/PgSQL
340 lines
16 KiB
PL/PgSQL
-- QuyUn v2 数据库 DDL(PostgreSQL)
|
||
-- 说明:本文件用于规格参考,需与 backend/database/migrations 保持一致。
|
||
|
||
BEGIN;
|
||
|
||
-- Users
|
||
CREATE TABLE IF NOT EXISTS users(
|
||
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||
username varchar(255) NOT NULL UNIQUE, -- 用户名:唯一,用于登录
|
||
password varchar(255) NOT NULL, -- 密码:加密存储
|
||
roles text[] DEFAULT '{user}', -- 角色:用户角色列表,如 {user, super_admin}
|
||
status varchar(50) DEFAULT 'active', -- 状态:active/inactive/banned
|
||
metas jsonb DEFAULT '{}', -- 元数据:额外扩展信息
|
||
balance bigint DEFAULT 0, -- 全局可用余额:分/最小货币单位
|
||
balance_frozen bigint DEFAULT 0, -- 全局冻结余额:分/最小货币单位
|
||
verified_at timestamp with time zone, -- 实名认证时间
|
||
nickname varchar(255) DEFAULT '', -- 昵称:用户显示名称
|
||
avatar varchar(512) DEFAULT '', -- 头像:URL地址
|
||
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 -- 删除时间:软删除
|
||
);
|
||
|
||
-- Tenants
|
||
CREATE TABLE IF NOT EXISTS tenants(
|
||
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||
user_id bigint NOT NULL, -- 创建者ID:关联 users.id
|
||
code varchar(64) NOT NULL UNIQUE, -- 租户代码:唯一标识,用于 URL 等
|
||
uuid uuid NOT NULL, -- UUID:全局唯一标识
|
||
name varchar(128) NOT NULL, -- 租户名称
|
||
status varchar(64) NOT NULL, -- 状态:pending_verify/verified/banned
|
||
config jsonb DEFAULT '{}', -- 配置:租户配置信息
|
||
expired_at timestamp with time zone, -- 过期时间:租户有效期
|
||
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:默认 now()
|
||
updated_at timestamp with time zone DEFAULT NOW() -- 更新时间:默认 now()
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_tenants_user_id ON tenants(user_id);
|
||
|
||
-- TenantUsers
|
||
CREATE TABLE IF NOT EXISTS tenant_users(
|
||
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||
tenant_id bigint NOT NULL, -- 租户ID:关联 tenants.id
|
||
user_id bigint NOT NULL, -- 用户ID:关联 users.id
|
||
role text[] DEFAULT '{member}', -- 角色:member/tenant_admin
|
||
status varchar(50) DEFAULT 'verified', -- 状态:pending_verify/verified/banned
|
||
created_at timestamp with time zone DEFAULT NOW(), -- 创建时间:默认 now()
|
||
updated_at timestamp with time zone DEFAULT NOW(), -- 更新时间:默认 now()
|
||
UNIQUE (tenant_id, user_id)
|
||
);
|
||
|
||
-- Contents
|
||
CREATE TABLE IF NOT EXISTS contents(
|
||
id bigserial PRIMARY KEY, -- 主键ID:自增;用于内容引用
|
||
tenant_id bigint NOT NULL, -- 租户ID:多租户隔离关键字段
|
||
user_id bigint NOT NULL, -- 用户ID:内容创建者/发布者
|
||
title varchar(255) NOT NULL, -- 标题:用于列表展示与搜索
|
||
description text NOT NULL, -- 描述:用于详情页展示
|
||
status varchar(32) DEFAULT 'draft', -- 状态:draft/reviewing/published/unpublished/blocked
|
||
visibility varchar(32) DEFAULT 'tenant_only', -- 可见性:public/tenant_only/private
|
||
preview_seconds int DEFAULT 60, -- 试看秒数:默认 60
|
||
preview_downloadable boolean DEFAULT FALSE, -- 试看是否允许下载
|
||
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 INDEX IF NOT EXISTS idx_contents_tenant_id ON contents(tenant_id);
|
||
|
||
-- MediaAssets
|
||
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 -- 软删除时间
|
||
);
|
||
|
||
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(
|
||
id bigserial PRIMARY KEY, -- 主键ID:自增
|
||
tenant_id bigint NOT NULL, -- 租户ID
|
||
user_id bigint NOT NULL, -- 用户ID
|
||
type varchar(32) DEFAULT 'content_purchase', -- 订单类型
|
||
status varchar(32) DEFAULT 'created', -- 订单状态
|
||
currency varchar(16) DEFAULT 'CNY', -- 币种
|
||
amount_original bigint NOT NULL, -- 原价金额
|
||
amount_discount bigint NOT NULL, -- 优惠金额
|
||
amount_paid bigint NOT NULL, -- 实付金额
|
||
snapshot jsonb DEFAULT '{}', -- 订单快照
|
||
idempotency_key varchar(128) NOT NULL, -- 幂等键
|
||
paid_at timestamp with time zone, -- 支付时间
|
||
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表示未使用)
|
||
);
|
||
|
||
-- OrderItems
|
||
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() -- 更新时间
|
||
);
|
||
|
||
-- TenantLedgers
|
||
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;
|