@llryiop/avatar-boot-cli 1.0.1 → 1.0.2
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/docs/exam-question-generate-api.md +163 -0
- package/package.json +1 -1
- package/src/prompts.js +3 -3
- package/src/transform.js +1 -1
- package/templates/.claude/skills/avatar-boot-starter-feign/README.md +243 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/SKILL.md +47 -219
- package/templates/.claude/skills/avatar-boot-starter-feign/references//345/212/237/350/203/275/350/257/246/350/247/243.md +65 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/references//345/277/253/351/200/237/346/216/245/345/205/245/346/214/207/345/215/227.md +75 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/references//351/205/215/347/275/256/345/217/202/350/200/203.md +70 -0
- package/templates/.claude/skills/avatar-boot-starter-job/README.md +437 -0
- package/templates/.claude/skills/avatar-boot-starter-job/SKILL.md +35 -414
- package/templates/.claude/skills/avatar-boot-starter-job/references//345/270/270/350/247/201/351/227/256/351/242/230.md +55 -0
- package/templates/.claude/skills/avatar-boot-starter-job/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +124 -0
- package/templates/.claude/skills/avatar-boot-starter-job/references//347/233/221/346/216/247/346/214/207/346/240/207.md +72 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/README.md +580 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/SKILL.md +36 -560
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/234/200/344/275/263/345/256/236/350/267/265.md +43 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/240/270/345/277/203/345/212/237/350/203/275.md +117 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//351/205/215/347/275/256/345/217/202/350/200/203.md +54 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/README.md +572 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/SKILL.md +40 -550
- package/templates/.claude/skills/avatar-boot-starter-mysql/references//345/256/236/344/275/223/344/270/216/345/212/237/350/203/275.md +96 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/346/225/260/346/215/256/346/272/220.md +91 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/references//351/253/230/347/272/247/347/211/271/346/200/247/344/270/216/351/205/215/347/275/256.md +59 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/README.md +901 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/SKILL.md +40 -879
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/212/237/350/203/275/344/275/277/347/224/250.md +134 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +96 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//346/225/205/351/232/234/346/216/222/346/237/245.md +64 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/README.md +594 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/SKILL.md +52 -570
- package/templates/.claude/skills/avatar-boot-starter-oss/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +77 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/references//346/240/270/345/277/203/345/212/237/350/203/275.md +94 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/references//350/247/204/350/214/203/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.md +61 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/README.md +586 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/SKILL.md +42 -566
- package/templates/.claude/skills/avatar-boot-starter-redis/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +78 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/references//346/225/260/346/215/256/346/223/215/344/275/234.md +111 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/references//351/253/230/347/272/247/345/212/237/350/203/275.md +90 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/README.md +662 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/SKILL.md +48 -640
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//346/240/270/345/277/203/345/212/237/350/203/275.md +101 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/205/215/347/275/256/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.md +44 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/253/230/347/272/247/347/211/271/346/200/247.md +71 -0
- package/templates/.claude/skills/avatar-boot-starter-web/README.md +1007 -0
- package/templates/.claude/skills/avatar-boot-starter-web/SKILL.md +150 -1003
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-LogInfo/346/263/250/350/247/243.md +75 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/345/205/250/345/261/200/345/274/202/345/270/270/345/244/204/347/220/206.md +90 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/346/214/207/346/240/207/347/233/221/346/216/247.md +74 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/346/227/245/345/277/227/344/275/223/347/263/273.md +73 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/350/257/267/346/261/202/344/270/212/344/270/213/346/226/207.md +77 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/277/253/351/200/237/346/216/245/345/205/245/346/214/207/345/215/227.md +52 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//346/263/250/346/204/217/344/272/213/351/241/271.md +68 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//350/207/252/345/256/232/344/271/211/346/211/251/345/261/225/346/214/207/345/215/227.md +107 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//351/205/215/347/275/256/345/217/202/350/200/203.md +107 -0
- package/templates/.claude/skills/crud-generator/SKILL.md +133 -64
- package/templates/.claude/skills/database-design/README.md +207 -0
- package/templates/.claude/skills/database-design/SKILL.md +469 -82
- package/templates/.claude/skills/database-design/references//345/221/275/345/220/215/350/247/204/350/214/203.md +232 -0
- package/templates/.claude/skills/database-design/references//345/255/227/346/256/265/347/261/273/345/236/213/350/247/204/350/214/203.md +400 -0
- package/templates/.claude/skills/database-design/references//347/264/242/345/274/225/350/247/204/350/214/203.md +506 -0
- package/templates/avatar-scaffold-api/pom.xml +0 -5
- package/templates/avatar-scaffold-service/pom.xml +25 -87
- package/templates/avatar-scaffold-service/src/main/resources/application-dev.yaml +3 -5
- package/templates/avatar-scaffold-service/src/main/resources/application-local.yaml +2 -2
- package/templates/pom.xml +9 -18
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# 配置参考
|
|
2
|
+
|
|
3
|
+
## 完整配置项
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
avatar:
|
|
7
|
+
web:
|
|
8
|
+
# 是否启用请求拦截器(默认: true)
|
|
9
|
+
interceptor-enabled: true
|
|
10
|
+
|
|
11
|
+
# 是否启用全局异常处理(默认: true)
|
|
12
|
+
exception-handler-enabled: true
|
|
13
|
+
|
|
14
|
+
# 拦截器配置
|
|
15
|
+
interceptor:
|
|
16
|
+
# TraceId 请求头名称(默认: X-Trace-Id)
|
|
17
|
+
trace-id-header: X-Trace-Id
|
|
18
|
+
|
|
19
|
+
# 拦截路径(默认: /**)
|
|
20
|
+
include-paths:
|
|
21
|
+
- /**
|
|
22
|
+
|
|
23
|
+
# 排除路径
|
|
24
|
+
exclude-paths:
|
|
25
|
+
- /error
|
|
26
|
+
- /actuator/**
|
|
27
|
+
- /swagger-ui/**
|
|
28
|
+
- /v3/api-docs/**
|
|
29
|
+
|
|
30
|
+
# 日志配置
|
|
31
|
+
log:
|
|
32
|
+
# 是否记录请求日志(默认: false)
|
|
33
|
+
request-enabled: false
|
|
34
|
+
|
|
35
|
+
# 是否记录响应日志(默认: false)
|
|
36
|
+
response-enabled: false
|
|
37
|
+
|
|
38
|
+
# 慢请求阈值(毫秒,默认: 3000)
|
|
39
|
+
slow-request-threshold: 3000
|
|
40
|
+
|
|
41
|
+
# 指标监控配置
|
|
42
|
+
metrics:
|
|
43
|
+
# 是否启用指标记录(默认: true,需要 Micrometer)
|
|
44
|
+
enabled: true
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 常用场景配置
|
|
48
|
+
|
|
49
|
+
### 只拦截 /api/** 路径
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
avatar:
|
|
53
|
+
web:
|
|
54
|
+
interceptor:
|
|
55
|
+
include-paths:
|
|
56
|
+
- /api/**
|
|
57
|
+
exclude-paths:
|
|
58
|
+
- /api/public/**
|
|
59
|
+
- /health
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 开启请求/响应日志(调试用)
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
avatar:
|
|
66
|
+
web:
|
|
67
|
+
log:
|
|
68
|
+
request-enabled: true
|
|
69
|
+
response-enabled: true
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
> 生产环境建议关闭,避免敏感数据写入日志。
|
|
73
|
+
|
|
74
|
+
### 调整慢请求阈值
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
avatar:
|
|
78
|
+
web:
|
|
79
|
+
log:
|
|
80
|
+
slow-request-threshold: 5000 # 5秒
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 关闭全局异常处理(自行实现时)
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
avatar:
|
|
87
|
+
web:
|
|
88
|
+
exception-handler-enabled: false
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 关闭指标监控
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
avatar:
|
|
95
|
+
web:
|
|
96
|
+
metrics:
|
|
97
|
+
enabled: false
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 自定义 TraceId 请求头名称
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
avatar:
|
|
104
|
+
web:
|
|
105
|
+
interceptor:
|
|
106
|
+
trace-id-header: X-Request-Id # 改为自定义名称
|
|
107
|
+
```
|
|
@@ -20,25 +20,25 @@ description: |
|
|
|
20
20
|
### 方式一:提供表 DDL
|
|
21
21
|
|
|
22
22
|
```sql
|
|
23
|
-
CREATE TABLE
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
CREATE TABLE zz_plt_user (
|
|
24
|
+
id BIGINT NOT NULL COMMENT '主键ID',
|
|
25
|
+
username VARCHAR(64) NOT NULL COMMENT '用户名',
|
|
26
|
+
email VARCHAR(128) DEFAULT NULL COMMENT '邮箱',
|
|
27
|
+
phone VARCHAR(20) DEFAULT NULL COMMENT '手机号',
|
|
28
|
+
status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:0-禁用 1-启用',
|
|
29
|
+
create_time DATETIME NOT NULL COMMENT '创建时间',
|
|
30
|
+
update_time DATETIME NOT NULL COMMENT '更新时间',
|
|
31
|
+
is_deleted TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-未删除 1-已删除',
|
|
32
|
+
PRIMARY KEY (id),
|
|
33
|
+
UNIQUE KEY uk_username (username),
|
|
34
|
+
KEY idx_email (email)
|
|
35
35
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
### 方式二:提供表结构描述
|
|
39
39
|
|
|
40
40
|
```
|
|
41
|
-
表名:
|
|
41
|
+
表名: zz_plt_user (用户表)
|
|
42
42
|
字段:
|
|
43
43
|
- username: 用户名, VARCHAR(64), 必填, 唯一
|
|
44
44
|
- email: 邮箱, VARCHAR(128), 可选
|
|
@@ -52,7 +52,7 @@ CREATE TABLE t_user (
|
|
|
52
52
|
|
|
53
53
|
## 输出文件列表
|
|
54
54
|
|
|
55
|
-
以 `
|
|
55
|
+
以 `zz_plt_user` 表为例,生成的文件按垂直功能组织:
|
|
56
56
|
|
|
57
57
|
### API 模块 (`avatar-api`)
|
|
58
58
|
|
|
@@ -68,23 +68,57 @@ CREATE TABLE t_user (
|
|
|
68
68
|
|
|
69
69
|
| 文件 | 路径 |
|
|
70
70
|
|------|------|
|
|
71
|
-
| Entity | `com/iflytek/avatar/
|
|
72
|
-
| Mapper | `com/iflytek/avatar/
|
|
71
|
+
| Entity | `com/iflytek/avatar/repository/entity/UserEntity.java` |
|
|
72
|
+
| Mapper | `com/iflytek/avatar/repository/mapper/UserMapper.java` |
|
|
73
|
+
| Repository | `com/iflytek/avatar/repository/UserRepository.java` |
|
|
73
74
|
| Service 接口 | `com/iflytek/avatar/service/UserService.java` |
|
|
74
75
|
| Service 实现 | `com/iflytek/avatar/service/impl/UserServiceImpl.java` |
|
|
75
76
|
| Controller | `com/iflytek/avatar/controller/UserController.java` |
|
|
76
77
|
|
|
77
78
|
---
|
|
78
79
|
|
|
80
|
+
## 架构设计原则
|
|
81
|
+
|
|
82
|
+
### Repository 层设计模式
|
|
83
|
+
|
|
84
|
+
本项目采用 **Repository 模式** 进行数据访问层的封装:
|
|
85
|
+
|
|
86
|
+
- **Repository 是唯一可以修改数据的类**:所有数据库操作必须通过 Repository 层进行
|
|
87
|
+
- **Service 层通过 Repository 访问数据**:Service 不直接使用 Mapper,而是依赖 Repository
|
|
88
|
+
- **Repository 继承 ServiceImpl**:Repository 类继承 `ServiceImpl<Mapper, Entity>`,封装 MyBatis Plus 的 CRUD 能力
|
|
89
|
+
- **目录结构**:
|
|
90
|
+
- `repository/` - Repository 类(数据访问层封装)
|
|
91
|
+
- `repository/entity/` - Entity 实体类
|
|
92
|
+
- `repository/mapper/` - MyBatis Mapper 接口
|
|
93
|
+
|
|
94
|
+
### 分层职责
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Controller → Service → Repository → Mapper → Database
|
|
98
|
+
↓ ↓ ↓
|
|
99
|
+
Request DTO 业务逻辑 数据访问封装
|
|
100
|
+
Response DTO
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- **Controller**:参数校验、Result 封装
|
|
104
|
+
- **Service**:业务逻辑编排、事务管理
|
|
105
|
+
- **Repository**:数据访问封装、CRUD 操作(唯一可以修改数据的层)
|
|
106
|
+
- **Mapper**:MyBatis 接口定义
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
79
110
|
## 代码模板
|
|
80
111
|
|
|
81
|
-
### 1. Entity — `
|
|
112
|
+
### 1. Entity — `repository/entity/UserEntity.java`
|
|
82
113
|
|
|
83
114
|
```java
|
|
84
|
-
package com.iflytek.avatar.
|
|
115
|
+
package com.iflytek.avatar.repository.entity;
|
|
85
116
|
|
|
86
117
|
import com.baomidou.mybatisplus.annotation.*;
|
|
118
|
+
import lombok.AllArgsConstructor;
|
|
119
|
+
import lombok.Builder;
|
|
87
120
|
import lombok.Data;
|
|
121
|
+
import lombok.NoArgsConstructor;
|
|
88
122
|
|
|
89
123
|
import java.time.LocalDateTime;
|
|
90
124
|
|
|
@@ -94,8 +128,11 @@ import java.time.LocalDateTime;
|
|
|
94
128
|
* @author avatar-generator
|
|
95
129
|
*/
|
|
96
130
|
@Data
|
|
97
|
-
@
|
|
98
|
-
|
|
131
|
+
@Builder
|
|
132
|
+
@NoArgsConstructor
|
|
133
|
+
@AllArgsConstructor
|
|
134
|
+
@TableName("zz_plt_user")
|
|
135
|
+
public class UserEntity {
|
|
99
136
|
|
|
100
137
|
/**
|
|
101
138
|
* 主键ID
|
|
@@ -143,13 +180,13 @@ public class User {
|
|
|
143
180
|
}
|
|
144
181
|
```
|
|
145
182
|
|
|
146
|
-
### 2. Mapper — `
|
|
183
|
+
### 2. Mapper — `repository/mapper/UserMapper.java`
|
|
147
184
|
|
|
148
185
|
```java
|
|
149
|
-
package com.iflytek.avatar.
|
|
186
|
+
package com.iflytek.avatar.repository.mapper;
|
|
150
187
|
|
|
151
188
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
152
|
-
import com.iflytek.avatar.
|
|
189
|
+
import com.iflytek.avatar.repository.entity.UserEntity;
|
|
153
190
|
import org.apache.ibatis.annotations.Mapper;
|
|
154
191
|
|
|
155
192
|
/**
|
|
@@ -158,19 +195,45 @@ import org.apache.ibatis.annotations.Mapper;
|
|
|
158
195
|
* @author avatar-generator
|
|
159
196
|
*/
|
|
160
197
|
@Mapper
|
|
161
|
-
public interface UserMapper extends BaseMapper<
|
|
198
|
+
public interface UserMapper extends BaseMapper<UserEntity> {
|
|
162
199
|
|
|
163
200
|
}
|
|
164
201
|
```
|
|
165
202
|
|
|
166
|
-
### 3.
|
|
203
|
+
### 3. Repository — `repository/UserRepository.java`
|
|
204
|
+
|
|
205
|
+
```java
|
|
206
|
+
package com.iflytek.avatar.repository;
|
|
207
|
+
|
|
208
|
+
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
209
|
+
import com.iflytek.avatar.repository.entity.UserEntity;
|
|
210
|
+
import com.iflytek.avatar.repository.mapper.UserMapper;
|
|
211
|
+
import org.springframework.stereotype.Component;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 用户数据访问层(Repository 层)
|
|
215
|
+
*
|
|
216
|
+
* 🔴 重要:Repository 是唯一可以修改数据的类
|
|
217
|
+
* - 所有数据库操作必须通过 Repository 进行
|
|
218
|
+
* - Service 层通过 Repository 访问数据,不直接使用 Mapper
|
|
219
|
+
* - 继承 ServiceImpl 封装 MyBatis Plus 的 CRUD 能力
|
|
220
|
+
*
|
|
221
|
+
* @author avatar-generator
|
|
222
|
+
*/
|
|
223
|
+
@Component
|
|
224
|
+
public class UserRepository extends ServiceImpl<UserMapper, UserEntity> {
|
|
225
|
+
|
|
226
|
+
// 可以在这里添加自定义的数据访问方法
|
|
227
|
+
// 例如:复杂查询、批量操作等
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 4. Service 接口 — `service/UserService.java`
|
|
167
232
|
|
|
168
233
|
```java
|
|
169
234
|
package com.iflytek.avatar.service;
|
|
170
235
|
|
|
171
236
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
172
|
-
import com.baomidou.mybatisplus.extension.service.IService;
|
|
173
|
-
import com.iflytek.avatar.dao.beans.User;
|
|
174
237
|
import com.iflytek.avatar.entity.request.UserCreateRequest;
|
|
175
238
|
import com.iflytek.avatar.entity.request.UserPageRequest;
|
|
176
239
|
import com.iflytek.avatar.entity.request.UserUpdateRequest;
|
|
@@ -181,7 +244,7 @@ import com.iflytek.avatar.entity.response.UserResponse;
|
|
|
181
244
|
*
|
|
182
245
|
* @author avatar-generator
|
|
183
246
|
*/
|
|
184
|
-
public interface UserService
|
|
247
|
+
public interface UserService {
|
|
185
248
|
|
|
186
249
|
/**
|
|
187
250
|
* 创建用户
|
|
@@ -225,7 +288,7 @@ public interface UserService extends IService<User> {
|
|
|
225
288
|
}
|
|
226
289
|
```
|
|
227
290
|
|
|
228
|
-
###
|
|
291
|
+
### 5. ServiceImpl — `service/impl/UserServiceImpl.java`
|
|
229
292
|
|
|
230
293
|
```java
|
|
231
294
|
package com.iflytek.avatar.service.impl;
|
|
@@ -233,13 +296,12 @@ package com.iflytek.avatar.service.impl;
|
|
|
233
296
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
234
297
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
235
298
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
236
|
-
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
237
|
-
import com.iflytek.avatar.dao.beans.User;
|
|
238
|
-
import com.iflytek.avatar.dao.mapper.UserMapper;
|
|
239
299
|
import com.iflytek.avatar.entity.request.UserCreateRequest;
|
|
240
300
|
import com.iflytek.avatar.entity.request.UserPageRequest;
|
|
241
301
|
import com.iflytek.avatar.entity.request.UserUpdateRequest;
|
|
242
302
|
import com.iflytek.avatar.entity.response.UserResponse;
|
|
303
|
+
import com.iflytek.avatar.repository.UserRepository;
|
|
304
|
+
import com.iflytek.avatar.repository.entity.UserEntity;
|
|
243
305
|
import com.iflytek.avatar.service.UserService;
|
|
244
306
|
import lombok.RequiredArgsConstructor;
|
|
245
307
|
import org.springframework.beans.BeanUtils;
|
|
@@ -251,81 +313,87 @@ import java.util.Objects;
|
|
|
251
313
|
/**
|
|
252
314
|
* 用户表 Service 实现类
|
|
253
315
|
*
|
|
316
|
+
* 🔴 重要:Service 层通过 Repository 访问数据
|
|
317
|
+
* - 不直接使用 Mapper,而是依赖 Repository
|
|
318
|
+
* - Repository 是唯一可以修改数据的类
|
|
319
|
+
*
|
|
254
320
|
* @author avatar-generator
|
|
255
321
|
*/
|
|
256
322
|
@Service
|
|
257
323
|
@RequiredArgsConstructor
|
|
258
|
-
public class UserServiceImpl
|
|
324
|
+
public class UserServiceImpl implements UserService {
|
|
325
|
+
|
|
326
|
+
private final UserRepository userRepository;
|
|
259
327
|
|
|
260
328
|
@Override
|
|
261
329
|
@Transactional(rollbackFor = Exception.class)
|
|
262
330
|
public UserResponse create(UserCreateRequest request) {
|
|
263
|
-
|
|
264
|
-
BeanUtils.copyProperties(request,
|
|
265
|
-
|
|
266
|
-
return toResponse(
|
|
331
|
+
UserEntity entity = new UserEntity();
|
|
332
|
+
BeanUtils.copyProperties(request, entity);
|
|
333
|
+
userRepository.save(entity);
|
|
334
|
+
return toResponse(entity);
|
|
267
335
|
}
|
|
268
336
|
|
|
269
337
|
@Override
|
|
270
338
|
@Transactional(readOnly = true)
|
|
271
339
|
public UserResponse getDetail(Long id) {
|
|
272
|
-
|
|
273
|
-
if (Objects.isNull(
|
|
340
|
+
UserEntity entity = userRepository.getById(id);
|
|
341
|
+
if (Objects.isNull(entity)) {
|
|
274
342
|
throw new RuntimeException("用户不存在,ID: " + id);
|
|
275
343
|
}
|
|
276
|
-
return toResponse(
|
|
344
|
+
return toResponse(entity);
|
|
277
345
|
}
|
|
278
346
|
|
|
279
347
|
@Override
|
|
280
348
|
@Transactional(rollbackFor = Exception.class)
|
|
281
349
|
public UserResponse update(Long id, UserUpdateRequest request) {
|
|
282
|
-
|
|
283
|
-
if (Objects.isNull(
|
|
350
|
+
UserEntity entity = userRepository.getById(id);
|
|
351
|
+
if (Objects.isNull(entity)) {
|
|
284
352
|
throw new RuntimeException("用户不存在,ID: " + id);
|
|
285
353
|
}
|
|
286
|
-
BeanUtils.copyProperties(request,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return toResponse(
|
|
354
|
+
BeanUtils.copyProperties(request, entity);
|
|
355
|
+
entity.setId(id);
|
|
356
|
+
userRepository.updateById(entity);
|
|
357
|
+
return toResponse(entity);
|
|
290
358
|
}
|
|
291
359
|
|
|
292
360
|
@Override
|
|
293
361
|
@Transactional(rollbackFor = Exception.class)
|
|
294
362
|
public void delete(Long id) {
|
|
295
|
-
|
|
296
|
-
if (Objects.isNull(
|
|
363
|
+
UserEntity entity = userRepository.getById(id);
|
|
364
|
+
if (Objects.isNull(entity)) {
|
|
297
365
|
throw new RuntimeException("用户不存在,ID: " + id);
|
|
298
366
|
}
|
|
299
|
-
|
|
367
|
+
userRepository.removeById(id);
|
|
300
368
|
}
|
|
301
369
|
|
|
302
370
|
@Override
|
|
303
371
|
@Transactional(readOnly = true)
|
|
304
372
|
public IPage<UserResponse> page(UserPageRequest request) {
|
|
305
|
-
Page<
|
|
306
|
-
LambdaQueryWrapper<
|
|
373
|
+
Page<UserEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
|
|
374
|
+
LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
|
|
307
375
|
|
|
308
376
|
// 条件查询(按需添加)
|
|
309
377
|
if (request.getUsername() != null) {
|
|
310
|
-
wrapper.like(
|
|
378
|
+
wrapper.like(UserEntity::getUsername, request.getUsername());
|
|
311
379
|
}
|
|
312
380
|
if (request.getStatus() != null) {
|
|
313
|
-
wrapper.eq(
|
|
381
|
+
wrapper.eq(UserEntity::getStatus, request.getStatus());
|
|
314
382
|
}
|
|
315
383
|
|
|
316
384
|
// 默认按创建时间倒序
|
|
317
|
-
wrapper.orderByDesc(
|
|
385
|
+
wrapper.orderByDesc(UserEntity::getCreateTime);
|
|
318
386
|
|
|
319
|
-
IPage<
|
|
387
|
+
IPage<UserEntity> result = userRepository.page(page, wrapper);
|
|
320
388
|
return result.convert(this::toResponse);
|
|
321
389
|
}
|
|
322
390
|
|
|
323
391
|
/**
|
|
324
392
|
* Entity 转 Response DTO
|
|
325
393
|
*/
|
|
326
|
-
private UserResponse toResponse(
|
|
394
|
+
private UserResponse toResponse(UserEntity entity) {
|
|
327
395
|
UserResponse response = new UserResponse();
|
|
328
|
-
BeanUtils.copyProperties(
|
|
396
|
+
BeanUtils.copyProperties(entity, response);
|
|
329
397
|
return response;
|
|
330
398
|
}
|
|
331
399
|
}
|
|
@@ -723,7 +791,7 @@ class UserServiceTest {
|
|
|
723
791
|
|
|
724
792
|
```
|
|
725
793
|
请根据以下 DDL 只生成 Entity 和 Mapper:
|
|
726
|
-
CREATE TABLE
|
|
794
|
+
CREATE TABLE zz_plt_order (...);
|
|
727
795
|
```
|
|
728
796
|
|
|
729
797
|
### 自定义字段映射
|
|
@@ -752,16 +820,17 @@ throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在,ID: " +
|
|
|
752
820
|
---
|
|
753
821
|
|
|
754
822
|
## 命名转换规则
|
|
823
|
+
表名规则 {部门}_{业务域}_{实体}, 转成类名直接是{实体}
|
|
755
824
|
|
|
756
825
|
| 数据库命名 | Java 命名 | 示例 |
|
|
757
826
|
|-----------|-----------|------|
|
|
758
|
-
| 表名 `
|
|
827
|
+
| 表名 `zz_plt_user_order` | 类名 `UserOrder` | 去掉 `t_` 前缀,转 PascalCase |
|
|
759
828
|
| 列名 `user_name` | 字段名 `userName` | 转 camelCase |
|
|
760
|
-
| 表名 `
|
|
761
|
-
| 表名 `
|
|
762
|
-
| 表名 `
|
|
763
|
-
| 表名 `
|
|
764
|
-
| 表名 `
|
|
829
|
+
| 表名 `zz_plt_user` | URL `/api/v1/users` | 去掉 `t_` 前缀,复数形式 |
|
|
830
|
+
| 表名 `zz_plt_user` | Mapper `UserMapper` | 类名 + Mapper |
|
|
831
|
+
| 表名 `zz_plt_user` | Service `UserService` | 类名 + Service |
|
|
832
|
+
| 表名 `zz_plt_user` | ServiceImpl `UserServiceImpl` | 类名 + ServiceImpl |
|
|
833
|
+
| 表名 `zz_plt_user` | Controller `UserController` | 类名 + Controller |
|
|
765
834
|
|
|
766
835
|
---
|
|
767
836
|
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# MySQL 建表语句生成器 Skill
|
|
2
|
+
|
|
3
|
+
MySQL 建表语句自动生成工具,帮助开发者快速创建符合 Avatar Boot 规范的标准数据库表结构。
|
|
4
|
+
|
|
5
|
+
## 适用对象
|
|
6
|
+
|
|
7
|
+
- **后端开发**:需要创建新的数据库表
|
|
8
|
+
- **架构设计**:设计数据库表结构
|
|
9
|
+
- **新成员**:快速了解建表规范并生成标准 SQL
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
将本目录复制到项目的 `.claude/skills/` 或全局 `~/.claude/skills/` 目录,在 Claude Code 中描述需求即可触发:
|
|
14
|
+
|
|
15
|
+
- "帮我创建一个用户表"
|
|
16
|
+
- "生成一个角色表的建表语句"
|
|
17
|
+
- "创建一个文章和标签的关联表"
|
|
18
|
+
- "检查这个建表语句是否符合规范"
|
|
19
|
+
|
|
20
|
+
## 功能覆盖
|
|
21
|
+
|
|
22
|
+
| 功能 | 说明 |
|
|
23
|
+
|:--|:--|
|
|
24
|
+
| 创建新表 | 自动生成符合规范的完整建表语句 |
|
|
25
|
+
| 生成关联表 | 创建中间表/关联表的标准结构 |
|
|
26
|
+
| 验证表结构 | 检查现有建表语句是否符合规范 |
|
|
27
|
+
| 查看规范 | 快速查阅命名、字段、索引规范 |
|
|
28
|
+
|
|
29
|
+
## 核心特性
|
|
30
|
+
|
|
31
|
+
### 1. 智能询问
|
|
32
|
+
通过交互式问答收集必要信息:
|
|
33
|
+
- 所属部门(讯飞智作、交互平台、资产平台、大模型)
|
|
34
|
+
- 业务域(平台、用户、内容等)
|
|
35
|
+
- 实体名称(角色、用户、文章等)
|
|
36
|
+
- 业务字段(根据实际需求)
|
|
37
|
+
|
|
38
|
+
### 2. 自动生成
|
|
39
|
+
根据规范自动生成:
|
|
40
|
+
- 标准表名(`{部门}_{业务域}_{实体}`)
|
|
41
|
+
- 基础字段(id, created_at, updated_at, is_deleted)
|
|
42
|
+
- 可选审计字段(created_by, updated_by)
|
|
43
|
+
- 合适的索引(主键、唯一索引、普通索引)
|
|
44
|
+
- 完整的注释(表注释、字段注释)
|
|
45
|
+
|
|
46
|
+
### 3. 规范检查
|
|
47
|
+
验证建表语句是否符合规范:
|
|
48
|
+
- 表名格式检查
|
|
49
|
+
- 基础字段完整性检查
|
|
50
|
+
- 字段注释检查
|
|
51
|
+
- 索引规范检查
|
|
52
|
+
- 引擎和字符集检查
|
|
53
|
+
|
|
54
|
+
### 4. 实体类建议
|
|
55
|
+
提供 Spring 实体类命名建议:
|
|
56
|
+
- 表名 `zz_plt_role` → 实体类 `Role`
|
|
57
|
+
- 自动去除前缀,使用驼峰命名
|
|
58
|
+
|
|
59
|
+
## 目录结构
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
mysql-table-generator-skill/
|
|
63
|
+
├── SKILL.md # Skill 主文件
|
|
64
|
+
├── README.md # 说明文档
|
|
65
|
+
└── references/
|
|
66
|
+
├── 命名规范.md # 表名、字段名、索引名规范
|
|
67
|
+
├── 字段类型规范.md # 数据类型选择指南
|
|
68
|
+
└── 索引规范.md # 索引设计原则
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 使用示例
|
|
72
|
+
|
|
73
|
+
### 示例 1:创建业务表
|
|
74
|
+
|
|
75
|
+
**用户**:"帮我创建一个角色表"
|
|
76
|
+
|
|
77
|
+
**助手**:
|
|
78
|
+
1. 询问所属部门 → 用户选择"讯飞智作 (zz)"
|
|
79
|
+
2. 询问业务域 → 用户输入"plt"
|
|
80
|
+
3. 询问实体名 → 用户输入"role"
|
|
81
|
+
4. 询问业务字段 → 用户输入"角色编码、角色名称、描述、是否启用、排序权重"
|
|
82
|
+
5. 生成完整建表语句
|
|
83
|
+
|
|
84
|
+
**输出**:
|
|
85
|
+
```sql
|
|
86
|
+
CREATE TABLE `zz_plt_role` (
|
|
87
|
+
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
|
88
|
+
`role_code` VARCHAR(64) NOT NULL COMMENT '角色编码',
|
|
89
|
+
`role_name` VARCHAR(128) NOT NULL COMMENT '角色名称',
|
|
90
|
+
`description` VARCHAR(512) DEFAULT NULL COMMENT '角色描述',
|
|
91
|
+
`is_enabled` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用:0-禁用,1-启用',
|
|
92
|
+
`sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序权重',
|
|
93
|
+
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
94
|
+
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
|
95
|
+
`created_by` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '创建人ID',
|
|
96
|
+
`updated_by` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '更新人ID',
|
|
97
|
+
`is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-未删除,1-已删除',
|
|
98
|
+
PRIMARY KEY (`id`),
|
|
99
|
+
UNIQUE KEY `uk_zz_plt_role_code` (`role_code`),
|
|
100
|
+
KEY `idx_zz_plt_role_name` (`role_name`)
|
|
101
|
+
) ENGINE=InnoDB
|
|
102
|
+
DEFAULT CHARSET=utf8mb4
|
|
103
|
+
COLLATE=utf8mb4_0900_ai_ci
|
|
104
|
+
COMMENT='智作平台-角色表 [zz][plt]';
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 示例 2:创建关联表
|
|
108
|
+
|
|
109
|
+
**用户**:"创建虚拟人和角色的关联表"
|
|
110
|
+
|
|
111
|
+
**助手**:
|
|
112
|
+
1. 询问所属部门和业务域
|
|
113
|
+
2. 自动生成关联表结构
|
|
114
|
+
3. 包含联合唯一索引和外键索引
|
|
115
|
+
|
|
116
|
+
**输出**:
|
|
117
|
+
```sql
|
|
118
|
+
CREATE TABLE `zz_plt_avatar_role_rel` (
|
|
119
|
+
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
|
120
|
+
`avatar_id` BIGINT UNSIGNED NOT NULL COMMENT '虚拟人ID',
|
|
121
|
+
`role_id` BIGINT UNSIGNED NOT NULL COMMENT '角色ID',
|
|
122
|
+
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
123
|
+
`is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-未删除,1-已删除',
|
|
124
|
+
PRIMARY KEY (`id`),
|
|
125
|
+
UNIQUE KEY `uk_zz_plt_avatar_role_rel` (`avatar_id`, `role_id`),
|
|
126
|
+
KEY `idx_zz_plt_avatar_role_rel_role` (`role_id`)
|
|
127
|
+
) ENGINE=InnoDB
|
|
128
|
+
DEFAULT CHARSET=utf8mb4
|
|
129
|
+
COLLATE=utf8mb4_0900_ai_ci
|
|
130
|
+
COMMENT='智作平台-虚拟人角色关联表 [zz][plt]';
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 示例 3:验证表结构
|
|
134
|
+
|
|
135
|
+
**用户**:"检查这个建表语句是否符合规范:CREATE TABLE user ..."
|
|
136
|
+
|
|
137
|
+
**助手**:
|
|
138
|
+
1. 分析表名格式
|
|
139
|
+
2. 检查基础字段
|
|
140
|
+
3. 检查字段注释
|
|
141
|
+
4. 检查索引配置
|
|
142
|
+
5. 检查引擎和字符集
|
|
143
|
+
6. 给出修改建议
|
|
144
|
+
|
|
145
|
+
## 规范要点
|
|
146
|
+
|
|
147
|
+
### 表命名规范
|
|
148
|
+
- 格式:`{部门缩写}_{业务域}_{实体名}`
|
|
149
|
+
- 示例:`zz_plt_role`(讯飞智作-平台-角色)
|
|
150
|
+
- 全小写,下划线分隔
|
|
151
|
+
|
|
152
|
+
### 必须包含的基础字段
|
|
153
|
+
```sql
|
|
154
|
+
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
|
155
|
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
156
|
+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
|
157
|
+
is_deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-未删除,1-已删除',
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 索引命名规范
|
|
161
|
+
- 主键:自动创建,无需显式声明
|
|
162
|
+
- 唯一索引:`uk_{表名}_{字段}`
|
|
163
|
+
- 普通索引:`idx_{表名}_{字段}`
|
|
164
|
+
- 联合索引:`idx_{表名}_{字段1}_{字段2}`
|
|
165
|
+
|
|
166
|
+
### 引擎和字符集
|
|
167
|
+
```sql
|
|
168
|
+
ENGINE=InnoDB
|
|
169
|
+
DEFAULT CHARSET=utf8mb4
|
|
170
|
+
COLLATE=utf8mb4_0900_ai_ci
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 版本要求
|
|
174
|
+
|
|
175
|
+
- MySQL 8.0+
|
|
176
|
+
- Java 21+ / Spring Boot 3.5.3+
|
|
177
|
+
- MyBatis-Plus 3.5.15
|
|
178
|
+
|
|
179
|
+
## 相关文档
|
|
180
|
+
|
|
181
|
+
- [MySQL 数据库规范](../../database/mysql-specification.md)
|
|
182
|
+
- [Avatar Boot MySQL Starter](../avatar-boot-starter-mysql-skill/)
|
|
183
|
+
|
|
184
|
+
## 注意事项
|
|
185
|
+
|
|
186
|
+
1. **表名前缀**:Spring 实体类不需要前缀,直接使用实体名
|
|
187
|
+
2. **逻辑删除**:所有查询必须带 `AND is_deleted = 0` 条件
|
|
188
|
+
3. **唯一索引**:需要在业务层做唯一性校验
|
|
189
|
+
4. **字段注释**:每个字段都必须有清晰的注释
|
|
190
|
+
5. **索引数量**:单表索引不超过 5 个
|
|
191
|
+
|
|
192
|
+
## 常见问题
|
|
193
|
+
|
|
194
|
+
**Q: 为什么要使用 BIGINT UNSIGNED 作为主键?**
|
|
195
|
+
A: INT 最大约 21 亿,高频写入表容易溢出,BIGINT UNSIGNED 可以支持更大的数据量。
|
|
196
|
+
|
|
197
|
+
**Q: 为什么使用 DATETIME 而不是 TIMESTAMP?**
|
|
198
|
+
A: TIMESTAMP 有 2038 年问题,DATETIME 范围更大,更适合长期存储。
|
|
199
|
+
|
|
200
|
+
**Q: 为什么不使用 ENUM 类型?**
|
|
201
|
+
A: ENUM 修改需要 DDL,高并发下有锁风险,建议使用 TINYINT + 注释。
|
|
202
|
+
|
|
203
|
+
**Q: 关联表需要 updated_at 字段吗?**
|
|
204
|
+
A: 关联表通常只有创建和删除操作,不需要 updated_at 字段。
|
|
205
|
+
|
|
206
|
+
**Q: 如何处理多租户场景?**
|
|
207
|
+
A: 添加 `tenant_id` 字段和相关索引,详见 SKILL.md 中的特殊场景处理。
|