Files
FruitServer/sql/data.sql
T
Vicky b3179fc836 refactor: 后端标识统一为 FruitShorts,并落地 05 离线下载
为什么:
1) 产品已定名 FruitShorts,但后端仍是 reelshort 系列标识 —— Java 包 com.reelshort、
   模块名与 jar 名 reelshort-*、spring.application.name、配置前缀 reelshort.*,
   这些会出现在启动日志、命令行和 IDE 里,与产品名不一致。本次整体替换为 fruitshorts,
   数据库连接名上一轮已改名,保持不变。
2) 第一阶段下一批第 1 步(05 离线下载)要求把下载授权(设备绑定/有效期/吊销)、
   下载任务与断点续传、配额与过期清理、仅 Wi-Fi 规则做成完整接口,本提交一并落地。
3) 顺带修复:schema-phase1.sql 里 playback_ticket / order_event 仍按普通表定义唯一索引,
   表分区化之后重跑脚本必定报错(分区表的唯一索引必须包含分区键)。改为在本脚本里就
   按分区表定义,并验证脚本可重复执行。
2026-10-15 11:44:26 +08:00

192 lines
14 KiB
SQL
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.
-- FruitShorts 短剧服务 · 初始化数据(PostgreSQL 18,可重复执行)
-- 演示账号:admin / admin123(其余种子账号密码相同)
--
-- MySQL 的 ON DUPLICATE KEY UPDATE 在这里换成 ON CONFLICT (id) DO UPDATE;
-- INSERT IGNORE 换成 ON CONFLICT DO NOTHING。
-- 末尾会把自增序列对齐到已有最大 ID,避免后续插入主键冲突。
-- ---------- 角色分类 ----------
INSERT INTO sys_role_category (id, name, description, sort) VALUES
(1, '系统管理员', '负责账号、权限和菜单配置', 1),
(2, '内容管理', '负责短剧与剧集内容维护', 2),
(3, '数据分析', '负责查看运营数据', 3)
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, description = EXCLUDED.description, sort = EXCLUDED.sort;
-- ---------- 角色 ----------
INSERT INTO sys_role (id, name, code, category_id, level, description, status, is_builtin) VALUES
(1, '超级管理员', 'super_admin', 1, 1, '拥有系统全部管理权限', 1, 1),
(2, '内容运营', 'content_operator', 2, 2, '管理短剧、剧集及封面素材', 1, 1),
(3, '审核专员', 'content_reviewer', 2, 3, '审核短剧内容与发布状态', 1, 1),
(4, '数据分析师', 'data_analyst', 3, 4, '查看内容数据与运营报表', 1, 1)
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, code = EXCLUDED.code,
description = EXCLUDED.description, category_id = EXCLUDED.category_id, level = EXCLUDED.level;
-- ---------- 权限点 ----------
INSERT INTO sys_permission (id, code, name, group_name, type, sort) VALUES
(1, 'drama:list', '查看短剧列表', '短剧管理', 'BUTTON', 1),
(2, 'drama:create', '创建短剧', '短剧管理', 'BUTTON', 2),
(3, 'drama:update', '编辑短剧信息', '短剧管理', 'BUTTON', 3),
(4, 'drama:delete', '删除短剧', '短剧管理', 'BUTTON', 4),
(5, 'episode:list', '查看剧集列表', '剧集管理', 'BUTTON', 5),
(6, 'episode:upload', '上传剧集视频', '剧集管理', 'BUTTON', 6),
(7, 'episode:sort', '管理剧集排序', '剧集管理', 'BUTTON', 7),
(8, 'cover:upload', '上传封面素材', '封面管理', 'BUTTON', 8),
(9, 'drama:review', '审核并发布', '审核与系统', 'BUTTON', 9),
(10, 'stat:view', '查看数据报表', '审核与系统', 'BUTTON', 10),
(11, 'system:role', '角色与权限配置', '后台管理', 'BUTTON', 11),
(12, 'system:admin-user', '管理员用户列表', '后台管理', 'BUTTON', 12),
(13, 'system:menu', '菜单管理', '后台管理', 'BUTTON', 13),
(14, 'system:role-category', '角色分类管理', '后台管理', 'BUTTON', 14),
(15, 'banner:list', '查看轮播图', '运营编排', 'BUTTON', 15),
(16, 'banner:create', '新建轮播图', '运营编排', 'BUTTON', 16),
(17, 'banner:update', '编辑轮播图', '运营编排', 'BUTTON', 17),
(18, 'banner:delete', '删除轮播图', '运营编排', 'BUTTON', 18),
(19, 'log:list', '查看操作日志', '后台管理', 'BUTTON', 19)
ON CONFLICT (id) DO UPDATE SET code = EXCLUDED.code, name = EXCLUDED.name,
group_name = EXCLUDED.group_name, sort = EXCLUDED.sort;
-- ---------- 菜单 ----------
INSERT INTO sys_menu (id, parent_id, title, route_path, route_name, component, redirect, icon,
permission_code, type, always_show, affix, sort) VALUES
(1, 0, '工作台', '/dashboard', 'Dashboard', '#', '/dashboard/index', 'ant-design:dashboard-filled', 'drama:list', 'CATALOG', 0, 0, 1),
(2, 1, '工作台', 'index', 'dashboard', 'views/common/DashboardView', '', 'ant-design:dashboard-filled', 'drama:list', 'MENU', 0, 1, 1),
(3, 0, '内容管理', '/content', 'Content', '#', '/content/dramas', 'ep:video-camera', 'drama:list', 'CATALOG', 1, 0, 2),
(4, 3, '短剧管理', 'dramas', 'dramas', 'views/contentManagement/DramaManagementView', '', '', 'drama:list', 'MENU', 0, 0, 1),
(5, 3, '剧集管理', 'episodes', 'episodes', 'views/contentManagement/EpisodeManagementView', '', '', 'episode:list', 'MENU', 0, 0, 2),
(12, 3, '轮播图管理', 'banners', 'banners', 'views/contentManagement/BannerManagementView', '', '', 'banner:list', 'MENU', 0, 0, 3),
(13, 3, '类型管理', 'categories', 'categories', 'views/contentManagement/CategoryManagementView','', '', 'drama:list', 'MENU', 0, 0, 4),
(6, 0, '后台管理', '/system', 'System', '#', '/system/access', 'ep:setting', 'system:role', 'CATALOG', 1, 0, 3),
(7, 6, '角色权限配置', 'access', 'access', 'views/permission/RoleManagementView', '', '', 'system:role', 'MENU', 0, 0, 1),
(8, 6, '管理员用户列表','admin-users','admin-users', 'views/userManagement/AdminUsersView', '', '', 'system:admin-user','MENU', 0, 0, 2),
(9, 6, '菜单管理', 'menus', 'menus', 'views/permission/MenuManagementView', '', '', 'system:menu', 'MENU', 0, 0, 3),
(10, 6, '角色分类', 'role-categories','role-categories','views/permission/RoleCategoriesView', '', '', 'system:role-category','MENU', 0, 0, 4),
(11, 6, '系统设置', 'settings', 'settings', 'views/systemManagement/SettingsView', '', '', 'system:role', 'MENU', 0, 0, 5)
ON CONFLICT (id) DO UPDATE SET parent_id = EXCLUDED.parent_id, title = EXCLUDED.title,
route_path = EXCLUDED.route_path, route_name = EXCLUDED.route_name, component = EXCLUDED.component,
redirect = EXCLUDED.redirect, icon = EXCLUDED.icon, permission_code = EXCLUDED.permission_code,
type = EXCLUDED.type, always_show = EXCLUDED.always_show, affix = EXCLUDED.affix, sort = EXCLUDED.sort;
-- 操作日志菜单(挂在后台管理下,仅超级管理员可见)
INSERT INTO sys_menu (id, parent_id, title, route_path, route_name, component, redirect, icon,
permission_code, type, always_show, affix, sort) VALUES
(14, 6, '操作日志', 'operation-logs', 'operation-logs', 'views/systemManagement/OperationLogView', '', '', 'log:list', 'MENU', 0, 0, 6)
ON CONFLICT (id) DO UPDATE SET parent_id = EXCLUDED.parent_id, title = EXCLUDED.title,
route_path = EXCLUDED.route_path, route_name = EXCLUDED.route_name, component = EXCLUDED.component,
redirect = EXCLUDED.redirect, icon = EXCLUDED.icon, permission_code = EXCLUDED.permission_code,
type = EXCLUDED.type, always_show = EXCLUDED.always_show, affix = EXCLUDED.affix, sort = EXCLUDED.sort;
-- ---------- 角色-权限 ----------
INSERT INTO sys_role_permission (role_id, permission_id)
SELECT r.id, p.id FROM sys_role r CROSS JOIN sys_permission p WHERE r.code = 'super_admin'
ON CONFLICT DO NOTHING;
INSERT INTO sys_role_permission (role_id, permission_id)
SELECT r.id, p.id FROM sys_role r CROSS JOIN sys_permission p
WHERE r.code = 'content_operator'
AND p.code IN ('drama:list','drama:create','drama:update','drama:delete',
'episode:list','episode:upload','episode:sort','cover:upload',
'banner:list','banner:create','banner:update','banner:delete')
ON CONFLICT DO NOTHING;
INSERT INTO sys_role_permission (role_id, permission_id)
SELECT r.id, p.id FROM sys_role r CROSS JOIN sys_permission p
WHERE r.code = 'content_reviewer'
AND p.code IN ('drama:list','episode:list','drama:review','stat:view','banner:list')
ON CONFLICT DO NOTHING;
INSERT INTO sys_role_permission (role_id, permission_id)
SELECT r.id, p.id FROM sys_role r CROSS JOIN sys_permission p
WHERE r.code = 'data_analyst'
AND p.code IN ('drama:list','stat:view','banner:list')
ON CONFLICT DO NOTHING;
-- ---------- 角色-菜单 ----------
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT r.id, m.id FROM sys_role r CROSS JOIN sys_menu m WHERE r.code = 'super_admin'
ON CONFLICT DO NOTHING;
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT r.id, m.id FROM sys_role r CROSS JOIN sys_menu m
WHERE r.code IN ('content_operator','content_reviewer','data_analyst') AND m.id IN (1,2,3,4,5,12,13)
ON CONFLICT DO NOTHING;
-- ---------- 管理员(密码均为 admin123) ----------
INSERT INTO sys_admin_user (id, username, password, real_name, mobile, email, status, ip_whitelist,
two_factor, last_login_at, created_at) VALUES
(1001, 'admin', '$2a$10$cknSDsmYgEADwwv0HdwzUOPqiz8D6mO/OOWMm3QEx.zmJW4iQqLcq', '系统管理员', '', '', 1, '', 0, NULL, '2026-09-01 09:00:00'),
(1002, 'lin.xiaoman', '$2a$10$cknSDsmYgEADwwv0HdwzUOPqiz8D6mO/OOWMm3QEx.zmJW4iQqLcq', '林小满', '', '', 1, '', 1, '2026-10-12 09:41:22', '2026-09-18 09:30:00'),
(1003, 'content.editor01', '$2a$10$cknSDsmYgEADwwv0HdwzUOPqiz8D6mO/OOWMm3QEx.zmJW4iQqLcq', '陈一诺', '', '', 1, '', 0, '2026-10-11 16:20:15', '2026-09-21 10:15:00'),
(1004, 'content.editor02', '$2a$10$cknSDsmYgEADwwv0HdwzUOPqiz8D6mO/OOWMm3QEx.zmJW4iQqLcq', '周子瑜', '', '', 1, '', 0, '2026-10-11 13:34:10', '2026-09-25 14:20:00'),
(1005, 'content.reviewer01', '$2a$10$cknSDsmYgEADwwv0HdwzUOPqiz8D6mO/OOWMm3QEx.zmJW4iQqLcq', '林晓彤', '', '', 1, '', 1, '2026-10-10 11:20:08', '2026-10-02 11:05:00'),
(1006, 'data.analyst01', '$2a$10$cknSDsmYgEADwwv0HdwzUOPqiz8D6mO/OOWMm3QEx.zmJW4iQqLcq', '程予安', '', '', 1, '', 0, '2026-10-09 14:10:02', '2026-10-05 13:02:00')
ON CONFLICT (id) DO UPDATE SET username = EXCLUDED.username, real_name = EXCLUDED.real_name,
status = EXCLUDED.status, two_factor = EXCLUDED.two_factor, last_login_at = EXCLUDED.last_login_at;
INSERT INTO sys_admin_user_role (user_id, role_id) VALUES
(1001, 1), (1002, 1), (1003, 2), (1004, 2), (1005, 3), (1006, 4)
ON CONFLICT DO NOTHING;
-- ---------- 系统配置 ----------
INSERT INTO sys_config (config_key, config_value, remark) VALUES
('workspace.name', 'FruitShorts Studio', '工作空间名称'),
('content.default-status', 'draft', '内容默认状态')
ON CONFLICT (config_key) DO UPDATE SET config_value = EXCLUDED.config_value, remark = EXCLUDED.remark;
-- ---------- 短剧类型 ----------
INSERT INTO drama_category (id, name, sort, status) VALUES
(1, '都市情感', 1, 1),
(2, '重生逆袭', 2, 1),
(3, '甜宠爱情', 3, 1),
(4, '悬疑复仇', 4, 1)
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, sort = EXCLUDED.sort, status = EXCLUDED.status;
-- ---------- 短剧 ----------
INSERT INTO drama (id, code, title, category_id, genre, synopsis, total_episodes, free_episodes,
unlock_coin, is_hot, status, published_at, view_count, sort, created_at) VALUES
(1, 'D20250612001', '替嫁新娘:总裁的掌心宠', 1, '都市情感',
'一场意外替嫁,让她成为冷面总裁的契约新娘。', 68, 3, 60, 1, 'published', '2025-06-12 10:00:00', 2400000, 1, '2025-06-01 09:00:00'),
(2, 'D20250618002', '重生之我在豪门当千金', 2, '重生逆袭',
'重活一世,她要拿回属于自己的一切。', 42, 3, 60, 0, 'reviewing', NULL, 0, 2, '2025-06-05 09:00:00'),
(3, 'D20250529003', '心动信号:请和我恋爱', 3, '甜宠爱情',
'恋爱观察室里,心动正在悄悄发生。', 56, 3, 50, 0, 'published', '2025-05-29 10:00:00', 1800000, 3, '2025-05-20 09:00:00'),
(4, 'D20250620004', '她从深渊中走来', 4, '悬疑复仇',
'真相只有一个,而她亲手揭开迷雾。', 24, 3, 80, 0, 'draft', NULL, 0, 4, '2025-06-15 09:00:00'),
(5, 'D20250521005', '闪婚后,傅先生每天都在撒糖', 1, '都市情感',
'一纸婚约,开启了甜蜜又心动的同居生活。', 72, 3, 60, 1, 'published', '2025-05-21 10:00:00', 3100000, 5, '2025-05-10 09:00:00')
ON CONFLICT (id) DO UPDATE SET code = EXCLUDED.code, title = EXCLUDED.title, genre = EXCLUDED.genre,
synopsis = EXCLUDED.synopsis, category_id = EXCLUDED.category_id, status = EXCLUDED.status,
total_episodes = EXCLUDED.total_episodes, free_episodes = EXCLUDED.free_episodes,
unlock_coin = EXCLUDED.unlock_coin, is_hot = EXCLUDED.is_hot, view_count = EXCLUDED.view_count;
-- ---------- 剧集(示例:短剧 1) ----------
INSERT INTO drama_episode (id, drama_id, ep_no, title, duration_sec, is_free, unlock_coin, status, play_count) VALUES
(1, 1, 1, '命运的相遇', 138, 1, 0, 'published', 48201),
(2, 1, 2, '意外的婚约', 116, 1, 0, 'published', 42817),
(3, 1, 3, '心动的开始', 124, 1, 0, 'published', 39506),
(4, 1, 4, '他的秘密', 151, 0, 60, 'draft', 0)
ON CONFLICT (id) DO UPDATE SET drama_id = EXCLUDED.drama_id, ep_no = EXCLUDED.ep_no,
title = EXCLUDED.title, duration_sec = EXCLUDED.duration_sec, is_free = EXCLUDED.is_free,
unlock_coin = EXCLUDED.unlock_coin, status = EXCLUDED.status, play_count = EXCLUDED.play_count;
-- ---------- 对齐自增序列 ----------
-- 上面用了显式 ID,但 IDENTITY 序列不会因此前移;不对齐的话,后续插入会从 1 开始而撞主键。
DO $$
DECLARE
t text;
seq text;
maxid bigint;
BEGIN
FOREACH t IN ARRAY ARRAY[
'sys_admin_user','sys_role_category','sys_role','sys_admin_user_role','sys_permission',
'sys_menu','sys_role_permission','sys_role_menu','sys_config','sys_operation_log',
'drama_category','drama','drama_episode','drama_review_record','content_banner',
'media_asset','media_upload_task'
] LOOP
seq := pg_get_serial_sequence(t, 'id');
EXECUTE format('SELECT COALESCE(MAX(id), 0) FROM %I', t) INTO maxid;
IF seq IS NOT NULL AND maxid > 0 THEN
PERFORM setval(seq, maxid);
END IF;
END LOOP;
END $$;