ai-engineering-init 1.4.3 → 1.6.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 (131) hide show
  1. package/.cursor/skills/bug-detective/SKILL.md +19 -19
  2. package/.cursor/skills/project-navigator/SKILL.md +164 -258
  3. package/README.md +20 -236
  4. package/bin/index.js +437 -7
  5. package/package.json +7 -1
  6. package/scripts/build-skills.js +180 -0
  7. package/src/platform-map.json +56 -0
  8. package/src/skills/add-skill/SKILL.md +488 -0
  9. package/src/skills/add-todo/SKILL.md +269 -0
  10. package/src/skills/api-development/SKILL.md +266 -0
  11. package/src/skills/architecture-design/SKILL.md +262 -0
  12. package/src/skills/backend-annotations/SKILL.md +302 -0
  13. package/src/skills/banana-image/CHANGELOG.md +37 -0
  14. package/src/skills/banana-image/README.md +146 -0
  15. package/src/skills/banana-image/SKILL.md +171 -0
  16. package/src/skills/banana-image/assets/logo.png +0 -0
  17. package/src/skills/banana-image/references/advanced-usage.md +189 -0
  18. package/src/skills/banana-image/scripts/apply_template.py +125 -0
  19. package/src/skills/banana-image/scripts/banana_image_exec.ts +412 -0
  20. package/src/skills/banana-image/scripts/batch_prep.py +82 -0
  21. package/src/skills/banana-image/scripts/package-lock.json +1437 -0
  22. package/src/skills/banana-image/scripts/package.json +18 -0
  23. package/src/skills/banana-image/scripts/requirements.txt +10 -0
  24. package/src/skills/banana-image/templates/poster.json +22 -0
  25. package/src/skills/banana-image/templates/product.json +17 -0
  26. package/src/skills/banana-image/templates/social.json +22 -0
  27. package/src/skills/banana-image/templates/thumbnail.json +17 -0
  28. package/src/skills/brainstorm/SKILL.md +216 -0
  29. package/src/skills/bug-detective/SKILL.md +256 -0
  30. package/src/skills/bug-detective/references/error-patterns.md +242 -0
  31. package/src/skills/check/SKILL.md +367 -0
  32. package/src/skills/code-patterns/SKILL.md +280 -0
  33. package/src/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  34. package/src/skills/codex-code-review/SKILL.md +135 -0
  35. package/src/skills/collaborating-with-codex/SKILL.md +174 -0
  36. package/src/skills/collaborating-with-codex/scripts/codex_bridge.py +275 -0
  37. package/src/skills/collaborating-with-gemini/SKILL.md +194 -0
  38. package/src/skills/collaborating-with-gemini/scripts/gemini_bridge.py +275 -0
  39. package/src/skills/crud/SKILL.md +265 -0
  40. package/src/skills/crud-development/SKILL.md +409 -0
  41. package/src/skills/data-permission/SKILL.md +292 -0
  42. package/src/skills/data-permission/references/custom-data-scope.md +90 -0
  43. package/src/skills/database-ops/SKILL.md +407 -0
  44. package/src/skills/dev/SKILL.md +187 -0
  45. package/src/skills/error-handler/SKILL.md +371 -0
  46. package/src/skills/file-oss-management/SKILL.md +255 -0
  47. package/src/skills/file-oss-management/references/entities.md +105 -0
  48. package/src/skills/file-oss-management/references/service-impl.md +104 -0
  49. package/src/skills/git-workflow/SKILL.md +397 -0
  50. package/src/skills/init-docs/SKILL.md +194 -0
  51. package/src/skills/json-serialization/SKILL.md +357 -0
  52. package/src/skills/leniu-api-development/SKILL.md +319 -0
  53. package/src/skills/leniu-api-development/references/real-examples.md +273 -0
  54. package/src/skills/leniu-architecture-design/SKILL.md +383 -0
  55. package/src/skills/leniu-backend-annotations/SKILL.md +277 -0
  56. package/src/skills/leniu-brainstorm/SKILL.md +242 -0
  57. package/src/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  58. package/src/skills/leniu-code-patterns/SKILL.md +411 -0
  59. package/src/skills/leniu-crud-development/SKILL.md +404 -0
  60. package/src/skills/leniu-crud-development/references/templates.md +597 -0
  61. package/src/skills/leniu-customization-location/SKILL.md +410 -0
  62. package/src/skills/leniu-data-permission/SKILL.md +341 -0
  63. package/src/skills/leniu-database-ops/SKILL.md +426 -0
  64. package/src/skills/leniu-error-handler/SKILL.md +462 -0
  65. package/src/skills/leniu-java-amount-handling/SKILL.md +461 -0
  66. package/src/skills/leniu-java-code-style/SKILL.md +510 -0
  67. package/src/skills/leniu-java-concurrent/SKILL.md +400 -0
  68. package/src/skills/leniu-java-entity/SKILL.md +237 -0
  69. package/src/skills/leniu-java-entity/references/templates.md +237 -0
  70. package/src/skills/leniu-java-export/SKILL.md +570 -0
  71. package/src/skills/leniu-java-logging/SKILL.md +229 -0
  72. package/src/skills/leniu-java-logging/references/data-mask.md +46 -0
  73. package/src/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  74. package/src/skills/leniu-java-mq/SKILL.md +338 -0
  75. package/src/skills/leniu-java-mybatis/SKILL.md +267 -0
  76. package/src/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  77. package/src/skills/leniu-java-report-query-param/SKILL.md +291 -0
  78. package/src/skills/leniu-java-task/SKILL.md +367 -0
  79. package/src/skills/leniu-java-total-line/SKILL.md +196 -0
  80. package/src/skills/leniu-marketing-price-rule-customizer/SKILL.md +301 -0
  81. package/src/skills/leniu-marketing-recharge-rule-customizer/SKILL.md +285 -0
  82. package/src/skills/leniu-mealtime/SKILL.md +215 -0
  83. package/src/skills/leniu-redis-cache/SKILL.md +331 -0
  84. package/src/skills/leniu-report-customization/SKILL.md +335 -0
  85. package/src/skills/leniu-report-customization/references/table-fields.md +93 -0
  86. package/src/skills/leniu-report-standard-customization/SKILL.md +328 -0
  87. package/src/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  88. package/src/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  89. package/src/skills/leniu-security-guard/SKILL.md +306 -0
  90. package/src/skills/leniu-utils-toolkit/SKILL.md +380 -0
  91. package/src/skills/mysql-debug/SKILL.md +364 -0
  92. package/src/skills/next/SKILL.md +137 -0
  93. package/src/skills/openspec-apply-change/SKILL.md +165 -0
  94. package/src/skills/openspec-archive-change/SKILL.md +122 -0
  95. package/src/skills/openspec-bulk-archive-change/SKILL.md +254 -0
  96. package/src/skills/openspec-continue-change/SKILL.md +126 -0
  97. package/src/skills/openspec-explore/SKILL.md +299 -0
  98. package/src/skills/openspec-ff-change/SKILL.md +109 -0
  99. package/src/skills/openspec-new-change/SKILL.md +82 -0
  100. package/src/skills/openspec-onboard/SKILL.md +414 -0
  101. package/src/skills/openspec-sync-specs/SKILL.md +146 -0
  102. package/src/skills/openspec-verify-change/SKILL.md +176 -0
  103. package/src/skills/performance-doctor/SKILL.md +303 -0
  104. package/src/skills/progress/SKILL.md +193 -0
  105. package/src/skills/project-navigator/SKILL.md +211 -0
  106. package/src/skills/redis-cache/SKILL.md +333 -0
  107. package/src/skills/redis-cache/references/listeners.md +23 -0
  108. package/src/skills/scheduled-jobs/SKILL.md +314 -0
  109. package/src/skills/security-guard/SKILL.md +353 -0
  110. package/src/skills/security-guard/references/encrypt-config.md +103 -0
  111. package/src/skills/security-guard/references/sensitive-strategies.md +42 -0
  112. package/src/skills/sms-mail/SKILL.md +308 -0
  113. package/src/skills/sms-mail/references/mail-config.md +88 -0
  114. package/src/skills/sms-mail/references/sms-config.md +74 -0
  115. package/src/skills/social-login/SKILL.md +266 -0
  116. package/src/skills/social-login/references/provider-configs.md +118 -0
  117. package/src/skills/start/SKILL.md +154 -0
  118. package/src/skills/store-pc/SKILL.md +366 -0
  119. package/src/skills/sync/SKILL.md +149 -0
  120. package/src/skills/task-tracker/SKILL.md +307 -0
  121. package/src/skills/tech-decision/SKILL.md +393 -0
  122. package/src/skills/tenant-management/SKILL.md +288 -0
  123. package/src/skills/tenant-management/references/tenant-scenarios.md +91 -0
  124. package/src/skills/test-development/SKILL.md +301 -0
  125. package/src/skills/test-development/references/parameterized-examples.md +119 -0
  126. package/src/skills/ui-pc/SKILL.md +438 -0
  127. package/src/skills/update-status/SKILL.md +159 -0
  128. package/src/skills/utils-toolkit/SKILL.md +362 -0
  129. package/src/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  130. package/src/skills/websocket-sse/SKILL.md +271 -0
  131. package/src/skills/workflow-engine/SKILL.md +321 -0
