Files
FruitServer/sql/data-phase1.sql
T
Vicky af1dc48494 feat: 06 互动与内容治理落地(评论 / 点赞 / 举报 / 敏感词 / 审核留证)
为什么:
1) 产品侧要先把内容治理闭环跑通才能谈上线:评论可发布、可翻页、可删除,
   违规内容能在后台被审核与驳回,举报要有工单可追溯。本提交把这套补齐。
2) 审核不能只靠人肉:敏感词按 BLOCK/REPLACE/REVIEW 三档处置,
   机审通过即发布(可配置为 PRE_REVIEW 全部先审后发),人审与机审的结论
   都写进 content_audit_record,争议时可回答"当时凭什么放行/驳回"。
3) 举报处理必须与处置打通:结论成立会联动驳回被举报评论,并可选同时封禁被举报用户,
   避免"工单处理完了但违规内容还挂着"。
4) 顺带修复一个真实缺陷:user_favorite / content_like 上有唯一索引,而全局配置会把
   deleteById 改写成逻辑删除,导致取消收藏/点赞后旧的 deleted 行仍占位,
   再次收藏或点赞直接撞唯一索引报错。关系类数据没有留证价值,改为显式物理删除,
   并补了"取消后再来一次"的回归自测。
2026-10-15 12:03:32 +08:00

95 lines
4.9 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)
--
-- 只放「代码已经实现、需要权限点才能调通」的数据。
-- 菜单(sys_menu)暂时不加:前端页面还没做,加了会出现指向不存在组件的动态路由,
-- 等 fruitshorts-web 的 App 用户管理页落地后再补菜单与角色菜单绑定。
--
-- 幂等:可重复执行。
-- 先对齐 IDENTITY 序列:历史种子数据用了显式 ID,序列没有前移,
-- 不对齐的话下面的插入会从 1 开始而撞主键。
DO $$
DECLARE
t text;
seq text;
maxid bigint;
BEGIN
FOREACH t IN ARRAY ARRAY['sys_permission','sys_menu','sys_role_permission','sys_role_menu',
'product','app_user','app_user_credential','orders','wallet'] LOOP
seq := pg_get_serial_sequence(t, 'id');
IF seq IS NULL THEN
CONTINUE;
END IF;
EXECUTE format('SELECT COALESCE(MAX(id), 0) FROM %I', t) INTO maxid;
IF maxid > 0 THEN
PERFORM setval(seq, maxid);
END IF;
END LOOP;
END $$;
INSERT INTO sys_permission (code, name, group_name, type, sort) VALUES
('app-user:list', '查看 App 用户', '用户管理', 'BUTTON', 101),
('app-user:update', '处置 App 用户', '用户管理', 'BUTTON', 102)
ON CONFLICT (code) DO NOTHING;
INSERT INTO sys_permission (code, name, group_name, type, sort) VALUES
('download:list', '查看下载授权', '用户管理', 'BUTTON', 103),
('download:revoke', '吊销下载授权', '用户管理', 'BUTTON', 104)
ON CONFLICT (code) DO NOTHING;
INSERT INTO sys_permission (code, name, group_name, type, sort) VALUES
('comment:list', '查看评论', '内容治理', 'BUTTON', 111),
('comment:audit', '审核评论', '内容治理', 'BUTTON', 112),
('report:list', '查看举报', '内容治理', 'BUTTON', 113),
('report:handle', '处理举报', '内容治理', 'BUTTON', 114),
('sensitive-word:list', '查看敏感词', '内容治理', 'BUTTON', 115),
('sensitive-word:update','维护敏感词', '内容治理', 'BUTTON', 116)
ON CONFLICT (code) 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 = 'super_admin'
AND p.code IN ('app-user:list', 'app-user:update', 'download:list', 'download:revoke',
'comment:list', 'comment:audit', 'report:list', 'report:handle',
'sensitive-word:list', 'sensitive-word:update')
ON CONFLICT DO NOTHING;
-- 第一阶段新增的白名单数据(当前阶段都是免费内容,先把演示商品占位好)
INSERT INTO product (code, name, type, platform, store_product_id, coin_amount, bonus_coin,
price_amount, currency, region_codes, sort, status)
SELECT 'coin_100', '100 金币', 'COIN_PACK', 'ALL', '', 100, 0, 0.99, 'USD', 'ID', 1, 1
WHERE NOT EXISTS (SELECT 1 FROM product WHERE code = 'coin_100');
INSERT INTO product (code, name, type, platform, store_product_id, coin_amount, bonus_coin,
price_amount, currency, region_codes, sort, status)
SELECT 'coin_550', '550 金币', 'COIN_PACK', 'ALL', '', 500, 50, 4.99, 'USD', 'ID', 2, 1
WHERE NOT EXISTS (SELECT 1 FROM product WHERE code = 'coin_550');
INSERT INTO product (code, name, type, platform, store_product_id, coin_amount, bonus_coin,
price_amount, currency, region_codes, sort, status)
SELECT 'coin_1200', '1200 金币', 'COIN_PACK', 'ALL', '', 1000, 200, 9.99, 'USD', 'ID', 3, 1
WHERE NOT EXISTS (SELECT 1 FROM product WHERE code = 'coin_1200');
-- ---------- 菜单:用户管理 ----------
-- C 端用户与后台管理员是两套账号体系,单独挂一个一级目录,避免和管理员列表混淆。
-- component 指向 src/views/userManagement/AppUsersView.vue,前端按这个字符串动态加载。
INSERT INTO sys_menu (id, parent_id, title, route_path, route_name, component, redirect, icon,
permission_code, type, always_show, affix, sort) VALUES
(15, 0, '用户管理', '/user', 'UserCenter', '#', '/user/app-users', 'ep:user', 'app-user:list', 'CATALOG', 1, 0, 4),
(16, 15, 'App 用户', 'app-users', 'app-users', 'views/userManagement/AppUsersView', '', '', 'app-user:list', 'MENU', 0, 0, 1)
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_menu (role_id, menu_id)
SELECT r.id, m.id
FROM sys_role r
CROSS JOIN sys_menu m
WHERE r.code = 'super_admin'
AND m.id IN (15, 16)
ON CONFLICT DO NOTHING;