diff --git a/docs/前端建设/C端H5页面接口矩阵.md b/docs/前端建设/C端H5页面接口矩阵.md new file mode 100644 index 0000000..5397876 --- /dev/null +++ b/docs/前端建设/C端H5页面接口矩阵.md @@ -0,0 +1,176 @@ +# C 端 H5 页面接口矩阵 + +> C 端是独立 H5,使用个人客户体系和 `/api/c/v1`,不复用管理 Web/H5 的账号密码登录、菜单或角色。 + +## 一、C 端产品定位 + +当前 C 端是“围绕资产提供查询、充值、购包和设备控制”的服务 H5,不是完整电商商城。 + +客户通常从资产二维码、设备标签或外部链接进入,通过资产标识完成验证和微信身份登录。登录后可查看本人绑定的卡或设备,并围绕该资产操作。 + +首期不应设计购物车、商品分类、收货地址簿等页面,因为当前没有对应后端能力。 + +## 二、进入与登录流程 + +```mermaid +sequenceDiagram + participant U as 客户 + participant H as C端H5 + participant A as 后端 + participant W as 微信 + + U->>H: 扫码或输入资产标识 + H->>A: POST /auth/verify-asset + A-->>H: asset_token、资产类型、微信配置 + H->>W: 公众号OAuth或小程序登录 + W-->>H: code + H->>A: POST /auth/wechat-login 或 miniapp-login + A-->>H: JWT、客户信息、need_bind_phone + alt 需要绑定手机号 + H->>A: POST /auth/send-code + H->>A: POST /auth/bind-phone + end + H->>A: GET /asset/info + A-->>H: 资产首页数据 +``` + +关键约束: + +- `verify-asset` 支持 ICCID、虚拟号、MSISDN、IMEI、SN。 +- 设备内绑定卡不能以独立卡身份登录,应提示客户使用设备标识。 +- `asset_token` 是短期登录凭证,不等同于登录后的 JWT。 +- C 端 JWT 由签名和 Redis 当前 Token 双重校验;同一客户后登录可能使旧会话失效。 +- C 端没有 Refresh Token 接口,认证失效后重新走资产验证和微信登录。 + +## 三、页面矩阵 + +### 3.1 启动、登录和账户 + +| 页面 | 输入 | 展示字段 | 操作 | 接口 | +| --- | --- | --- | --- | --- | +| 启动初始化 | 当前完整 URL | `app_id`、JSSDK 配置、环境错误 | 初始化微信能力 | `GET /wechat/appid`、`GET /wechat/jssdk-config` | +| 资产验证 | 资产标识 | 资产类型、脱敏资产摘要、登录提示 | 验证并获取 `asset_token` | `POST /auth/verify-asset` | +| 微信登录 | `asset_token`、OAuth `code` | 客户、是否新用户、是否需绑手机、Token | 公众号/小程序登录 | `POST /auth/wechat-login`、`POST /auth/miniapp-login` | +| 手机号绑定 | 手机号、验证码 | 绑定结果 | 发送验证码、绑定、更换手机号 | `/auth/send-code`、`/auth/bind-phone`、`/auth/change-phone` | +| 个人资料 | 无或昵称、头像 | 客户 ID、昵称、头像、手机号、状态 | 查看、更新 | `GET|PUT /profile` | +| 退出登录 | 无 | 无 | 使当前 Token 失效 | `POST /auth/logout` | + +公开接口必须在没有 Bearer Token 时也能访问:微信配置、资产验证、微信/小程序登录、发送验证码。 + +### 3.2 资产首页 + +| 区块 | 关键展示字段 | 交互 | 接口 | +| --- | --- | --- | --- | +| 资产身份 | `asset_type`、主标识、ICCID/虚拟号/IMEI/SN、设备名 | 复制标识 | `GET /asset/info` | +| 状态 | 业务状态、网络/在线状态、实名状态及名称、最后同步时间 | 刷新 | `GET /asset/info`、`POST /asset/refresh` | +| 流量 | 总量、已用、剩余、使用比例、周期 | 查看套餐历史 | `GET /asset/info`、`GET /asset/package-history` | +| 当前套餐 | 套餐名、类型、生效/到期、预计最终到期、排队信息 | 查看可购套餐 | `GET /asset/info` | +| 钱包 | 余额、冻结金额、资产类型 | 充值、查看流水 | `GET /wallet/detail` | +| 实名 | `effective_realname_policy`、`realname_required`、`realname_status` | 去实名 | `GET /asset/info`、`GET /realname/link` | +| 支付能力 | `allowed_payment_methods` | 控制购买和充值按钮 | `GET /asset/info` | + +前端不得根据“卡还是设备”自行推断实名策略和支付方式。 + +### 3.3 套餐购买 + +| 页面 | 主要输入/筛选 | 展示字段 | 操作 | 接口 | +| --- | --- | --- | --- | --- | +| 可购套餐 | 资产标识、分页/类型(以 OpenAPI 为准) | 套餐 ID、名称、系列、类型、流量、周期、售价、上下架/可购状态、有效期说明 | 选择套餐 | `GET /asset/packages` | +| 下单确认 | 资产标识、套餐 ID、支付方式、应用类型 | 资产、套餐、价格、实名要求、强充提示、允许支付方式 | 创建订单 | `POST /orders/create` | +| 支付 | 订单 ID | 应付金额、支付方式、订单状态 | 钱包支付、微信支付、支付宝支付 | `POST /orders/:id/pay` | +| 订单列表 | 状态、分页 | 订单号、资产、套餐、金额、支付方式、状态名称、创建时间 | 查看详情 | `GET /orders` | +| 订单详情 | 订单 ID | 订单、套餐、资产、金额、支付、状态时间、权益结果 | 重新支付 | `GET /orders/:id` | + +调用顺序: + +1. 先查询 `/asset/info`,取得实名策略和允许支付方式。 +2. 查询 `/asset/packages`。 +3. 提交 `/orders/create`。 +4. 如果响应已包含强充支付参数,按响应拉起支付。 +5. 普通待支付订单调用 `/orders/:id/pay`。 +6. 钱包支付成功后直接刷新详情;第三方支付返回页面后重新查询订单详情。 + +当前没有独立 C 端支付状态接口,也没有客户端主动取消订单接口。页面通过订单详情确认后端最终状态。 + +### 3.4 钱包与充值 + +| 页面 | 输入/筛选 | 展示字段 | 操作 | 接口 | +| --- | --- | --- | --- | --- | +| 钱包详情 | 资产标识 | 资产类型/ID、余额、冻结金额、可用余额 | 进入充值 | `GET /wallet/detail` | +| 钱包流水 | 类型、时间、分页 | 流水号、变动金额、前后余额、业务类型、关联订单、状态、时间 | 查看关联业务 | `GET /wallet/transactions` | +| 充值校验 | 资产标识、金额/场景 | 最低/最高金额、允许支付方式、实名/强充规则 | 进入充值 | `GET /wallet/recharge-check` | +| 创建充值 | 资产、金额、支付方式、应用类型、幂等请求标识 | 充值单号、支付参数或支付宝链接、状态 | 拉起支付 | `POST /wallet/recharge` | +| 充值记录 | 状态、分页 | 充值单号、金额、方式、支付状态、到账状态、时间 | 查看详情 | `GET /wallet/recharges`、`GET /recharge-orders` | +| 充值详情 | 充值订单 ID | 金额、资产、渠道、第三方单号、支付/到账时间、状态名称 | 刷新状态 | `GET /recharge-orders/:id` | + +充值只使用接口返回的支付方式。钱包不能给自己钱包充值,因此强充和普通充值通常只提供微信、支付宝等第三方方式。 + +### 3.5 实名 + +| 页面 | 输入 | 展示字段 | 操作 | 接口 | +| --- | --- | --- | --- | --- | +| 实名引导 | 资产标识 | 是否需要实名、实名状态、模式、运营商、提示 | 获取实名链接 | `GET /realname/link` | + +可能的策略: + +- `none`:无需实名。 +- `before_order`:未实名时禁止充值或购买。 +- `after_order`:可先购买,支付后继续引导实名。 + +页面必须使用 `effective_realname_policy`,不能只读资产原始策略。 + +### 3.6 设备控制 + +仅设备资产显示该模块。 + +| 页面/动作 | 输入 | 展示字段 | 接口 | +| --- | --- | --- | --- | +| 卡槽列表 | 设备标识 | 卡槽号、ICCID、运营商、网络/实名/激活状态、当前卡 | `GET /device/cards` | +| 切卡 | 设备标识、目标卡/卡槽 | 操作结果、当前卡 | `POST /device/switch-card` | +| 配置 WiFi | SSID、密码等 DTO 字段 | 操作结果 | `POST /device/wifi` | +| 重启 | 设备标识 | 操作结果 | `POST /device/reboot` | +| 恢复出厂 | 设备标识、确认 | 操作结果 | `POST /device/factory-reset` | + +重启、切卡、WiFi、恢复出厂都应防止重复点击;恢复出厂必须二次确认。 + +### 3.7 换货 + +| 页面 | 输入 | 展示字段 | 操作 | 接口 | +| --- | --- | --- | --- | --- | +| 待处理换货提醒 | 当前登录资产 | 换货单号、旧资产、状态、提交期限 | 进入收货信息 | `GET /exchange/pending` | +| 收货信息 | 收件人、手机号、地区、详细地址 | 换货摘要 | 提交 | `POST /exchange/:id/shipping-info` | + +C 端不能创建、发货、完成或取消换货,只负责查询待补资料换货单并提交收货信息。 + +### 3.8 通知 + +| 页面 | 筛选/输入 | 展示字段 | 操作 | 接口 | +| --- | --- | --- | --- | --- | +| 未读提示 | 无 | 未读数 | 打开通知中心 | `GET /notifications/unread-count` | +| 通知列表 | 类型、状态、分页 | 类型、标题、内容、风险、关联资源、时间、已读状态 | 标记已读 | `GET /notifications`、`PUT /notifications/:id/read` | +| 全部已读 | 无 | 无 | 全部标记已读 | `PUT /notifications/read-all` | + +## 四、全局交互状态 + +C 端至少统一处理: + +- 首次加载、局部刷新、空数据和网络异常。 +- Token 失效后回到资产验证入口,并保留当前进入链接。 +- 403 表示当前客户未绑定该资产或无权操作,不显示“资产不存在”的差异提示。 +- 支付取消、支付失败、支付结果未知和支付成功。 +- Gateway 操作已提交但结果未知,禁止无限自动重试。 +- 订单、充值、换货使用后端 `status_name` 展示中文状态。 + +## 五、当前缺口 + +以下页面没有现成接口支撑,不纳入首期: + +- 独立商品详情和商品分类。 +- 购物车。 +- 收货地址簿。 +- 客户主动取消订单。 +- 客户主动申请退款。 +- 客户资产列表和主动切换当前资产。 +- 独立支付状态查询。 + +若产品要求其中任一能力,应先作为独立后端用例设计,不能只在前端模拟。 diff --git a/docs/前端建设/README.md b/docs/前端建设/README.md new file mode 100644 index 0000000..1577ef2 --- /dev/null +++ b/docs/前端建设/README.md @@ -0,0 +1,146 @@ +# 前端建设总览 + +> 状态:前端尚未创建,本目录用于统一产品、UI、前端和后端对系统业务、页面范围与接口契约的理解。 +> +> 接口字段的唯一权威来源是 [`docs/admin-openapi.yaml`](../admin-openapi.yaml)。本目录只说明业务语义、页面需要什么、接口按什么顺序调用,不复制完整 DTO。 + +## 一、已经确认的产品形态 + +系统包含三个前端使用场景,不存在独立的“代理端”或“企业端”后端: + +| 使用场景 | 形态 | 登录用户 | 后端接口 | +| --- | --- | --- | --- | +| 管理 Web | 桌面浏览器管理系统 | 超级管理员、平台账号、代理账号、企业账号 | `/api/auth`、`/api/admin` | +| 管理 H5 | 移动浏览器管理系统 | 超级管理员、平台账号、代理账号、企业账号 | `/api/auth`、`/api/admin` | +| C 端 H5 | 面向个人客户的资产服务 H5 | 个人客户 | `/api/c/v1` | + +管理 Web 和管理 H5 的菜单不是按“平台端、代理端、企业端”写死,而由登录账号的角色权限决定。账号身份只决定组织关系和数据范围: + +- 超级管理员:不分配角色,获取当前终端全部启用权限。 +- 平台账号:可分配多个平台角色,数据范围为全平台。 +- 代理账号:归属一个店铺,可分配一个客户角色,数据范围为本店及下级店铺。 +- 企业账号:归属一个企业,可分配一个客户角色,数据范围应限制为本企业。 +- 个人客户:独立用户体系,不参与管理端 RBAC,通过客户与资产绑定控制数据范围。 + +登录请求中的 `device` 决定返回哪一套菜单: + +- 管理 Web 传 `web`。 +- 管理 H5 传 `h5`。 +- 权限记录的 `platform=all` 同时适用于两端。 + +## 二、系统业务全景 + +系统管理两类核心资产:IoT 卡和设备。设备可以绑定多张 IoT 卡;资产由平台导入后,沿店铺层级进行分配,并可进一步授权给企业使用。 + +```mermaid +flowchart LR + A[平台配置运营商、套餐和规则] --> B[导入 IoT 卡和设备] + B --> C[分配给代理店铺] + C --> D[代理向直属下级继续分配] + C --> E[授权给企业客户使用] + C --> F[个人客户绑定资产] + D --> F + E --> G[企业查看被授权资产] + F --> H[C 端查询流量、实名和套餐] + H --> I[充值或购买套餐] + I --> J[支付回调和套餐生效] + J --> K[轮询流量、状态和实名] + J --> L[生成钱包流水、差价和佣金] + J --> M[退款、换货和通知] + L --> N[代理提现或继续采购] +``` + +### 2.1 身份与组织 + +`Account` 是管理端账号;`Shop` 是代理组织;`Enterprise` 是企业组织;`PersonalCustomer` 是独立 C 端客户。 + +- 店铺最多形成 7 级上下级关系。 +- 代理账号必须关联一个店铺。 +- 企业账号必须关联一个企业。 +- 企业可以归属于平台,也可以归属于某个店铺。 +- 个人客户通过微信身份、手机号和资产绑定建立使用关系。 + +### 2.2 资产 + +- IoT 卡可独立使用,也可绑定在设备卡槽中。 +- 卡和设备均有平台/店铺归属、业务状态、实名策略、套餐系列等信息。 +- 设备分配时,其绑定卡需要同步处理归属。 +- 企业授权是使用权,不改变资产的店铺归属。 +- C 端客户绑定资产后,只能操作本人已绑定的资产。 + +### 2.3 套餐与分销 + +平台先创建套餐系列和套餐,再将系列、套餐和价格逐级下发给店铺。 + +- 上级只能将自己有权销售的套餐分配给下级。 +- 代理通常只能向直属下级分配。 +- 下级成本价不能低于上级成本价。 +- 主套餐在已有生效主套餐时进入排队。 +- 加油包要求已有主套餐,并立即生效,其有效期跟随主套餐。 +- 下架套餐默认不再进入新客户可购列表;符合历史续费条件的资产可继续按已有套餐 ID 下单。 + +### 2.4 订单与支付 + +订单来源包括管理端代购、C 端自助购买和批量购买。 + +- 管理端先调用购买校验,再创建订单。 +- C 端先查询资产信息和可购套餐,再创建订单。 +- 支付方式由后端按资产类型、业务场景和配置计算,前端使用 `allowed_payment_methods`。 +- 钱包支付同步完成扣款;微信、支付宝等第三方支付依赖服务端回调更新状态。 +- 支付成功后,后端负责套餐激活、排队、佣金和通知,前端不能自行修改业务状态。 + +### 2.5 钱包、佣金与提现 + +系统存在资产钱包和代理主钱包两套资金语义: + +- 资产钱包:归属于卡或设备,供 C 端充值和购买套餐。 +- 代理主钱包:归属于店铺,用于代理采购、代购和经营结算。 +- 佣金钱包/记录:记录差价收益和一次性佣金。 +- 提现:代理提交申请,系统冻结金额,审批完成后结算或解冻。 +- 所有金额接口以“分”的整数为准,前端只在展示层转换为元。 + +### 2.6 售后 + +- 退款:围绕原订单、实付金额、套餐权益和审批状态处理。 +- 换货:后台建单,C 端填写收货信息,后台发货并选择是否迁移旧资产权益。 +- 套餐失效:退款或人工任务只失效目标订单产生的权益。 +- 通知:管理账号和个人客户使用两套通知读取接口。 + +### 2.7 异步任务 + +导入、导出、批量购买、批量分配和部分扫描任务不在单次 HTTP 请求内完成: + +1. 前端获取对象存储预签名地址。 +2. 文件直传对象存储。 +3. 将 `file_key` 和业务参数提交给任务接口。 +4. 获得任务 ID。 +5. 轮询列表或详情。 +6. 展示总数、成功数、失败数和逐行失败原因。 + +## 三、前端建设产物 + +- [前端选型与代码组织](前端选型与代码组织.md) +- [管理 Web 与管理 H5 页面接口矩阵](管理端页面接口矩阵.md) +- [C 端 H5 页面接口矩阵](C端H5页面接口矩阵.md) +- [权限矩阵与接口联调契约](权限矩阵与接口联调契约.md) +- [完整 OpenAPI](../admin-openapi.yaml) +- [现有系统流程图](../系统流程图/) + +## 四、契约优先级 + +出现冲突时按以下顺序判断: + +1. 当前代码中的路由、DTO 和权限实现。 +2. `docs/admin-openapi.yaml` 生成契约。 +3. 本目录的业务和页面说明。 +4. 历史功能总结和历史流程图。 + +历史文档仍可能出现 `/api/admin/login`、`/api/h5/login` 等旧路径。当前统一认证入口是 `/api/auth/*`,新前端不得继续使用旧路径。 + +## 五、当前启动前阻塞项 + +1. 管理端逐接口权限门禁尚未形成统一闭环,前端隐藏菜单不能替代后端鉴权。 +2. 企业账号的数据范围需要使用真实 Token 对企业、资产和授权接口做越权验证。 +3. 管理 H5 的首期页面范围尚未最终确认;本文给出任务型 MVP 建议,不默认复制全部 Web 页面。 +4. C 端目前是“围绕当前资产直接购买”的服务 H5,没有购物车、地址簿、独立商品详情和主动退款等完整商城能力。 +5. 前端技术栈尚未落地,先完成选型决策再创建脚手架。 diff --git a/docs/前端建设/前端选型与代码组织.md b/docs/前端建设/前端选型与代码组织.md new file mode 100644 index 0000000..41d7e95 --- /dev/null +++ b/docs/前端建设/前端选型与代码组织.md @@ -0,0 +1,213 @@ +# 前端选型与代码组织 + +> 状态:推荐方案,尚未创建脚手架或安装依赖。 + +## 一、推荐结论 + +推荐使用 Vue 3 + TypeScript + Vite,并采用 pnpm workspace 单仓库、三个独立应用: + +```text +frontend/ +├── apps/ +│ ├── admin-web/ # 管理 Web +│ ├── admin-h5/ # 管理 H5 +│ └── client-h5/ # 独立 C 端 H5 +└── packages/ + └── api/ # OpenAPI 生成类型和请求客户端 +``` + +推荐组合: + +| 领域 | 选择 | 理由 | +| --- | --- | --- | +| 框架 | Vue 3 + TypeScript | 管理后台和 H5 生态成熟,单文件组件适合页面型业务 | +| 构建 | Vite | 配置少,三应用可独立构建和发布 | +| 工作区 | pnpm workspace | 只解决多应用依赖和共享 API 包,不引入额外编排平台 | +| 管理 Web UI | Element Plus | 表格、表单、树、分页、弹窗等后台能力完整 | +| 管理 H5/C 端 UI | Vant | 移动表单、列表、弹层、支付结果页等 H5 交互成熟 | +| 路由 | Vue Router | 三个应用分别维护静态路由表 | +| 客户端状态 | Pinia | 只保存登录态、当前用户、菜单和按钮权限 | +| 接口类型 | openapi-typescript | 从现有 OpenAPI 生成 TypeScript 类型 | +| 请求客户端 | openapi-fetch + 原生 fetch | 类型直接复用,减少手写接口和额外封装 | + +不在首期引入:Nx、Turborepo、大型后台模板、服务端状态缓存库、自研组件库、微前端。 + +## 二、为什么建议三个应用 + +管理 Web 和管理 H5 使用同一套后端业务与权限,但它们是两个真实的交互界面: + +- Web 以高密度表格、批量操作、复杂配置为主。 +- 管理 H5 以资产查询、现场操作、审批、资金和通知为主。 +- 两端登录分别传 `device=web` 和 `device=h5`,后端会返回不同菜单。 +- Element Plus 和 Vant 的布局与交互模型不同,强行在一个应用混用会增加条件渲染和包体积。 +- C 端 H5 使用完全不同的个人客户认证、微信 OAuth、支付回跳和资产绑定流程,必须独立。 + +三个应用放在同一仓库,可以统一 TypeScript、Lint、构建和 OpenAPI 类型,又不会把三种页面体验绑在一个发布包中。 + +## 三、何时可以改成两个应用 + +如果管理 H5 最终只保留以下少量页面,可以使用“自适应管理端 + C 端 H5”两应用方案: + +- 登录和个人中心。 +- 通知。 +- 统一资产搜索和只读详情。 +- 少量订单、退款、换货审批。 + +一旦管理 H5 需要独立导航、设备控制、企业授权、资金、上传或大量移动表单,就应使用独立 `admin-h5`。当前页面矩阵已经超过纯只读壳层,因此默认采用三个应用。 + +## 四、共享边界 + +首期只共享 `packages/api`: + +```text +Go 路由和 DTO + ↓ +docs/admin-openapi.yaml + ↓ +openapi-typescript + ↓ +packages/api 类型与客户端 + ↓ +admin-web / admin-h5 / client-h5 +``` + +暂不共享: + +- 页面组件。 +- 登录页面。 +- 业务状态管理。 +- Web/H5 表单组件。 +- 业务流程组合函数。 + +等两个应用出现真实、稳定、完全相同的重复后再提取。不要先创建 `shared-business`、`shared-components` 等空泛包。 + +## 五、推荐仓库结构 + +```text +frontend/ +├── apps/ +│ ├── admin-web/ +│ │ └── src/ +│ │ ├── app/ +│ │ ├── pages/ +│ │ ├── routes/ +│ │ └── stores/ +│ ├── admin-h5/ +│ │ └── src/ +│ │ ├── app/ +│ │ ├── pages/ +│ │ ├── routes/ +│ │ └── stores/ +│ └── client-h5/ +│ └── src/ +│ ├── app/ +│ ├── pages/ +│ ├── routes/ +│ └── stores/ +├── packages/ +│ └── api/ +│ ├── generated/ +│ ├── client.ts +│ └── index.ts +├── package.json +├── pnpm-workspace.yaml +└── tsconfig.base.json +``` + +目录保持扁平。页面内部先就近放置组件,不按 `api/service/model/controller` 重建一套前端分层。 + +## 六、请求模块的唯一职责 + +`packages/api` 只负责: + +1. OpenAPI 生成类型。 +2. Base URL。 +3. Bearer Token 注入。 +4. 管理端 Refresh Token 单次刷新队列。 +5. `{code,msg,data,timestamp}` 解包。 +6. 401、403、429、5xx 统一错误事件。 +7. Request ID 提取。 + +它不负责: + +- 页面跳转。 +- Toast 文案拼接。 +- 将订单状态改成本地状态机。 +- 缓存所有列表和详情。 +- 替页面吞掉错误。 + +这使请求模块保持为一个小接口、深实现的公共模块,三应用只需要学习同一套调用方式。 + +## 七、动态菜单实现 + +后端菜单只决定“哪些本地路由可见和可进入”,不能直接决定加载哪个源代码文件。 + +正确方式: + +1. 每个管理应用维护静态路由表:`routeKey/url → 页面组件`。 +2. 登录后读取 `menus`。 +3. 将后端菜单与本地静态路由表求交集。 +4. 生成导航和路由白名单。 +5. 未匹配到本地页面时记录告警并隐藏,不允许字符串动态 import 任意组件。 +6. 使用 `buttons` 控制操作按钮。 + +## 八、状态管理边界 + +Pinia 首期只保存: + +- Access Token、Refresh Token。 +- 当前用户。 +- 菜单、按钮和权限码。 +- 当前终端类型。 +- 少量跨页面 UI 状态。 + +订单列表、资产详情、套餐列表等服务端数据由页面直接请求并局部刷新。等出现跨页面共享缓存、复杂失效和后台自动刷新需求后,再评估服务端状态库。 + +## 九、OpenAPI 工作流 + +建议建立固定流水线: + +```text +go run ./cmd/gendocs + ↓ +更新 docs/admin-openapi.yaml + ↓ +生成 packages/api/generated + ↓ +TypeScript 类型检查 + ↓ +构建三个应用 +``` + +生成文件不手改。字段不正确时修改 Go DTO、RouteSpec 或文档生成器,然后重新生成。 + +当前 `admin-openapi.yaml` 同时包含管理端、C 端、开放接口和回调,文件名虽然偏旧,但首期无需为前端拆分多份 OpenAPI。 + +## 十、方案对比 + +| 方案 | 优点 | 风险 | 结论 | +| --- | --- | --- | --- | +| Vue 三应用单仓库 | Web/H5 体验清晰;共享接口类型;独立发布 | 有少量工程重复 | 推荐 | +| Vue 自适应管理端 + C端H5 | 少一个应用,首期代码更少 | Web/H5 组件混用、条件页面和包体增长 | 仅管理 H5 很小时使用 | +| React 三应用 | 也能满足需求,团队成熟时可选 | 当前没有团队技术偏好,初始约定和库选择更多 | 团队明显更熟 React 时替换推荐方案 | + +如果实施团队已有稳定 React 经验,应优先服从团队能力,使用 React + TypeScript + Vite、Ant Design、Ant Design Mobile,仍保持“三应用单仓库+只共享 OpenAPI 包”的结构,不必为追求 Vue 统一而增加学习成本。 + +## 十一、创建脚手架前需要确认 + +1. 前端团队更熟 Vue 还是 React。 +2. 管理 H5 是否作为独立正式产品发布。 +3. 三个应用的域名、Base URL 和环境配置。 +4. 微信公众号 OAuth 回调域名和支付回跳地址。 +5. 首期页面范围及权限种子数据。 +6. 后端企业数据范围和逐接口权限门禁是否完成验证。 + +## 十二、参考资料 + +- [Vue TypeScript](https://vuejs.org/guide/typescript/overview.html) +- [Pinia](https://pinia.vuejs.org/) +- [Element Plus](https://element-plus.org/) +- [Vant](https://vant-ui.github.io/vant/) +- [openapi-typescript](https://openapi-ts.dev/introduction) +- [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) +- [pnpm Workspace](https://pnpm.io/workspaces) diff --git a/docs/前端建设/权限矩阵与接口联调契约.md b/docs/前端建设/权限矩阵与接口联调契约.md new file mode 100644 index 0000000..3b245d7 --- /dev/null +++ b/docs/前端建设/权限矩阵与接口联调契约.md @@ -0,0 +1,306 @@ +# 权限矩阵与接口联调契约 + +## 一、管理端权限计算模型 + +管理页面和操作的最终可用性不是只看 `user_type`,而是四个条件的交集: + +```text +终端适用范围 web/h5/all + ∩ +账号所绑定角色的菜单和按钮权限 + ∩ +账号身份的硬性业务限制 + ∩ +当前组织的数据范围 +``` + +### 1.1 终端 + +权限记录包含 `platform`: + +- `web`:只在管理 Web 登录时返回。 +- `h5`:只在管理 H5 登录时返回。 +- `all`:两端都返回。 + +### 1.2 角色 + +- 超级管理员不分配角色。 +- 平台账号使用平台角色,可绑定多个。 +- 代理和企业账号使用客户角色,最多绑定一个。 +- 登录返回 `menus`、`buttons` 和兼容字段 `permissions`。 + +因此,“代理可用什么”应由给该代理账号绑定的客户角色决定,而不是维护一套固定代理菜单。 + +### 1.3 身份硬限制 + +角色权限不能突破组织身份的业务限制。例如: + +- 企业账号即使错误分配了店铺菜单,也不应管理店铺。 +- 企业账号不应访问代理资金、佣金、提现和代理充值。 +- 代理账号不能越过本店及下级店铺的数据范围。 +- 代理账号不能管理平台直属企业。 +- 只有超管或平台管理身份可以维护支付、企微和全局系统配置。 + +### 1.4 数据范围 + +| 用户身份 | 组织字段 | 正常数据范围 | +| --- | --- | --- | +| 超级管理员 | 无 | 全平台 | +| 平台账号 | 无 | 全平台,但功能仍受角色权限控制 | +| 代理账号 | `shop_id` | 本店及全部下级店铺 | +| 企业账号 | `enterprise_id` | 本企业有效授权资产和本企业业务记录 | +| 个人客户 | `customer_id` | 本人绑定资产及本人订单、充值、通知 | + +## 二、目标权限矩阵 + +下表是产品和安全目标,不代表当前每条后端接口都已完整实现。 + +图例: + +- `权限控制`:角色有相应菜单/按钮且数据范围满足时可用。 +- `范围受限`:可用,但只能处理当前组织范围。 +- `只读建议`:首期只开放查询。 +- `禁止`:角色配置也不得突破。 + +| 业务模块 | 超管 | 平台账号 | 代理账号 | 企业账号 | 个人客户 | +| --- | --- | --- | --- | --- | --- | +| 账号管理 | 全部 | 权限控制 | 范围受限 | 禁止 | 不适用 | +| 角色/权限配置 | 全部 | 权限控制 | 建议禁止 | 禁止 | 不适用 | +| 店铺管理 | 全部 | 权限控制 | 本店及下级、权限控制 | 禁止 | 不适用 | +| 企业管理 | 全部 | 权限控制 | 本店及下级企业、权限控制 | 只读本企业资料 | 不适用 | +| 企业资产授权 | 全部 | 权限控制 | 本店及下级企业、权限控制 | 只读本企业授权 | 不适用 | +| 卡/设备库存 | 全部 | 权限控制 | 本店及下级、权限控制 | 仅本企业授权资产 | 仅本人绑定资产 | +| 资产分配 | 全部 | 权限控制 | 通常仅直属下级、权限控制 | 禁止 | 禁止 | +| 资产状态与设备控制 | 全部 | 权限控制 | 范围受限、权限控制 | 本企业授权范围、权限控制 | 本人绑定范围 | +| 运营商配置 | 全部 | 权限控制 | 禁止 | 禁止 | 不适用 | +| 套餐系列/套餐设计 | 全部 | 权限控制 | 建议只读 | 禁止 | 只看可购投影 | +| 套餐授权/分配/定价 | 全部 | 权限控制 | 直属下级、权限控制 | 禁止 | 禁止 | +| 管理端订单 | 全部 | 权限控制 | 范围受限、权限控制 | 视业务角色决定 | 仅本人 C 端订单 | +| 退款/换货 | 全部 | 权限控制 | 范围受限、权限控制 | 只读建议 | C 端只提交换货收货信息 | +| 代理主钱包/佣金/提现 | 全部 | 权限控制 | 本店及下级、权限控制 | 禁止 | 不适用 | +| 代理充值 | 全部 | 权限控制 | 本店在线充值、权限控制 | 禁止 | 不适用 | +| 资产钱包 | 全部 | 权限控制 | 范围受限、权限控制 | 授权资产只读建议 | 本人绑定资产 | +| 导入/批量处理 | 全部 | 权限控制 | 范围受限、权限控制 | 禁止 | 禁止 | +| 导出 | 全部 | 权限控制 | 按数据范围导出 | 只导本企业且需明确开放 | 禁止 | +| 微信/支付宝/企微配置 | 全部 | 权限控制 | 禁止 | 禁止 | 禁止 | +| 轮询、告警、清理 | 全部 | 权限控制 | 只读建议 | 禁止 | 禁止 | +| 通知 | 全部 | 当前账号 | 当前账号 | 当前账号 | 当前客户 | + +## 三、统一认证契约 + +### 3.1 管理 Web/H5 登录 + +```http +POST /api/auth/login +Content-Type: application/json +``` + +```json +{ + "username": "账号或手机号", + "password": "密码", + "device": "web" +} +``` + +管理 H5 将 `device` 改为 `h5`。 + +成功后保存: + +```json +{ + "access_token": "...", + "refresh_token": "...", + "expires_in": 86400, + "user": { + "id": 1, + "username": "admin", + "user_type": 2, + "user_type_name": "平台用户", + "shop_id": 0, + "enterprise_id": 0 + }, + "menus": [], + "buttons": [], + "permissions": [] +} +``` + +所有受保护请求携带: + +```http +Authorization: Bearer +``` + +### 3.2 Token 刷新 + +```http +POST /api/auth/refresh-token +``` + +```json +{ + "refresh_token": "..." +} +``` + +前端请求模块需要实现单次刷新队列:多个并发请求同时收到 401 时,只允许一个请求刷新 Token,其余等待结果;刷新失败统一清除会话并跳转登录。 + +### 3.3 C 端认证 + +C 端使用 `/api/c/v1/auth/*`,不使用管理端登录或刷新 Token: + +1. `verify-asset`。 +2. `wechat-login` 或 `miniapp-login`。 +3. 必要时 `bind-phone`。 +4. 后续请求携带 C 端 Bearer Token。 +5. 认证失效重新走资产验证和微信登录。 + +## 四、响应与错误契约 + +### 4.1 统一响应 + +```json +{ + "code": 0, + "msg": "success", + "data": {}, + "timestamp": "2026-07-29T12:00:00+08:00" +} +``` + +前端成功判断必须同时尊重 HTTP 状态和业务 `code`,不能只判断 HTTP 200。 + +### 4.2 分页 + +常见请求参数为 `page`、`page_size`,常见返回为: + +```json +{ + "items": [], + "total": 0, + "page": 1, + "size": 20 +} +``` + +不同历史模块的列表 DTO 可能有差异,类型生成和页面开发必须以对应 OpenAPI Operation 为准,不能强制假设所有列表结构完全相同。 + +### 4.3 HTTP 错误处理 + +| HTTP 状态 | 前端行为 | +| --- | --- | +| 400 | 定位请求字段,展示后端安全中文提示 | +| 401 | 管理端尝试刷新;C 端重新登录 | +| 403 | 显示无权限,不重试,不猜测资源是否存在 | +| 404 | 显示资源不存在或已失效 | +| 409 | 提示状态已变化,重新拉取详情 | +| 429 | 提示操作频繁,按 `Retry-After` 或短时退避 | +| 5xx | 展示通用错误和 Request ID,允许用户手动重试 | + +## 五、数据展示契约 + +- 金额:接口整数单位通常为分,展示时格式化为元,提交时转换回分;禁止浮点数直接参与计算。 +- 状态:优先使用响应中的 `status_name`、`*_name`,不要在多个前端重复维护中文枚举。 +- 时间:按 ISO 8601 解析,统一展示为当前业务时区;提交日期范围按接口约定处理起止边界。 +- ID:前端将 ID 当作不透明标识,不参与金额或业务计算。 +- 空值:区分 `null`、空字符串、0 和空数组,不能用统一假值替换。 +- 资产标识:按字符串保存和上传,避免 ICCID 被转为科学计数法或丢失前导零。 +- 支付方式:使用 `allowed_payment_methods` 或支付方式查询接口,不写死微信/支付宝/钱包组合。 +- 状态流转:按钮是否出现先看权限和当前状态;提交后仍以后端状态机结果为准。 + +## 六、关键接口调用顺序 + +### 6.1 管理端创建订单 + +1. 解析或选择资产。 +2. 查询资产可用套餐。 +3. `POST /api/admin/orders/purchase-check`。 +4. 展示后端计算的购买条件、金额和支付方式。 +5. `POST /api/admin/orders`。 +6. 查询订单详情确认最终状态。 + +### 6.2 代理在线充值 + +1. `GET /api/admin/agent-recharges/payment-methods`。 +2. `POST /api/admin/agent-recharges`。 +3. 按响应拉起支付。 +4. 轮询 `GET /api/admin/agent-recharges/:id/payment-status`。 +5. 查询详情和主钱包流水确认到账。 + +### 6.3 企业资产授权 + +1. 查询企业详情。 +2. 查询候选卡或设备。 +3. 提交 `allocate-cards` 或 `allocate-devices`。 +4. 重新查询企业卡/设备列表。 +5. 查询授权记录确认结果。 + +设备授权由后端同步处理绑定卡,前端不得自行拆分请求。 + +### 6.4 文件上传和异步任务 + +1. `POST /api/admin/storage/upload-url`。 +2. 直接向响应的对象存储 URL 上传。 +3. 将 `file_key` 提交业务任务接口。 +4. 轮询任务详情。 +5. 完成后展示结果或下载文件。 + +### 6.5 第三方支付 + +1. 创建业务订单或充值单。 +2. 使用后端返回的支付参数/链接拉起支付。 +3. 支付平台回调只由服务端接收,前端不得调用 `/api/callback/*`。 +4. 用户返回页面后重新查询业务单状态。 +5. 结果未知时保持“处理中”,不在前端直接改为成功。 + +## 七、管理 Web/H5 的路由和权限约定 + +1. 登录后以 `menus[].url` 建立可访问路由白名单。 +2. 路由守卫同时检查登录状态和菜单权限。 +3. 按钮组件检查 `buttons`,但按钮隐藏只负责体验,不是安全门禁。 +4. Web/H5 使用同一权限码,不创建 `web_xxx`、`h5_xxx` 两套业务权限码;终端差异使用权限记录的 `platform` 字段。 +5. 不给当前终端返回的菜单不得通过手输 URL 进入。 +6. 页面加载收到 403 后应移除当前不可用操作并提示重新登录获取最新权限。 + +## 八、联调验收矩阵 + +每个管理接口至少使用以下账号验证: + +| 用例 | 超管 | 有权限平台 | 无权限平台 | 有权限代理 | 越权代理 | 企业账号 | +| --- | --- | --- | --- | --- | --- | --- | +| 菜单是否返回 | 验证 | 验证 | 不返回 | 验证 | 验证 | 验证 | +| 页面能否进入 | 验证 | 验证 | 禁止 | 验证 | 视权限 | 视权限 | +| API 能否调用 | 验证 | 验证 | 403 | 验证 | 403/空范围 | 仅目标能力 | +| 列表数据范围 | 全部 | 全部 | 无调用 | 本店及下级 | 不含平级/上级 | 仅本企业 | +| 详情越权 | 可见 | 可见 | 403 | 非范围资源 403 | 403 | 非本企业 403 | +| 写操作越权 | 可操作 | 按权限 | 403 | 仅允许范围 | 403 | 仅明确开放能力 | + +C 端接口至少覆盖:本人绑定资产、本人未绑定资产、其他客户订单、Token 被新登录替换、资产解绑、店铺禁止新 C 端登录。 + +## 九、当前后端安全缺口 + +以下问题是上线门禁,不应交给前端规避: + +1. `/api/admin` 当前统一挂载认证中间件,但没有发现逐路由普遍挂载 `RequirePermission`。 +2. 当前 `menus/buttons` 主要用于前端显示,不能证明每个接口已做相同权限校验。 +3. 部分接口明确说明按钮权限不在后端校验。 +4. 企业账号没有店铺下级范围,部分使用宽松店铺过滤的查询可能需要专项验证。 +5. 企业、企业授权、卡和设备列表需要使用真实企业 Token 做越权测试。 + +前端可以按权限正确隐藏界面,但生产上线前必须由后端补齐或验证: + +- 功能权限门禁。 +- 资源级权限校验。 +- 企业数据范围。 +- 写操作状态机和幂等。 +- 敏感配置和高风险动作的身份限制。 + +## 十、联调权威来源 + +1. 路由和 DTO:`internal/routes`、`internal/model/dto`。 +2. 机器可读契约:`docs/admin-openapi.yaml`。 +3. 业务和页面组合:`docs/前端建设`。 +4. 七月迭代新增字段:`docs/7月迭代/七月迭代实现与接口对接说明.md`。 + +发现接口与 OpenAPI 不一致时,先修正文档生成器和 DTO,不在前端编写长期兼容分支掩盖契约问题。 diff --git a/docs/前端建设/管理端页面接口矩阵.md b/docs/前端建设/管理端页面接口矩阵.md new file mode 100644 index 0000000..7180aca --- /dev/null +++ b/docs/前端建设/管理端页面接口矩阵.md @@ -0,0 +1,186 @@ +# 管理 Web 与管理 H5 页面接口矩阵 + +> 本文描述页面需要承载的业务信息和接口组合。完整请求、响应字段、校验规则和枚举以 [`docs/admin-openapi.yaml`](../admin-openapi.yaml) 为准。 + +## 一、页面生成原则 + +管理 Web 和管理 H5 都允许超级管理员、平台账号、代理账号、企业账号登录,但不按账号类型写死整套路由。 + +登录后按以下顺序生成可用界面: + +1. 使用 `user.user_type` 确定组织身份和数据范围提示。 +2. 使用后端返回的 `menus` 生成路由和导航。 +3. 使用 `buttons` 控制创建、编辑、删除、审核等操作入口。 +4. 服务端返回 403 时仍必须阻止操作,不能因为前端存在按钮就认为有权限。 +5. Web 登录传 `device=web`,管理 H5 登录传 `device=h5`。 + +管理 H5 不建议机械复制全部 Web 表格。首期应覆盖查询、现场操作、审批和通知;复杂配置、批量导入和大报表优先保留在 Web。 + +## 二、公共页面 + +| 页面 | Web | 管理 H5 | 核心字段 | 主要操作 | 接口 | +| --- | --- | --- | --- | --- | --- | +| 登录 | 必须 | 必须 | 用户名/手机号、密码、终端 | 登录、记住账号 | `POST /api/auth/login` | +| 当前账号 | 必须 | 必须 | 用户名、手机号、用户类型、店铺、企业 | 查看当前身份 | `GET /api/auth/me` | +| 修改密码 | 必须 | 必须 | 旧密码、新密码、确认密码 | 修改并重新登录 | `PUT /api/auth/password` | +| 通知中心 | 必须 | 必须 | 类型、标题、内容、风险、关联资源、时间、已读状态 | 查看目标、单条已读、全部已读 | `/api/admin/notifications/*` | +| 退出登录 | 必须 | 必须 | 无 | 注销 Token | `POST /api/auth/logout` | + +登录响应需持久化:`access_token`、`refresh_token`、`expires_in`、`user`、`menus`、`buttons`、`permissions`。权限变更后菜单不会自动刷新,应重新登录或提供“刷新会话”动作。 + +## 三、工作台建议 + +当前后端没有统一 Dashboard 接口。首期不要为了首页一次性改造后端,可使用现有轻量接口拼装: + +| 卡片 | 数据来源 | 适用说明 | +| --- | --- | --- | +| 未读通知 | `GET /api/admin/notifications/unread-summary` | 所有具备通知菜单的账号 | +| 代理资金概况 | `GET /api/admin/shops/fund-summary` | 具备代理资金菜单且非企业账号 | +| 临期资产 | `GET /api/admin/expiring-assets` | 具备资产/套餐运营权限的账号 | +| 轮询状态 | `GET /api/admin/polling-stats` | 运维角色,优先 Web | +| 待处理退款 | `GET /api/admin/refunds` | 使用状态筛选,具体权限由菜单和服务端决定 | +| 待处理换货 | `GET /api/admin/exchanges` | 使用状态筛选 | + +页面加载时各卡片独立失败、独立重试,不能因一个无权限卡片导致整个工作台失败。 + +## 四、组织与权限 + +### 4.1 账号管理 + +| 页面 | 主要查询字段 | 列表/详情字段 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 账号列表 | 用户名、手机号、用户类型、状态、店铺、企业、分页 | 用户名、手机号、用户类型名称、所属店铺/企业、状态名称、企微绑定状态、创建时间 | 新建、编辑、启停、重置密码、删除、分配角色、绑定企微 | `/api/admin/accounts*` | 查询和启停可做;复杂角色分配优先 Web | + +表单关键规则: + +- 平台账号不关联店铺或企业。 +- 代理账号关联 `shop_id`。 +- 企业账号关联 `enterprise_id`。 +- 超级管理员不分配角色;平台账号可多角色;代理和企业账号最多一个客户角色。 + +### 4.2 角色与权限 + +| 页面 | 核心字段 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | +| 角色列表/编辑 | 角色名、角色类型、状态、默认信用额度 | 新建、编辑、启停、删除 | `/api/admin/roles*` | 只读或不做 | +| 角色权限配置 | 权限树、终端 `web/h5/all`、菜单/按钮类型 | 分配、单项移除、批量移除 | `/api/admin/roles/:id/permissions*` | 不做 | +| 权限管理 | 权限名、权限码、菜单/按钮类型、适用终端、父级、路由、排序、状态 | 新建、编辑、删除 | `/api/admin/permissions*` | 不做 | + +权限记录的 `available_for_role_types` 区分平台角色和客户角色;代理、企业均使用客户角色,不应按“代理端菜单”硬编码。 + +### 4.3 店铺 + +| 页面 | 主要查询字段 | 列表/详情字段 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 店铺列表 | 关键词、店铺编号、联系人手机号、状态、层级、父店铺、分页 | 店铺名、编号、层级、上级、联系人、地址、业务员、状态、C端登录限制 | 创建、编辑、删除、查看详情 | `GET|POST /api/admin/shops`、`GET|PUT|DELETE /api/admin/shops/:id` | 列表、详情可做;复杂建档优先 Web | +| 店铺级联选择 | 关键词、父节点 | 店铺 ID、名称、层级、子节点 | 选择目标店铺 | `GET /api/admin/shops/cascade` | 必须复用 | +| 店铺默认角色 | 店铺 ID | 已分配客户角色 | 分配、移除 | `/api/admin/shops/:shop_id/roles*` | 不做或只读 | +| 店铺授信 | 店铺 ID | 现金余额、信用额度、总可用、欠款 | 调整信用额度 | `PUT /api/admin/shops/:id/credit-limit` | 可做但必须二次确认 | + +企业账号不得进入店铺管理。代理账号只允许管理本店及下级店铺,能否创建和修改仍取决于菜单、按钮和服务端校验。 + +## 五、企业与授权 + +| 页面 | 主要查询字段 | 列表/详情字段 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 企业列表 | 名称、编号、联系人、状态、归属店铺、分页 | 企业名、编号、归属店铺、联系人、地址、状态、企业账号 | 创建、编辑、启停、重置企业密码 | `/api/admin/enterprises*` | 查询和详情可做 | +| 企业卡授权 | 企业 ID、卡关键词、状态、分页 | ICCID/虚拟号、运营商、归属店铺、授权状态、授权时间 | 分配、回收 | `/api/admin/enterprises/:id/allocate-cards`、`recall-cards`、`cards` | 现场授权可做 | +| 企业设备授权 | 企业 ID、设备关键词、状态、分页 | 虚拟号、IMEI、SN、型号、归属店铺、授权状态、绑定卡 | 分配、回收 | `/api/admin/enterprises/:id/allocate-devices`、`recall-devices`、`devices` | 现场授权可做 | +| 授权记录 | 企业、资产类型、资产标识、授权状态、时间、分页 | 企业、资产摘要、授权人、授权时间、回收人、回收时间、备注 | 详情、修改备注 | `/api/admin/authorizations*` | 列表和详情可做 | + +企业授权不改变卡或设备的店铺归属。设备授权时,后端会同步处理其绑定卡;前端只提交设备选择结果,不自行拆成多次卡授权。 + +## 六、资产 + +### 6.1 统一资产工作台 + +| 页面 | 输入/筛选 | 需要展示 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 资产快速查询 | ICCID、虚拟号、MSISDN、IMEI、SN | 资产类型、主标识、归属店铺、企业授权、业务状态、网络状态、实名、当前套餐、余额、换货链 | 进入详情 | `GET /api/admin/assets/resolve/:identifier` | 必须 | +| 资产详情 | 资产标识 | 实时状态、套餐、当前套餐、钱包、订单、操作日志 | 刷新、停机、复机、停用、修改实名/轮询、调整套餐用量/到期时间 | `/api/admin/assets/:identifier/*` | 必须,但高风险动作二次确认 | +| 分配记录 | 单号、资产类型、来源、目标、状态、时间、分页 | 分配单号、来源/目标、总数、成功数、失败数、操作人 | 查看详情 | `/api/admin/asset-allocation-records*` | 查询可做 | +| 临期资产 | 资产类型、关键词、店铺、套餐、剩余天数、日期、分页 | 资产、套餐、预计最终到期、剩余天数、临期级别、优先标记 | 跳转资产、手动扫描 | `/api/admin/expiring-assets*` | 列表可做,扫描优先 Web | + +### 6.2 IoT 卡 + +| 页面 | 主要查询字段 | 需要展示 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 独立卡列表 | ICCID/虚拟号/MSISDN、运营商、店铺、状态、实名、系列、分页 | 标识、运营商、店铺、流量、网络/实名/业务状态、系列、轮询状态 | 分配、回收、批量实名策略、批量系列绑定、实名链接、固定档位限速 | `/api/admin/iot-cards/*` | 查询、分配、实名链接可做;导入和批量配置优先 Web | +| 卡导入任务 | 任务号、状态、分页 | 文件、总数、成功/失败数、状态、失败原因、时间 | 上传、创建任务、查看详情 | `/api/admin/iot-cards/import*` | 不做 | + +固定档位限速只适用于 IoT 卡,设备页面不得出现限速按钮。 + +### 6.3 设备 + +| 页面 | 主要查询字段 | 需要展示 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 设备列表 | 虚拟号、IMEI、SN、店铺、状态、实名、在线状态、系列、分页 | 设备标识、型号、店铺、在线状态、业务状态、实名策略、系列、卡槽摘要 | 分配、回收、绑定/解绑卡、实名策略、系列绑定、删除 | `/api/admin/devices*` | 查询、分配、卡槽操作可做 | +| 设备控制 | 设备标识 | 网关卡槽、WiFi、切卡模式、在线状态、最后同步 | WiFi、切卡、切换模式、重启、恢复出厂 | `/api/admin/devices/by-identifier/:identifier/*` | 必须,危险操作二次确认 | +| 设备导入/批量分配任务 | 任务类型、状态、分页 | 文件、操作类型、目标、总数、成功/失败数、错误明细 | 上传、导入、批量分配、查看任务 | `/api/admin/devices/import*` | 不做 | + +## 七、运营商、套餐与分销 + +| 页面 | 主要字段 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | +| 运营商 | 名称、类型、接口配置、状态 | CRUD、启停 | `/api/admin/carriers*` | 不做 | +| 套餐系列 | 名称、编码、佣金触发规则、状态 | CRUD、启停 | `/api/admin/package-series*` | 只读 | +| 套餐 | 系列、名称、类型、周期、流量、成本价、零售价、上下架、有效期基准 | CRUD、启停、上下架、调价 | `/api/admin/packages*` | 查询可做 | +| 套餐用量明细 | 套餐使用 ID、日期范围 | 每日使用量、剩余量 | 查询 | `GET /api/admin/package-usage/:id/daily-records` | 可做 | +| 系列授权 | 目标店铺、系列、允许套餐、状态 | 创建、编辑、删除、批量管理套餐 | `/api/admin/shop-series-grants*` | 查询可做,配置优先 Web | +| 套餐批量分配 | 目标店铺、套餐列表、成本价、零售价、上下架、有效期覆盖 | 批量分配 | `POST /api/admin/shop-package-batch-allocations` | 不做 | +| 套餐批量定价 | 目标店铺、套餐和价格 | 批量调价 | `POST /api/admin/shop-package-batch-pricing` | 不做 | + +## 八、订单与售后 + +| 页面 | 主要查询字段 | 需要展示 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 订单列表/详情 | 订单号、资产、店铺、状态、支付方式、购买角色、时间、分页 | 订单号、资产、套餐、买卖方、金额、实付、支付/订单状态、来源、审批/退款摘要 | 购买校验、创建、取消 | `/api/admin/orders*` | 列表、详情、现场代购可做 | +| 退款 | 退款号、订单号、资产、店铺、状态、审批状态、提交人、时间、分页 | 申请金额、实付、原因、凭证、审批渠道/状态、套餐权益结果 | 创建、通过、驳回、退回、重新提交 | `/api/admin/refunds*` | 查询、提交、审批可做 | +| 换货 | 旧资产、新资产、店铺、状态、提交人、时间、分页 | 新旧资产、收货信息、物流、状态时间线、迁移结果 | 创建、发货、完成、取消、续期 | `/api/admin/exchanges*` | 查询、发货、完成可做 | +| 批量购买套餐 | 文件、套餐、支付方式、凭证 | 任务状态、逐行资产、订单结果、失败原因 | 上传、创建任务、查询详情 | `/api/admin/asset-package-batch-orders*` | 不做 | +| 套餐失效任务 | 订单、任务状态、时间、分页 | 任务状态、处理结果和失败原因 | 创建、查询 | `/api/admin/order-package-invalidate-tasks*` | 不做 | + +企微审批启用后,前端只读展示 `approval_provider`、`approval_status`、`approval_status_name`;存在企微审批实例时,不再显示旧人工通过、驳回或线下确认按钮。 + +## 九、代理资金业务 + +“代理资金”是管理系统中的业务模块,不是独立前端。账号是否可见由权限控制,企业账号应禁止访问。 + +| 页面 | 主要查询字段 | 需要展示 | 操作 | 接口 | H5建议 | +| --- | --- | --- | --- | --- | --- | +| 店铺资金概况 | 店铺、欠款、状态、分页 | 现金余额、冻结金额、信用额度、总可用、欠款、佣金 | 查看店铺明细、调额 | `GET /api/admin/shops/fund-summary` | 必须 | +| 主钱包流水 | 店铺、类型、时间、分页 | 变动金额、前后余额、关联业务、资产、操作人 | 查看关联业务 | `GET /api/admin/shops/:shop_id/main-wallet/transactions` | 必须 | +| 佣金明细/统计 | 店铺、类型、状态、时间、分页 | 订单、来源、佣金类型、金额、状态、每日趋势 | 查看、修正待审记录 | `/api/admin/shops/:shop_id/commission-*` | 必须 | +| 提现申请 | 店铺、状态、时间、分页 | 申请金额、手续费、实付、收款信息、冻结状态、审批结果 | 代理提交、平台审批/驳回 | `/shops/:shop_id/withdrawal-requests`、`/commission/withdrawal-requests*` | 必须 | +| 提现配置 | 最低金额、每日次数、手续费率、生效状态 | 新建配置、查看当前和历史 | `/api/admin/commission/withdrawal-settings*` | 不做 | +| 代理充值 | 店铺、充值号、方式、状态、审批状态、时间、分页 | 金额、支付方式、支付状态、凭证、提交人、审批状态 | 在线充值、线下代充值、查询支付、线下确认、驳回 | `/api/admin/agent-recharges*` | 必须 | + +在线充值创建后使用 `GET /agent-recharges/:id/payment-status` 轮询本地支付和到账状态。 + +## 十、系统配置、集成与运维 + +| 页面 | 主要内容 | 接口 | H5建议 | +| --- | --- | --- | --- | +| 微信支付配置 | 配置列表、生效配置、启停 | `/api/admin/wechat-configs*` | 不做 | +| 系统配置 | 注册状态、Key、值、说明 | `/api/admin/system-configs*` | 不做 | +| 企业微信审批配置 | 应用、连接测试、成员同步、默认发起人、模板解析、场景映射 | `/api/admin/wecom*` | 不做 | +| 超管操作密码 | 是否已设置、重新设置 | `/api/admin/super-admin/operation-password*` | 可做但仅超管 | +| 导出任务 | 场景、筛选快照、状态、文件、失败原因 | `/api/admin/export-tasks*` | 查询和下载可做 | +| 对象存储 | 上传用途、文件名、类型、大小;批量下载对象 Key | `/api/admin/storage*` | 上传凭证可做 | +| 轮询配置/监控 | 配置、并发、队列、任务、初始化进度、手动触发 | `/api/admin/polling-*` | 监控可做,配置优先 Web | +| 告警与清理 | 告警规则/历史、清理配置/预览/进度/日志 | `/api/admin/polling-alert-*`、`/api/admin/data-cleanup*` | 告警查看可做,配置不做 | + +## 十一、管理 H5 首期建议 + +管理 H5 首期建议只实现以下任务型页面: + +1. 登录、当前账号、修改密码、通知。 +2. 工作台待办。 +3. 统一资产搜索和详情。 +4. 卡/设备列表、状态查看和必要现场操作。 +5. 订单、退款、换货列表和详情。 +6. 代理资金概况、充值、佣金和提现。 +7. 企业卡/设备授权。 +8. 导出文件下载和异步任务结果查看。 + +账号、角色、权限、运营商、套餐复杂配置、企微配置、轮询配置、数据清理、批量导入优先放在 Web。若后续业务确认移动端必须配置,再按权限增加,不提前复制整套页面。