@@ -0,0 +1,404 @@
1
+ ---
2
+ name: leniu-crud-development
3
+ description: |
4
+ leniu 项目 CRUD 开发规范。基于 pigx-framework 四层架构(Controller -> Business -> Service -> Mapper)。
5
+ 涵盖命名规范、代码模板、分页模式、事务管理、并发处理、代码质量要点。
6
+
7
+ 触发场景:
8
+ - 新建 leniu 业务模块的 CRUD 功能
9
+ - 创建 Entity、DTO、VO、Service、Mapper、Controller
10
+ - 分页查询(PageHelper / MyBatis-Plus)
11
+ - 事务管理(多表操作、self 自注入)
12
+ - 报表 Service 模式(含数据权限、并发查询)
13
+
14
+ 适用项目:
15
+ - leniu-tengyun-core(云食堂核心服务)
16
+ - leniu-yunshitang(云食堂业务服务)
17
+
18
+ 触发词:CRUD、增删改查、新建模块、Business层、Service、Mapper、Controller、分页查询、LeRequest、PageDTO、PageVO、事务管理、报表Service
19
+ ---
20
+
21
+ # leniu CRUD 开发规范
22
+
23
+ > 完整代码模板见 `references/templates.md`
24
+
25
+ ## 项目路径
26
+
27
+ | 项目 | 路径 |
28
+ |------|------|
29
+ | leniu-tengyun-core | `/Users/xujiajun/Developer/gongsi_proj/leniu-api/leniu-tengyun-core` |
30
+ | leniu-yunshitang | `/Users/xujiajun/Developer/gongsi_proj/leniu-api/leniu-tengyun/leniu-yunshitang` |
31
+ | 包名前缀 | `net.xnzn.core.*` |
32
+
33
+ ---
34
+
35
+ ## 架构概览
36
+
37
+ | 项 | 规范 |
38
+ |----|------|
39
+ | 架构 | Controller -> Business -> Service -> Mapper(四层) |
40
+ | 无 DAO 层 | Service 直接注入 Mapper |
41
+ | 对象转换 | `BeanUtil.copyProperties()` (Hutool) |
42
+ | Entity 基类 | 无基类,自定义审计字段 |
43
+ | 请求封装 | `LeRequest<T>` |
44
+ | 响应封装 | `Page<T>` / `LeResponse<T>` / `void` |
45
+ | 分组校验 | `InsertGroup` / `UpdateGroup` |
46
+ | 认证注解 | `@RequiresAuthentication` / `@RequiresGuest` |
47
+ | 异常类 | `LeException` |
48
+ | 审计字段 | crby/crtime/upby/uptime |
49
+ | 逻辑删除 | del_flag(1=删除, 2=正常) |
50
+ | 主键 | 雪花ID `Id.next()` 或自增 |
51
+ | Mapper XML | 与 Java 同目录(非 resources/mapper) |
52
+ | 验证包 | `jakarta.validation.*`(JDK 21) |
53
+
54
+ ---
55
+
56
+ ## 标准包结构
57
+
58
+ ```
59
+ net.xnzn.core.[module]/
60
+ +-- controller/ # 按端分:web/mobile/android
61
+ +-- business/impl/ # 业务编排(跨 Service 协调)
62
+ +-- service/impl/ # 单表 CRUD、事务
63
+ +-- mapper/ # Mapper + XML(同目录)
64
+ +-- model/ # Entity
65
+ +-- vo/ # 响应对象
66
+ +-- dto/ # 请求参数
67
+ +-- constants/ # 枚举和常量
68
+ ```
69
+
70
+ ---
71
+
72
+ ## 命名规范
73
+
74
+ | 类型 | 命名 | 示例 |
75
+ |------|------|------|
76
+ | Entity | `Xxx` / `XxxEntity` | `OrderInfo` |
77
+ | DTO | `XxxDTO` | `OrderInfoDTO` |
78
+ | VO | `XxxVO` | `OrderInfoVO` |
79
+ | Service 接口 | `XxxService` | `OrderInfoService` |
80
+ | Service 实现 | `XxxServiceImpl` | `OrderInfoServiceImpl` |
81
+ | Mapper | `XxxMapper` | `OrderInfoMapper` |
82
+ | Controller (Web) | `XxxWebController` | `OrderInfoWebController` |
83
+ | Business | `XxxWebBusiness` | `OrderWebBusiness` |
84
+
85
+ ### Controller 路由前缀
86
+
87
+ | 端 | 前缀 |
88
+ |----|------|
89
+ | Web 管理端 | `/api/v2/web/{module}` |
90
+ | 移动端 | `/api/v2/mobile/{module}` |
91
+ | 设备端 | `/api/v2/android/{module}` |
92
+ | 开放接口 | `/api/v2/open/{module}` |
93
+
94
+ ---
95
+
96
+ ## 核心代码片段
97
+
98
+ ### Entity 审计字段
99
+
100
+ ```java
101
+ @TableField(value = "crby", fill = FieldFill.INSERT)
102
+ private String crby;
103
+ @TableField(value = "crtime", fill = FieldFill.INSERT)
104
+ private LocalDateTime crtime;
105
+ @TableField(value = "upby", fill = FieldFill.INSERT_UPDATE)
106
+ private String upby;
107
+ @TableField(value = "uptime", fill = FieldFill.INSERT_UPDATE)
108
+ private LocalDateTime uptime;
109
+ @TableField("del_flag")
110
+ private Integer delFlag; // 1=删除, 2=正常
111
+ ```
112
+
113
+ ### Service 注入模式
114
+
115
+ ```java
116
+ @Slf4j
117
+ @Service
118
+ public class XxxServiceImpl implements XxxService {
119
+ @Resource
120
+ private XxxMapper xxxMapper; // 直接注入 Mapper,无 DAO 层
121
+
122
+ // 不继承 ServiceImpl,只实现接口
123
+ }
124
+ ```
125
+
126
+ ### Controller 请求封装
127
+
128
+ ```java
129
+ @PostMapping("/add")
130
+ @RequiresAuthentication
131
+ public Long add(@Validated(InsertGroup.class) @RequestBody LeRequest<XxxDTO> request) {
132
+ return xxxService.add(request.getContent());
133
+ }
134
+
135
+ @GetMapping("/get/{id}")
136
+ @RequiresGuest
137
+ public XxxVO getById(@PathVariable Long id) {
138
+ return xxxService.getById(id);
139
+ }
140
+ ```
141
+
142
+ ### 查询条件构建
143
+
144
+ ```java
145
+ private LambdaQueryWrapper<XxxEntity> buildWrapper(XxxDTO dto) {
146
+ LambdaQueryWrapper<XxxEntity> wrapper = Wrappers.lambdaQuery();
147
+ wrapper.eq(XxxEntity::getDelFlag, 2); // 只查正常数据
148
+ // String -> like, 非 String -> eq/in/between
149
+ if (StrUtil.isNotBlank(dto.getName())) {
150
+ wrapper.like(XxxEntity::getName, dto.getName());
151
+ }
152
+ if (ObjectUtil.isNotNull(dto.getStatus())) {
153
+ wrapper.eq(XxxEntity::getStatus, dto.getStatus());
154
+ }
155
+ wrapper.orderByDesc(XxxEntity::getCrtime);
156
+ return wrapper;
157
+ }
158
+ ```
159
+
160
+ ### 对象转换与空值防护
161
+
162
+ ```java
163
+ // 新增
164
+ XxxEntity entity = BeanUtil.copyProperties(dto, XxxEntity.class);
165
+ entity.setDelFlag(2);
166
+ xxxMapper.insert(entity);
167
+
168
+ // 查询判空
169
+ XxxEntity entity = Optional.ofNullable(xxxMapper.selectById(id))
170
+ .orElseThrow(() -> new LeException("记录不存在"));
171
+ return BeanUtil.copyProperties(entity, XxxVO.class);
172
+
173
+ // 列表空值兜底
174
+ List<XxxEntity> list = xxxMapper.selectList(wrapper);
175
+ if (CollUtil.isEmpty(list)) {
176
+ return Collections.emptyList();
177
+ }
178
+ return BeanUtil.copyToList(list, XxxVO.class);
179
+ ```
180
+
181
+ ---
182
+
183
+ ## 分页查询
184
+
185
+ ### MyBatis-Plus 分页
186
+
187
+ ```java
188
+ public Page<XxxVO> page(XxxDTO dto) {
189
+ LambdaQueryWrapper<XxxEntity> wrapper = buildWrapper(dto);
190
+ Page<XxxEntity> page = new Page<>(dto.getPageNum(), dto.getPageSize());
191
+ Page<XxxEntity> result = xxxMapper.selectPage(page, wrapper);
192
+
193
+ Page<XxxVO> voPage = new Page<>();
194
+ BeanUtil.copyProperties(result, voPage, "records");
195
+ voPage.setRecords(BeanUtil.copyToList(result.getRecords(), XxxVO.class));
196
+ return voPage;
197
+ }
198
+ ```
199
+
200
+ ### PageHelper 分页(报表场景)
201
+
202
+ ```java
203
+ public PageVO<XxxVO> pageList(XxxPageParam param) {
204
+ if (Objects.nonNull(param.getPage())) {
205
+ PageMethod.startPage(param.getPage()); // 传 PageDTO,紧接查询前调用
206
+ }
207
+ List<XxxVO> records = xxxMapper.pageList(param);
208
+ return PageVO.of(records);
209
+ }
210
+ ```
211
+
212
+ ### 带合计行的分页
213
+
214
+ ```java
215
+ public ReportBaseTotalVO<XxxVO> pageWithTotal(XxxPageParam param) {
216
+ MgrUserAuthPO authPO = mgrAuthApi.getUserAuthPO();
217
+ ReportDataPermissionParam dp = reportDataPermissionService.getDataPermission(authPO);
218
+
219
+ if (Objects.nonNull(param.getPage())) {
220
+ PageMethod.startPage(param.getPage());
221
+ }
222
+ List<XxxVO> list = xxxMapper.getSummaryList(param, authPO, dp);
223
+ XxxVO totalLine = Optional.ofNullable(xxxMapper.getSummaryTotal(param, authPO, dp))
224
+ .orElse(new XxxVO());
225
+ return new ReportBaseTotalVO<XxxVO>()
226
+ .setResultPage(PageVO.of(list))
227
+ .setTotalLine(totalLine);
228
+ }
229
+ ```
230
+
231
+ **分页关键规则**:
232
+ 1. `PageMethod.startPage(param.getPage())` 传 PageDTO 对象,紧接查询前调用
233
+ 2. startPage 与查询之间不能插入其他查询
234
+ 3. Mapper 方法返回 List 即可,PageHelper 自动转换
235
+
236
+ ---
237
+
238
+ ## 事务管理
239
+
240
+ ### 多表操作必须加事务
241
+
242
+ ```java
243
+ @Transactional(rollbackFor = Exception.class)
244
+ public void createOrderWithStock(OrderDTO dto) {
245
+ orderMapper.insert(order);
246
+ orderDetailMapper.insert(details);
247
+ stockMapper.deduct(dto.getStockId(), dto.getQuantity());
248
+ }
249
+ ```
250
+
251
+ ### Self 自注入(同类事务调用)
252
+
253
+ ```java
254
+ @Slf4j
255
+ @Service
256
+ public class OrderPlaceBusiness {
257
+ @Autowired @Lazy
258
+ private OrderPlaceBusiness self; // 自注入,触发 AOP 代理
259
+
260
+ public void doSave(OrderSavePO po) {
261
+ self.save(po, false, false); // 通过 self 调用,@Transactional 生效
262
+ }
263
+
264
+ @Transactional(rollbackFor = Exception.class)
265
+ public void save(OrderSavePO po, boolean orderExists, boolean removeDetails) {
266
+ // 多表操作...
267
+ }
268
+ }
269
+ ```
270
+
271
+ **规则**:同类方法互调,被调用方有 `@Transactional` -> 必须 `self.xxx()` 而非 `this.xxx()`
272
+
273
+ ---
274
+
275
+ ## 报表 Service 模式
276
+
277
+ ```java
278
+ @Slf4j
279
+ @Service
280
+ public class ReportXxxService { // 无接口,直接 @Service 类
281
+ @Autowired private ReportXxxMapper reportXxxMapper;
282
+ @Autowired private MgrAuthV2Api mgrAuthApi;
283
+ @Autowired private ReportDataPermissionService reportDataPermissionService;
284
+ @Resource(name = "yunshitangTaskExecutor")
285
+ private AsyncTaskExecutor asyncTaskExecutor;
286
+
287
+ public ReportBaseTotalVO<XxxVO> pageXxx(XxxParam param) {
288
+ long start = System.currentTimeMillis();
289
+ MgrUserAuthPO authPO = mgrAuthApi.getUserAuthPO();
290
+ ReportDataPermissionParam dp = reportDataPermissionService.getDataPermission(authPO);
291
+ // ... 查询 + 合计行
292
+ log.info("pageXxx耗时:{}", System.currentTimeMillis() - start);
293
+ return result;
294
+ }
295
+ }
296
+ ```
297
+
298
+ **关键点**:`mgrAuthApi.getUserAuthPO()` 获取权限、`reportDataPermissionService.getDataPermission()` 获取数据权限、线程池 `yunshitangTaskExecutor`
299
+
300
+ ---
301
+
302
+ ## 并发处理
303
+
304
+ ### CompletableFuture 并行查询
305
+
306
+ ```java
307
+ @Resource(name = "yunshitangTaskExecutor")
308
+ private AsyncTaskExecutor asyncTaskExecutor;
309
+
310
+ CompletableFuture<List<A>> futureA = CompletableFuture
311
+ .supplyAsync(() -> mapper.getTypeA(param, authPO, dp), asyncTaskExecutor);
312
+ CompletableFuture<List<B>> futureB = CompletableFuture
313
+ .supplyAsync(() -> mapper.getTypeB(param, authPO, dp), asyncTaskExecutor);
314
+ CompletableFuture.allOf(futureA, futureB).join();
315
+ ```
316
+
317
+ ### Redisson 分布式锁
318
+
319
+ ```java
320
+ RLock lock = redissonClient.getLock("import:lock:" + TenantContextHolder.getTenantId());
321
+ if (!lock.tryLock(5, 60, TimeUnit.SECONDS)) {
322
+ throw new LeException("正在处理中,请稍后再试");
323
+ }
324
+ try {
325
+ doImport(file);
326
+ } finally {
327
+ if (lock.isLocked() && lock.isHeldByCurrentThread()) {
328
+ lock.unlock();
329
+ }
330
+ }
331
+ ```
332
+
333
+ ---
334
+
335
+ ## 建表 SQL 模板
336
+
337
+ ```sql
338
+ CREATE TABLE `xxx_table` (
339
+ `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
340
+ `name` VARCHAR(100) NOT NULL COMMENT '名称',
341
+ `status` TINYINT(1) DEFAULT 1 COMMENT '状态(0停用 1启用)',
342
+ `del_flag` TINYINT(1) DEFAULT 2 COMMENT '删除标识(1删除 2正常)',
343
+ `revision` INT DEFAULT 0 COMMENT '乐观锁版本号',
344
+ `crby` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
345
+ `crtime` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
346
+ `upby` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
347
+ `uptime` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
348
+ PRIMARY KEY (`id`),
349
+ KEY `idx_status` (`status`),
350
+ KEY `idx_crtime` (`crtime`),
351
+ KEY `idx_del_flag` (`del_flag`)
352
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='XXX表';
353
+ -- 无需 tenant_id(双库物理隔离)
354
+ ```
355
+
356
+ ---
357
+
358
+ ## 禁止项速查
359
+
360
+ ```java
361
+ // ---- 错误 ---- | ---- 正确 ----
362
+ package org.dromara.xxx; // -> net.xnzn.core.xxx
363
+ import javax.validation.Valid; // -> jakarta.validation.Valid
364
+ @Validated(AddGroup.class) // -> InsertGroup.class
365
+ private String createBy; // -> crby
366
+ entity.setDelFlag(0); // -> setDelFlag(2) 表示正常
367
+ throw new ServiceException("..."); // -> throw new LeException("...")
368
+ MapstructUtils.convert(src, Dst.class); // -> BeanUtil.copyProperties(src, Dst.class)
369
+ extends ServiceImpl<XxxMapper, Xxx> // -> implements XxxService(不继承)
370
+ @Resource private XxxDao xxxDao; // -> @Resource private XxxMapper xxxMapper
371
+ // XML 放 resources/mapper/ // -> 与 Java 同目录
372
+ return null; // -> return Collections.emptyList()
373
+ ```
374
+
375
+ ---
376
+
377
+ ## 生成前检查清单
378
+
379
+ - [ ] 包名 `net.xnzn.core.*`
380
+ - [ ] Service 只实现接口,不继承基类
381
+ - [ ] Service 直接注入 Mapper(无 DAO)
382
+ - [ ] 审计字段 crby/crtime/upby/uptime
383
+ - [ ] delFlag: 1=删除, 2=正常
384
+ - [ ] `BeanUtil.copyProperties()` 转换对象
385
+ - [ ] `jakarta.validation.*` 校验
386
+ - [ ] `InsertGroup` / `UpdateGroup` 分组
387
+ - [ ] Mapper XML 与 Java 同目录
388
+ - [ ] `LeException` 抛异常
389
+ - [ ] `@RequiresAuthentication` / `@RequiresGuest` 认证
390
+ - [ ] `LeRequest<T>` 请求封装
391
+ - [ ] 多表操作加 `@Transactional(rollbackFor = Exception.class)`
392
+ - [ ] 返回 List 有空集合兜底
393
+ - [ ] selectOne/selectById 结果判空
394
+
395
+ ---
396
+
397
+ ## 参考代码
398
+
399
+ | 类型 | 路径 |
400
+ |------|------|
401
+ | Controller | `core-attendance/.../controller/AttendanceLeaveInfoController.java` |
402
+ | Service | `core-attendance/.../service/impl/AttendanceLeaveInfoServiceImpl.java` |
403
+ | Mapper | `core-attendance/.../mapper/AttendanceLeaveInfoMapper.java` |
404
+ | Entity | `core-attendance/.../model/AttendanceLeaveInfo.java` |