From 4abb65129b50271d3ae5e3bc5aa2d862d488d6f1 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Wed, 1 Apr 2026 11:03:28 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=B2=BE=E7=AE=80=20README=20=E5=92=8C?= =?UTF-8?q?=20openspec=20=E9=85=8D=E7=BD=AE=EF=BC=8C=E6=B7=BB=E5=8A=A0=20A?= =?UTF-8?q?GENTS.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 1 + README.md | 349 +++++++++++++++++-------------------------- openspec/config.yaml | 11 +- 3 files changed, 141 insertions(+), 220 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..874fa8e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +严格遵守openspec/config.yaml中context声明的项目规范 \ No newline at end of file diff --git a/README.md b/README.md index 53dd7a2..fe7fce7 100644 --- a/README.md +++ b/README.md @@ -1,260 +1,181 @@ # Spring Boot Service Template -微服务快速开发能力模板,提供标准化的能力模块,帮助开发者快速构建 Spring Boot 微服务应用。 +微服务快速开发能力模板,v1.1.0-SNAPSHOT。Java 17, Spring Boot 4.0.0, Spring Cloud 2025.1.0。 -**当前版本**: 1.1.0-SNAPSHOT +GroupId: `com.lanyuanxiaoyao`,根包: `com.lanyuanxiaoyao.service.template`。 -## 1. 项目概述 - -Spring Boot Service Template 是一个能力模块化的微服务开发模板。每个能力模块封装特定领域的通用功能,开发者只需引入依赖、实现少量代码即可获得完整的业务能力。 - -**核心价值**: -- 能力模块化:每个模块独立可用,按需引入 -- 零样板代码:通用逻辑已封装,专注业务实现 -- 多实现支持:同一能力支持多种技术实现,灵活选择 - -## 2. 架构 +## 模块 ``` -┌─────────────────────────────────────────────────────────────────────┐ -│ Spring Boot Service Template │ -├─────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌──────────────────────────────────────────────────────────────┐ │ -│ │ 能力模块 (Capability) │ │ -│ │ │ │ -│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ -│ │ │ database │ │ user │ │ payment │ ... │ │ -│ │ │ ✅ 已实现 │ │ 🔜 规划中 │ │ 🔜 规划中 │ │ │ -│ │ └──────┬──────┘ └─────────────┘ └─────────────┘ │ │ -│ │ │ │ │ -│ │ ▼ │ │ -│ │ ┌─────────────────────────────────────────────┐ │ │ -│ │ │ jpa │ eq │ xbatis (实现) │ │ │ -│ │ └─────────────────────────────────────────────┘ │ │ -│ └──────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────────────┐ │ -│ │ 通用基础 (Common) │ │ -│ │ │ │ -│ │ ObjectHelper (对象工具) │ SnowflakeHelper (ID生成) │ │ -│ └──────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────┘ +spring-boot-service-template/ (根 POM, packaging=pom) +├── spring-boot-service-template-common/ (jar — 通用工具) +└── spring-boot-service-template-database/ (jar — JPA 数据库能力) ``` -**模块依赖关系**: +模块命名规则: `spring-boot-service-template-{capability}[-{impl}]` + +## 包结构 ``` -┌─────────────┐ -│ 应用 │ -└──────┬──────┘ - │ - ▼ -┌─────────────────┐ ┌───────────────────┐ -│ capability-common│────▶│ capability-impl │ -│ (接口定义) │ │ (jpa/eq/xbatis) │ -└───────┬─────────┘ └───────────────────┘ - │ - ▼ -┌─────────────┐ -│ common │ -│ (通用工具) │ -└─────────────┘ +com.lanyuanxiaoyao.service.template.{module}/ + configuration/ # @Configuration(用 configuration 不用 config) + controller/ # REST 控制器 + 接口 + entity/ # JPA 实体、Query、GlobalResponse 等数据对象 + exception/ # 自定义异常(用 exception 不用 exceptions) + helper/ # 工具类(用 helper 不用 util/utils) + repository/ # Spring Data 仓库 + service/ # 业务服务 ``` -## 3. 通用规范 +无独立 DTO/VO 包,DTO 作为 Controller 内部 record。 -### 3.1 模块命名 +## database 模块 -| 模块类型 | 命名格式 | 示例 | -|---------|---------|------| -| 能力模块 | `spring-boot-service-template-{capability}` | database | -| 通用定义 | `spring-boot-service-template-{capability}-common` | database-common | -| 具体实现 | `spring-boot-service-template-{capability}-{impl}` | database-jpa | -| 通用基础 | `spring-boot-service-template-common` | common | +单表 CRUD → REST 接口的快速实现框架。基于 JPA + Fenix + QueryDSL + MapStruct。 -### 3.2 依赖原则 +### 实体继承 -- **common 模块**:与业务无关的工具类,不依赖任何能力模块 -- **capability-common**:定义接口和通用实体,不依赖具体实现技术 -- **最小化第三方依赖**:优先使用 JDK 和 Spring 内置能力 - -### 3.3 响应格式 - -所有 API 使用统一的 `GlobalResponse` 格式: - -```json -{ - "status": 0, - "message": "OK", - "data": { ... } -} +``` +IdOnlyEntity (id: Long, @SnowflakeId) ← @MappedSuperclass + ↑ +SimpleEntity (+ createdTime: LocalDateTime, ← @MappedSuperclass + modifiedTime: LocalDateTime) + ↑ +业务实体 (具体 @Entity) ``` -| 字段 | 说明 | -|-----|------| -| status | 状态码:0=成功,500=错误 | -| message | 描述信息 | -| data | 业务数据 | +- ID: Long,雪花算法,字段标 `@SnowflakeId`(自定义注解) +- 时间字段: `@CreatedDate`/`@LastModifiedDate`,JPA `AuditingEntityListener` 自动填充 +- 列注释: `@Column(comment = "...")` +- 物理命名: `PhysicalNamingStrategySnakeCaseImpl`(camelCase→snake_case) +- 保存: Fenix `saveOrUpdateByNotNullProperties()`,自动 INSERT/UPDATE,仅更新非 null 字段 -列表数据封装: +### Repository -```json -{ - "status": 0, - "message": "OK", - "data": { - "items": [...], - "total": 100 - } -} +```java +@NoRepositoryBean +public interface SimpleRepository extends + FenixJpaRepository, + FenixJpaSpecificationExecutor, + ListQueryByExampleExecutor, + ListQuerydslPredicateExecutor {} ``` -### 3.4 代码风格 +业务 Repository 直接继承: `interface EmployeeRepository extends SimpleRepository {}` -- **接口与实现分离**:接口定义在 `*-common`,实现在具体模块 -- **空值检查**:使用 `ObjectHelper.isNull/isNotNull/isEmpty/isNotEmpty` -- **异常定义**:继承 `RuntimeException`,构造器接收业务参数 -- **注解使用**:`@Getter` / `@Setter` / `@FieldNameConstants` / `@NoArgsConstructor` +无 XML Mapper,无自定义 SQL,查询通过 JPA Criteria / Fenix / QueryDSL 动态构建。 -## 4. 能力模块 +### 接口组合模式 -### 4.1 database 模块 - -单表 CRUD → REST 接口的快速实现,支持三种数据库访问方式。 - -#### 模块概述 - -| 功能 | 说明 | -|-----|------| -| 保存 | 单条/批量保存,自动判断新增/更新 | -| 查询 | 详情查询、列表查询、分页查询、条件查询 | -| 删除 | 单条/批量删除 | - -#### 实现方式对比 - -| 特性 | JPA | Easy Query | Xbatis | -|-----|-----|------------|--------| -| 类型安全查询 | ✅ QueryDSL | ✅ Proxy API | ❌ | -| 自动审计 | ✅ | ❌ | ❌ | -| 逻辑删除 | ❌ | ✅ | ✅ | -| 复杂 SQL | 中等 | 中等 | 强 | -| 适用场景 | 标准 JPA 项目 | 类型安全 + 逻辑删除 | 复杂查询场景 | - -#### 快速开始 - -**1. 添加依赖** - -```xml - - - com.lanyuanxiaoyao - spring-boot-service-template-database-jpa - 1.1.0-SNAPSHOT - +```java +SimpleService extends SaveService, QueryService, RemoveService +SimpleController extends SaveController, QueryController, RemoveController ``` -**2. 实现 CRUD 的 5 个步骤** +抽象基类: `SimpleServiceSupport`(Service) / `SimpleControllerSupport`(Controller),用 `*Support` 后缀(非 `*Impl`)。 -参考测试代码:`spring-boot-service-template-database-jpa/src/test/java/.../` +Controller 子类必须提供三个 mapper 函数: `saveItemMapper()`, `listItemMapper()`, `detailItemMapper()` -| 步骤 | 说明 | 参考文件 | -|-----|------|---------| -| 1. 创建实体 | 继承 `SimpleEntity` | `entity/Employee.java` | -| 2. 创建 Repository | 继承 `SimpleRepository` | `repository/EmployeeRepository.java` | -| 3. 创建 Service | 继承 `SimpleServiceSupport` | `service/EmployeeService.java` | -| 4. 创建 DTO | 定义 SaveItem, ListItem, DetailItem | `controller/EmployeeController.java` | -| 5. 创建 Controller | 继承 `SimpleControllerSupport`,实现 3 个 Mapper | `controller/EmployeeController.java` | +### CRUD 五步 -**3. 查询条件语法** +1. 创建实体 — 继承 `SimpleEntity` +2. 创建 Repository — 继承 `SimpleRepository` +3. 创建 Service — 继承 `SimpleServiceSupport` +4. 创建 DTO — 在 Controller 内定义 `SaveItem`/`ListItem`/`DetailItem` record +5. 创建 Controller — 继承 `SimpleControllerSupport`,实现 3 个 mapper -```json -{ - "query": { - "equal": { "name": "张三" }, - "like": { "name": "%张%" }, - "contain": { "name": "张" }, - "startWith": { "name": "张" }, - "endWith": { "name": "三" }, - "great": { "age": 18 }, - "less": { "age": 60 }, - "greatEqual": { "age": 18 }, - "lessEqual": { "age": 60 }, - "between": { "age": { "start": 18, "end": 60 } }, - "inside": { "id": [1, 2, 3] }, - "notInside": { "id": [1, 2, 3] }, - "nullEqual": ["deletedTime"], - "notNullEqual": ["name"] - }, - "sort": [{ "column": "createdTime", "direction": "DESC" }], - "page": { "index": 1, "size": 10 } -} -``` +也可用 `DatabaseHelper.generateBasicFiles()` 自动生成上述脚手架,`@RequestMapping` 路径由实体名 camelCase→snake_case 推导。`DatabaseHelper.generateDDL()` 可从实体类生成 DDL SQL。 -#### 模块特定规范 +### API 端点 -**分层结构**: -``` -Controller (HTTP处理、DTO转换) - │ - ▼ -Service (业务逻辑、事务管理) - │ - ▼ -Repository/Mapper (数据访问) - │ - ▼ -Entity (数据模型) -``` +| 操作 | 方法 | 路径 | +| --------- | ---- | ---------------- | +| 新增/更新 | POST | `/save` | +| 全部列表 | GET | `/list` | +| 条件列表 | POST | `/list` | +| 详情 | GET | `/detail/{id}` | +| 删除 | GET | `/remove/{id}` | -**泛型参数**: -- `ENTITY` - 实体类型 -- `SAVE_ITEM` - 保存请求 DTO -- `LIST_ITEM` - 列表响应 DTO -- `DETAIL_ITEM` - 详情响应 DTO +统一响应: `GlobalResponse(status:Integer, message:String, data:T)`,成功 status=0,失败 status=500。 -**实体继承**: -- JPA: `IdOnlyEntity` → `SimpleEntity` → 业务实体 -- EQ/Xbatis: `IdOnlyEntity` → `SimpleEntity` 或 `LogicDeleteEntity` +- 列表: `data = ListItem(items:Iterable, total:Long)` +- 详情: `data = DetailItem(item:T)` -### 4.2 user 模块 +### 查询条件 -🚧 规划中... +查询对象: `Query(Queryable query, List sort, Pageable page)` -### 4.3 payment 模块 +支持: equal/notEqual/like/notLike/contain/notContain/startWith/endWith/great/less/greatEqual/lessEqual/between/notBetween/inside/notInside/nullEqual/notNullEqual/empty/notEmpty -🚧 规划中... +分页: `Pageable(index, size)`,index 从 1 开始,默认 `(1, 10)`,无排序默认 `createdTime DESC` -## 5. 技术栈 +## 开发规范 -| 组件 | 版本 | -|-----|------| -| Java | 17 | -| Spring Boot | 4.0.0 | -| Spring Cloud | 2025.1.0 | -| Hibernate | 7.1.8.Final | -| QueryDSL | 7.1 | -| Easy Query | 3.1.68 | -| Xbatis | 1.9.7-spring-boot4 | -| Lombok | - | -| MapStruct | 1.6.3 | +### 命名 -## 6. 开发与测试 +| 类别 | 模式 | 示例 | +| --------------- | ---------------------------------------- | ---------------------------------- | +| 实体基类 | `*Entity` | `IdOnlyEntity`, `SimpleEntity` | +| 业务实体 | 纯名词 | `Employee` | +| 控制器接口 | `*Controller` | `SaveController` | +| 控制器抽象基类 | `*ControllerSupport` | `SimpleControllerSupport` | +| 服务接口 | `*Service` | `SaveService` | +| 服务抽象基类 | `*ServiceSupport` | `SimpleServiceSupport` | +| 仓库 | `*Repository` | `EmployeeRepository` | +| 工具类 | `*Helper` | `ObjectHelper` | +| 配置类 | `*Configuration` | `QueryDSLConfiguration` | +| 异常 | `*Exception` | `IdNotFoundException` | +| 内部 DTO record | `SaveItem`/`ListItem`/`DetailItem` | Controller 内部 | + +- 接口不加 `I` 前缀 +- 方法: 动词开头 `save()`/`list()`/`detail()`/`remove()`;布尔用 `is`/`has` 前缀 +- 常量 UPPER_SNAKE_CASE;字段常量用 `@FieldNameConstants` 生成 `{Class}.Fields.{field}` +- 泛型: 简单用 `T`/`E`,领域用 `ENTITY`/`SAVE_ITEM`/`LIST_ITEM`/`DETAIL_ITEM` + +### 代码风格 + +- 2 空格缩进,K&R 大括号,不用 Tab +- Import 排序: `java.*` → `jakarta.*` → 第三方 → `com.lanyuanxiaoyao.*`,不用通配符 +- 积极使用 Java 17 特性: `record`(DTO) / `var` / `instanceof` 模式匹配 / Text Blocks / `String.formatted()` +- JavaDoc 用中文,含 `@param`/`@return`/`@see`,可用 `

