From 788ba4c53a2946385d9905ccfedc9f58b16eb551 Mon Sep 17 00:00:00 2001 From: Rogee Date: Wed, 14 Jan 2026 16:25:18 +0800 Subject: [PATCH] feat: extend superadmin navigation --- docs/superadmin_plan.md | 200 +++++++----------- .../src/components/PendingPanel.vue | 36 ++++ frontend/superadmin/src/layout/AppMenu.vue | 8 +- frontend/superadmin/src/router/index.js | 30 +++ .../superadmin/src/service/ContentService.js | 21 +- .../superadmin/src/service/TenantService.js | 16 +- .../superadmin/src/service/UserService.js | 21 +- frontend/superadmin/src/service/auth.js | 1 - .../src/views/superadmin/Assets.vue | 11 + .../src/views/superadmin/Contents.vue | 23 +- .../src/views/superadmin/Coupons.vue | 11 + .../src/views/superadmin/Creators.vue | 18 ++ .../src/views/superadmin/Finance.vue | 11 + .../src/views/superadmin/Notifications.vue | 11 + .../src/views/superadmin/OrderDetail.vue | 5 +- .../src/views/superadmin/Orders.vue | 23 +- .../src/views/superadmin/Reports.vue | 11 + .../src/views/superadmin/TenantDetail.vue | 29 +-- .../src/views/superadmin/Tenants.vue | 19 +- .../src/views/superadmin/UserDetail.vue | 34 +-- .../superadmin/src/views/superadmin/Users.vue | 39 +--- 21 files changed, 248 insertions(+), 330 deletions(-) create mode 100644 frontend/superadmin/src/components/PendingPanel.vue create mode 100644 frontend/superadmin/src/views/superadmin/Assets.vue create mode 100644 frontend/superadmin/src/views/superadmin/Coupons.vue create mode 100644 frontend/superadmin/src/views/superadmin/Creators.vue create mode 100644 frontend/superadmin/src/views/superadmin/Finance.vue create mode 100644 frontend/superadmin/src/views/superadmin/Notifications.vue create mode 100644 frontend/superadmin/src/views/superadmin/Reports.vue diff --git a/docs/superadmin_plan.md b/docs/superadmin_plan.md index 4a3c03d..90aaefe 100644 --- a/docs/superadmin_plan.md +++ b/docs/superadmin_plan.md @@ -1,148 +1,100 @@ -# 超级管理员后台功能规划(按页面拆解) +# 超级管理员后台功能规划(与当前系统功能对齐) -> 目标:基于现有 `/super/v1/*` 能力,补齐平台级“管理 + 统计”闭环。以下按页面拆分,分别给出管理动作、统计指标与接口对照。 +> 目标:在不脱离现有后端能力的前提下,确保“系统已有功能超管可介入管理”,并通过统一入口、跨租户筛选与批量操作提升运营效率。 -## 0) 全局约定 +## 0) 设计原则 -- **鉴权**:`Authorization: Bearer `;登录后本地持久化 token。 -- **路由基座**:`/super/`(前端),API 基座 `/super/v1`。 -- **分页**:统一 `page/limit`,响应为 `requests.Pager`。 -- **枚举**:优先取 `/super/v1/tenants/statuses`、`/super/v1/users/statuses`。 +- **全量可管**:覆盖租户、用户、内容、订单、优惠券、钱包、提现、上传、通知等现有能力。 +- **便捷优先**:跨租户统一筛选、全局搜索、批量处理、审核队列,减少重复跳转。 +- **风险可控**:默认只读,危险操作需二次确认,动作全量记录。 +- **接口对齐**:优先复用 `/super/v1/*` 现有能力,其它模块按“超管包装层”补齐。 -## 1) 登录 `/auth/login` +## 1) 当前系统能力地图(基于现有路由) -- 管理功能:账号登录、token 写入、自动续期。 -- 统计功能:可选记录登录失败次数、IP、设备指纹(审计)。 -- 现有接口: - - `POST /super/v1/auth/login`(需补齐实现) - - `GET /super/v1/auth/token`(token 校验/续期) +- **租户与成员**:租户列表/详情、创建、状态变更、续期、健康检查、成员关注/加入/邀请。 +- **用户与认证**:登录/OTP、资料更新、实名、钱包/充值、订单、收藏/点赞、通知、优惠券。 +- **内容与互动**:内容列表/详情、话题、评论、点赞/收藏。 +- **创作者与运营**:申请、内容 CRUD、优惠券 CRUD/发放、成员审核/邀请、订单与退款、报表、提现、结算账户、设置。 +- **交易与支付**:订单创建/支付/状态、支付回调。 +- **资产与存储**:分片/直传上传、哈希检查、上传完成、媒体资产删除、存储签名上传/下载。 -## 2) 概览 Dashboard `/` +## 2) 超管平台页面规划(按业务域) -- 管理功能:快捷入口(租户/用户/订单/内容)。 -- 统计指标(建议): - - 租户总数/活跃数/过期数 - - 用户总数/活跃数(按状态拆分) - - 订单数/成交额/退款额(按日、按状态) - - 内容总数/新增内容/被封禁内容 -- 现有接口: - - `GET /super/v1/users/statistics`(需补齐实现) - - `GET /super/v1/orders/statistics`(需补齐实现) - - `GET /super/v1/tenants?limit=1&page=1`(可取 total) - - `GET /super/v1/contents?limit=1&page=1`(可取 total) +### 2.1 登录与权限 `/auth/login` +- **功能**:登录、token 续期、权限校验。 +- **接口**:`POST /super/v1/auth/login`,`GET /super/v1/auth/token`。 -## 3) 租户管理 `/superadmin/tenants` +### 2.2 平台概览 `/` +- **功能**:核心指标、异常概览、快捷入口。 +- **接口**:`GET /super/v1/users/statistics`,`GET /super/v1/orders/statistics`,`GET /super/v1/tenants`(count),`GET /super/v1/contents`(count)。 +- **缺口**:平台级内容/订单趋势、退款率、提现统计。 -- 管理功能: - - 新建租户(绑定管理员) - - 更新租户状态(正常/禁用) - - 续期/变更过期时间 -- 统计指标: - - 状态分布(待审核/正常/禁用) - - 即将过期租户数(7/30 天) - - 租户 GMV Top N(需补接口) -- 现有接口: - - `POST /super/v1/tenants` - - `GET /super/v1/tenants` - - `PATCH /super/v1/tenants/{tenantID}/status` - - `PATCH /super/v1/tenants/{tenantID}`(续期) - - `GET /super/v1/tenants/statuses` +### 2.3 租户管理 `/superadmin/tenants` +- **功能**:租户列表、创建、状态变更、续期、健康检查。 +- **接口**:`GET/POST /super/v1/tenants`,`PATCH /super/v1/tenants/:id/status`,`PATCH /super/v1/tenants/:id`,`GET /super/v1/tenants/health`,`GET /super/v1/tenants/statuses`。 -## 4) 租户详情 `/superadmin/tenants/:tenantID` +### 2.4 租户详情 `/superadmin/tenants/:tenantID` +- **功能**:租户信息、成员、内容、订单、资金与运营概览。 +- **接口**:`GET /super/v1/tenants/:id`,`GET /super/v1/tenants/:tenantID/users`,`GET /super/v1/tenants/:tenantID/contents`,`GET /super/v1/orders`(按 tenant_id 过滤)。 +- **缺口**:租户成员邀请/审核、租户级财务/报表聚合。 -- 管理功能(建议): - - 基本信息/状态/过期时间编辑 - - 管理员与成员列表(角色管理) - - 内容列表、订单列表、资金汇总 -- 统计指标(建议): - - 租户用户数、内容数、订单数、GMV -- 现有接口: - - `GET /super/v1/tenants/{tenantID}`(已有) -- 建议补充接口: - - `GET /super/v1/tenants/{tenantID}/users` - - `GET /super/v1/tenants/{tenantID}/contents` - - `GET /super/v1/tenants/{tenantID}/orders` - - `GET /super/v1/tenants/{tenantID}/statistics` +### 2.5 用户管理 `/superadmin/users` +- **功能**:用户列表、状态/角色、关联租户、账户概要(余额/冻结/实名认证)。 +- **接口**:`GET /super/v1/users`,`PATCH /super/v1/users/:id/status`,`PATCH /super/v1/users/:id/roles`,`GET /super/v1/users/statistics`,`GET /super/v1/users/statuses`。 +- **缺口**:实名信息、钱包明细、通知、优惠券、充值记录等超管视图接口。 -## 5) 用户管理 `/superadmin/users` +### 2.6 用户详情 `/superadmin/users/:userID` +- **功能**:资料、角色、加入/拥有租户、订单与内容消费、收藏/点赞/关注、优惠券与通知。 +- **接口**:`GET /super/v1/users/:id`,`GET /super/v1/users/:id/tenants`,`GET /super/v1/orders`(按 user_id 过滤)。 +- **缺口**:用户钱包/通知/优惠券明细需要新接口。 -- 管理功能: - - 用户列表筛选(用户名/状态/角色/所属租户) - - 状态变更、角色授予 -- 统计指标: - - 用户状态统计(已提供) -- 现有接口: - - `GET /super/v1/users` - - `PATCH /super/v1/users/{userID}/status` - - `PATCH /super/v1/users/{userID}/roles` - - `GET /super/v1/users/statistics` - - `GET /super/v1/users/statuses` +### 2.7 内容治理 `/superadmin/contents` +- **功能**:跨租户内容列表、审核、状态变更、违规处置。 +- **接口**:`GET /super/v1/contents`,`POST /super/v1/contents/:id/review`,`PATCH /super/v1/tenants/:tenantID/contents/:contentID/status`。 +- **缺口**:评论治理、内容举报、内容资产明细(若需要)。 -## 6) 用户详情 `/superadmin/users/:userID` +### 2.8 订单与退款 `/superadmin/orders` +- **功能**:订单列表、退款/强制退款、问题订单标记、支付状态核对。 +- **接口**:`GET /super/v1/orders`,`GET /super/v1/orders/:id`,`POST /super/v1/orders/:id/refund`。 -- 管理功能(建议): - - 用户资料、角色、状态 - - 用户所属/拥有租户列表 - - 用户订单与内容购买记录 -- 统计指标(建议): - - 用户消费总额、退款次数 -- 现有接口: - - `GET /super/v1/users/{userID}`(已有) -- 建议补充接口: - - `GET /super/v1/users/{userID}/tenants` - - `GET /super/v1/users/{userID}/orders` - - `GET /super/v1/users/{userID}/contents` +### 2.9 创作者与成员审核 `/superadmin/creators` +- **功能**:创作者申请审核、成员加入审核/邀请、创作者设置查看、提现与结算账户审核。 +- **接口**:租户级 `POST /t/:tenantCode/v1/creator/apply`、`POST /t/:tenantCode/v1/creator/members/:id/review`、`POST /t/:tenantCode/v1/creator/members/invite`、`GET /t/:tenantCode/v1/creator/payout-accounts`、`POST /t/:tenantCode/v1/creator/withdraw`。 +- **缺口**:超管跨租户管理接口(建议新增 `/super/v1/creators/*`)。 -## 7) 订单管理 `/superadmin/orders` +### 2.10 优惠券 `/superadmin/coupons` +- **功能**:跨租户优惠券列表、状态变更、发放记录、异常核查。 +- **接口**:租户级 `GET/POST/PUT /t/:tenantCode/v1/creator/coupons`、`POST /t/:tenantCode/v1/creator/coupons/:id/grant`、用户侧 `/t/:tenantCode/v1/me/coupons*`。 +- **缺口**:超管聚合查询与冻结/归档接口。 -- 管理功能: - - 订单列表(按租户/用户/状态/时间过滤) - - 退款操作(平台侧) -- 统计指标: - - 订单状态分布、GMV、退款额 -- 现有接口: - - `GET /super/v1/orders` - - `POST /super/v1/orders/{orderID}/refund`(需补齐实现) - - `GET /super/v1/orders/statistics`(需补齐实现) +### 2.11 财务与钱包 `/superadmin/finance` +- **功能**:提现审核、用户钱包概况、异常充值/退款排查。 +- **接口**:租户级 `POST /t/:tenantCode/v1/creator/withdraw`、用户侧 `GET/POST /t/:tenantCode/v1/me/wallet*`。 +- **缺口**:超管提现列表与审批接口、钱包流水接口。 -## 8) 订单详情 `/superadmin/orders/:orderID` +### 2.12 报表与导出 `/superadmin/reports` +- **功能**:跨租户报表、导出运营数据(订单、内容、退款、提现)。 +- **接口**:租户级 `GET /t/:tenantCode/v1/creator/reports/overview`、`POST /t/:tenantCode/v1/creator/reports/export`。 +- **缺口**:超管聚合与导出接口。 -- 管理功能: - - 查看订单快照、支付信息、退款信息 - - 退款/强制关闭 -- 现有接口: - - `GET /super/v1/orders/{orderID}`(需补齐实现) +### 2.13 资产与上传 `/superadmin/assets` +- **功能**:上传记录、媒体资产清理、异常上传排查、存储用量。 +- **接口**:租户级 `POST /t/:tenantCode/v1/upload/*`、`DELETE /t/:tenantCode/v1/media-assets/:id`、`/t/:tenantCode/v1/storage/*`。 +- **缺口**:资产列表/用量统计/跨租户查询接口。 -## 9) 内容管理 `/superadmin/contents` +### 2.14 通知与消息 `/superadmin/notifications` +- **功能**:通知查看、批量触达、模板管理。 +- **接口**:用户侧 `GET /t/:tenantCode/v1/me/notifications`。 +- **缺口**:超管发送与批量触达接口、通知模板管理接口。 -- 管理功能: - - 跨租户内容列表 - - 内容状态更新(封禁/下架) -- 统计指标: - - 内容状态分布、热门内容 Top N -- 现有接口: - - `GET /super/v1/contents` - - `PATCH /super/v1/tenants/{tenantID}/contents/{contentID}/status` +## 3) 导航与便捷性设计(建议) -## 10) 财务/提现(可选) +- 统一筛选器:租户/用户/时间/状态为默认筛选维度。 +- 快捷入口:租户详情可直接跳转到用户/内容/订单/提现。 +- 审核队列:内容审核、退款、创作者申请、提现审核统一入口。 -- 管理功能: - - 提现订单审核(通过/驳回) - - 记录操作原因 -- 统计指标: - - 提现订单数、金额、失败率 -- 现有接口:无(服务层有 `ListWithdrawals/Approve/Reject`,需补 controller + route) - -## 11) 审计日志 / 操作记录(建议) - -- 管理功能: - - 展示后台操作日志(操作人、对象、动作、时间) - - 支持导出 -- 现有接口:无(可基于 `services.Audit` 扩展) - -## 12) 系统配置 / 平台策略(建议) - -- 管理功能: - - 平台佣金比例、内容审核策略、默认到期策略 -- 现有接口:无(需新增配置表与接口) +## 4) 推进顺序(与现有接口匹配) +- **P0(已有接口即可落地)**:登录、概览、租户管理、用户管理、内容治理、订单退款。 +- **P1(需补超管接口)**:创作者审核、优惠券、提现/钱包、报表导出。 +- **P2(扩展增强)**:资产/上传、通知中心、审计与系统配置。 diff --git a/frontend/superadmin/src/components/PendingPanel.vue b/frontend/superadmin/src/components/PendingPanel.vue new file mode 100644 index 0000000..b3df81d --- /dev/null +++ b/frontend/superadmin/src/components/PendingPanel.vue @@ -0,0 +1,36 @@ + + + diff --git a/frontend/superadmin/src/layout/AppMenu.vue b/frontend/superadmin/src/layout/AppMenu.vue index 68fc8b5..394d1d4 100644 --- a/frontend/superadmin/src/layout/AppMenu.vue +++ b/frontend/superadmin/src/layout/AppMenu.vue @@ -14,7 +14,13 @@ const model = ref([ { label: 'Tenants', icon: 'pi pi-fw pi-building', to: '/superadmin/tenants' }, { label: 'Users', icon: 'pi pi-fw pi-users', to: '/superadmin/users' }, { label: 'Orders', icon: 'pi pi-fw pi-shopping-cart', to: '/superadmin/orders' }, - { label: 'Contents', icon: 'pi pi-fw pi-file', to: '/superadmin/contents' } + { label: 'Contents', icon: 'pi pi-fw pi-file', to: '/superadmin/contents' }, + { label: 'Creators', icon: 'pi pi-fw pi-star', to: '/superadmin/creators' }, + { label: 'Coupons', icon: 'pi pi-fw pi-ticket', to: '/superadmin/coupons' }, + { label: 'Finance', icon: 'pi pi-fw pi-wallet', to: '/superadmin/finance' }, + { label: 'Reports', icon: 'pi pi-fw pi-chart-line', to: '/superadmin/reports' }, + { label: 'Assets', icon: 'pi pi-fw pi-folder', to: '/superadmin/assets' }, + { label: 'Notifications', icon: 'pi pi-fw pi-bell', to: '/superadmin/notifications' } ] } ]); diff --git a/frontend/superadmin/src/router/index.js b/frontend/superadmin/src/router/index.js index 7819a87..03dd1ee 100644 --- a/frontend/superadmin/src/router/index.js +++ b/frontend/superadmin/src/router/index.js @@ -144,6 +144,36 @@ const router = createRouter({ name: 'superadmin-contents', component: () => import('@/views/superadmin/Contents.vue') }, + { + path: '/superadmin/creators', + name: 'superadmin-creators', + component: () => import('@/views/superadmin/Creators.vue') + }, + { + path: '/superadmin/coupons', + name: 'superadmin-coupons', + component: () => import('@/views/superadmin/Coupons.vue') + }, + { + path: '/superadmin/finance', + name: 'superadmin-finance', + component: () => import('@/views/superadmin/Finance.vue') + }, + { + path: '/superadmin/reports', + name: 'superadmin-reports', + component: () => import('@/views/superadmin/Reports.vue') + }, + { + path: '/superadmin/assets', + name: 'superadmin-assets', + component: () => import('@/views/superadmin/Assets.vue') + }, + { + path: '/superadmin/notifications', + name: 'superadmin-notifications', + component: () => import('@/views/superadmin/Notifications.vue') + }, { path: '/superadmin/orders/:orderID', name: 'superadmin-order-detail', diff --git a/frontend/superadmin/src/service/ContentService.js b/frontend/superadmin/src/service/ContentService.js index 7cca17e..929f832 100644 --- a/frontend/superadmin/src/service/ContentService.js +++ b/frontend/superadmin/src/service/ContentService.js @@ -67,23 +67,7 @@ export const ContentService = { items: normalizeItems(data?.items) }; }, - async listTenantContents( - tenantID, - { - page, - limit, - keyword, - status, - visibility, - user_id, - published_at_from, - published_at_to, - created_at_from, - created_at_to, - sortField, - sortOrder - } = {} - ) { + async listTenantContents(tenantID, { page, limit, keyword, status, visibility, user_id, published_at_from, published_at_to, created_at_from, created_at_to, sortField, sortOrder } = {}) { if (!tenantID) throw new Error('tenantID is required'); const iso = (d) => { @@ -117,8 +101,7 @@ export const ContentService = { total: data?.total ?? 0, items: normalizeItems(data?.items) }; - } - , + }, async updateTenantContentStatus(tenantID, contentID, { status } = {}) { if (!tenantID) throw new Error('tenantID is required'); if (!contentID) throw new Error('contentID is required'); diff --git a/frontend/superadmin/src/service/TenantService.js b/frontend/superadmin/src/service/TenantService.js index 615f82c..6ad194c 100644 --- a/frontend/superadmin/src/service/TenantService.js +++ b/frontend/superadmin/src/service/TenantService.js @@ -7,21 +7,7 @@ function normalizeItems(items) { } export const TenantService = { - async listTenants({ - page, - limit, - id, - user_id, - name, - code, - status, - expired_at_from, - expired_at_to, - created_at_from, - created_at_to, - sortField, - sortOrder - } = {}) { + async listTenants({ page, limit, id, user_id, name, code, status, expired_at_from, expired_at_to, created_at_from, created_at_to, sortField, sortOrder } = {}) { const iso = (d) => { if (!d) return undefined; const date = d instanceof Date ? d : new Date(d); diff --git a/frontend/superadmin/src/service/UserService.js b/frontend/superadmin/src/service/UserService.js index 2fa057e..b3a418b 100644 --- a/frontend/superadmin/src/service/UserService.js +++ b/frontend/superadmin/src/service/UserService.js @@ -7,21 +7,7 @@ function normalizeItems(items) { } export const UserService = { - async listUsers({ - page, - limit, - id, - tenant_id, - username, - status, - role, - created_at_from, - created_at_to, - verified_at_from, - verified_at_to, - sortField, - sortOrder - } = {}) { + async listUsers({ page, limit, id, tenant_id, username, status, role, created_at_from, created_at_to, verified_at_from, verified_at_to, sortField, sortOrder } = {}) { const iso = (d) => { if (!d) return undefined; const date = d instanceof Date ? d : new Date(d); @@ -98,10 +84,7 @@ export const UserService = { if (!userID) throw new Error('userID is required'); return requestJson(`/super/v1/users/${userID}`); }, - async listUserTenants( - userID, - { page, limit, tenant_id, code, name, role, status, created_at_from, created_at_to } = {} - ) { + async listUserTenants(userID, { page, limit, tenant_id, code, name, role, status, created_at_from, created_at_to } = {}) { if (!userID) throw new Error('userID is required'); const iso = (d) => { diff --git a/frontend/superadmin/src/service/auth.js b/frontend/superadmin/src/service/auth.js index 9737022..928fbcf 100644 --- a/frontend/superadmin/src/service/auth.js +++ b/frontend/superadmin/src/service/auth.js @@ -39,4 +39,3 @@ export async function refreshSuperToken() { if (token) setSuperAuthToken(token); return token; } - diff --git a/frontend/superadmin/src/views/superadmin/Assets.vue b/frontend/superadmin/src/views/superadmin/Assets.vue new file mode 100644 index 0000000..2e84ced --- /dev/null +++ b/frontend/superadmin/src/views/superadmin/Assets.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/superadmin/src/views/superadmin/Contents.vue b/frontend/superadmin/src/views/superadmin/Contents.vue index 3de178d..2b0b6e9 100644 --- a/frontend/superadmin/src/views/superadmin/Contents.vue +++ b/frontend/superadmin/src/views/superadmin/Contents.vue @@ -292,11 +292,7 @@ onMounted(() => { - diff --git a/frontend/superadmin/src/views/superadmin/Orders.vue b/frontend/superadmin/src/views/superadmin/Orders.vue index cd319aa..6988979 100644 --- a/frontend/superadmin/src/views/superadmin/Orders.vue +++ b/frontend/superadmin/src/views/superadmin/Orders.vue @@ -328,15 +328,7 @@ loadOrders(); @@ -352,9 +344,7 @@ loadOrders();
-
- 该操作会将订单从 paid 推进到 refunding 并提交异步退款任务。 -
+
该操作会将订单从 paid 推进到 refunding 并提交异步退款任务。
@@ -366,14 +356,7 @@ loadOrders();
diff --git a/frontend/superadmin/src/views/superadmin/Reports.vue b/frontend/superadmin/src/views/superadmin/Reports.vue new file mode 100644 index 0000000..2f28f88 --- /dev/null +++ b/frontend/superadmin/src/views/superadmin/Reports.vue @@ -0,0 +1,11 @@ + + + diff --git a/frontend/superadmin/src/views/superadmin/TenantDetail.vue b/frontend/superadmin/src/views/superadmin/TenantDetail.vue index f6f352c..82664ab 100644 --- a/frontend/superadmin/src/views/superadmin/TenantDetail.vue +++ b/frontend/superadmin/src/views/superadmin/TenantDetail.vue @@ -111,9 +111,7 @@ async function ensureStatusOptionsLoaded() { statusOptionsLoading.value = true; try { const list = await TenantService.getTenantStatuses(); - statusOptions.value = (list || []) - .map((kv) => ({ label: kv?.value ?? kv?.key ?? '-', value: kv?.key ?? '' })) - .filter((item) => item.value); + statusOptions.value = (list || []).map((kv) => ({ label: kv?.value ?? kv?.key ?? '-', value: kv?.key ?? '' })).filter((item) => item.value); } finally { statusOptionsLoading.value = false; } @@ -642,14 +640,7 @@ onMounted(() => { + +