Files
quyun-v2/frontend/admin/ADMIN_PAGES.md

9.3 KiB
Raw Blame History

QuyUn Tenant Adminfrontend/admin页面与功能规划

基于 backend/docs/swagger.json/t/{tenantCode}/v1/admin/* 管理端接口(租户维度),规划 frontend/admin/ 的信息架构、页面路由与核心交互。

当前 frontend/admin/src/tenant.ts 的路由基座为 /t/:tenantCode/admin/API 基座为 /t/:tenantCode/v1;本文中 API 路径均以该 baseURL 为前缀(即请求 /admin/...)。

0. 全局约定(前端通用能力)

  • 租户上下文:从 URL 解析 tenantCode(已存在 getTenantCodeFromPath),所有接口都带上路径参数 {tenantCode}
  • 分页/排序:多数列表接口使用 page/limit,部分支持 asc/desc;统一封装 Pager 查询参数与列表组件。
  • 过滤条件同步 URL:列表页筛选项写入 query便于分享/刷新不丢失)。
  • 危险操作二次确认 + 审计信息:退款、禁用邀请码、审批加入申请、移除成员、删除媒体资源等,弹窗确认并强制填写 reason(后端字段标注为可选,但管理端建议必填以便追溯)。
  • 枚举展示:基于 swagger 的 consts.* 枚举做 label 映射(见文末“枚举”)。

1. 路由与菜单(建议)

路由均相对 getAdminRouterBase()/t/:tenantCode/admin/

  • /dashboard:概览
  • /members:成员管理
  • /invites:邀请码管理
  • /join-requests:加入申请
  • /orders:订单管理
  • /orders/:orderID:订单详情
  • /ledgers:余额流水(审计)
  • /media:媒体资源库
  • /media/upload:上传媒体资源
  • /media/:assetID:媒体资源详情
  • /contents:内容管理(接口缺口见“待补接口/风险”)
  • /contents/new:创建内容(草稿)
  • /contents/:contentID:内容编辑(基础信息/价格/绑定资源)

2. 页面规格(页面 → 功能 → API

2.1 概览 /dashboard

目标:提供“运营入口 + 关键待办”。

  • 待办卡片:加入申请待处理数量最近退款/退款中订单最近上传失败媒体资源
  • 快捷入口:跳转到成员/订单/媒体/内容
  • 数据来源(可先不做聚合,使用列表接口取前 N 条):
    • 加入申请列表:GET /admin/join-requests?status=pending&limit=10&page=1
    • 订单列表:GET /admin/orders?status=refunding,refunded,paid&limit=10&page=1(按 paid_at/created_at 排序)
    • 媒体资源列表:GET /admin/media_assets?status=failed,processing&limit=10&page=1

2.2 成员管理 /members

核心对象:租户成员关系 + 用户基础信息(dto.AdminTenantUserItem 组合 models.TenantUser + models.User)。

  • 成员列表(带筛选/分页)
    • 过滤:usernameuser_idrolestatus
    • APIGET /admin/users
  • 添加成员(通过 userID 加入)
    • 交互:输入 userID(或未来可通过用户名搜索,当前 swagger 未提供)
    • APIPOST /admin/users/{userID}/join
  • 设置角色
    • 交互:角色下拉(member / tenant_admin
    • APIPATCH /admin/users/{userID}/roledto.AdminTenantUserRoleUpdateForm
  • 移除成员
    • APIDELETE /admin/users/{userID}

2.3 邀请码管理 /invites

  • 邀请码列表(筛选/分页)
    • 过滤:codestatus
    • APIGET /admin/invites
  • 创建邀请码
    • 表单字段:code?expires_at?max_uses?remark?dto.AdminTenantInviteCreateForm
    • APIPOST /admin/invites
  • 禁用邀请码
    • 表单字段:reason?(建议必填;dto.AdminTenantInviteDisableForm
    • APIPATCH /admin/invites/{inviteID}/disable

2.4 加入申请 /join-requests

  • 加入申请列表(筛选/分页)
    • 过滤:statususer_id
    • APIGET /admin/join-requests
  • 审核通过 / 拒绝
    • 表单字段:reason?(建议必填;dto.AdminTenantJoinRequestDecideForm
    • API
      • POST /admin/join-requests/{requestID}/approve
      • POST /admin/join-requests/{requestID}/reject

2.5 订单管理 /orders

  • 订单列表(筛选/分页/导出)
    • 过滤:
      • 金额:amount_paid_min / amount_paid_max(单位分)
      • 订单:statustype
      • 用户:user_idusername
      • 内容:content_idcontent_title
      • 时间:created_at_from/topaid_at_from/to
    • 排序:asc / desc
    • API
      • 列表:GET /admin/orders
      • 导出:GET /admin/orders/export(应与当前筛选条件一致)
  • 订单详情入口:点击行跳 /orders/:orderID

2.6 订单详情 /orders/:orderID

  • 详情展示
    • APIGET /admin/orders/{orderID}(返回 dto.AdminOrderDetail,内含 models.Order,其中 items 为订单项)
  • 退款操作
    • 表单字段:reason(建议必填)、idempotency_key(前端生成 UUIDforce(受控开关,默认 false
    • APIPOST /admin/orders/{orderID}/refunddto.AdminOrderRefundForm
    • 交互退款前展示校验信息当前接口描述存在“paid_at + 24h”窗口逻辑并将强制退款标注为高危操作

2.7 余额流水(审计)/ledgers

  • 流水列表(筛选/分页)
    • 过滤:user_idorder_idoperator_user_idbiz_ref_typebiz_ref_idtypecreated_at_from/to
    • APIGET /admin/ledgers
  • 展示重点:
    • dto.AdminLedgerItem.type_description 直接用于 UI 展示
    • 金额字段以“分”为单位的,统一格式化为元(保留两位)

2.8 媒体资源库 /media

  • 资源列表(筛选/分页/排序)
    • 过滤:typestatuscreated_at_from/to
    • 排序:asc/desc
    • APIGET /admin/media_assets
  • 删除资源(软删)
    • APIDELETE /admin/media_assets/{assetID}
  • 进入详情:跳 /media/:assetID

2.9 上传媒体资源 /media/upload

建议采用“上传任务”模型(可多文件队列):

  1. 初始化上传(创建资源记录 + 获取上传参数)
  • APIPOST /admin/media_assets/upload_initdto.AdminMediaAssetUploadInitFormdto.AdminMediaAssetUploadInitResponse
  • 表单字段:type(必填)、variantsource_asset_id?sha256?file_size?content_type?
  1. 直传到对象存储
  • 使用返回的 upload_url + form_fields/headers 完成上传
  1. 确认上传完成,触发后端处理
  • APIPOST /admin/media_assets/{assetID}/upload_completedto.AdminMediaAssetUploadCompleteForm

2.10 媒体资源详情 /media/:assetID

  • APIGET /admin/media_assets/{assetID}
  • 展示:type/variant/status/provider/bucket/object_key/meta/created_at 等;对 failed 状态展示失败原因(若后端写在 meta

2.11 内容管理 /contents(待补接口)

swagger 中目前仅提供:

  • 创建草稿:POST /admin/contentsdto.ContentCreateForm
  • 更新内容:PATCH /admin/contents/{contentID}dto.ContentUpdateForm
  • 设置价格:PUT /admin/contents/{contentID}/pricedto.ContentPriceUpsertForm
  • 绑定媒体资源:POST /admin/contents/{contentID}/assetsdto.ContentAssetAttachForm

建议页面拆分:

  • 内容列表 /contents:需要后端补 GET /admin/contents(支持状态/可见性/标题搜索/分页),否则前端无法管理草稿/下架内容。
  • 内容创建 /contents/new:填写 title/description/preview_seconds/visibility
  • 内容编辑 /contents/:contentID
    • 基础信息:PATCH /admin/contents/{contentID}
    • 价格与折扣:PUT /admin/contents/{contentID}/price
    • 资源绑定:从媒体资源库选择 asset_id,按 role(main/cover/preview) 绑定到内容

3. 枚举UI 需要的固定值)

(直接来自 swagger definitions/consts.*

  • 成员角色 consts.TenantUserRolemembertenant_admin
  • 邀请码状态 consts.TenantInviteStatusactivedisabledexpired
  • 加入申请状态 consts.TenantJoinRequestStatuspendingapprovedrejected
  • 媒体类型 consts.MediaAssetTypevideoaudioimage
  • 媒体状态 consts.MediaAssetStatusuploadedprocessingreadyfaileddeleted
  • 订单状态 consts.OrderStatuscreatedpaidrefundingrefundedcanceledfailed
  • 订单类型 consts.OrderTypecontent_purchase
  • 流水类型 consts.TenantLedgerTypedebit_purchasecredit_refundfreezeunfreezeadjustment
  • 内容可见性 consts.ContentVisibilitypublictenant_onlyprivate
  • 内容状态 consts.ContentStatusdraftreviewingpublishedunpublishedblocked
  • 内容资源角色 consts.ContentAssetRolemaincoverpreview
  • 折扣类型 consts.DiscountTypenonepercentamount
  • 币种 consts.CurrencyCNY

4. 待补接口 / 风险点(从 swagger 反推)

  • 内容列表缺失:没有 GET /admin/contents;无法做内容管理主列表、草稿管理、下架列表等。
  • 分页返回结构疑似不完整:多个列表接口在 swagger 中将 items 描述为单个 object$ref models.*),但实际应为数组;前端需以实际返回为准,或推动后端修正 swaggeritems: { type: array, items: ... })。
  • 鉴权机制未在 swagger 体现securityDefinitions 仅有 BasicAuth,且各接口未标注 security前端需确认实际鉴权方式JWT/Cookie/BasicAuth并统一处理 401/403。