diff --git a/.gitignore b/.gitignore index c4c664d..b9a19d7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ /target /.claude/ /classpath.txt + +# 规划临时文件(仅本地使用) +/findings.md +/progress.md +/task_plan.md diff --git a/findings.md b/findings.md deleted file mode 100644 index a845a42..0000000 --- a/findings.md +++ /dev/null @@ -1,150 +0,0 @@ -# OARMS 权限体系设计 — 发现记录 - -## 现有代码分析 - -### 1. Sa-Token 框架集成现状 - -**配置**(application.yml): -- token-name: `satoken` -- timeout: 2592000s(30 天) -- token-style: UUID -- is-concurrent: true(允许并发登录) - -**拦截器**(SpringMvcConfig): -- 已注册 SaInterceptor -- 当前仅 `StpUtil.checkLogin()`,无角色/权限校验 -- 白名单路径: `/user/auth/**`, `/test/**`, `/doc.html**`, `/swagger*`, `/cms/**`, `/network/ping` -- 注释掉了按路由模块的权限检查(TODO) - -### 2. 认证流程现状 - -**LoginController**: -- POST `/user/auth/login` — 硬编码 userId,无密码校验,admin 权限 -- GET `/user/auth/login/info` — 从 session 取 UserBase -- GET `/user/auth/logout` — StpUtil.logout() -- GET `/user/auth/perm/list` — StpUtil.getPermissionList()(返回空列表) - -**UserBaseServiceImpl**: -- login() — 返回 null(未实现) -- getCurrentUser() — 从 SaSession 取,异常时返回 guest -- getUserInfoByLoginId() — 返回 null - -### 3. 框架 UserBase 类 - -**来源**: youfool-framework-springboot3:1.0.4 -**包**: com.chinaweal.youfool.framework.springboot.user.entity.UserBase -**已知字段**: username (String), permission (Set) -**已知方法**: setUsername(), setPermission() - -**限制**: UserBase 字段较少,不满足 PRD 需求(需要 realName, roles, districtCode, orgName 等) -**方案**: 创建 LoginUserVO 扩展返回信息,session 中存储 LoginUserVO 替代 UserBase - -### 4. 前端权限现状 - -**user.js store**: -- 登录响应取 headers 中的 satoken -- getInfo() 获取用户信息(userId, username, role, permission, nickname) -- roles 从 `data.role` 或 `data.permission` 转数组 - -**permission.js store**: -- `hasPermission(roles, route)` — 检查 route.meta.roles -- admin 角色直接放行所有路由 -- 非 admin 按角色过滤 - -**routes.js**: -- constantRoutes: login, home, 404(roles: ['guest']) -- asyncRoutes: 业务路由,**无 roles 配置**(依赖 admin 全通) - -### 5. PRD 权限矩阵(各模块详细) - -#### BS-1 大屏基础信息 - -| 操作 | 市局 | 区局 | 运营商 | -|------|------|------|--------| -| 查看列表 | 全市 | 本辖区 | 本公司 | -| 新增 | Y | N | Y(本公司) | -| 编辑 | Y | N | Y(本公司) | -| 删除 | Y | N | N | -| 导出 | 全市 | 本辖区 | N | - -#### AM-1 录屏设置 - -| 操作 | 市局 | 区局 | 运营商 | -|------|------|------|--------| -| 查看配置 | 全市 | 本辖区 | 本公司 | -| 新增/编辑 | Y | N | N | - -#### AM-3 画面监控 - -| 操作 | 市局 | 区局 | 运营商 | -|------|------|------|--------| -| 查看监控 | 全市 | 本辖区 | 无权限 | -| 处理监控 | Y | Y(本辖区) | 无权限 | - -#### MR-1 监测规则 - -| 操作 | 市局 | 区局 | 运营商 | -|------|------|------|--------| -| 查看规则 | Y | Y(只读) | 无权限 | -| 增删改 | Y | N | N | - -#### CW-1~CW-4 预警流程 - -| 操作 | 市局 | 区局 | 运营商 | -|------|------|------|--------| -| 全部操作 | 全市 | 本辖区 | 无权限 | - -### 6. 技术选型决策 - -| 决策点 | 选择 | 理由 | -|--------|------|------| -| 密码加密 | BCrypt | Spring Security 默认,安全可靠 | -| 权限模型 | RBAC + 数据权限 | PRD 要求操作权限 + 数据范围 | -| 权限粒度 | 模块:操作(如 screen:create) | 覆盖 PRD 全部场景 | -| 数据权限 | Service 层动态过滤 | 不引入 AOP 复杂度 | -| Session 存储 | SaSession 存 LoginUserVO | 复用现有 Sa-Token 机制 | -| 前端按钮控制 | v-permission 指令 | Element Plus 生态常见方案 | - -### 7. 包路径规划 - -系统管理模块放在 `modules/system/` 下: - -``` -com.chinaweal.youfool.prj.modules.system/ -├── entity/ # SysUser/SysRole/SysPermission 等 -├── mapper/ -├── service/ -└── controller/ -``` - -与其他业务模块(screen, law, rule, monitor, evidence)平级。 - -### 8. 数据权限实现思路 - -数据权限需要在查询时动态追加条件: - -```java -// 在 Service 层 -LoginUserVO user = (LoginUserVO) StpUtil.getSession().get(USER_KEY); - -if (user.getRoles().contains("CITY_SUPERVISOR")) { - // 不过滤 -} else if (user.getRoles().contains("DISTRICT_SUPERVISOR")) { - query.setDistrictCode(user.getDistrictCode()); -} else if (user.getRoles().contains("OPERATOR")) { - query.setOrgName(user.getOrgName()); -} -``` - -**影响范围**: 现有 10 个模块的 query 方法可能需要增加 districtCode/orgName 参数。 -**DDL 确认**: 现有表(如 bs_screen)已有 district 字段,可以用于辖区过滤。org_name 可通过大屏关联的业主/运营单位匹配。 - ---- - -## 风险与注意事项 - -1. **框架 UserBase 限制**: UserBase 字段少,需要扩展或替换 session 存储对象 -2. **现有接口兼容**: /user/auth/login/info 返回类型改变可能影响前端 -3. **数据权限复杂度**: 区局按辖区、运营商按公司,过滤条件不同 -4. **密码策略**: 初始密码、密码强度要求需确认 -5. **Swagger 分组**: 新增 system 模块需要加 springdoc 分组配置 diff --git a/progress.md b/progress.md deleted file mode 100644 index 0ed2bbe..0000000 --- a/progress.md +++ /dev/null @@ -1,101 +0,0 @@ -# OARMS 权限体系设计 — 进度日志 - -## 当前状态 - -**阶段**: 第一轮完成(Phase 1-3 + Phase 7 编译验证) -**进度**: Phase 1/2/3/7 已完成 - ---- - -## 阶段进度 - -| 阶段 | 状态 | 备注 | -|------|------|------| -| Phase 1: DDL 设计 | ✅ 完成 | 5 张表 + 初始数据 | -| Phase 2: Entity/Mapper | ✅ 完成 | system 模块 5 Entity + 5 Mapper + 2 Service | -| Phase 3: 认证流程 | ✅ 完成 | LoginController + StpInterfaceImpl + UserBaseServiceImpl | -| Phase 4: 鉴权+数据权限 | ✅ 完成 | 9 Controller 28 个方法添加 @SaCheckPermission | -| Phase 5: 前端角色路由 | ✅ 完成 | routes.js + permission.js + user.js + v-permission | -| Phase 6: 用户管理接口 | pending | 可选 | -| Phase 7: 编译验证 | ✅ 完成 | BUILD SUCCESS | - ---- - -## 会话记录 - -### 2026-05-24 — 权限体系规划 - -**操作**: -1. 检查现有登录/用户模块实现 → 发现全部 TODO 未实现 -2. 确认 PRD 中有角色定义 → 第三章 3 个角色 + 操作权限 + 数据权限 -3. 研究后端代码 → Sa-Token 已集成,StpInterfaceImpl/LoginController/UserBaseServiceImpl 均未实现 -4. 研究前端代码 → 角色/路由框架存在,但仅 admin/guest -5. 研究框架 UserBase → 字段有限(username, permission),需扩展 - -**结论**: -- 现有代码是认证骨架,核心逻辑全部 TODO -- PRD 定义了 3 角色 × 操作权限 + 数据权限的完整 RBAC 模型 -- 需从 DDL → Entity/Mapper → Service → Controller → 前端全链路实现 - -**设计决策**: -- 5 张新表:SYS_USER, SYS_ROLE, SYS_USER_ROLE, SYS_PERMISSION, SYS_ROLE_PERMISSION -- 新模块路径:modules/system/ -- 权限码格式:`module:action`(如 screen:create) -- 数据权限:Service 层按角色动态追加查询条件 -- Session 存储:LoginUserVO 替代 UserBase - -### 2026-05-24 — 第一轮执行(Phase 1-3 + 7) - -**创建的文件**: - -| 文件 | 说明 | -|------|------| -| `docs/db/sql/V11.0.0__SYS_system_ddl.sql` | 5 张表 DDL | -| `docs/db/sql/V11.0.0__SYS_system_init_data.sql` | 3 角色 + 27 权限 + 3 用户 | -| `modules/system/entity/SysUserEntity.java` | 用户实体 | -| `modules/system/entity/SysRoleEntity.java` | 角色实体 | -| `modules/system/entity/SysUserRoleEntity.java` | 用户角色关联实体 | -| `modules/system/entity/SysPermissionEntity.java` | 权限实体 | -| `modules/system/entity/SysRolePermissionEntity.java` | 角色权限关联实体 | -| `modules/system/entity/vo/LoginUserVO.java` | 登录用户信息 VO | -| `modules/system/entity/vo/SysUserVO.java` | 用户管理 VO | -| `modules/system/entity/query/SysUserQuery.java` | 用户查询条件 | -| `modules/system/mapper/SysUserMapper.java` | 用户 Mapper | -| `modules/system/mapper/SysRoleMapper.java` | 角色 Mapper(含自定义 SQL) | -| `modules/system/mapper/SysUserRoleMapper.java` | 用户角色关联 Mapper | -| `modules/system/mapper/SysPermissionMapper.java` | 权限 Mapper(含自定义 SQL) | -| `modules/system/mapper/SysRolePermissionMapper.java` | 角色权限关联 Mapper | -| `modules/system/service/ISysUserService.java` | 用户 Service 接口 | -| `modules/system/service/ISysRoleService.java` | 角色 Service 接口 | -| `modules/system/service/impl/SysUserServiceImpl.java` | 用户 Service 实现 | -| `modules/system/service/impl/SysRoleServiceImpl.java` | 角色 Service 实现 | -| `config/PasswordConfig.java` | BCrypt 密码加密 Bean | - -**修改的文件**: - -| 文件 | 变更 | -|------|------| -| `controller/LoginController.java` | 数据库认证替代硬编码,返回 LoginUserVO | -| `service/impl/StpInterfaceImpl.java` | 对接 SysRoleMapper/SysPermissionMapper | -| `service/impl/UserBaseServiceImpl.java` | 从 LoginUserVO 转换 UserBase | -| `pom.xml` | 添加 spring-security-crypto 依赖 | - -**编译错误与修复**: - -| 错误 | 修复 | -|------|------| -| `lambdaQuery()` 不存在 | ISysUserService 不继承 IService,改用 SysUserMapper 直接查询 | -| `RestResult.fail()` 不存在 | 框架只有 `RestResult.ok()`,改用 `AssertUtils.isTrue()` | -| `AssertUtils.isTrue(boolean, String)` 签名不匹配 | 改为三参数 `isTrue(boolean, ResultCode, String)` | - -**编译结果**: BUILD SUCCESS - ---- - -## 遇到的错误 - -| 错误 | 尝试次数 | 解决方案 | -|------|---------|---------| -| lambdaQuery() 在 ISysUserService 上不存在 | 1 | 改用 SysUserMapper.selectOne() | -| RestResult.fail() 方法不存在 | 1 | 用 AssertUtils.isTrue() 替代 | -| AssertUtils.isTrue(boolean, String) 签名不匹配 | 1 | 改为 isTrue(boolean, ResultCode, String) | diff --git a/task_plan.md b/task_plan.md deleted file mode 100644 index ed16f5d..0000000 --- a/task_plan.md +++ /dev/null @@ -1,389 +0,0 @@ -# OARMS 权限体系设计与实现计划 - -## 目标 - -基于 PRD 第三章"角色权限"定义,设计并实现完整的 RBAC + 数据权限体系,覆盖后端认证/鉴权 + 前端路由/按钮控制。 - -## PRD 角色定义 - -| 角色 | 角色代码 | 操作范围 | 数据范围 | -|------|---------|---------|---------| -| 市局广告监管人员 | `CITY_SUPERVISOR` | 全模块读写 | 全市数据 | -| 区局广告监管人员 | `DISTRICT_SUPERVISOR` | 监控/取证/规则只读 | 本辖区数据 | -| 广告大屏运营商 | `OPERATOR` | 大屏维护/录屏查看 | 本公司大屏数据 | - -## 当前状态 - -| 组件 | 现状 | 缺失 | -|------|------|------| -| Sa-Token 框架 | 已集成,拦截器已配置 | 仅 checkLogin,无角色/权限校验 | -| LoginController | 硬编码 userId,admin 权限 | 无数据库校验 | -| StpInterfaceImpl | 返回空列表 | 未对接数据库 | -| UserBaseServiceImpl | login() 返回 null | 未实现 | -| 数据库 | 无用户/角色表 | 需建表 | -| 前端路由 | 仅 admin/guest | 需增加 3 个角色 | -| 前端权限守卫 | admin 全通 | 需角色过滤 | - ---- - -## 实现阶段(7 个 Phase) - -### Phase 1:数据库设计 — 用户/角色/权限表(DDL) - -在 OARMS schema 下创建系统管理相关表,表前缀 `sys_`。 - -**表设计**: - -#### 1.1 `SYS_USER` 用户表 - -| 列名 | 类型 | 说明 | -|------|------|------| -| ID | VARCHAR(32) PK | UUID | -| USERNAME | VARCHAR(50) NOT NULL UNIQUE | 登录用户名 | -| PASSWORD | VARCHAR(100) NOT NULL | BCrypt 加密密码 | -| REAL_NAME | VARCHAR(50) | 真实姓名 | -| PHONE | VARCHAR(20) | 联系电话 | -| ORG_NAME | VARCHAR(100) | 所属单位 | -| DISTRICT_CODE | VARCHAR(20) | 所属区域编码(区局/运营商用) | -| STATUS | TINYINT DEFAULT 1 | 1=正常 0=停用 | -| + SuperEntity 审计字段 | | createBy/createTime/updateBy/updateTime/updateName | - -#### 1.2 `SYS_ROLE` 角色表 - -| 列名 | 类型 | 说明 | -|------|------|------| -| ID | VARCHAR(32) PK | UUID | -| ROLE_CODE | VARCHAR(30) NOT NULL UNIQUE | 角色编码(CITY_SUPERVISOR 等) | -| ROLE_NAME | VARCHAR(50) NOT NULL | 角色显示名 | -| DESCRIPTION | VARCHAR(200) | 描述 | -| STATUS | TINYINT DEFAULT 1 | 1=正常 0=停用 | -| + SuperEntity 审计字段 | | | - -#### 1.3 `SYS_USER_ROLE` 用户角色关联表 - -| 列名 | 类型 | 说明 | -|------|------|------| -| ID | VARCHAR(32) PK | UUID | -| USER_ID | VARCHAR(32) NOT NULL | 关联 SYS_USER.ID | -| ROLE_ID | VARCHAR(32) NOT NULL | 关联 SYS_ROLE.ID | -| + createBy/createTime | | | - -#### 1.4 `SYS_PERMISSION` 权限表(操作权限码) - -| 列名 | 类型 | 说明 | -|------|------|------| -| ID | VARCHAR(32) PK | UUID | -| PERM_CODE | VARCHAR(50) NOT NULL UNIQUE | 权限编码(如 `screen:view`、`evidence:create`) | -| PERM_NAME | VARCHAR(100) NOT NULL | 权限名称 | -| MODULE | VARCHAR(30) | 所属模块(BS/LB/AM/MR/CW) | -| + SuperEntity 审计字段 | | | - -#### 1.5 `SYS_ROLE_PERMISSION` 角色权限关联表 - -| 列名 | 类型 | 说明 | -|------|------|------| -| ID | VARCHAR(32) PK | UUID | -| ROLE_ID | VARCHAR(32) NOT NULL | 关联 SYS_ROLE.ID | -| PERM_ID | VARCHAR(32) NOT NULL | 关联 SYS_PERMISSION.ID | -| + createBy/createTime | | | - -#### 1.6 初始数据 - -3 条角色 + 3 条管理员用户(各角色 1 个)+ 权限码 + 角色权限映射。 - -**权限码清单**(按模块): - -| 权限码 | 说明 | 市局 | 区局 | 运营商 | -|--------|------|------|------|--------| -| `screen:view` | 查看大屏 | Y | Y(本辖区) | Y(本公司) | -| `screen:create` | 新增大屏 | Y | N | Y(本公司) | -| `screen:edit` | 编辑大屏 | Y | N | Y(本公司) | -| `screen:remove` | 删除大屏 | Y | N | N | -| `screen:export` | 导出大屏 | Y | Y(本辖区) | N | -| `law:view` | 查看法律条款 | Y | Y | Y | -| `law:create` | 新增条款 | Y | N | N | -| `law:edit` | 编辑条款 | Y | N | N | -| `law:remove` | 删除条款 | Y | N | N | -| `monitoring-rule:view` | 查看规则 | Y | Y | N | -| `monitoring-rule:create` | 新增规则 | Y | N | N | -| `monitoring-rule:edit` | 编辑规则 | Y | N | N | -| `monitoring-rule:remove` | 删除规则 | Y | N | N | -| `recording-config:view` | 查看录屏配置 | Y | Y(本辖区) | Y(本公司) | -| `recording-config:create` | 新增录屏配置 | Y | N | N | -| `recording-config:edit` | 编辑录屏配置 | Y | N | N | -| `recording-task:view` | 查看录屏任务 | Y | Y(本辖区) | Y(本公司) | -| `monitor-record:view` | 查看监控记录 | Y | Y(本辖区) | N | -| `monitor-record:handle` | 处理监控 | Y | Y(本辖区) | N | -| `evidence:view` | 查看取证 | Y | Y(本辖区) | N | -| `evidence:create` | 固化取证 | Y | Y(本辖区) | N | -| `evidence-relation:view` | 查看规则关联 | Y | Y(本辖区) | N | -| `evidence-relation:bind` | 关联规则 | Y | Y(本辖区) | N | -| `monitoring-clue:view` | 查看线索 | Y | Y(本辖区) | N | -| `monitoring-clue:create` | 生成线索 | Y | Y(本辖区) | N | -| `clue-transfer:view` | 查看转办 | Y | Y(本辖区) | N | -| `clue-transfer:create` | 发起转办 | Y | Y(本辖区) | N | - -**数据权限**(不在权限码中,在角色级别控制): - -| 角色 | 数据范围 | 实现方式 | -|------|---------|---------| -| CITY_SUPERVISOR | 全市 | 无 SQL 过滤 | -| DISTRICT_SUPERVISOR | 本辖区 | 按 district_code 过滤 | -| OPERATOR | 本公司 | 按 org_name 过滤 | - -**阶段输出**: DDL SQL 文件 + 初始数据 SQL - -**状态**: ✅ 完成 - ---- - -### Phase 2:后端 Entity/Mapper 层 - -按项目约定创建: - -``` -modules/system/ -├── entity/ -│ ├── SysUserEntity.java -│ ├── SysRoleEntity.java -│ ├── SysUserRoleEntity.java -│ ├── SysPermissionEntity.java -│ ├── SysRolePermissionEntity.java -│ ├── query/ -│ │ └── SysUserQuery.java -│ └── vo/ -│ ├── SysUserVO.java -│ └── LoginUserVO.java # 登录后返回给前端的信息 -├── mapper/ -│ ├── SysUserMapper.java -│ ├── SysRoleMapper.java -│ ├── SysUserRoleMapper.java -│ ├── SysPermissionMapper.java -│ └── SysRolePermissionMapper.java -└── service/ - ├── ISysUserService.java - ├── ISysRoleService.java - └── impl/ - ├── SysUserServiceImpl.java - └── SysRoleServiceImpl.java -``` - -**关键方法**: -- `SysUserMapper.findByUsername(username)` — 登录查询 -- `SysRoleMapper.selectByUserId(userId)` — 查用户角色 -- `SysPermissionMapper.selectByUserId(userId)` — 查用户权限码 -- `SysPermissionMapper.selectByRoleCode(roleCode)` — 查角色权限 - -**LoginUserVO** 返回给前端的信息: -```json -{ - "userId": "...", - "username": "...", - "realName": "...", - "roles": ["CITY_SUPERVISOR"], - "roleNames": ["市局广告监管人员"], - "permissions": ["screen:view", "screen:create", ...], - "districtCode": null, - "orgName": "广州市市场监督管理局" -} -``` - -**状态**: ✅ 完成 - ---- - -### Phase 3:认证流程实现(LoginController + StpInterfaceImpl) - -#### 3.1 LoginController 改造 - -``` -POST /user/auth/login - → SysUserService.findByUsername(username) - → BCrypt.checkPassword(password, user.password) - → StpUtil.login(user.id) - → session.set(USER_KEY, LoginUserVO) - → response.setHeader("satoken", token) - → return RestResult.ok(LoginUserVO) -``` - -#### 3.2 StpInterfaceImpl 实现 - -``` -getPermissionList(loginId) → SysPermissionMapper.selectByUserId(loginId) -getRoleList(loginId) → SysRoleMapper.selectRoleCodesByUserId(loginId) -``` - -#### 3.3 /user/auth/login/info 改造 - -返回 LoginUserVO(含 roles + permissions + districtCode + orgName)。 - -#### 3.4 UserBaseServiceImpl 完善 - -- login() 对接 SysUserService -- getCurrentUser() 从 session 取 LoginUserVO - -**状态**: ✅ 完成 - ---- - -### Phase 4:鉴权拦截器 + 数据权限 - -#### 4.1 SpringMvcConfig 权限路由 - -按模块配置权限检查: - -```java -SaRouter.match("/api/screen/**", r -> StpUtil.checkLogin()); -SaRouter.match("/api/monitoring-rule/**", r -> { - StpUtil.checkLogin(); - // 具体 CRUD 方法用注解控制 -}); -// ... 其余模块类似 -``` - -#### 4.2 Controller 方法级权限注解 - -在需要权限控制的 Controller 方法上加: - -```java -@SaCheckPermission("screen:create") -@PostMapping("save") -public RestResult save(...) { ... } - -@SaCheckPermission("screen:remove") -@PostMapping("remove") -public RestResult remove(...) { ... } -``` - -#### 4.3 数据权限过滤 - -在 Service 层的查询方法中,根据当前用户的角色过滤数据: - -- CITY_SUPERVISOR: 不过滤 -- DISTRICT_SUPERVISOR: 在 Query 中追加 `district_code = currentUser.districtCode` -- OPERATOR: 在 Query 中追加 `org_name = currentUser.orgName` - -实现方式:在 Service 中获取当前用户,动态拼装查询条件。 - -**注意**:数据权限需要修改现有 10 个模块的 Service 查询方法,影响范围较大。**建议先实现 Phase 1-3 的认证和操作权限,Phase 4 数据权限单独迭代。** - -**实际实施**: -- 创建 `DataScopeHelper` 工具类(`modules/system/util/`),提供角色判断静态方法 -- 修改 7 个 Service 的 queryList 方法,添加数据权限过滤: - - ScreenServiceImpl: queryList + exportData + getScreenOptions - - RecordingConfigServiceImpl: queryList + getConfigurableScreens - - RecordingTaskServiceImpl: queryList - - MonitorRecordServiceImpl: queryList - - EvidenceRecordServiceImpl: queryList - - MonitoringClueServiceImpl: queryList - - ClueTransferServiceImpl: queryList + queryPendingClues -- 过滤规则: - - CITY_SUPERVISOR: 不过滤(全市数据) - - DISTRICT_SUPERVISOR: 按 `district = currentUser.districtCode` 过滤 - - OPERATOR: Screen 按 `operatorUnit = orgName`,其他模块通过 screenId 关联 Screen 过滤 -- ClueTransferServiceImpl 特殊处理:OR 条件(转办目标辖区 + 线索来源辖区) -- 跳过模块:LawClauseServiceImpl(无区域字段)、MonitoringRuleServiceImpl(复杂 scope JSON)、EvidenceRuleRelationServiceImpl(关联表) - -**状态**: ✅ 完成 - ---- - -### Phase 5:前端角色路由映射 - -#### 5.1 定义角色常量 - -```javascript -// src/utils/constants.js 或 src/router/roles.js -export const ROLES = { - CITY_SUPERVISOR: 'CITY_SUPERVISOR', - DISTRICT_SUPERVISOR: 'DISTRICT_SUPERVISOR', - OPERATOR: 'OPERATOR' -} -``` - -#### 5.2 更新 routes.js 的 meta.roles - -按 PRD 权限矩阵为每个业务路由分配角色: - -```javascript -// BS-大屏基础库 - 三个角色都能访问 -meta: { roles: [ROLES.CITY_SUPERVISOR, ROLES.DISTRICT_SUPERVISOR, ROLES.OPERATOR] } - -// MR-监测规则 - 市局+区局 -meta: { roles: [ROLES.CITY_SUPERVISOR, ROLES.DISTRICT_SUPERVISOR] } - -// CW-内容预警 - 市局+区局 -meta: { roles: [ROLES.CITY_SUPERVISOR, ROLES.DISTRICT_SUPERVISOR] } -``` - -#### 5.3 更新 permission.js - -- 去掉 admin 硬编码全通逻辑 -- 使用后端返回的 permissions 数组做按钮级控制 - -#### 5.4 按钮级权限指令 - -添加 `v-permission` 指令,控制按钮显示: - -```html -新增 -删除 -``` - -**状态**: ✅ 完成 - ---- - -### Phase 6:用户管理接口(可选) - -提供用户 CRUD 接口供后台管理使用: - -- `POST /api/sys-user/query` — 用户列表(分页) -- `POST /api/sys-user/save` — 新增用户 -- `POST /api/sys-user/update` — 编辑用户 -- `POST /api/sys-user/remove` — 删除用户 -- `POST /api/sys-user/reset-password` — 重置密码 -- `GET /api/sys-user/role-options` — 角色选项列表 - -前端对应的管理页面可后续迭代。 - -**状态**: pending - ---- - -### Phase 7:编译验证 + 端到端测试 - -1. DDL 执行到 DM8 数据库 -2. 后端编译通过(`mvn compile -Dcheckstyle.skip=true`) -3. 启动后端,验证登录流程 -4. 验证权限校验(无权限返回 403) -5. 前端 `npm run lint` 通过 -6. 前端登录后路由正确过滤 - -**状态**: ✅ 完成(BUILD SUCCESS) - ---- - -## 实施建议 - -### 优先级排序 - -| 优先级 | Phase | 说明 | -|--------|-------|------| -| **P0 必须** | Phase 1-3 | DDL + Entity/Mapper + 认证流程,使登录对接真实数据库 | -| **P1 重要** | Phase 5 | 前端角色路由,使不同角色看到不同菜单 | -| **P2 增强** | Phase 4 | 操作权限注解 + 数据权限过滤 | -| **P3 可选** | Phase 6 | 用户管理 CRUD | -| **P0 验证** | Phase 7 | 编译 + 测试 | - -### 建议实施路径 - -**第一轮(核心认证)**: Phase 1 → 2 → 3 → 7 -**第二轮(前端权限)**: Phase 5 → 7 -**第三轮(精细控制)**: Phase 4 → 6 - ---- - -## 修复决策 - -(实施过程中记录)