@llryiop/avatar-boot-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +309 -0
  2. package/bin/cli.js +3 -0
  3. package/docs/plans/2026-03-12-avatar-boot-cli-design.md +73 -0
  4. package/docs/plans/2026-03-12-avatar-boot-cli-plan.md +681 -0
  5. package/package.json +28 -0
  6. package/src/index.js +78 -0
  7. package/src/prompts.js +78 -0
  8. package/src/template.js +37 -0
  9. package/src/transform.js +172 -0
  10. package/src/utils.js +34 -0
  11. package/templates/.claude/rules/architecture-redlines.md +146 -0
  12. package/templates/.claude/rules/code-review-standards.md +137 -0
  13. package/templates/.claude/rules/coding-standards.md +56 -0
  14. package/templates/.claude/rules/git-commit.md +59 -0
  15. package/templates/.claude/rules/layered-architecture.md +201 -0
  16. package/templates/.claude/rules/mybatis-plus.md +263 -0
  17. package/templates/.claude/rules/tech-stack.md +41 -0
  18. package/templates/.claude/rules/version.md +467 -0
  19. package/templates/.claude/settings.local.json +18 -0
  20. package/templates/.claude/skills/ai-tool-guide/SKILL.md +314 -0
  21. package/templates/.claude/skills/api-design/SKILL.md +200 -0
  22. package/templates/.claude/skills/api-doc-generator/SKILL.md +380 -0
  23. package/templates/.claude/skills/api-service-module-creator/SKILL.md +1114 -0
  24. package/templates/.claude/skills/avatar-boot-starter-feign/SKILL.md +243 -0
  25. package/templates/.claude/skills/avatar-boot-starter-job/SKILL.md +437 -0
  26. package/templates/.claude/skills/avatar-boot-starter-kafka/SKILL.md +580 -0
  27. package/templates/.claude/skills/avatar-boot-starter-mysql/SKILL.md +572 -0
  28. package/templates/.claude/skills/avatar-boot-starter-nacos/SKILL.md +901 -0
  29. package/templates/.claude/skills/avatar-boot-starter-oss/SKILL.md +594 -0
  30. package/templates/.claude/skills/avatar-boot-starter-redis/SKILL.md +586 -0
  31. package/templates/.claude/skills/avatar-boot-starter-rocketmq/SKILL.md +662 -0
  32. package/templates/.claude/skills/avatar-boot-starter-web/SKILL.md +1007 -0
  33. package/templates/.claude/skills/changelog-generator/SKILL.md +114 -0
  34. package/templates/.claude/skills/code-review/SKILL.md +239 -0
  35. package/templates/.claude/skills/crud-generator/SKILL.md +824 -0
  36. package/templates/.claude/skills/database-design/SKILL.md +377 -0
  37. package/templates/.claude/skills/deployment-config/SKILL.md +277 -0
  38. package/templates/.claude/skills/incident-analysis/SKILL.md +241 -0
  39. package/templates/.claude/skills/integration-test-generator/SKILL.md +496 -0
  40. package/templates/.claude/skills/prompt-engineering/SKILL.md +249 -0
  41. package/templates/.claude/skills/requirement-management/SKILL.md +244 -0
  42. package/templates/.claude/skills/security-audit/SKILL.md +330 -0
  43. package/templates/.claude/skills/test-case-design/SKILL.md +257 -0
  44. package/templates/.claude/skills/testing-workflow/SKILL.md +68 -0
  45. package/templates/.claude/skills/troubleshooting/SKILL.md +240 -0
  46. package/templates/CLAUDE.md +173 -0
  47. package/templates/README.md +303 -0
  48. package/templates/avatar-scaffold-api/pom.xml +41 -0
  49. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/api/LoginFeignClient.java +40 -0
  50. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/constant/LoginConstant.java +21 -0
  51. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/dto/request/LoginRequest.java +17 -0
  52. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/dto/request/RefreshTokenRequest.java +14 -0
  53. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/dto/response/LoginResponse.java +31 -0
  54. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/dto/response/TokenInfoResponse.java +25 -0
  55. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/enums/LoginTypeEnum.java +23 -0
  56. package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/exception/LoginException.java +23 -0
  57. package/templates/avatar-scaffold-service/k8s-app/Dockerfile +14 -0
  58. package/templates/avatar-scaffold-service/k8s-app/Dockerfile-arm64 +14 -0
  59. package/templates/avatar-scaffold-service/packaging/assembly.xml +16 -0
  60. package/templates/avatar-scaffold-service/pom.xml +150 -0
  61. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/Application.java +21 -0
  62. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/config/LoginConfig.java +20 -0
  63. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/controller/LoginController.java +37 -0
  64. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/converter/LoginConverter.java +54 -0
  65. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/feign/DemoFeign.java +21 -0
  66. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/entity/UserLoginEntity.java +33 -0
  67. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/entity/UserTokenEntity.java +39 -0
  68. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/mapper/UserLoginMapper.java +20 -0
  69. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/service/LoginService.java +22 -0
  70. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/service/impl/LoginServiceImpl.java +43 -0
  71. package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/utils/LoginUtils.java +31 -0
  72. package/templates/avatar-scaffold-service/src/main/resources/application-dev.yaml +29 -0
  73. package/templates/avatar-scaffold-service/src/main/resources/application-local.yaml +61 -0
  74. package/templates/avatar-scaffold-service/src/main/resources/application-prod.yaml +28 -0
  75. package/templates/avatar-scaffold-service/src/main/resources/application-test.yaml +28 -0
  76. package/templates/avatar-scaffold-service/src/main/resources/application.yaml +12 -0
  77. package/templates/pom.xml +98 -0