`/`

`/`
    `/`
    `
    +- 不写 `//` 行内注释,除非必要
    +
    +### 注解
    +
    +用:
    +
    +- 实体: `@Getter` `@Setter` `@ToString` `@FieldNameConstants`,子类加 `@ToString(callSuper = true)`
    +- 日志: `@Slf4j`
    +- 注入: `@RequiredArgsConstructor(access = AccessLevel.PROTECTED)`(构造器注入)
    +- 事务: 写 `@Transactional(rollbackFor = Throwable.class)`,读 `@Transactional(readOnly = true)`
    +- 实体基类: `@MappedSuperclass` `@EntityListeners(AuditingEntityListener.class)`
    +
    +不用:
    +
    +- 不用 `@Valid`/`@NotNull` 等校验注解
    +- 不用 Swagger/OpenAPI 注解
    +- 不用 `@Autowired` 字段注入
    +- 不写代码注释(`//`),除非必要
    +
    +### 异常
    +
    +继承 `RuntimeException`,构造器用 `String.formatted()`。查无数据用 `Optional.orElseThrow(() -> new IdNotFoundException(id))`。无全局 `@ControllerAdvice`。
    +
    +### 依赖管理
    +
    +版本集中在根 POM `` + ``,子模块不声明版本。
    +全局继承: `lombok` / `jspecify:1.0.0`
    +核心: `spring-boot-starter-data-jpa` / `fenix-spring-boot-starter:4.0.0` / `querydsl-jpa:7.1` / `mapstruct:1.6.3`
    +database 模块注解处理器: lombok → hibernate-jpamodelgen → querydsl-apt(jpa) → jakarta.persistence-api → mapstruct-processor
    +
    +### 通用原则
    +
    +- 文档/注释/commit 用中文,代码标识符用英文
    +- 不引入新依赖前先复用已有组件,优先 JDK 和 Spring 内置能力
    +- 构造器注入,不使用 `@Autowired` 字段注入
    +
    +### 构建
     
    -**构建项目**:
     ```bash
     mvn clean package
     ```
    -
    -**运行测试**:
    -```bash
    -mvn test
    -```
    -
    -测试使用 H2 内存数据库,无需额外配置。
    -
    -## 7. 文档索引
    -
    -- 详细文档:`docs/` 目录
    -- 测试示例:各模块的 `src/test/java/` 目录
    diff --git a/openspec/config.yaml b/openspec/config.yaml
    index 1fb1755..3e4642c 100644
    --- a/openspec/config.yaml
    +++ b/openspec/config.yaml
    @@ -1,12 +1,11 @@
     schema: spec-driven
     
     context: |
    -  - maven管理的java项目,遵循java代码最佳实践规范
    -  - 交流、文档、注释、提交信息使用中文,代码命名使用英文
    -  - 新增代码要遵循原有代码的设计风格和模式,优先考虑复用已有组件、工具、依赖库
    -  - **优先阅读README.md**,README.md文档是项目的开发文档,记录代码结构和关键开发模式,优先读取获取上下文
    -  - 涉及页面/路由/组件/功能模块变更或技术栈调整时,同步更新README.md
    -  - Git提交: 仅中文; 格式为"类型: 简短描述",类型可选: feat(新功能)/fix(修复)/refactor(重构)/docs(文档)/style(格式)/test(测试)/chore(构建/工具); 多行描述空行后加详细说明; 禁创建git操作task
    +  - **优先阅读README.md**获取项目结构与开发规范,所有代码风格、命名、注解、依赖、API等规范以README为准
    +  - 新增代码优先复用已有组件、工具、依赖库,不引入新依赖
    +  - 涉及模块结构、API、实体等变更时同步更新README.md
    +  - Git提交: 仅中文; 格式"类型: 简短描述", 类型: feat/fix/refactor/docs/style/test/chore; 多行描述空行后写详细说明
    +  - 禁止创建git操作task
     
     rules:
       proposal: