Files
junhong_cmp_fiber/docs/前端建设/权限矩阵与接口联调契约.md
break 5ba227eff5
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 1m8s
111
2026-07-29 14:58:28 +08:00

307 lines
12 KiB
Markdown
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.
# 权限矩阵与接口联调契约
## 一、管理端权限计算模型
管理页面和操作的最终可用性不是只看 `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 <access_token>
```
### 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不在前端编写长期兼容分支掩盖契约问题。