ai-engineering-init 1.7.0 → 1.10.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.
- package/.claude/agents/bug-analyzer.md +103 -0
- package/.claude/agents/code-reviewer.md +115 -5
- package/.claude/agents/image-reader.md +154 -0
- package/.claude/agents/loki-runner.md +80 -0
- package/.claude/agents/mysql-runner.md +81 -0
- package/.claude/agents/requirements-analyzer.md +162 -0
- package/.claude/agents/task-fetcher.md +75 -0
- package/.claude/commands/dev.md +29 -0
- package/.claude/commands/next.md +31 -1
- package/.claude/commands/progress.md +23 -1
- package/.claude/hooks/skill-forced-eval.js +46 -62
- package/.claude/settings.json +10 -1
- package/.claude/skills/api-development/SKILL.md +179 -130
- package/.claude/skills/architecture-design/SKILL.md +102 -212
- package/.claude/skills/backend-annotations/SKILL.md +166 -220
- package/.claude/skills/bug-detective/SKILL.md +225 -186
- package/.claude/skills/code-patterns/SKILL.md +127 -244
- package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.claude/skills/crud-development/SKILL.md +226 -307
- package/.claude/skills/data-permission/SKILL.md +131 -202
- package/.claude/skills/database-ops/SKILL.md +158 -355
- package/.claude/skills/error-handler/SKILL.md +224 -285
- package/.claude/skills/file-oss-management/SKILL.md +174 -169
- package/.claude/skills/git-workflow/SKILL.md +123 -341
- package/.claude/skills/json-serialization/SKILL.md +121 -137
- package/.claude/skills/performance-doctor/SKILL.md +83 -89
- package/.claude/skills/redis-cache/SKILL.md +134 -185
- package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
- package/.claude/skills/security-guard/SKILL.md +168 -276
- package/.claude/skills/sms-mail/SKILL.md +266 -228
- package/.claude/skills/social-login/SKILL.md +257 -195
- package/.claude/skills/tenant-management/SKILL.md +172 -188
- package/.claude/skills/utils-toolkit/SKILL.md +214 -222
- package/.claude/skills/websocket-sse/SKILL.md +251 -172
- package/.claude/skills/workflow-engine/SKILL.md +178 -250
- package/.codex/skills/api-development/SKILL.md +179 -130
- package/.codex/skills/architecture-design/SKILL.md +102 -212
- package/.codex/skills/backend-annotations/SKILL.md +166 -220
- package/.codex/skills/bug-detective/SKILL.md +225 -186
- package/.codex/skills/code-patterns/SKILL.md +127 -244
- package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.codex/skills/crud-development/SKILL.md +226 -307
- package/.codex/skills/data-permission/SKILL.md +131 -202
- package/.codex/skills/database-ops/SKILL.md +158 -355
- package/.codex/skills/dev/SKILL.md +476 -131
- package/.codex/skills/error-handler/SKILL.md +224 -285
- package/.codex/skills/file-oss-management/SKILL.md +174 -169
- package/.codex/skills/git-workflow/SKILL.md +123 -341
- package/.codex/skills/json-serialization/SKILL.md +121 -137
- package/.codex/skills/next/SKILL.md +186 -42
- package/.codex/skills/performance-doctor/SKILL.md +83 -89
- package/.codex/skills/progress/SKILL.md +147 -76
- package/.codex/skills/redis-cache/SKILL.md +134 -185
- package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
- package/.codex/skills/security-guard/SKILL.md +168 -276
- package/.codex/skills/sms-mail/SKILL.md +266 -228
- package/.codex/skills/social-login/SKILL.md +257 -195
- package/.codex/skills/tenant-management/SKILL.md +172 -188
- package/.codex/skills/utils-toolkit/SKILL.md +214 -222
- package/.codex/skills/websocket-sse/SKILL.md +251 -172
- package/.codex/skills/workflow-engine/SKILL.md +178 -250
- package/.cursor/agents/bug-analyzer.md +102 -0
- package/.cursor/agents/code-reviewer.md +80 -97
- package/.cursor/agents/image-reader.md +154 -0
- package/.cursor/agents/loki-runner.md +80 -0
- package/.cursor/agents/mysql-runner.md +81 -0
- package/.cursor/agents/project-manager.md +1 -1
- package/.cursor/agents/requirements-analyzer.md +141 -0
- package/.cursor/agents/task-fetcher.md +75 -0
- package/.cursor/hooks/cursor-skill-eval.js +66 -6
- package/.cursor/skills/api-development/SKILL.md +179 -130
- package/.cursor/skills/architecture-design/SKILL.md +102 -212
- package/.cursor/skills/backend-annotations/SKILL.md +166 -220
- package/.cursor/skills/bug-detective/SKILL.md +225 -186
- package/.cursor/skills/code-patterns/SKILL.md +127 -244
- package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
- package/.cursor/skills/crud-development/SKILL.md +226 -307
- package/.cursor/skills/data-permission/SKILL.md +131 -202
- package/.cursor/skills/database-ops/SKILL.md +158 -355
- package/.cursor/skills/error-handler/SKILL.md +224 -285
- package/.cursor/skills/file-oss-management/SKILL.md +174 -169
- package/.cursor/skills/git-workflow/SKILL.md +123 -341
- package/.cursor/skills/json-serialization/SKILL.md +121 -137
- package/.cursor/skills/performance-doctor/SKILL.md +83 -89
- package/.cursor/skills/redis-cache/SKILL.md +134 -185
- package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
- package/.cursor/skills/security-guard/SKILL.md +168 -276
- package/.cursor/skills/sms-mail/SKILL.md +266 -228
- package/.cursor/skills/social-login/SKILL.md +257 -195
- package/.cursor/skills/tenant-management/SKILL.md +172 -188
- package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
- package/.cursor/skills/websocket-sse/SKILL.md +251 -172
- package/.cursor/skills/workflow-engine/SKILL.md +178 -250
- package/AGENTS.md +117 -540
- package/CLAUDE.md +105 -117
- package/README.md +37 -6
- package/bin/index.js +5 -1
- package/package.json +1 -1
- package/src/skills/api-development/SKILL.md +179 -130
- package/src/skills/architecture-design/SKILL.md +102 -212
- package/src/skills/backend-annotations/SKILL.md +166 -220
- package/src/skills/bug-detective/SKILL.md +225 -186
- package/src/skills/code-patterns/SKILL.md +127 -244
- package/src/skills/collaborating-with-codex/SKILL.md +96 -113
- package/src/skills/crud-development/SKILL.md +226 -307
- package/src/skills/data-permission/SKILL.md +131 -202
- package/src/skills/database-ops/SKILL.md +158 -355
- package/src/skills/error-handler/SKILL.md +224 -285
- package/src/skills/file-oss-management/SKILL.md +174 -169
- package/src/skills/git-workflow/SKILL.md +123 -341
- package/src/skills/json-serialization/SKILL.md +121 -137
- package/src/skills/performance-doctor/SKILL.md +83 -89
- package/src/skills/redis-cache/SKILL.md +134 -185
- package/src/skills/scheduled-jobs/SKILL.md +187 -224
- package/src/skills/security-guard/SKILL.md +168 -276
- package/src/skills/sms-mail/SKILL.md +266 -228
- package/src/skills/social-login/SKILL.md +257 -195
- package/src/skills/tenant-management/SKILL.md +172 -188
- package/src/skills/utils-toolkit/SKILL.md +214 -222
- package/src/skills/websocket-sse/SKILL.md +251 -172
- package/src/skills/workflow-engine/SKILL.md +178 -250
- package/.claude/skills/skill-creator/LICENSE.txt +0 -202
- package/.claude/skills/skill-creator/SKILL.md +0 -479
- package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
- package/.claude/skills/skill-creator/agents/comparator.md +0 -202
- package/.claude/skills/skill-creator/agents/grader.md +0 -223
- package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
- package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
- package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
- package/.claude/skills/skill-creator/references/schemas.md +0 -430
- package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
- package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
- package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
- package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
- package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
- package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
- package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
- package/.claude/skills/skill-creator/scripts/utils.py +0 -47
|
@@ -1,409 +1,328 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: crud-development
|
|
3
3
|
description: |
|
|
4
|
-
|
|
4
|
+
通用 CRUD 开发指南。基于 Spring Boot 三层架构(Controller -> Service -> Mapper),
|
|
5
|
+
提供 Entity、DTO、VO、Service、Controller 的标准模板。
|
|
6
|
+
触发场景:新增业务模块、增删改查开发、快速生成 CRUD 代码。
|
|
7
|
+
触发词:CRUD、增删改查、新增模块、生成代码。
|
|
8
|
+
注意:如果项目有专属技能(如 `leniu-crud`),优先使用专属版本。
|
|
9
|
+
---
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
- 新建业务模块的 CRUD 功能
|
|
8
|
-
- 创建 Entity、BO、VO、Service、Mapper、Controller
|
|
9
|
-
- 分页查询、新增、修改、删除、导出
|
|
10
|
-
- 查询条件构建(buildQueryWrapper)
|
|
11
|
+
# CRUD 开发指南
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
> 通用模板。如果项目有专属技能(如 `leniu-crud`),优先使用。
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
- 三层架构,Service 直接注入 Mapper,无 DAO 层。
|
|
16
|
-
- 查询条件在 Service 层构建(buildQueryWrapper)。
|
|
17
|
-
- 使用 @AutoMapper(单数)而非 @AutoMappers。
|
|
18
|
-
- API 路径使用标准 RESTful 格式(/list、/{id})。
|
|
19
|
-
---
|
|
15
|
+
## 核心规范
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
### 三层架构
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
| 层 | 职责 | 命名示例 |
|
|
20
|
+
|----|------|---------|
|
|
21
|
+
| Controller | 接收请求、参数校验、路由分发 | `OrderController` |
|
|
22
|
+
| Service | 业务逻辑、事务管理 | `OrderService` / `OrderServiceImpl` |
|
|
23
|
+
| Mapper | 数据访问(ORM 映射) | `OrderMapper` |
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|----|------|
|
|
27
|
-
| **包名前缀** | `org.dromara.*` |
|
|
28
|
-
| **架构** | Controller -> Service -> Mapper(无 DAO 层) |
|
|
29
|
-
| **查询构建** | Service 层 `buildQueryWrapper()` |
|
|
30
|
-
| **Mapper** | 继承 `BaseMapperPlus<Entity, VO>` |
|
|
31
|
-
| **对象转换** | `MapstructUtils.convert()` |
|
|
32
|
-
| **Entity 基类** | `TenantEntity`(多租户) |
|
|
33
|
-
| **BO 映射** | `@AutoMapper`(单数) |
|
|
34
|
-
| **API 路径** | RESTful:`/list`、`/{id}` |
|
|
25
|
+
### 标准包结构
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
```
|
|
28
|
+
[你的包名]/
|
|
29
|
+
├── controller/ # 控制器
|
|
30
|
+
├── service/
|
|
31
|
+
│ └── impl/ # 服务实现
|
|
32
|
+
├── mapper/ # 数据访问层
|
|
33
|
+
├── entity/ # 实体类
|
|
34
|
+
├── dto/ # 请求参数对象
|
|
35
|
+
├── vo/ # 响应视图对象
|
|
36
|
+
├── enums/ # 枚举常量
|
|
37
|
+
└── config/ # 模块配置
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 代码示例
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
### 1. Entity(实体类)
|
|
39
43
|
|
|
40
44
|
```java
|
|
41
|
-
package
|
|
45
|
+
package [你的包名].entity;
|
|
42
46
|
|
|
43
|
-
import org.dromara.common.tenant.core.TenantEntity;
|
|
44
47
|
import com.baomidou.mybatisplus.annotation.*;
|
|
45
48
|
import lombok.Data;
|
|
46
|
-
import
|
|
47
|
-
import java.io.Serial;
|
|
49
|
+
import java.time.LocalDateTime;
|
|
48
50
|
|
|
49
51
|
@Data
|
|
50
|
-
@
|
|
51
|
-
|
|
52
|
-
public class Xxx extends TenantEntity {
|
|
52
|
+
@TableName("t_order")
|
|
53
|
+
public class Order {
|
|
53
54
|
|
|
54
|
-
@
|
|
55
|
-
private static final long serialVersionUID = 1L;
|
|
56
|
-
|
|
57
|
-
@TableId(value = "id")
|
|
55
|
+
@TableId(type = IdType.ASSIGN_ID)
|
|
58
56
|
private Long id;
|
|
59
57
|
|
|
60
|
-
private String
|
|
58
|
+
private String orderNo;
|
|
59
|
+
|
|
60
|
+
private Integer status;
|
|
61
|
+
|
|
62
|
+
private Long amount;
|
|
63
|
+
|
|
64
|
+
@TableField(fill = FieldFill.INSERT)
|
|
65
|
+
private String createBy;
|
|
66
|
+
|
|
67
|
+
@TableField(fill = FieldFill.INSERT)
|
|
68
|
+
private LocalDateTime createTime;
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
71
|
+
private String updateBy;
|
|
63
72
|
|
|
64
|
-
@
|
|
65
|
-
private
|
|
73
|
+
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
74
|
+
private LocalDateTime updateTime;
|
|
75
|
+
|
|
76
|
+
@TableLogic(value = "0", delval = "1")
|
|
77
|
+
private Integer deleted;
|
|
66
78
|
}
|
|
67
79
|
```
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
### 2. DTO(请求参数)
|
|
70
82
|
|
|
71
83
|
```java
|
|
72
|
-
package
|
|
84
|
+
package [你的包名].dto;
|
|
73
85
|
|
|
74
|
-
import io.github.linpeilie.annotations.AutoMapper;
|
|
75
|
-
import org.dromara.demo.domain.Xxx;
|
|
76
|
-
import org.dromara.common.core.validate.AddGroup;
|
|
77
|
-
import org.dromara.common.core.validate.EditGroup;
|
|
78
|
-
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
|
79
|
-
import lombok.Data;
|
|
80
|
-
import lombok.EqualsAndHashCode;
|
|
81
86
|
import jakarta.validation.constraints.*;
|
|
87
|
+
import lombok.Data;
|
|
82
88
|
|
|
83
89
|
@Data
|
|
84
|
-
|
|
85
|
-
@AutoMapper(target = Xxx.class, reverseConvertGenerate = false)
|
|
86
|
-
public class XxxBo extends BaseEntity {
|
|
90
|
+
public class OrderCreateDTO {
|
|
87
91
|
|
|
88
|
-
@
|
|
89
|
-
private
|
|
92
|
+
@NotBlank(message = "订单号不能为空")
|
|
93
|
+
private String orderNo;
|
|
90
94
|
|
|
91
|
-
@
|
|
92
|
-
|
|
95
|
+
@NotNull(message = "金额不能为空")
|
|
96
|
+
@Min(value = 1, message = "金额必须大于0")
|
|
97
|
+
private Long amount;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
93
100
|
|
|
94
|
-
|
|
101
|
+
```java
|
|
102
|
+
package [你的包名].dto;
|
|
103
|
+
|
|
104
|
+
import lombok.Data;
|
|
105
|
+
|
|
106
|
+
@Data
|
|
107
|
+
public class OrderQueryDTO {
|
|
108
|
+
|
|
109
|
+
private String orderNo;
|
|
110
|
+
|
|
111
|
+
private Integer status;
|
|
112
|
+
|
|
113
|
+
private Integer pageNum = 1;
|
|
114
|
+
|
|
115
|
+
private Integer pageSize = 10;
|
|
95
116
|
}
|
|
96
117
|
```
|
|
97
118
|
|
|
98
|
-
|
|
119
|
+
### 3. VO(响应对象)
|
|
99
120
|
|
|
100
121
|
```java
|
|
101
|
-
package
|
|
122
|
+
package [你的包名].vo;
|
|
102
123
|
|
|
103
|
-
import io.github.linpeilie.annotations.AutoMapper;
|
|
104
|
-
import org.dromara.demo.domain.Xxx;
|
|
105
|
-
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
|
106
|
-
import cn.idev.excel.annotation.ExcelProperty;
|
|
107
124
|
import lombok.Data;
|
|
108
|
-
import java.
|
|
109
|
-
import java.io.Serializable;
|
|
110
|
-
import java.util.Date;
|
|
125
|
+
import java.time.LocalDateTime;
|
|
111
126
|
|
|
112
127
|
@Data
|
|
113
|
-
|
|
114
|
-
@AutoMapper(target = Xxx.class)
|
|
115
|
-
public class XxxVo implements Serializable {
|
|
116
|
-
|
|
117
|
-
@Serial
|
|
118
|
-
private static final long serialVersionUID = 1L;
|
|
128
|
+
public class OrderVO {
|
|
119
129
|
|
|
120
|
-
@ExcelProperty(value = "主键")
|
|
121
130
|
private Long id;
|
|
122
131
|
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
private String orderNo;
|
|
133
|
+
|
|
134
|
+
private Integer status;
|
|
125
135
|
|
|
126
|
-
|
|
127
|
-
private String status;
|
|
136
|
+
private Long amount;
|
|
128
137
|
|
|
129
|
-
|
|
130
|
-
private Date createTime;
|
|
138
|
+
private LocalDateTime createTime;
|
|
131
139
|
}
|
|
132
140
|
```
|
|
133
141
|
|
|
134
|
-
|
|
142
|
+
### 4. Mapper
|
|
135
143
|
|
|
136
144
|
```java
|
|
137
|
-
package
|
|
138
|
-
|
|
139
|
-
import
|
|
140
|
-
import
|
|
141
|
-
import org.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
public interface IXxxService {
|
|
147
|
-
XxxVo queryById(Long id);
|
|
148
|
-
List<XxxVo> queryList(XxxBo bo);
|
|
149
|
-
TableDataInfo<XxxVo> queryPageList(XxxBo bo, PageQuery pageQuery);
|
|
150
|
-
Boolean insertByBo(XxxBo bo);
|
|
151
|
-
Boolean updateByBo(XxxBo bo);
|
|
152
|
-
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
|
145
|
+
package [你的包名].mapper;
|
|
146
|
+
|
|
147
|
+
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
148
|
+
import [你的包名].entity.Order;
|
|
149
|
+
import org.apache.ibatis.annotations.Mapper;
|
|
150
|
+
|
|
151
|
+
@Mapper
|
|
152
|
+
public interface OrderMapper extends BaseMapper<Order> {
|
|
153
153
|
}
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
### 5. Service
|
|
157
157
|
|
|
158
158
|
```java
|
|
159
|
-
package
|
|
159
|
+
package [你的包名].service;
|
|
160
|
+
|
|
161
|
+
import com.baomidou.mybatisplus.extension.service.IService;
|
|
162
|
+
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
163
|
+
import [你的包名].entity.Order;
|
|
164
|
+
import [你的包名].dto.OrderCreateDTO;
|
|
165
|
+
import [你的包名].dto.OrderQueryDTO;
|
|
166
|
+
import [你的包名].vo.OrderVO;
|
|
167
|
+
|
|
168
|
+
public interface IOrderService extends IService<Order> {
|
|
169
|
+
|
|
170
|
+
Long createOrder(OrderCreateDTO dto);
|
|
171
|
+
|
|
172
|
+
void updateOrder(Long id, OrderCreateDTO dto);
|
|
173
|
+
|
|
174
|
+
OrderVO getOrderDetail(Long id);
|
|
175
|
+
|
|
176
|
+
Page<OrderVO> pageQuery(OrderQueryDTO query);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
```java
|
|
181
|
+
package [你的包名].service.impl;
|
|
160
182
|
|
|
161
183
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
162
|
-
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
163
184
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
185
|
+
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
186
|
+
import [你的包名].dto.OrderCreateDTO;
|
|
187
|
+
import [你的包名].dto.OrderQueryDTO;
|
|
188
|
+
import [你的包名].entity.Order;
|
|
189
|
+
import [你的包名].mapper.OrderMapper;
|
|
190
|
+
import [你的包名].service.IOrderService;
|
|
191
|
+
import [你的包名].vo.OrderVO;
|
|
164
192
|
import lombok.RequiredArgsConstructor;
|
|
165
193
|
import org.springframework.stereotype.Service;
|
|
166
|
-
import org.
|
|
167
|
-
import org.
|
|
168
|
-
import org.dromara.common.core.utils.StringUtils;
|
|
169
|
-
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
170
|
-
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
171
|
-
import org.dromara.demo.domain.Xxx;
|
|
172
|
-
import org.dromara.demo.domain.bo.XxxBo;
|
|
173
|
-
import org.dromara.demo.domain.vo.XxxVo;
|
|
174
|
-
import org.dromara.demo.mapper.XxxMapper;
|
|
175
|
-
import org.dromara.demo.service.IXxxService;
|
|
176
|
-
import java.util.Collection;
|
|
177
|
-
import java.util.List;
|
|
178
|
-
import java.util.Map;
|
|
194
|
+
import org.springframework.transaction.annotation.Transactional;
|
|
195
|
+
import org.springframework.util.StringUtils;
|
|
179
196
|
|
|
180
197
|
@Service
|
|
181
198
|
@RequiredArgsConstructor
|
|
182
|
-
public class
|
|
183
|
-
|
|
184
|
-
private final XxxMapper baseMapper; // 直接注入 Mapper(无 DAO 层)
|
|
199
|
+
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
|
|
185
200
|
|
|
186
201
|
@Override
|
|
187
|
-
|
|
188
|
-
|
|
202
|
+
@Transactional(rollbackFor = Exception.class)
|
|
203
|
+
public Long createOrder(OrderCreateDTO dto) {
|
|
204
|
+
Order order = new Order();
|
|
205
|
+
// 使用 [你的对象转换工具] 或手动赋值
|
|
206
|
+
order.setOrderNo(dto.getOrderNo());
|
|
207
|
+
order.setAmount(dto.getAmount());
|
|
208
|
+
order.setStatus(0);
|
|
209
|
+
this.save(order);
|
|
210
|
+
return order.getId();
|
|
189
211
|
}
|
|
190
212
|
|
|
191
213
|
@Override
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
@Override
|
|
204
|
-
public Boolean insertByBo(XxxBo bo) {
|
|
205
|
-
Xxx add = MapstructUtils.convert(bo, Xxx.class);
|
|
206
|
-
validEntityBeforeSave(add);
|
|
207
|
-
return baseMapper.insert(add) > 0;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
@Override
|
|
211
|
-
public Boolean updateByBo(XxxBo bo) {
|
|
212
|
-
Xxx update = MapstructUtils.convert(bo, Xxx.class);
|
|
213
|
-
validEntityBeforeSave(update);
|
|
214
|
-
return baseMapper.updateById(update) > 0;
|
|
214
|
+
@Transactional(rollbackFor = Exception.class)
|
|
215
|
+
public void updateOrder(Long id, OrderCreateDTO dto) {
|
|
216
|
+
Order order = this.getById(id);
|
|
217
|
+
if (order == null) {
|
|
218
|
+
throw new [你的业务异常类]("订单不存在");
|
|
219
|
+
}
|
|
220
|
+
order.setOrderNo(dto.getOrderNo());
|
|
221
|
+
order.setAmount(dto.getAmount());
|
|
222
|
+
this.updateById(order);
|
|
215
223
|
}
|
|
216
224
|
|
|
217
225
|
@Override
|
|
218
|
-
public
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
throw new ServiceException("您没有删除权限!");
|
|
223
|
-
}
|
|
226
|
+
public OrderVO getOrderDetail(Long id) {
|
|
227
|
+
Order order = this.getById(id);
|
|
228
|
+
if (order == null) {
|
|
229
|
+
throw new [你的业务异常类]("订单不存在");
|
|
224
230
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
lqw.like(StringUtils.isNotBlank(bo.getXxxName()), Xxx::getXxxName, bo.getXxxName());
|
|
234
|
-
lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
|
|
235
|
-
Xxx::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
|
|
236
|
-
lqw.orderByAsc(Xxx::getId);
|
|
237
|
-
return lqw;
|
|
231
|
+
OrderVO vo = new OrderVO();
|
|
232
|
+
// 使用 [你的对象转换工具] 或手动赋值
|
|
233
|
+
vo.setId(order.getId());
|
|
234
|
+
vo.setOrderNo(order.getOrderNo());
|
|
235
|
+
vo.setStatus(order.getStatus());
|
|
236
|
+
vo.setAmount(order.getAmount());
|
|
237
|
+
vo.setCreateTime(order.getCreateTime());
|
|
238
|
+
return vo;
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
@Override
|
|
242
|
+
public Page<OrderVO> pageQuery(OrderQueryDTO query) {
|
|
243
|
+
Page<Order> page = new Page<>(query.getPageNum(), query.getPageSize());
|
|
244
|
+
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<Order>()
|
|
245
|
+
.like(StringUtils.hasText(query.getOrderNo()), Order::getOrderNo, query.getOrderNo())
|
|
246
|
+
.eq(query.getStatus() != null, Order::getStatus, query.getStatus())
|
|
247
|
+
.orderByDesc(Order::getCreateTime);
|
|
248
|
+
Page<Order> result = this.page(page, wrapper);
|
|
249
|
+
|
|
250
|
+
// 转换为 VO
|
|
251
|
+
Page<OrderVO> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
|
|
252
|
+
voPage.setRecords(result.getRecords().stream().map(order -> {
|
|
253
|
+
OrderVO vo = new OrderVO();
|
|
254
|
+
vo.setId(order.getId());
|
|
255
|
+
vo.setOrderNo(order.getOrderNo());
|
|
256
|
+
vo.setStatus(order.getStatus());
|
|
257
|
+
vo.setAmount(order.getAmount());
|
|
258
|
+
vo.setCreateTime(order.getCreateTime());
|
|
259
|
+
return vo;
|
|
260
|
+
}).toList());
|
|
261
|
+
return voPage;
|
|
242
262
|
}
|
|
243
263
|
}
|
|
244
264
|
```
|
|
245
265
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
```java
|
|
249
|
-
package org.dromara.demo.mapper;
|
|
250
|
-
|
|
251
|
-
import org.dromara.demo.domain.Xxx;
|
|
252
|
-
import org.dromara.demo.domain.vo.XxxVo;
|
|
253
|
-
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
|
254
|
-
|
|
255
|
-
public interface XxxMapper extends BaseMapperPlus<Xxx, XxxVo> {
|
|
256
|
-
// 已提供 selectVoById、selectVoPage、selectVoList 等方法
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## 7. Controller
|
|
266
|
+
### 6. Controller
|
|
261
267
|
|
|
262
268
|
```java
|
|
263
|
-
package
|
|
269
|
+
package [你的包名].controller;
|
|
264
270
|
|
|
265
|
-
import
|
|
266
|
-
import
|
|
271
|
+
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
272
|
+
import [你的包名].dto.OrderCreateDTO;
|
|
273
|
+
import [你的包名].dto.OrderQueryDTO;
|
|
274
|
+
import [你的包名].service.IOrderService;
|
|
275
|
+
import [你的包名].vo.OrderVO;
|
|
276
|
+
import jakarta.validation.Valid;
|
|
267
277
|
import lombok.RequiredArgsConstructor;
|
|
268
|
-
import
|
|
269
|
-
import jakarta.validation.constraints.*;
|
|
270
|
-
import cn.dev33.satoken.annotation.SaCheckPermission;
|
|
278
|
+
import org.springframework.http.ResponseEntity;
|
|
271
279
|
import org.springframework.web.bind.annotation.*;
|
|
272
|
-
import org.springframework.validation.annotation.Validated;
|
|
273
|
-
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
|
274
|
-
import org.dromara.common.log.annotation.Log;
|
|
275
|
-
import org.dromara.common.log.enums.BusinessType;
|
|
276
|
-
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
277
|
-
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
278
|
-
import org.dromara.common.web.core.BaseController;
|
|
279
|
-
import org.dromara.common.core.domain.R;
|
|
280
|
-
import org.dromara.common.core.validate.AddGroup;
|
|
281
|
-
import org.dromara.common.core.validate.EditGroup;
|
|
282
|
-
import org.dromara.common.excel.utils.ExcelUtil;
|
|
283
|
-
import org.dromara.demo.domain.vo.XxxVo;
|
|
284
|
-
import org.dromara.demo.domain.bo.XxxBo;
|
|
285
|
-
import org.dromara.demo.service.IXxxService;
|
|
286
|
-
|
|
287
|
-
@Validated
|
|
288
|
-
@RequiredArgsConstructor
|
|
289
|
-
@RestController
|
|
290
|
-
@RequestMapping("/demo/xxx")
|
|
291
|
-
public class XxxController extends BaseController {
|
|
292
280
|
|
|
293
|
-
|
|
281
|
+
@RestController
|
|
282
|
+
@RequestMapping("/api/v1/orders")
|
|
283
|
+
@RequiredArgsConstructor
|
|
284
|
+
public class OrderController {
|
|
294
285
|
|
|
295
|
-
|
|
296
|
-
@GetMapping("/list")
|
|
297
|
-
public TableDataInfo<XxxVo> list(XxxBo bo, PageQuery pageQuery) {
|
|
298
|
-
return xxxService.queryPageList(bo, pageQuery);
|
|
299
|
-
}
|
|
286
|
+
private final IOrderService orderService;
|
|
300
287
|
|
|
301
|
-
@
|
|
302
|
-
@
|
|
303
|
-
|
|
304
|
-
return R.ok(xxxService.queryById(id));
|
|
288
|
+
@PostMapping
|
|
289
|
+
public ResponseEntity<Long> create(@Valid @RequestBody OrderCreateDTO dto) {
|
|
290
|
+
return ResponseEntity.ok(orderService.createOrder(dto));
|
|
305
291
|
}
|
|
306
292
|
|
|
307
|
-
@
|
|
308
|
-
@
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return toAjax(xxxService.insertByBo(bo));
|
|
293
|
+
@PutMapping("/{id}")
|
|
294
|
+
public ResponseEntity<Void> update(@PathVariable Long id,
|
|
295
|
+
@Valid @RequestBody OrderCreateDTO dto) {
|
|
296
|
+
orderService.updateOrder(id, dto);
|
|
297
|
+
return ResponseEntity.ok().build();
|
|
313
298
|
}
|
|
314
299
|
|
|
315
|
-
@
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
@PutMapping()
|
|
319
|
-
public R<Void> edit(@Validated(EditGroup.class) @RequestBody XxxBo bo) {
|
|
320
|
-
return toAjax(xxxService.updateByBo(bo));
|
|
300
|
+
@GetMapping("/{id}")
|
|
301
|
+
public ResponseEntity<OrderVO> detail(@PathVariable Long id) {
|
|
302
|
+
return ResponseEntity.ok(orderService.getOrderDetail(id));
|
|
321
303
|
}
|
|
322
304
|
|
|
323
|
-
@
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
|
|
327
|
-
return toAjax(xxxService.deleteWithValidByIds(Arrays.asList(ids), true));
|
|
305
|
+
@GetMapping
|
|
306
|
+
public ResponseEntity<Page<OrderVO>> page(OrderQueryDTO query) {
|
|
307
|
+
return ResponseEntity.ok(orderService.pageQuery(query));
|
|
328
308
|
}
|
|
329
309
|
|
|
330
|
-
@
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
List<XxxVo> list = xxxService.queryList(bo);
|
|
335
|
-
ExcelUtil.exportExcel(list, "XXX数据", XxxVo.class, response);
|
|
310
|
+
@DeleteMapping("/{id}")
|
|
311
|
+
public ResponseEntity<Void> delete(@PathVariable Long id) {
|
|
312
|
+
orderService.removeById(id);
|
|
313
|
+
return ResponseEntity.ok().build();
|
|
336
314
|
}
|
|
337
315
|
}
|
|
338
316
|
```
|
|
339
317
|
|
|
340
|
-
##
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
update_by BIGINT(20) DEFAULT NULL COMMENT '更新人',
|
|
352
|
-
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
|
353
|
-
remark VARCHAR(255) DEFAULT NULL COMMENT '备注',
|
|
354
|
-
del_flag BIGINT(20) DEFAULT 0 COMMENT '删除标志(0正常 1已删除)',
|
|
355
|
-
PRIMARY KEY (id)
|
|
356
|
-
) ENGINE=InnoDB COMMENT='XXX表';
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
---
|
|
360
|
-
|
|
361
|
-
## 常见错误速查
|
|
362
|
-
|
|
363
|
-
```java
|
|
364
|
-
// ---- 错误写法 ----
|
|
365
|
-
private final IXxxDao xxxDao; // 本项目没有 DAO 层
|
|
366
|
-
BeanUtil.copyProperties(bo, entity); // 必须用 MapstructUtils.convert()
|
|
367
|
-
class XxxServiceImpl extends ServiceImpl<...> {} // Service 不继承基类
|
|
368
|
-
@AutoMappers({@AutoMapper(...)}) // 用单数 @AutoMapper
|
|
369
|
-
@GetMapping("/pageXxxs") // 应该是 /list
|
|
370
|
-
@GetMapping("/getXxx/{id}") // 应该是 /{id}
|
|
371
|
-
|
|
372
|
-
// ---- 正确写法 ----
|
|
373
|
-
private final XxxMapper baseMapper; // 直接注入 Mapper
|
|
374
|
-
MapstructUtils.convert(bo, Xxx.class); // MapstructUtils 转换
|
|
375
|
-
class XxxServiceImpl implements IXxxService {} // 只实现接口
|
|
376
|
-
@AutoMapper(target = Xxx.class) // 单数注解
|
|
377
|
-
@GetMapping("/list") // RESTful 路径
|
|
378
|
-
@GetMapping("/{id}") // RESTful 路径
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
|
-
## 检查清单
|
|
384
|
-
|
|
385
|
-
- [ ] 包名是 `org.dromara.*`?
|
|
386
|
-
- [ ] Service 只实现接口,不继承基类?
|
|
387
|
-
- [ ] Service 直接注入 Mapper(无 DAO)?
|
|
388
|
-
- [ ] `buildQueryWrapper()` 在 Service 层?
|
|
389
|
-
- [ ] Entity 继承 `TenantEntity`?
|
|
390
|
-
- [ ] BO 使用 `@AutoMapper`(单数)?
|
|
391
|
-
- [ ] 使用 `MapstructUtils.convert()` 转换?
|
|
392
|
-
- [ ] Mapper 继承 `BaseMapperPlus<Entity, VO>`?
|
|
393
|
-
- [ ] Controller 使用 RESTful 路径?
|
|
394
|
-
- [ ] SQL 使用 `del_flag`(0正常 1删除)?
|
|
395
|
-
- [ ] 主键使用雪花 ID(无 AUTO_INCREMENT)?
|
|
396
|
-
- [ ] 代码注释和 SQL COMMENT 使用中文?
|
|
397
|
-
|
|
398
|
-
---
|
|
399
|
-
|
|
400
|
-
## 参考实现
|
|
401
|
-
|
|
402
|
-
| 类型 | 类名 |
|
|
403
|
-
|------|------|
|
|
404
|
-
| Entity | `org.dromara.demo.domain.TestDemo` |
|
|
405
|
-
| BO | `org.dromara.demo.domain.bo.TestDemoBo` |
|
|
406
|
-
| VO | `org.dromara.demo.domain.vo.TestDemoVo` |
|
|
407
|
-
| Service | `org.dromara.demo.service.impl.TestDemoServiceImpl` |
|
|
408
|
-
| Mapper | `org.dromara.demo.mapper.TestDemoMapper` |
|
|
409
|
-
| Controller | `org.dromara.demo.controller.TestDemoController` |
|
|
318
|
+
## 常见错误
|
|
319
|
+
|
|
320
|
+
| 错误 | 正确做法 |
|
|
321
|
+
|------|---------|
|
|
322
|
+
| Controller 里写业务逻辑 | 业务逻辑放 Service 层 |
|
|
323
|
+
| 直接返回 Entity 给前端 | 使用 VO 封装响应数据 |
|
|
324
|
+
| 用 Map 传递业务数据 | 使用 DTO/VO 强类型对象 |
|
|
325
|
+
| 忘记加 `@Transactional` | 写操作方法加事务注解 |
|
|
326
|
+
| 逻辑删除字段值搞反 | 确认项目约定(通用:0=正常, 1=删除) |
|
|
327
|
+
| 分页参数未设默认值 | DTO 中给 pageNum/pageSize 默认值 |
|
|
328
|
+
| Service 之间循环依赖 | 提取公共 Service 或使用事件机制解耦 |
|