@@ -0,0 +1,56 @@
1
+ # 编码规范
2
+
3
+ > 规则类型: 🔴 强制执行
4
+ > 更新频率: 中(团队规范调整时更新)
5
+ > 相关规则: [architecture-redlines.md](architecture-redlines.md) | [git-commit.md](git-commit.md) | [version.md](version.md)
6
+
7
+ ---
8
+
9
+ ## Java 代码规范
10
+
11
+ ### 命名规范
12
+
13
+ - 类名: PascalCase(如 `UserController`)
14
+ - 方法名: camelCase(如 `getUserById`)
15
+ - 常量: UPPER_SNAKE_CASE(如 `MAX_RETRY_COUNT`)
16
+ - 包名: 全小写,使用点分隔(如 `com.iflytek.avatar.login`)
17
+
18
+ ### 代码长度限制
19
+
20
+ - 方法长度不超过 50 行
21
+ - 类文件长度不超过 500 行,超过需拆分
22
+ - 单行代码长度不超过 120 字符
23
+
24
+ ### 注释规范
25
+
26
+ - 公共 API 必须有 Javadoc 注释
27
+ - 复杂业务逻辑必须有行内注释
28
+ - 禁止无意义的注释(如 `// 获取用户` 在 `getUser()` 方法上)
29
+
30
+ ### 异常处理
31
+
32
+ - 使用 `@RestControllerAdvice` 统一处理异常
33
+ - 业务异常继承自自定义 `BusinessException`
34
+ - 禁止捕获异常后不处理(空 catch 块)
35
+
36
+ ### 日志规范
37
+
38
+ - 使用 SLF4J + Logback
39
+ - 日志级别: ERROR(错误)、WARN(警告)、INFO(关键信息)、DEBUG(调试信息)
40
+ - 禁止使用 `System.out.println()`
41
+
42
+ ---
43
+
44
+ ## Maven 配置规范
45
+
46
+ > **完整规则详见**: [version.md](version.md)
47
+
48
+ ---
49
+
50
+ ## 提交前检查
51
+
52
+ - [ ] 是否编写了单元测试
53
+ - [ ] 测试覆盖率是否达标
54
+ - [ ] 是否所有测试都通过
55
+ - [ ] 是否有 `System.out.println()`
56
+ - [ ] 是否有注释掉的大段代码
@@ -0,0 +1,59 @@
1
+ # Git 提交规范
2
+
3
+ > 规则类型: 🔴 强制执行
4
+ > 更新频率: 低
5
+ > 相关规则: [coding-standards.md](coding-standards.md)
6
+
7
+ ---
8
+
9
+ ## Commit Message 格式
10
+
11
+ ```
12
+ <type>(<scope>): <subject>
13
+
14
+ <body>
15
+
16
+ <footer>
17
+ ```
18
+
19
+ ## Type 类型
20
+
21
+ | Type | 说明 |
22
+ |------|------|
23
+ | `feat` | 新功能 |
24
+ | `fix` | 修复 bug |
25
+ | `refactor` | 重构(不改变功能) |
26
+ | `perf` | 性能优化 |
27
+ | `style` | 代码格式调整(不影响逻辑) |
28
+ | `test` | 测试相关 |
29
+ | `docs` | 文档更新 |
30
+ | `chore` | 构建/工具/依赖更新 |
31
+ | `revert` | 回滚提交 |
32
+
33
+ ## 示例
34
+
35
+ ```
36
+ feat(login): 添加手机号登录功能
37
+
38
+ - 新增手机号验证码发送接口
39
+ - 新增手机号登录接口
40
+ - 集成短信服务
41
+
42
+ Closes #123
43
+ ```
44
+
45
+ ```
46
+ fix(user): 修复用户信息更新失败的问题
47
+
48
+ 用户更新时未正确处理空值字段,导致更新失败
49
+
50
+ Fixes #456
51
+ ```
52
+
53
+ ## 提交规则
54
+
55
+ - 每次提交必须附带有意义的描述
56
+ - 一次提交只做一件事
57
+ - 提交前必须通过本地测试
58
+ - 禁止提交包含 `System.out.println()` 的代码
59
+ - 禁止提交注释掉的大段代码
@@ -0,0 +1,201 @@
1
+ # Spring Boot 分层架构规范
2
+
3
+ > 规则类型: 🔴 强制执行
4
+ > 更新频率: 低(架构调整时更新)
5
+ > 相关规则: [architecture-redlines.md](architecture-redlines.md) | [coding-standards.md](coding-standards.md)
6
+
7
+ ---
8
+
9
+ ## Controller 层职责
10
+
11
+ Controller 层**仅负责**参数校验和 Result 封装,禁止包含业务逻辑。
12
+
13
+ ### ✅ 正确示例
14
+
15
+ ```java
16
+ @RestController
17
+ @RequestMapping("/api/user")
18
+ @RequiredArgsConstructor
19
+ public class UserController {
20
+
21
+ private final UserService userService;
22
+
23
+ @GetMapping("/{id}")
24
+ public Result<UserResponse> getById(@PathVariable Long id) {
25
+ return Result.success(userService.getById(id));
26
+ }
27
+
28
+ @PostMapping
29
+ public Result<Void> create(@RequestBody @Validated UserCreateRequest request) {
30
+ userService.create(request);
31
+ return Result.success();
32
+ }
33
+
34
+ @PutMapping("/{id}")
35
+ public Result<Void> update(@PathVariable Long id,
36
+ @RequestBody @Validated UserUpdateRequest request) {
37
+ userService.update(id, request);
38
+ return Result.success();
39
+ }
40
+
41
+ @DeleteMapping("/{id}")
42
+ public Result<Void> delete(@PathVariable Long id) {
43
+ userService.delete(id);
44
+ return Result.success();
45
+ }
46
+
47
+ @GetMapping("/page")
48
+ public Result<IPage<UserResponse>> page(UserPageRequest request) {
49
+ return Result.success(userService.page(request));
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### ❌ 错误示例
55
+
56
+ ```java
57
+ @RestController
58
+ public class UserController {
59
+
60
+ @Autowired
61
+ private UserMapper userMapper; // ❌ Controller 直接依赖 Mapper
62
+
63
+ @GetMapping("/api/user/{id}")
64
+ public UserEntity getById(@PathVariable Long id) { // ❌ 直接返回 Entity,未用 Result<T>
65
+ UserEntity user = userMapper.selectById(id); // ❌ Controller 包含数据访问逻辑
66
+ if (user == null) {
67
+ throw new RuntimeException("用户不存在"); // ❌ 应使用 BusinessException
68
+ }
69
+ return user;
70
+ }
71
+ }
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Service 层职责
77
+
78
+ Service 层负责**业务逻辑编排和事务管理**。
79
+
80
+ ### 规范要点
81
+
82
+ - Service 接口定义在 `service/` 包下,实现类使用 `Impl` 后缀
83
+ - 事务注解 `@Transactional` 只加在 Service 实现类方法上
84
+ - 写操作必须加 `@Transactional(rollbackFor = Exception.class)`
85
+ - 只读操作加 `@Transactional(readOnly = true)`
86
+ - Service 之间可以互相调用,但禁止循环依赖
87
+
88
+ ### ✅ 正确示例
89
+
90
+ ```java
91
+ public interface UserService extends IService<UserEntity> {
92
+ UserResponse getById(Long id);
93
+ void create(UserCreateRequest request);
94
+ IPage<UserResponse> page(UserPageRequest request);
95
+ }
96
+
97
+ @Service
98
+ @RequiredArgsConstructor
99
+ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity>
100
+ implements UserService {
101
+
102
+ @Override
103
+ @Transactional(readOnly = true)
104
+ public UserResponse getById(Long id) {
105
+ UserEntity entity = getBaseMapper().selectById(id);
106
+ if (entity == null) {
107
+ throw new BusinessException("用户不存在");
108
+ }
109
+ return convertToResponse(entity);
110
+ }
111
+
112
+ @Override
113
+ @Transactional(rollbackFor = Exception.class)
114
+ public void create(UserCreateRequest request) {
115
+ UserEntity entity = convertToEntity(request);
116
+ save(entity);
117
+ }
118
+ }
119
+ ```
120
+
121
+ ### ❌ 错误示例
122
+
123
+ ```java
124
+ @Service
125
+ public class UserServiceImpl {
126
+
127
+ @Transactional // ❌ 缺少 rollbackFor,默认只回滚 RuntimeException
128
+ public void create(UserCreateRequest request) {
129
+ // ...
130
+ }
131
+
132
+ public Result<UserResponse> getById(Long id) { // ❌ Service 不应返回 Result,那是 Controller 的职责
133
+ // ...
134
+ }
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Mapper(DAO)层职责
141
+
142
+ Mapper 层负责**纯数据访问**,禁止包含业务逻辑。
143
+
144
+ ### 规范要点
145
+
146
+ - Mapper 接口继承 `BaseMapper<T>`,放在 `dao/` 包下
147
+ - 数据库实体类放在 `dao/beans/` 包下
148
+ - 复杂 SQL 使用 XML 映射文件或 `@Select` 等注解
149
+ - 禁止在 Mapper 中编写业务判断逻辑
150
+
151
+ ### ✅ 正确示例
152
+
153
+ ```java
154
+ @Mapper
155
+ public interface UserMapper extends BaseMapper<UserEntity> {
156
+
157
+ @Select("SELECT * FROM t_user WHERE email = #{email} AND is_deleted = 0")
158
+ UserEntity selectByEmail(@Param("email") String email);
159
+ }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Entity / DTO / VO 严格区分
165
+
166
+ > 完整的模块包结构详见 [architecture-redlines.md](architecture-redlines.md#目录组织规范)
167
+
168
+ | 类型 | 所在模块 | 包路径 | 用途 |
169
+ |------|---------|--------|------|
170
+ | Entity (DO/PO) | Service 模块 | `dao/beans/` | 数据库表映射,仅在 Mapper 和 Service 层流转 |
171
+ | Request DTO | API 模块 | `entity/request/` | 接收前端/调用方请求参数 |
172
+ | Response DTO | API 模块 | `entity/response/` | 返回给前端/调用方的数据 |
173
+
174
+ ### 🔴 跨层依赖规则
175
+
176
+ ```
177
+ Controller → Service → Mapper
178
+ ↓ ↓ ↓
179
+ Request DTO Entity Entity
180
+ Response DTO Request DTO
181
+ Response DTO
182
+ ```
183
+
184
+ - ❌ Controller 禁止直接使用 Entity
185
+ - ❌ Entity 禁止出现在 API 模块中
186
+ - ❌ Mapper 层禁止使用 DTO
187
+ - ✅ Service 层负责 Entity ↔ DTO 的转换
188
+
189
+ ---
190
+
191
+ ## 分层检查清单
192
+
193
+ - [ ] Controller 是否只做参数校验和 Result 封装
194
+ - [ ] Controller 是否返回 `Result<T>` 类型
195
+ - [ ] Service 写操作是否加了 `@Transactional(rollbackFor = Exception.class)`
196
+ - [ ] Service 只读操作是否加了 `@Transactional(readOnly = true)`
197
+ - [ ] Entity 是否只在 Service 和 Mapper 层使用
198
+ - [ ] DTO 和 Entity 之间是否在 Service 层做了转换
199
+ - [ ] Mapper 是否继承了 `BaseMapper<T>`
200
+ - [ ] 是否存在 Controller 直接调用 Mapper 的情况
201
+ - [ ] 是否存在 Service 返回 `Result<T>` 的情况
@@ -0,0 +1,263 @@
1
+ # MyBatis Plus 使用规范
2
+
3
+ > 规则类型: 🔴 强制执行
4
+ > 更新频率: 低(框架升级时更新)
5
+ > 相关规则: [version.md](version.md)(MyBatis Plus 3.5.15)| [layered-architecture.md](layered-architecture.md)
6
+
7
+ ---
8
+
9
+ ## Entity 注解规范
10
+
11
+ ### 基础 Entity 模板
12
+
13
+ ```java
14
+ @Data
15
+ @TableName("t_user")
16
+ public class UserEntity {
17
+
18
+ @TableId(type = IdType.ASSIGN_ID)
19
+ private Long id;
20
+
21
+ @TableField("username")
22
+ private String username;
23
+
24
+ @TableField("email")
25
+ private String email;
26
+
27
+ @TableField("status")
28
+ private Integer status;
29
+
30
+ @TableField(fill = FieldFill.INSERT)
31
+ private LocalDateTime createTime;
32
+
33
+ @TableField(fill = FieldFill.INSERT_UPDATE)
34
+ private LocalDateTime updateTime;
35
+
36
+ @TableLogic
37
+ @TableField("is_deleted")
38
+ private Integer isDeleted;
39
+ }
40
+ ```
41
+
42
+ ### 注解说明
43
+
44
+ | 注解 | 用途 | 规范 |
45
+ |------|------|------|
46
+ | `@TableName` | 表名映射 | 🔴 必须显式指定,使用 `t_` 前缀 |
47
+ | `@TableId` | 主键 | 🔴 必须指定,推荐 `IdType.ASSIGN_ID`(雪花算法) |
48
+ | `@TableField` | 字段映射 | 🟡 字段名与列名不一致时必须指定 |
49
+ | `@TableLogic` | 逻辑删除 | 🔴 必须使用逻辑删除,字段名 `is_deleted` |
50
+ | `FieldFill` | 自动填充 | 🔴 `createTime` 和 `updateTime` 必须自动填充 |
51
+
52
+ ### ❌ 错误的 Entity 写法
53
+
54
+ ```java
55
+ @Data
56
+ public class User { // ❌ 缺少 @TableName
57
+ private Long id; // ❌ 缺少 @TableId
58
+ private Date createTime; // ❌ 使用 Date 而非 LocalDateTime,缺少自动填充
59
+ // ❌ 缺少 isDeleted 逻辑删除字段
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 自动填充配置
66
+
67
+ ```java
68
+ @Component
69
+ public class AvatarMetaObjectHandler implements MetaObjectHandler {
70
+
71
+ @Override
72
+ public void insertFill(MetaObject metaObject) {
73
+ this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
74
+ this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
75
+ }
76
+
77
+ @Override
78
+ public void updateFill(MetaObject metaObject) {
79
+ this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
80
+ }
81
+ }
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Mapper 规范
87
+
88
+ ```java
89
+ @Mapper
90
+ public interface UserMapper extends BaseMapper<UserEntity> {
91
+ // 简单 CRUD 直接继承 BaseMapper,无需手写
92
+ // 复杂查询使用 XML 或注解
93
+ }
94
+ ```
95
+
96
+ - 🔴 必须继承 `BaseMapper<T>`
97
+ - 🔴 必须添加 `@Mapper` 注解(或在启动类加 `@MapperScan`)
98
+
99
+ ---
100
+
101
+ ## Service 规范
102
+
103
+ ### ✅ 正确:继承 IService / ServiceImpl
104
+
105
+ ```java
106
+ public interface UserService extends IService<UserEntity> {
107
+ // 自定义业务方法
108
+ UserResponse getUserDetail(Long id);
109
+ }
110
+
111
+ @Service
112
+ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity>
113
+ implements UserService {
114
+
115
+ @Override
116
+ public UserResponse getUserDetail(Long id) {
117
+ UserEntity entity = getById(id);
118
+ // 转换为 DTO ...
119
+ return response;
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### ❌ 错误:不继承 IService
125
+
126
+ ```java
127
+ @Service
128
+ public class UserService { // ❌ 未继承 IService,无法使用内置 CRUD 方法
129
+ @Autowired
130
+ private UserMapper userMapper;
131
+
132
+ public UserEntity getById(Long id) {
133
+ return userMapper.selectById(id); // ❌ 手动调用 Mapper,重复造轮子
134
+ }
135
+ }
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 查询规范
141
+
142
+ ### 🔴 LambdaQueryWrapper 优先
143
+
144
+ ```java
145
+ // ✅ 正确:使用 LambdaQueryWrapper,类型安全
146
+ LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
147
+ wrapper.eq(UserEntity::getStatus, 1)
148
+ .like(StringUtils.isNotBlank(name), UserEntity::getUsername, name)
149
+ .orderByDesc(UserEntity::getCreateTime);
150
+ List<UserEntity> users = userMapper.selectList(wrapper);
151
+
152
+ // ❌ 错误:使用 QueryWrapper 字符串硬编码
153
+ QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
154
+ wrapper.eq("status", 1); // ❌ 字段名硬编码,重构不友好
155
+ ```
156
+
157
+ ### 🔴 分页查询必须使用 Page<T>
158
+
159
+ ```java
160
+ // ✅ 正确:使用 MyBatis Plus 分页
161
+ public IPage<UserEntity> pageQuery(int current, int size) {
162
+ Page<UserEntity> page = new Page<>(current, size);
163
+ LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
164
+ wrapper.eq(UserEntity::getStatus, 1);
165
+ return userMapper.selectPage(page, wrapper);
166
+ }
167
+
168
+ // ❌ 错误:手写 LIMIT 分页
169
+ @Select("SELECT * FROM t_user WHERE status = 1 LIMIT #{offset}, #{size}")
170
+ List<UserEntity> pageQuery(@Param("offset") int offset, @Param("size") int size);
171
+ ```
172
+
173
+ ### 分页插件配置
174
+
175
+ ```java
176
+ @Configuration
177
+ public class MyBatisPlusConfig {
178
+
179
+ @Bean
180
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
181
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
182
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
183
+ return interceptor;
184
+ }
185
+ }
186
+ ```
187
+
188
+ ---
189
+
190
+ ## 逻辑删除配置
191
+
192
+ ```yaml
193
+ mybatis-plus:
194
+ global-config:
195
+ db-config:
196
+ logic-delete-field: isDeleted
197
+ logic-delete-value: 1
198
+ logic-not-delete-value: 0
199
+ ```
200
+
201
+ 配置后,所有继承 `BaseMapper` 的查询/更新/删除方法自动追加逻辑删除条件。
202
+
203
+ ---
204
+
205
+ ## 性能反模式
206
+
207
+ ### ❌ N+1 查询问题
208
+
209
+ ```java
210
+ // ❌ 错误:循环查询数据库
211
+ List<OrderEntity> orders = orderMapper.selectList(null);
212
+ for (OrderEntity order : orders) {
213
+ UserEntity user = userMapper.selectById(order.getUserId()); // N 次查询!
214
+ }
215
+
216
+ // ✅ 正确:批量查询
217
+ List<OrderEntity> orders = orderMapper.selectList(null);
218
+ Set<Long> userIds = orders.stream().map(OrderEntity::getUserId).collect(Collectors.toSet());
219
+ List<UserEntity> users = userMapper.selectBatchIds(userIds); // 1 次查询
220
+ Map<Long, UserEntity> userMap = users.stream().collect(Collectors.toMap(UserEntity::getId, Function.identity()));
221
+ ```
222
+
223
+ ### ❌ 无 limit 的 selectList
224
+
225
+ ```java
226
+ // ❌ 危险:无条件全表查询,数据量大时 OOM
227
+ List<UserEntity> allUsers = userMapper.selectList(null);
228
+
229
+ // ✅ 正确:始终带条件或分页
230
+ Page<UserEntity> page = new Page<>(1, 100);
231
+ IPage<UserEntity> users = userMapper.selectPage(page, wrapper);
232
+ ```
233
+
234
+ ### ❌ 在循环中执行数据库操作
235
+
236
+ ```java
237
+ // ❌ 错误:循环插入
238
+ for (UserEntity user : userList) {
239
+ userMapper.insert(user);
240
+ }
241
+
242
+ // ✅ 正确:批量操作
243
+ userService.saveBatch(userList);
244
+ // 或指定批次大小
245
+ userService.saveBatch(userList, 500);
246
+ ```
247
+
248
+ ---
249
+
250
+ ## MyBatis Plus 使用检查清单
251
+
252
+ - [ ] Entity 是否标注 `@TableName` 并使用 `t_` 前缀
253
+ - [ ] 主键是否使用 `@TableId(type = IdType.ASSIGN_ID)`
254
+ - [ ] 是否包含 `createTime`、`updateTime` 自动填充字段
255
+ - [ ] 是否包含 `isDeleted` 逻辑删除字段
256
+ - [ ] Mapper 是否继承 `BaseMapper<T>`
257
+ - [ ] Service 是否继承 `IService<T>` / `ServiceImpl<M, T>`
258
+ - [ ] 查询是否使用 `LambdaQueryWrapper` 而非 `QueryWrapper`
259
+ - [ ] 分页是否使用 `Page<T>` 而非手写 LIMIT
260
+ - [ ] 是否存在 N+1 查询问题
261
+ - [ ] 是否存在无条件的 `selectList(null)` 全表查询
262
+ - [ ] 批量操作是否使用 `saveBatch` / `updateBatchById`
263
+ - [ ] 时间字段是否使用 `LocalDateTime` 而非 `Date`
@@ -0,0 +1,41 @@
1
+ # 技术栈约束
2
+
3
+ > 规则类型: 🔴 强制执行
4
+ > 更新频率: 低(框架升级时更新)
5
+ > 相关规则: [architecture-redlines.md](architecture-redlines.md) | [version.md](version.md)
6
+
7
+ ---
8
+
9
+ ## 必须使用的技术
10
+
11
+ | 模块 | 技术栈 | 版本 |
12
+ |------|--------|------|
13
+ | Java | OpenJDK | 21 |
14
+ | 构建工具 | Maven | 3.8.6+ |
15
+ | 框架核心 | Spring Boot | 3.5.3 |
16
+ | 微服务框架 | Spring Cloud | 2025.0.0 |
17
+ | 服务治理 | Spring Cloud Alibaba | 2023.0.3.2 |
18
+ | 注册中心 | Nacos | 通过 avatar-boot-starter-nacos |
19
+ | 服务调用 | OpenFeign | 通过 avatar-boot-starter-feign |
20
+ | 数据库 | MySQL | 通过 avatar-boot-starter-mysql |
21
+ | 缓存 | Redis | 通过 avatar-boot-starter-redis |
22
+ | ORM | MyBatis Plus | 3.5.15 |
23
+ | 工具库 | Hutool | 5.8.34 |
24
+ | JSON | Fastjson2 | 2.0.54 |
25
+
26
+ ---
27
+
28
+ ## 核心原则
29
+
30
+ ### 🔴 必须使用 Avatar Boot 封装组件
31
+
32
+ - ❌ **禁止**直接引用 Spring Boot、Spring Cloud 原生 starter
33
+ - ✅ **必须**使用 Avatar Boot 封装的 starter 组件
34
+ - ✅ **必须**配置 iFlytek Maven 仓库
35
+
36
+ ### 🔴 必须使用 Jakarta 命名空间
37
+
38
+ - ❌ `javax.*` 已废弃
39
+ - ✅ `jakarta.*` 是正确的命名空间
40
+
41
+ > **详细配置、示例和版本信息请参考**: [version.md](version.md)