From a635de7111daec6105af435cc6fa54d982839547 Mon Sep 17 00:00:00 2001 From: Vicky <10212746+haifeng-jiang@user.noreply.gitee.com> Date: Thu, 15 Oct 2026 14:47:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=2007=20=E5=88=9B=E4=BD=9C=E8=80=85?= =?UTF-8?q?=E4=B8=AD=E5=BF=83=E6=89=B9=205=EF=BC=88=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=89=80=E9=9C=80=E7=9A=84=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E3=80=81=E9=9A=90=E8=97=8F=E8=B7=AF=E7=94=B1=E4=B8=8E=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E5=AD=97=E6=AE=B5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为什么:创作者中心的四个页面要挂到后台菜单里,但「作品编辑」是详情页(/creator-center/dramas/:id), 不能出现在侧边栏。当前菜单体系只下发 visible=1 的行、且 meta 里没有 hidden 字段,直接加会导致 "要么侧边栏多出一条无意义菜单,要么详情页路由根本不存在(点编辑就 404)"。所以先把这套补上: - MenuVO.Meta 增加 hidden;MenuService 把 visible=0 翻译成 meta.hidden, 并让路由下发不再过滤 visible(隐藏项仍要注册路由,侧边栏由前端按 meta.hidden 过滤) - sql/data-phase1.sql 补创作者中心菜单 26-30(目录 + 我的作品 + 隐藏的作品编辑 + 收费配置 + 数据看板), 创作者角色与超管各授权这 5 条;创作者角色**没有任何运营后台菜单** - CreatorCenterDramaVO 补 subtitle/genre/description/trailerUrl/language:编辑页要回填这些字段, 之前详情接口只给列表用的那几个字段 - docs/api-phase1.md:07 行改「已实现」,2.10 补四个页面清单与菜单隔离说明 --- docs/api-phase1.md | 20 +++++++++-- .../creator/service/CreatorCenterService.java | 5 +++ .../creator/vo/CreatorCenterDramaVO.java | 7 ++++ .../system/service/MenuService.java | 7 ++-- .../com/fruitshorts/system/vo/MenuVO.java | 2 ++ sql/data-phase1.sql | 33 +++++++++++++++++++ 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/docs/api-phase1.md b/docs/api-phase1.md index 295977c..39291b7 100644 --- a/docs/api-phase1.md +++ b/docs/api-phase1.md @@ -461,7 +461,23 @@ POST /app/auth/register 取不到的一律 `null` 并在 `notes` 说明缺什么、怎么补,**不用 0 冒充**(与运营大盘同口径)。 -**进度**:批 5(前端页面)未开始。 +**创作者中心前端页面(批 5 已实现)** + +`ReelShortWeb` 里新增四个页面(菜单 id 26–30,`sql/data-phase1.sql` 幂等落库),沿用 `AppUsersView` 的 +「api 封装 + composable + 视图 + 样式」写法与 `console.css`: + +| 页面 | 路由 | 菜单组件路径 | 依赖权限点 | 覆盖接口 | +| --- | --- | --- | --- | --- | +| 我的作品 | `/creator-center/workspace` | `views/creator-center/WorkspaceView` | `creator-center:view` `creator-center:drama:edit` | 主体信息、作品列表(含审核进度)、通知、新建草稿、提交 / 撤回 | +| 作品编辑 | `/creator-center/dramas/:id` | `views/creator-center/DramaEditView` | `creator-center:drama:edit` `creator-center:upload` | 作品信息、分集增删改与排序、分片上传(含断点续传)、产物挂载、提交记录 | +| 收费配置 | `/creator-center/prices` | `views/creator-center/PriceConfigView` | `creator-center:price:update` | 免费集数、解锁金币、试看秒数 | +| 数据看板 | `/creator-center/dashboard` | `views/creator-center/DashboardView` | `creator-center:stat:view` | 看板概览(只读,缺口显示「暂无数据源」) | + +**创作者角色只挂这五条菜单**(含一条 `visible=0` 的隐藏路由):登录后侧边栏只有「创作者中心」, +看不到运营后台的任何菜单 —— 实测创作者菜单 JSON 里只有 `/creator-center` 及其子项,超管才拿得到全部。 +「作品编辑」是详情页,用 `visible=0` 下发(后端把它翻译成 `meta.hidden`),路由照常注册、侧边栏不显示。 + +**本阶段进度**:07 全部 5 批完成,第一阶段 05 / 06 / 07 / 08 四块闭环。 ## 3. 契约与实现状态对照 @@ -473,7 +489,7 @@ POST /app/auth/register | 04 播放器与播放控制 | 已建 | 已冻结 | 票据 + 签名 + 进度 已实现;多码率依赖转码 worker | | 05 记录、收藏与下载 | 已建 | 已冻结 | **已实现**:进度、观看流水、收藏、离线下载授权与任务 | | 06 评论、点赞与分享 | 已建 | 已冻结 | **已实现**:评论(游标翻页/审核/删除)、点赞、举报、敏感词;分享埋点在下一批 | -| 07 创作者中心 | 已建 | 已冻结 | 下一批(转码任务与产物记账已实现) | +| 07 创作者中心 | 已建 | 已冻结 | **已实现**:创作者工作台(我的作品 / 审核进度 / 通知)、内容编辑与分集管理、分片上传与断点续传、提交审核与上下架、分集收费与试看、数据看板;Web 端页面见 2.10,不含提现 / 结算 | | 08 平台运营后台 | 已建 | 已冻结 | **已实现**:后台接口(用户管理、内容治理、订单与权益、创作者与内容审核、数据看板)与后台页面(内容治理 / 订单与权益 / 创作者审核 / 数据看板,见 2.9)全部落地 | | 09 分集收费与支付 | 已建 | 已冻结 | 下一批(权益判定端口已预留,接上即生效) | | 10 质量、数据与上线 | 已建 | 已冻结 | 压测与埋点 下一批 | diff --git a/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/service/CreatorCenterService.java b/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/service/CreatorCenterService.java index 25ef472..a8495b3 100644 --- a/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/service/CreatorCenterService.java +++ b/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/service/CreatorCenterService.java @@ -177,7 +177,12 @@ public class CreatorCenterService { vo.setId(drama.getId()); vo.setCode(drama.getCode()); vo.setTitle(drama.getTitle()); + vo.setSubtitle(drama.getSubtitle()); + vo.setGenre(drama.getGenre()); + vo.setDescription(drama.getSynopsis()); vo.setCover(drama.getCoverUrl()); + vo.setTrailerUrl(drama.getTrailerUrl()); + vo.setLanguage(drama.getLanguage()); vo.setStatus(drama.getStatus()); vo.setStatusText(ContentStatus.textOf(drama.getStatus())); vo.setEpisodes(drama.getTotalEpisodes()); diff --git a/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/vo/CreatorCenterDramaVO.java b/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/vo/CreatorCenterDramaVO.java index f2bf54f..452c780 100644 --- a/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/vo/CreatorCenterDramaVO.java +++ b/fruitshorts-module-creator/src/main/java/com/fruitshorts/creator/vo/CreatorCenterDramaVO.java @@ -13,7 +13,14 @@ public class CreatorCenterDramaVO { private Long id; private String code; private String title; + private String subtitle; + private String genre; + /** 简介(实体字段是 synopsis) */ + private String description; private String cover; + /** 整剧预告片 */ + private String trailerUrl; + private String language; private String status; private String statusText; private Integer episodes; diff --git a/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/MenuService.java b/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/MenuService.java index b822e0f..b329636 100644 --- a/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/MenuService.java +++ b/fruitshorts-module-system/src/main/java/com/fruitshorts/system/service/MenuService.java @@ -74,9 +74,10 @@ public class MenuService { } private List listEnabled() { + // 只按 status 过滤:visible=0 的菜单(例如"作品编辑"这类详情页)也要下发给前端注册路由, + // 否则详情页点进去会 404。侧边栏由前端按 meta.hidden 过滤,不会把隐藏项露出来。 return menuMapper.selectList(Wrappers.lambdaQuery() .eq(Menu::getStatus, 1) - .eq(Menu::getVisible, 1) .orderByAsc(Menu::getSort)); } @@ -122,7 +123,9 @@ public class MenuService { menu.getTitle(), menu.getIcon().isEmpty() ? null : menu.getIcon(), menu.getAlwaysShow() != null && menu.getAlwaysShow() == 1 ? Boolean.TRUE : null, - menu.getAffix() != null && menu.getAffix() == 1 ? Boolean.TRUE : null)); + menu.getAffix() != null && menu.getAffix() == 1 ? Boolean.TRUE : null, + // 详情页这类路由要注册但不能出现在侧边栏:visible=0 → meta.hidden + menu.getVisible() != null && menu.getVisible() == 0 ? Boolean.TRUE : null)); nodes.put(menu.getId(), vo); } List roots = new ArrayList<>(); diff --git a/fruitshorts-module-system/src/main/java/com/fruitshorts/system/vo/MenuVO.java b/fruitshorts-module-system/src/main/java/com/fruitshorts/system/vo/MenuVO.java index b129493..7a121e8 100644 --- a/fruitshorts-module-system/src/main/java/com/fruitshorts/system/vo/MenuVO.java +++ b/fruitshorts-module-system/src/main/java/com/fruitshorts/system/vo/MenuVO.java @@ -36,5 +36,7 @@ public class MenuVO { private String icon; private Boolean alwaysShow; private Boolean affix; + /** visible=0 的菜单:路由要注册(详情页靠它),但不进侧边栏 */ + private Boolean hidden; } } diff --git a/sql/data-phase1.sql b/sql/data-phase1.sql index b8bcaab..0974006 100644 --- a/sql/data-phase1.sql +++ b/sql/data-phase1.sql @@ -214,3 +214,36 @@ CROSS JOIN sys_permission p WHERE r.code = 'creator' AND p.code IN ('cover:upload', 'episode:upload') ON CONFLICT DO NOTHING; + +-- ---------- 菜单:创作者中心(批 5,前端页面落地后才挂) ---------- +-- 26 是目录,27/29/30 是三个可见页面,28 是隐藏路由(作品编辑详情页,visible=0 → meta.hidden), +-- 组件路径对应 src/views/creator-center/ 下的四个页面。 +INSERT INTO sys_menu (id, parent_id, title, route_path, route_name, component, redirect, icon, + permission_code, type, always_show, affix, sort, visible) VALUES + (26, 0, '创作者中心', '/creator-center', 'CreatorCenter', '#', '/creator-center/workspace', 'ep:film', 'creator-center:view', 'CATALOG', 1, 0, 3, 1), + (27, 26, '我的作品', 'workspace', 'creator-workspace', 'views/creator-center/WorkspaceView', '', '', 'creator-center:view', 'MENU', 0, 0, 1, 1), + (28, 26, '作品编辑', 'dramas/:id', 'creator-drama-edit', 'views/creator-center/DramaEditView', '', '', 'creator-center:drama:edit', 'MENU', 0, 0, 2, 0), + (29, 26, '收费配置', 'prices', 'creator-prices', 'views/creator-center/PriceConfigView', '', '', 'creator-center:price:update', 'MENU', 0, 0, 3, 1), + (30, 26, '数据看板', 'dashboard', 'creator-dashboard', 'views/creator-center/DashboardView', '', '', 'creator-center:stat:view', 'MENU', 0, 0, 4, 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, visible = EXCLUDED.visible; + +-- 创作者角色:只挂创作者中心这五条(含隐藏的编辑页),**不给任何运营后台菜单** +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 = 'creator' + AND m.id IN (26, 27, 28, 29, 30) +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' + AND m.id IN (26, 27, 28, 29, 30) +ON CONFLICT DO NOTHING;