feat: 初始化短剧服务端(管理后台 API + 客户端 API)
Spring Boot 3.2 / MyBatis-Plus / PostgreSQL,7 个 Maven 模块;含认证鉴权、内容与媒资管理、操作日志,以及客户端 /app/** 接口。
This commit is contained in:
commit
a4aa749cc6
152 files changed
+8027
No files matched your search
+320
@@ -0,0 +1,320 @@
|
||||
-- ReelShort 短剧服务 · 建表脚本(PostgreSQL 18)
|
||||
--
|
||||
-- 与 MySQL 版本的对应关系:
|
||||
-- AUTO_INCREMENT -> GENERATED BY DEFAULT AS IDENTITY
|
||||
-- TINYINT -> SMALLINT
|
||||
-- DATETIME(3) -> TIMESTAMP(3)
|
||||
-- ON UPDATE CURRENT_TIMESTAMP -> set_updated_at() 触发器
|
||||
-- 表内 KEY / UNIQUE KEY -> 单独的 CREATE INDEX / UNIQUE 约束
|
||||
-- 列注释 -> 行内注释 + 表注释(COMMENT ON TABLE)
|
||||
|
||||
-- ========== 系统域 ==========
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_admin_user (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
username VARCHAR(64) NOT NULL, -- 登录名
|
||||
password VARCHAR(100) NOT NULL, -- BCrypt 哈希
|
||||
real_name VARCHAR(64) NOT NULL DEFAULT '',
|
||||
mobile VARCHAR(20) NOT NULL DEFAULT '',
|
||||
email VARCHAR(128) NOT NULL DEFAULT '',
|
||||
avatar VARCHAR(255) NOT NULL DEFAULT '',
|
||||
status SMALLINT NOT NULL DEFAULT 1, -- 1 启用 0 停用
|
||||
ip_whitelist VARCHAR(255) NOT NULL DEFAULT '',-- 空 = 不限
|
||||
two_factor SMALLINT NOT NULL DEFAULT 0,
|
||||
last_login_at TIMESTAMP(3),
|
||||
last_login_ip VARCHAR(64) NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_admin_user_username ON sys_admin_user (username);
|
||||
COMMENT ON TABLE sys_admin_user IS '管理员';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_role_category (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR(64) NOT NULL,
|
||||
description VARCHAR(255) NOT NULL DEFAULT '',
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_category_name ON sys_role_category (name);
|
||||
COMMENT ON TABLE sys_role_category IS '角色分类';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_role (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR(64) NOT NULL,
|
||||
code VARCHAR(64) NOT NULL, -- 如 super_admin
|
||||
category_id BIGINT NOT NULL DEFAULT 0,
|
||||
level INT NOT NULL DEFAULT 9, -- 越小权限越高
|
||||
description VARCHAR(255) NOT NULL DEFAULT '',
|
||||
status SMALLINT NOT NULL DEFAULT 1,
|
||||
is_builtin SMALLINT NOT NULL DEFAULT 0, -- 内置角色不可删除
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_code ON sys_role (code);
|
||||
COMMENT ON TABLE sys_role IS '角色';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_admin_user_role (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL,
|
||||
role_id BIGINT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_admin_user_role ON sys_admin_user_role (user_id, role_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_sys_admin_user_role_role ON sys_admin_user_role (role_id);
|
||||
COMMENT ON TABLE sys_admin_user_role IS '管理员-角色';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_permission (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
code VARCHAR(128) NOT NULL, -- 如 drama:create
|
||||
name VARCHAR(64) NOT NULL,
|
||||
group_name VARCHAR(64) NOT NULL DEFAULT '',
|
||||
type VARCHAR(16) NOT NULL DEFAULT 'BUTTON',
|
||||
sort INT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_permission_code ON sys_permission (code);
|
||||
COMMENT ON TABLE sys_permission IS '权限点';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_menu (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
parent_id BIGINT NOT NULL DEFAULT 0,
|
||||
title VARCHAR(64) NOT NULL,
|
||||
route_path VARCHAR(128) NOT NULL DEFAULT '',
|
||||
route_name VARCHAR(64) NOT NULL DEFAULT '',
|
||||
component VARCHAR(255) NOT NULL DEFAULT '',
|
||||
redirect VARCHAR(128) NOT NULL DEFAULT '',
|
||||
icon VARCHAR(64) NOT NULL DEFAULT '',
|
||||
permission_code VARCHAR(128) NOT NULL DEFAULT '',
|
||||
type VARCHAR(16) NOT NULL DEFAULT 'MENU', -- CATALOG/MENU/BUTTON
|
||||
always_show SMALLINT NOT NULL DEFAULT 0,
|
||||
affix SMALLINT NOT NULL DEFAULT 0,
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
visible SMALLINT NOT NULL DEFAULT 1,
|
||||
status SMALLINT NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_sys_menu_parent ON sys_menu (parent_id);
|
||||
COMMENT ON TABLE sys_menu IS '菜单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_role_permission (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
role_id BIGINT NOT NULL,
|
||||
permission_id BIGINT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_permission ON sys_role_permission (role_id, permission_id);
|
||||
COMMENT ON TABLE sys_role_permission IS '角色-权限';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_role_menu (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
role_id BIGINT NOT NULL,
|
||||
menu_id BIGINT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_role_menu ON sys_role_menu (role_id, menu_id);
|
||||
COMMENT ON TABLE sys_role_menu IS '角色-菜单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_config (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
config_key VARCHAR(128) NOT NULL,
|
||||
config_value VARCHAR(1024) NOT NULL DEFAULT '',
|
||||
remark VARCHAR(255) NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_sys_config_key ON sys_config (config_key);
|
||||
COMMENT ON TABLE sys_config IS '系统配置';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sys_operation_log (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
admin_user_id BIGINT NOT NULL DEFAULT 0,
|
||||
username VARCHAR(64) NOT NULL DEFAULT '',
|
||||
module VARCHAR(64) NOT NULL DEFAULT '',
|
||||
action VARCHAR(64) NOT NULL DEFAULT '',
|
||||
request_method VARCHAR(10) NOT NULL DEFAULT '',
|
||||
request_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
request_params TEXT, -- 查询串
|
||||
request_body TEXT, -- 请求体(已脱敏、截断)
|
||||
response_body TEXT, -- 响应体(截断)
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'SUCCESS', -- SUCCESS/FAIL
|
||||
error_msg VARCHAR(500) NOT NULL DEFAULT '',
|
||||
duration_ms INT NOT NULL DEFAULT 0,
|
||||
ip VARCHAR(64) NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_sys_operation_log_admin_time ON sys_operation_log (admin_user_id, created_at);
|
||||
COMMENT ON TABLE sys_operation_log IS '操作日志';
|
||||
|
||||
-- ========== 内容域 ==========
|
||||
|
||||
CREATE TABLE IF NOT EXISTS drama_category (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name VARCHAR(64) NOT NULL,
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
status SMALLINT NOT NULL DEFAULT 1
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_drama_category_name ON drama_category (name);
|
||||
COMMENT ON TABLE drama_category IS '短剧类型';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS drama (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
code VARCHAR(64) NOT NULL DEFAULT '',
|
||||
title VARCHAR(128) NOT NULL,
|
||||
subtitle VARCHAR(128) NOT NULL DEFAULT '',
|
||||
category_id BIGINT NOT NULL DEFAULT 0,
|
||||
genre VARCHAR(64) NOT NULL DEFAULT '',
|
||||
synopsis VARCHAR(1000) NOT NULL DEFAULT '',
|
||||
cover_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
horizontal_cover_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
language VARCHAR(16) NOT NULL DEFAULT 'zh-CN',
|
||||
total_episodes INT NOT NULL DEFAULT 0,
|
||||
free_episodes INT NOT NULL DEFAULT 3,
|
||||
unlock_coin INT NOT NULL DEFAULT 0,
|
||||
is_hot SMALLINT NOT NULL DEFAULT 0, -- 是否热门,供首页热门位使用
|
||||
-- draft/reviewing/approved/published/offline
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'draft',
|
||||
publish_at TIMESTAMP(3),
|
||||
published_at TIMESTAMP(3),
|
||||
view_count BIGINT NOT NULL DEFAULT 0,
|
||||
play_count BIGINT NOT NULL DEFAULT 0,
|
||||
favorite_count BIGINT NOT NULL DEFAULT 0,
|
||||
like_count BIGINT NOT NULL DEFAULT 0,
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
create_by BIGINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_status_publish ON drama (status, publish_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_category ON drama (category_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_updated ON drama (updated_at);
|
||||
-- C 端目录:按状态取热门 / 按分类取列表
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_status_hot ON drama (status, is_hot, sort DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_status_category ON drama (status, category_id, sort DESC);
|
||||
COMMENT ON TABLE drama IS '短剧';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS drama_episode (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
drama_id BIGINT NOT NULL,
|
||||
ep_no INT NOT NULL,
|
||||
title VARCHAR(128) NOT NULL DEFAULT '',
|
||||
duration_sec INT NOT NULL DEFAULT 0,
|
||||
cover_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
video_asset_id BIGINT NOT NULL DEFAULT 0,
|
||||
video_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
is_free SMALLINT NOT NULL DEFAULT 0,
|
||||
unlock_coin INT NOT NULL DEFAULT 0,
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'draft',
|
||||
release_at TIMESTAMP(3),
|
||||
play_count BIGINT NOT NULL DEFAULT 0,
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_drama_episode_no ON drama_episode (drama_id, ep_no);
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_episode_status ON drama_episode (drama_id, status);
|
||||
COMMENT ON TABLE drama_episode IS '剧集';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS drama_review_record (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
biz_type VARCHAR(16) NOT NULL, -- DRAMA/EPISODE
|
||||
biz_id BIGINT NOT NULL,
|
||||
action VARCHAR(16) NOT NULL, -- SUBMIT/APPROVE/REJECT/PUBLISH/OFFLINE
|
||||
reason VARCHAR(500) NOT NULL DEFAULT '',
|
||||
operator_id BIGINT NOT NULL DEFAULT 0,
|
||||
operator_name VARCHAR(64) NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_drama_review_biz ON drama_review_record (biz_type, biz_id, created_at);
|
||||
COMMENT ON TABLE drama_review_record IS '审核记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS content_banner (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
image_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
slot VARCHAR(32) NOT NULL DEFAULT 'HOME_TOP', -- 展示位置:HOME_TOP/DISCOVER
|
||||
link_type VARCHAR(16) NOT NULL DEFAULT 'NONE', -- NONE/DRAMA/URL
|
||||
link_value VARCHAR(512) NOT NULL DEFAULT '',
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
status SMALLINT NOT NULL DEFAULT 1,
|
||||
create_by BIGINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_content_banner_slot ON content_banner (slot, status, sort);
|
||||
COMMENT ON TABLE content_banner IS '轮播图';
|
||||
|
||||
-- ========== 媒资域 ==========
|
||||
-- 本地存储版本:文件落在 reelshort.media.root-dir 下,通过 /files/** 访问
|
||||
|
||||
CREATE TABLE IF NOT EXISTS media_asset (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
biz_type VARCHAR(32) NOT NULL DEFAULT 'EPISODE',
|
||||
file_name VARCHAR(255) NOT NULL DEFAULT '',
|
||||
object_key VARCHAR(512) NOT NULL DEFAULT '',
|
||||
source_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
size_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
md5 VARCHAR(64) NOT NULL DEFAULT '',
|
||||
duration_sec INT NOT NULL DEFAULT 0,
|
||||
width INT NOT NULL DEFAULT 0,
|
||||
height INT NOT NULL DEFAULT 0,
|
||||
-- uploading/uploaded/transcoding/ready/failed
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'uploading',
|
||||
hls_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
mp4_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
poster_url VARCHAR(512) NOT NULL DEFAULT '',
|
||||
create_by BIGINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted SMALLINT NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_media_asset_status ON media_asset (status);
|
||||
CREATE INDEX IF NOT EXISTS idx_media_asset_biz_type ON media_asset (biz_type);
|
||||
COMMENT ON TABLE media_asset IS '媒资';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS media_upload_task (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
upload_id VARCHAR(64) NOT NULL,
|
||||
biz_type VARCHAR(32) NOT NULL DEFAULT 'EPISODE',
|
||||
file_name VARCHAR(255) NOT NULL DEFAULT '',
|
||||
file_size BIGINT NOT NULL DEFAULT 0,
|
||||
chunk_size INT NOT NULL DEFAULT 0,
|
||||
total_chunks INT NOT NULL DEFAULT 0,
|
||||
received_chunks INT NOT NULL DEFAULT 0,
|
||||
object_key VARCHAR(512) NOT NULL DEFAULT '',
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'uploading',
|
||||
asset_id BIGINT NOT NULL DEFAULT 0,
|
||||
create_by BIGINT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uk_media_upload_task ON media_upload_task (upload_id);
|
||||
COMMENT ON TABLE media_upload_task IS '分片上传任务';
|
||||
|
||||
-- ========== updated_at 维护 ==========
|
||||
-- PostgreSQL 没有 ON UPDATE CURRENT_TIMESTAMP,用触发器统一维护
|
||||
|
||||
CREATE OR REPLACE FUNCTION set_updated_at() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
t text;
|
||||
BEGIN
|
||||
FOREACH t IN ARRAY ARRAY[
|
||||
'sys_admin_user', 'sys_role_category', 'sys_role', 'sys_menu',
|
||||
'drama', 'drama_episode', 'content_banner', 'media_asset', 'media_upload_task'
|
||||
] LOOP
|
||||
EXECUTE format('DROP TRIGGER IF EXISTS trg_%s_updated_at ON %I', t, t);
|
||||
EXECUTE format(
|
||||
'CREATE TRIGGER trg_%s_updated_at BEFORE UPDATE ON %I FOR EACH ROW EXECUTE FUNCTION set_updated_at()',
|
||||
t, t
|
||||
);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
Reference in new issue
Block a user