fix: 真流量虚流量权限
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m42s

This commit is contained in:
sexygoat
2026-05-14 10:52:11 +08:00
parent 1690252740
commit 38cf7d12e9
29 changed files with 859 additions and 198 deletions

View File

@@ -0,0 +1,47 @@
# Change: 列表状态字段无权限时改为隐藏而不是禁用
## Why
当前多个列表页对“状态 / 上架状态 / 激活状态”采用 `disabled` 开关来处理无权限用户。这样虽然阻止了正常点击,但仍然暴露了前端交互控件,既不符合“无权限不应展示操作入口”的权限体验,也会引发对 DOM 篡改后是否还能触发接口调用的安全疑虑。
业务现在明确要求:对于列表中的状态类交互字段,如果用户没有对应权限,则前端直接隐藏该字段,不再显示禁用态开关。
## What Changes
- 将以下列表页中的状态类交互字段统一从“无权限时禁用”改为“无权限时隐藏”:
- 角色管理:`role:update_status`
- 运营商管理:`carrier:update_status`
- 套餐系列:`package_series:update_status`
- 套餐列表-状态:`package:update_status`
- 套餐列表-上架状态:`package:update_away`
- 代理系列授权:`series_grants:update_status`
- 店铺列表:`shop:modify_status`
- 账号列表:`account:modify_status`
- 企业客户:`enterprise_customer:status`
- 微信配置-激活状态:`wechat_config:status`
- 对于无权限用户:
- 前端列表中不再渲染对应状态字段/列
- 前端不再渲染 disabled 的 `ElSwitch` 或其他禁用态交互控件作为占位
- 对于有权限用户:
- 保持现有状态切换交互与接口调用行为不变
- 套餐列表需要将“状态”和“上架状态”视为两个独立权限入口分别控制显示
- 本次仅调整列表页中的状态类交互字段展示策略,不修改搜索栏状态筛选项,也不扩展到详情页或新增/编辑弹窗中的表单字段
- 前端隐藏仅作为 UI 层权限收敛,不能替代后端接口鉴权;后端仍需继续拒绝无权限的直接状态更新请求
## Impact
- Affected specs:
- `list-status-permission-visibility`
- Affected code:
- `src/views/system/role/index.vue`
- `src/views/system/carrier-management/index.vue`
- `src/views/package-management/package-series/index.vue`
- `src/views/package-management/package-list/index.vue`
- `src/views/package-management/series-grants/index.vue`
- `src/views/shop-management/list/index.vue`
- `src/views/account-management/account/index.vue`
- `src/views/account-management/enterprise-customer/index.vue`
- `src/views/settings/wechat-config/index.vue`
- Dependencies:
- 现有 `useAuth` / `hasAuth` 权限判断
- 现有后端状态更新接口权限校验

View File

@@ -0,0 +1,59 @@
## ADDED Requirements
### Requirement: List Status Controls Must Be Hidden Without Permission
The system SHALL hide list-level status mutation fields from users who do not have the corresponding update permission, instead of rendering disabled switches or other disabled interactive controls.
This rule MUST apply to the following list pages and permission mappings:
- `角色管理` -> `role:update_status` -> `状态`
- `运营商管理` -> `carrier:update_status` -> `状态`
- `套餐系列` -> `package_series:update_status` -> `状态`
- `套餐列表` -> `package:update_status` -> `状态`
- `套餐列表` -> `package:update_away` -> `上架状态`
- `代理系列授权` -> `series_grants:update_status` -> `状态`
- `店铺列表` -> `shop:modify_status` -> `状态`
- `账号列表` -> `account:modify_status` -> `状态`
- `企业客户` -> `enterprise_customer:status` -> `状态`
- `微信配置` -> `wechat_config:status` -> `激活状态`
When the current user lacks the corresponding permission on one of the pages above, the page MUST NOT render the corresponding status field/column, and MUST NOT render a disabled `ElSwitch` or equivalent disabled interactive control in its place.
When the current user has the corresponding permission, the page MUST continue to render the existing status control and MUST preserve the current status update workflow.
This requirement only applies to list-level interactive status fields. Search filters, detail pages, and create/edit dialogs are outside the scope of this change.
Frontend hiding MUST NOT be treated as sufficient authorization. The system MUST continue to rely on backend permission checks for any status update API request.
#### Scenario: Render status field when the user has permission
- **GIVEN** 用户进入上述任一列表页
- **AND** 用户拥有该页面对应的状态更新权限
- **WHEN** 页面渲染列表
- **THEN** 页面 MUST 显示对应的状态类交互字段
- **AND** 页面 MUST 继续允许用户按现有流程发起状态更新
#### Scenario: Hide status field instead of disabling it when the user lacks permission
- **GIVEN** 用户进入 `角色管理``运营商管理``套餐系列``代理系列授权``店铺列表``账号列表``企业客户``微信配置` 列表页之一
- **AND** 用户不拥有该页面对应的状态更新权限
- **WHEN** 页面渲染列表
- **THEN** 页面 MUST NOT 显示对应的状态字段或列
- **AND** 页面 MUST NOT 显示 disabled 的状态开关作为占位
#### Scenario: Package list hides only the unauthorized status field
- **GIVEN** 用户进入 `套餐列表`
- **WHEN** 页面渲染列表
- **THEN** 若用户缺少 `package:update_status`,页面 MUST 隐藏 `状态` 字段
- **AND** 若用户缺少 `package:update_away`,页面 MUST 隐藏 `上架状态` 字段
- **AND** 页面 MUST 仅显示用户已被授权的状态类字段
- **AND** 页面 MUST NOT 用 disabled 开关展示未授权字段
#### Scenario: Backend authorization remains mandatory
- **GIVEN** 用户在前端列表页看不到某个状态更新入口
- **AND** 用户仍尝试通过直接构造请求或篡改页面 DOM 发起状态更新
- **WHEN** 请求到达状态更新接口
- **THEN** 系统 MUST 继续依赖后端权限校验来决定是否放行
- **AND** 前端隐藏行为 MUST NOT 被视为接口层放行依据

View File

@@ -0,0 +1,14 @@
## 1. Implementation
- [x] 1.1 梳理 9 个页面当前状态字段的 disabled 实现入口,统一改造为按权限动态隐藏字段/列
- [x] 1.2 在角色管理页中,无 `role:update_status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.3 在运营商管理页中,无 `carrier:update_status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.4 在套餐系列页中,无 `package_series:update_status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.5 在套餐列表页中,无 `package:update_status` 时隐藏“状态”字段;无 `package:update_away` 时隐藏“上架状态”字段
- [x] 1.6 在代理系列授权页中,无 `series_grants:update_status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.7 在店铺列表页中,无 `shop:modify_status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.8 在账号列表页中,无 `account:modify_status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.9 在企业客户页中,无 `enterprise_customer:status` 时隐藏状态字段,不再渲染禁用态开关
- [x] 1.10 在微信配置页中,无 `wechat_config:status` 时隐藏“激活状态”字段,不再渲染禁用态开关
- [x] 1.11 验证各页面在有权限时现有状态切换与接口调用行为保持不变
- [ ] 1.12 验证各页面在无权限时不再出现 disabled 状态控件,且前端隐藏不会被当作后端鉴权的替代