diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e0a5d67 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,212 @@ +# AGENTS.md + +## 适用范围 + +本说明适用于以 `C:\code\gitea\rdms\cn-rdms` 为根目录的整个仓库。 + +描述仓库现状时,以当前代码、当前配置、当前文档中可直接验证的事实为准;除非用户明确要求,不引入历史实现、过渡方案或已废弃模型来解释当前状态。 + +默认回答保持精简,优先给结论、改动点和必要风险,不做过多展开;如果存在你关心但未展开的细节,由你继续追问后再补充。 + +## 交互原则 + +- 默认先给执行方案,说明目标、涉及模块、预计改动点和验证方式。 +- 在用户评审并明确同意前,不直接开始实际修改、编译、测试、打包或其他执行动作。 +- 是否执行由用户决定;如果用户只要求分析、审阅或出方案,就停留在分析和方案层。 + +## 项目概览 + +这是一个面向 RDMS 服务的多模块 Maven 单仓库项目。 + +- Java 版本:17 +- 构建工具:Maven +- 根模块打包类型:`pom` +- Spring Boot 版本:`3.5.9` + +顶层模块: + +1. `rdms-system` +2. `rdms-framework` +3. `rdms-gateway` + +当前业务实现主要集中在 `rdms-system`,但这只是现阶段结构,不应被理解为长期只保留一个业务模块。 + +后续如果新增独立业务服务,例如项目/产品管理模块、工作流模块,应继续沿用当前仓库的模块拆分方式,而不是把所有后续业务长期堆进 `rdms-system`。 + +## 模块说明 + +### `rdms-system` + +当前已存在的系统业务聚合模块。 + +- `rdms-system/rdms-system-boot` + - 主应用模块 + - 启动入口:`rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/SystemServerApplication.java` + - 主包路径:`com.njcn.rdms.module.system` + - 常见子包:`api`、`controller`、`convert`、`dal`、`framework`、`job`、`service`、`util`、`websocket` +- `rdms-system/rdms-system-api` + - 供其他服务依赖的共享 API 模块 + - 包含对外 API 契约与枚举定义 + +说明: + +- 当前权限、用户、组织、岗位、菜单、角色等系统核心能力主要落在这里。 +- 如果后续只是给系统域补充新的系统子能力,可以继续在 `rdms-system` 内按现有结构扩展。 +- 如果后续形成独立业务域,例如 `rdms-project`、`rdms-workflow`,应优先建设为新的独立业务模块,而不是默认继续塞进 `rdms-system`。 + +### `rdms-framework` + +共享框架与内部 starter 模块。 + +- `rdms-framework/rdms-common` + - 核心通用工具与公共抽象 +- 其他 `rdms-spring-boot-starter-*` 模块 + - 内部 starter,覆盖 `env`、`web`、`rpc`、`security`、`mybatis`、`redis`、`mq`、`websocket`、`excel`、`protection`、`test`、`biz-ip` + +### `rdms-gateway` + +Spring Cloud Gateway 网关服务。 + +- 启动入口:`rdms-gateway/src/main/java/com/njcn/rdms/gateway/GatewayServerApplication.java` +- 主包路径:`com.njcn.rdms.gateway` +- 常见子包:`filter`、`handler`、`jackson`、`route`、`util` + +## 模块演进约束 + +后续新增业务能力时,先区分下面两种情况,不要混用: + +1. 新增独立微服务模块,例如 `rdms-project`、`rdms-workflow` +2. 只是在现有 `rdms-system` 中新增一个业务子域 + +### 新增独立微服务模块 + +如果后续能力已经具备独立服务边界,应优先按下面结构建设: + +```text +rdms-xxx +├─ rdms-xxx-api +└─ rdms-xxx-boot +``` + +约束: + +- 根 `pom.xml` 增加新的聚合模块 +- `api` 模块承载对外 RPC/Feign 接口、DTO、错误码、枚举、常量 +- `boot` 模块承载启动类、controller、service、dal、convert、api 实现、模块级 framework 配置和资源文件 +- 包路径、`spring.application.name`、`ApiConstants`、`RpcConstants`、`rdms.info.base-package` 必须保持一致 +- 新服务不是简单复制 `rdms-system` 的名字,而是复用它的工程骨架和分层习惯 + +### 在 `rdms-system` 中新增业务子域 + +如果只是给系统服务补一个当前阶段仍适合放在 `rdms-system` 内的子域,则继续沿用现有结构: + +- `controller/admin/...` 或 `controller/app/...` +- `service/...` +- `dal/dataobject/...` +- `dal/mysql/...` +- `convert/...` +- 需要跨模块暴露时,在 `rdms-system-api` 中补 API、DTO、错误码、枚举 + +约束: + +- 不要为了新增子域引入一套平行的 `application/domain/infrastructure/adapter` 分层语言 +- 不要让外部模块直接依赖 `rdms-system-boot` 的 service 或 mapper +- 如果某项能力未来明显会演进成独立微服务,文档和实现上都要避免把它写死成只能存在于 `rdms-system` + +## 代码目录 + +- Java 源码:`*/src/main/java` +- 资源文件:`*/src/main/resources` +- 测试代码:`*/src/test/java` +- 本地辅助脚本:`scripts/` + +## 分层职责约束 + +### `rdms-framework` + +- `rdms-framework` 承担基础能力,不承载具体业务语义。 +- 除非出现框架级缺陷,或该能力明确属于全局可复用基础设施,否则不要把业务判断硬塞进 framework。 + +### `rdms-gateway` + +- `rdms-gateway` 只负责统一入口、令牌校验、登录用户透传、路由和网关层横切逻辑。 +- 不要在 gateway 层承载组织、成员、负责人、项目、产品、工作流状态流转或数据可见性这类业务语义。 + +### Controller 层 + +- Controller 负责 HTTP 暴露、参数校验、权限注解、结果封装。 +- 不要在 controller 中直接编排复杂业务流程,也不要直接操作多个 mapper 拼装业务规则。 +- 请求和响应对象优先沿用 `ReqVO`、`RespVO` 风格,不要直接把 DO 暴露给前端。 + +### Service 层 + +- 核心业务规则、事务、缓存、领域编排应落在 service 层。 +- 如果是已有领域增强,优先在现有 service 下扩展,不要为了“看起来更整齐”平移整套代码。 +- 不要把复杂规则散落到 controller、mapper 或 `util` 中。 + +### DAL 层 + +- 新表应有对应的 DO 和 Mapper。 +- Mapper 优先继承 `BaseMapperX`,不要重复写样板 CRUD。 +- 查询条件优先沿用 `LambdaQueryWrapperX`、默认方法封装和现有 MyBatis Plus 风格,不要无必要回退到 XML。 +- Mapper 以查询封装为主,不承担领域校验职责。 + +### Convert 层 + +- 如果某个领域已经有 `convert` 风格,则继续沿用。 +- 简单场景允许直接使用 `BeanUtils`。 +- 不要为了统一而强推所有地方都改成 MapStruct,也不要反过来把已有 convert 全部删掉。 + +## 认证与共享调用约束 + +- 默认沿用现有 OAuth2 / Token / `LoginUser` / `login-user` 透传主链,不要另造一套认证上下文体系。 +- 不要额外发明 ThreadLocal、Session 或自定义 header 体系替代当前登录态恢复方式。 +- 接口级权限判断默认沿用 `@PreAuthorize("@ss.hasPermission(...)")` 这条链路,不要绕开现有权限框架另起一套实现。 +- 跨模块、跨服务访问能力时,优先通过对应的 `*-api` 模块定义 API、DTO、常量和枚举。 +- 不要让外部模块直接依赖某个 `*-boot` 模块的 service 或 mapper。 + +## 数据与 SQL 约束 + +- 新增业务表的 DO 优先复用当前 `BaseDO` / 审计字段风格;除非表本身明确不需要逻辑删除,不要再引入另一套审计基类。 +- 不要假设运行时存在自动数据库迁移;如果代码依赖新表、新字段或新索引,必须同步补齐对应 SQL 与文档说明。 +- SQL 脚本应放在目标模块的 `src/main/resources/sql/...` 下,并保持可审阅、可单独执行、语义清晰。 +- 变更缓存、日志、审计相关逻辑时,优先沿用现有机制,不要绕开现有登录上下文、缓存约定和审计字段填充方式。 + +## 注释与编码 + +- 新增或修改代码时,关键字段、关键分支、关键约束和非直观实现应补充简洁中文注释。 +- 不要为了省事删除原有有效注释,也不要添加无信息量的注释。 +- 写入中文内容时必须保持 UTF-8 编码,并自行检查中文显示是否正常;不要用“改成英文”规避乱码问题。 + +## 工作规则 + +1. 除非任务明确要求修改共享契约或 starter,否则优先进行有边界的模块内改动,避免跨模块扩散。 +2. 业务逻辑应放在对应业务模块的 `*-boot` 实现模块;可复用契约放在对应的 `*-api` 模块;可复用框架能力放在 `rdms-framework`。 +3. 除非任务本身就是环境配置调整,否则避免修改 `application-local.yaml` 和 `application-dev.yaml`。 +4. 将本地资源 YAML 视为可能带有机器环境差异的文件;修改前先检查 git 状态。 +5. 保持既有包结构约定不变: + - 控制器放在 `controller` + - 服务层放在 `service` + - 持久层放在 `dal` + - DTO/VO 转换放在 `convert` +6. 当前业务代码主要在 `rdms-system`,但这不是永久约束;新增业务能力时,先判断应该落在现有系统域内,还是应建设为新的 `rdms-xxx` 业务模块。 +7. 新增共享能力时,优先扩展现有 `rdms-spring-boot-starter-*` 模块,不要在业务服务里重复堆配置。 +8. 修改跨模块使用的 API 时,需要同时更新提供方实现和对应的 `rdms-system-api` 或对应 `rdms-xxx-api` 契约。 +9. 除非用户明确要求,否则不执行任何编译、构建、测试、打包或其他会实际运行项目的命令,包括但不限于 `mvn`、启动命令和脚本。 + +## 测试指引 + +先定义验证方式,再实施修改。默认通过以下方式验证: + +- 代码路径是否闭环,调用链是否与模块边界一致 +- 配置项、接口契约、权限标识、路由或资源注册是否前后一致 +- 改动范围是否控制在当前任务所需的最小集合内 +- 受影响的文档、SQL、配置或接口说明是否需要同步更新 + +如果任务影响了 Spring 配置、序列化、安全、路由、RPC 契约、MyBatis 行为或跨模块 API,一律明确说明哪些部分已静态检查、哪些部分尚未实际运行验证。 + +## 给后续 Agent 的说明 + +- 仓库中可能存在未提交的本地配置改动,不要覆盖与当前任务无关的编辑。 +- `docs/` 目录属于当前工作上下文的一部分,不是归档材料;做架构级修改前先查阅。 +- 根目录 `pom.xml` 负责统一版本和依赖对齐;涉及版本调整时,优先修改根 `pom.xml`,不要散落到子模块中。 diff --git a/rdms-gateway/src/main/resources/application-dev.yaml b/rdms-gateway/src/main/resources/application-dev.yaml index 197e44d..a93a128 100644 --- a/rdms-gateway/src/main/resources/application-dev.yaml +++ b/rdms-gateway/src/main/resources/application-dev.yaml @@ -6,10 +6,10 @@ spring: username: # Nacos 账号 password: # Nacos 密码 discovery: # 【配置中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP config: # 【注册中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP #################### 监控相关配置 #################### diff --git a/rdms-gateway/src/main/resources/application-local.yaml b/rdms-gateway/src/main/resources/application-local.yaml index f5587ae..5d2e345 100644 --- a/rdms-gateway/src/main/resources/application-local.yaml +++ b/rdms-gateway/src/main/resources/application-local.yaml @@ -6,10 +6,10 @@ spring: username: # Nacos 账号 password: # Nacos 密码 discovery: # 【配置中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP config: # 【注册中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP #################### 监控相关配置 #################### diff --git a/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/service/permission/PermissionServiceImpl.java b/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/service/permission/PermissionServiceImpl.java index 2557fc7..96b70ba 100644 --- a/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/service/permission/PermissionServiceImpl.java +++ b/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/service/permission/PermissionServiceImpl.java @@ -223,11 +223,7 @@ public class PermissionServiceImpl implements PermissionService { return Collections.emptySet(); } - // 如果是管理员的情况下,获取全部菜单编号 - if (roleService.hasAnySuperAdmin(roleIds)) { - return convertSet(menuService.filterDisableMenus(menuService.getMenuList()), MenuDO::getId); - } - // 如果是非管理员的情况下,仅返回当前仍然有效的菜单,并补齐其父链 + // 统一按角色实际授权返回当前仍然有效的菜单,并补齐其父链 Set menuIds = convertSet(roleMenuMapper.selectListByRoleId(roleIds), RoleMenuDO::getMenuId); List menus = menuService.filterDisableMenus(menuService.getMenuList(menuIds)); return expandMenuIdsWithAncestors(convertSet(menus, MenuDO::getId)); diff --git a/rdms-system/rdms-system-boot/src/main/resources/application-dev.yaml b/rdms-system/rdms-system-boot/src/main/resources/application-dev.yaml index 5661ca7..3237cc0 100644 --- a/rdms-system/rdms-system-boot/src/main/resources/application-dev.yaml +++ b/rdms-system/rdms-system-boot/src/main/resources/application-dev.yaml @@ -7,12 +7,12 @@ spring: username: # Nacos 账号 password: # Nacos 密码 discovery: # 【配置中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP metadata: version: 1.0.0 # 服务实例的版本号,可用于灰度发布 config: # 【注册中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP #################### 数据库相关配置 #################### diff --git a/rdms-system/rdms-system-boot/src/main/resources/application-local.yaml b/rdms-system/rdms-system-boot/src/main/resources/application-local.yaml index 11bc32e..69b9c07 100644 --- a/rdms-system/rdms-system-boot/src/main/resources/application-local.yaml +++ b/rdms-system/rdms-system-boot/src/main/resources/application-local.yaml @@ -6,12 +6,12 @@ spring: username: # Nacos 账号 password: # Nacos 密码 discovery: # 【配置中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP metadata: version: 1.0.0 # 服务实例的版本号,可用于灰度发布 config: # 【注册中心】配置项 - namespace: 1e0fcd92-49b4-4cda-b531-828c7d36fef5 # 命名空间。这里使用 dev 开发环境 + namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP #################### 数据库相关配置 #################### @@ -63,7 +63,7 @@ spring: data: redis: host: 127.0.0.1 # 地址 - port: 6379 # 端口 + port: 16379 # 端口 database: 1 # 数据库索引 # password: njcnpqs # 密码,建议生产环境开启