6aspec 2.0.0-dev.10
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/.6aspec/rules/biz/api_rule.md +578 -0
- package/.6aspec/rules/biz/background_job_rule.md +719 -0
- package/.6aspec/rules/biz/c_user_system_rule.md +240 -0
- package/.6aspec/rules/biz/code.md +39 -0
- package/.6aspec/rules/biz/event_subscriber_rule.md +529 -0
- package/.6aspec/rules/biz/project-structure.md +90 -0
- package/.6aspec/rules/biz/scheduled_job_rule.md +850 -0
- package/.6aspec/rules/brown/brown_archive_sop.md +132 -0
- package/.6aspec/rules/brown/brown_constitution.md +20 -0
- package/.6aspec/rules/brown/brown_continue_sop.md +97 -0
- package/.6aspec/rules/brown/brown_design_sop.md +155 -0
- package/.6aspec/rules/brown/brown_ff_sop.md +194 -0
- package/.6aspec/rules/brown/brown_impact_sop.md +293 -0
- package/.6aspec/rules/brown/brown_implement_sop.md +133 -0
- package/.6aspec/rules/brown/brown_list_sop.md +69 -0
- package/.6aspec/rules/brown/brown_new_sop.md +257 -0
- package/.6aspec/rules/brown/brown_proposal_sop.md +160 -0
- package/.6aspec/rules/brown/brown_quick_sop.md +134 -0
- package/.6aspec/rules/brown/brown_review_sop.md +270 -0
- package/.6aspec/rules/brown/brown_rollback_sop.md +188 -0
- package/.6aspec/rules/brown/brown_specs_sop.md +228 -0
- package/.6aspec/rules/brown/brown_status_sop.md +135 -0
- package/.6aspec/rules/brown/brown_tasks_sop.md +202 -0
- package/.6aspec/rules/brown/brown_understand_sop.md +208 -0
- package/.6aspec/rules/brown/brown_verify_sop.md +360 -0
- package/.6aspec/rules/green/6A_archive_sop.md +301 -0
- package/.6aspec/rules/green/6A_clarify_sop.md +238 -0
- package/.6aspec/rules/green/6A_code_implementation_sop.md +110 -0
- package/.6aspec/rules/green/6A_constitution.md +52 -0
- package/.6aspec/rules/green/6A_continue_sop.md +186 -0
- package/.6aspec/rules/green/6A_design_sop.md +228 -0
- package/.6aspec/rules/green/6A_import_model_table_sop.md +120 -0
- package/.6aspec/rules/green/6A_init_event_list_sop.md +62 -0
- package/.6aspec/rules/green/6A_init_map_sop.md +79 -0
- package/.6aspec/rules/green/6A_model_sop.md +210 -0
- package/.6aspec/rules/green/6A_new_sop.md +319 -0
- package/.6aspec/rules/green/6A_rollback_sop.md +198 -0
- package/.6aspec/rules/green/6A_status_sop.md +275 -0
- package/.6aspec/rules/green/6A_tasks_sop.md +181 -0
- package/.6aspec/rules/green/6A_visual_logic_sop.md +121 -0
- package/.6aspec/rules/green/green_status_schema.md +293 -0
- package/.6aspec/script/create_entities_from_markdown.py +688 -0
- package/.claude/commands/6aspec/brown/archive.md +11 -0
- package/.claude/commands/6aspec/brown/continue.md +11 -0
- package/.claude/commands/6aspec/brown/design.md +11 -0
- package/.claude/commands/6aspec/brown/ff.md +11 -0
- package/.claude/commands/6aspec/brown/impact.md +11 -0
- package/.claude/commands/6aspec/brown/implement.md +11 -0
- package/.claude/commands/6aspec/brown/list.md +11 -0
- package/.claude/commands/6aspec/brown/new.md +11 -0
- package/.claude/commands/6aspec/brown/proposal.md +11 -0
- package/.claude/commands/6aspec/brown/quick.md +11 -0
- package/.claude/commands/6aspec/brown/review.md +11 -0
- package/.claude/commands/6aspec/brown/rollback.md +11 -0
- package/.claude/commands/6aspec/brown/specs.md +11 -0
- package/.claude/commands/6aspec/brown/status.md +11 -0
- package/.claude/commands/6aspec/brown/tasks.md +11 -0
- package/.claude/commands/6aspec/brown/understand.md +11 -0
- package/.claude/commands/6aspec/brown/verify.md +11 -0
- package/.claude/commands/6aspec/green/archive.md +8 -0
- package/.claude/commands/6aspec/green/clarify.md +13 -0
- package/.claude/commands/6aspec/green/continue.md +8 -0
- package/.claude/commands/6aspec/green/design.md +8 -0
- package/.claude/commands/6aspec/green/execute-task.md +20 -0
- package/.claude/commands/6aspec/green/import-model-table.md +8 -0
- package/.claude/commands/6aspec/green/init.md +14 -0
- package/.claude/commands/6aspec/green/model.md +12 -0
- package/.claude/commands/6aspec/green/new.md +13 -0
- package/.claude/commands/6aspec/green/rollback.md +8 -0
- package/.claude/commands/6aspec/green/status.md +8 -0
- package/.claude/commands/6aspec/green/tasks.md +8 -0
- package/.claude/commands/6aspec/green/visual-logic.md +9 -0
- package/.claude/settings.local.json +8 -0
- package/.cursor/commands/6aspec/brown/archive.md +9 -0
- package/.cursor/commands/6aspec/brown/continue.md +9 -0
- package/.cursor/commands/6aspec/brown/design.md +9 -0
- package/.cursor/commands/6aspec/brown/ff.md +9 -0
- package/.cursor/commands/6aspec/brown/impact.md +9 -0
- package/.cursor/commands/6aspec/brown/implement.md +9 -0
- package/.cursor/commands/6aspec/brown/list.md +9 -0
- package/.cursor/commands/6aspec/brown/new.md +9 -0
- package/.cursor/commands/6aspec/brown/proposal.md +9 -0
- package/.cursor/commands/6aspec/brown/quick.md +9 -0
- package/.cursor/commands/6aspec/brown/review.md +9 -0
- package/.cursor/commands/6aspec/brown/rollback.md +9 -0
- package/.cursor/commands/6aspec/brown/specs.md +9 -0
- package/.cursor/commands/6aspec/brown/status.md +9 -0
- package/.cursor/commands/6aspec/brown/tasks.md +9 -0
- package/.cursor/commands/6aspec/brown/understand.md +9 -0
- package/.cursor/commands/6aspec/brown/verify.md +9 -0
- package/.cursor/commands/6aspec/green/archive.md +9 -0
- package/.cursor/commands/6aspec/green/clarify.md +14 -0
- package/.cursor/commands/6aspec/green/continue.md +9 -0
- package/.cursor/commands/6aspec/green/design.md +9 -0
- package/.cursor/commands/6aspec/green/execute-task.md +21 -0
- package/.cursor/commands/6aspec/green/import-model-table.md +9 -0
- package/.cursor/commands/6aspec/green/init.md +15 -0
- package/.cursor/commands/6aspec/green/model.md +13 -0
- package/.cursor/commands/6aspec/green/new.md +14 -0
- package/.cursor/commands/6aspec/green/rollback.md +9 -0
- package/.cursor/commands/6aspec/green/status.md +9 -0
- package/.cursor/commands/6aspec/green/tasks.md +9 -0
- package/.cursor/commands/6aspec/green/visual-logic.md +10 -0
- package/README.en.md +36 -0
- package/README.md +146 -0
- package/bin/6a-spec-install +54 -0
- package/bin/6aspec +64 -0
- package/lib/cli.js +451 -0
- package/lib/installer.js +333 -0
- package/package.json +62 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
# API 开发规范
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
本规范定义了系统中各类 API 接口的开发标准,包括包结构、注解使用、命名规范等。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 一、需用户登录的 API 接口
|
|
10
|
+
|
|
11
|
+
### 1.1 按端分类
|
|
12
|
+
|
|
13
|
+
**端的定义**:
|
|
14
|
+
- **B端(Business端)**:企业内部业务人员使用,包括 PC 管理后台和移动 APP,使用统一的权限体系(`@ActionRight`)
|
|
15
|
+
- **C端(Customer端)**:面向终端客户/用户,如 H5、小程序等,使用客户认证体系(`@IdentityUserPermission()`)
|
|
16
|
+
|
|
17
|
+
#### 1.1.1 B端 PC API
|
|
18
|
+
|
|
19
|
+
**适用场景**:PC 端管理后台使用的接口
|
|
20
|
+
|
|
21
|
+
**包路径规范**:
|
|
22
|
+
```
|
|
23
|
+
**.controller.modeling.bizapi
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**开发规范**:
|
|
27
|
+
- **继承**:`extends Controller`
|
|
28
|
+
- **类注解**:
|
|
29
|
+
- `@PubService(value = "/xxx", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
30
|
+
- `@Tag(name = "PC-{模块名称}")`
|
|
31
|
+
- **方法注解**:
|
|
32
|
+
- `@PubAction(value = "/methodName", method = RequestMethod.POST)`
|
|
33
|
+
- `@Operation(summary = "方法描述", description = "详细说明")`
|
|
34
|
+
- `@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功")})`
|
|
35
|
+
- **权限控制**(必需):
|
|
36
|
+
- 单个权限:`@ActionRight(ActionCode = "权限码", ActionName = "权限名称", BusinessCode = BusinessUnitCodeConstant.XXX)`
|
|
37
|
+
- 多个权限:`@ActionRights({@ActionRight(...), @ActionRight(...)})`
|
|
38
|
+
|
|
39
|
+
**参考示例**:
|
|
40
|
+
```java
|
|
41
|
+
@Tag(name = "PC-入住办理")
|
|
42
|
+
@PubService(value = "/checkIn", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.RENTAL_CARETAKER)
|
|
43
|
+
public class CheckInController extends Controller {
|
|
44
|
+
|
|
45
|
+
@PubAction(value = "/deleteCheckIn", method = RequestMethod.POST)
|
|
46
|
+
@Operation(summary = "删除", description = "删除")
|
|
47
|
+
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功")})
|
|
48
|
+
@ActionRight(ActionCode = "0103", ActionName = "删除入住单", BusinessCode = BusinessUnitCodeConstant.RENTAL_CARETAKER)
|
|
49
|
+
public void deleteCheckIn(UUID checkInId) {
|
|
50
|
+
// 业务逻辑
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### 1.1.2 B端移动 APP API
|
|
56
|
+
|
|
57
|
+
**适用场景**:移动 APP 端管理使用的接口(B端业务人员使用)
|
|
58
|
+
|
|
59
|
+
**包路径规范**:
|
|
60
|
+
```
|
|
61
|
+
**.controller.app.bizapi # 普通业务接口
|
|
62
|
+
**.controller.app.dataapi # DataApi 接口
|
|
63
|
+
**.controller.app.filter # 资源过滤接口
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**开发规范**:
|
|
67
|
+
- **继承**:`extends Controller`
|
|
68
|
+
- **类注解**:
|
|
69
|
+
- `@PubService(value = "/xxx", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
70
|
+
- `@Tag(name = "APP-{模块名称}")`
|
|
71
|
+
- **方法注解**:
|
|
72
|
+
- `@PubAction(value = "/methodName", method = RequestMethod.POST)`
|
|
73
|
+
- `@Operation(summary = "方法描述", description = "详细说明")`
|
|
74
|
+
- `@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功")})`
|
|
75
|
+
- **权限控制**(必需):
|
|
76
|
+
- 单个权限:`@ActionRight(ActionCode = "权限码", ActionName = "权限名称", BusinessCode = BusinessUnitCodeConstant.XXX)`
|
|
77
|
+
- 多个权限:`@ActionRights({@ActionRight(...), @ActionRight(...)})`
|
|
78
|
+
|
|
79
|
+
**特别说明**:
|
|
80
|
+
- `app` 包下的接口虽然是给移动端调用,但属于 **B端管理系统**,供企业内部业务人员使用
|
|
81
|
+
- 权限控制方式与 PC 端 B端 API 相同,使用 `@ActionRight` 注解
|
|
82
|
+
- Tag 命名建议使用 "APP-xxx" 前缀,便于区分移动端和 PC 端
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
#### 1.1.3 C端 H5 API
|
|
87
|
+
|
|
88
|
+
**适用场景**:H5 移动端、小程序等客户端使用的接口(面向终端用户/客户)
|
|
89
|
+
|
|
90
|
+
**包路径规范**:
|
|
91
|
+
```
|
|
92
|
+
**.controller.h5.bizapi # 普通业务接口
|
|
93
|
+
**.controller.h5.dataapi # DataApi 接口
|
|
94
|
+
**.controller.h5.filter # 资源过滤接口
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**开发规范**:
|
|
98
|
+
- **继承**:`extends Controller`
|
|
99
|
+
- **类注解**:
|
|
100
|
+
- `@PubService(value = "/xxx", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
101
|
+
- `@Tag(name = "H5-{模块名称}")`
|
|
102
|
+
- `@AuthOpenApi(model = UserType.Customer)` - 标识客户端认证
|
|
103
|
+
- **方法注解**:
|
|
104
|
+
- `@PubAction(value = "/methodName", method = RequestMethod.POST)`
|
|
105
|
+
- `@Operation(summary = "方法描述", description = "详细说明")`
|
|
106
|
+
- `@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功", content = {...})})`
|
|
107
|
+
- **权限控制**(必需):
|
|
108
|
+
- `@IdentityUserPermission()` - 身份用户权限验证
|
|
109
|
+
|
|
110
|
+
**参考示例**:
|
|
111
|
+
```java
|
|
112
|
+
@Tag(name = "H5-入住")
|
|
113
|
+
@PubService(value = "/h5CheckIn", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.RENTAL_CARETAKER)
|
|
114
|
+
@AuthOpenApi(model = UserType.Customer)
|
|
115
|
+
public class H5CheckInController extends Controller {
|
|
116
|
+
|
|
117
|
+
@PubAction(value = "/getCheckInInfoById")
|
|
118
|
+
@Operation(summary = "根据入住单Id获取入住信息", description = "根据入住单Id获取入住信息")
|
|
119
|
+
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = CheckInDTO.class))})})
|
|
120
|
+
@IdentityUserPermission()
|
|
121
|
+
public CheckInDTO getCheckInInfoById(UUID checkInId){
|
|
122
|
+
// 业务逻辑
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### 1.2 按类型分类
|
|
130
|
+
|
|
131
|
+
#### 1.2.1 普通 BizApi 接口
|
|
132
|
+
|
|
133
|
+
**适用场景**:标准的 CRUD 操作接口
|
|
134
|
+
|
|
135
|
+
**包路径规范**(根据端选择):
|
|
136
|
+
```
|
|
137
|
+
**.controller.modeling.bizapi # B端 PC 端
|
|
138
|
+
**.controller.app.bizapi # B端移动 APP 端
|
|
139
|
+
**.controller.h5.bizapi # C端 H5 端
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**开发规范**:
|
|
143
|
+
- **B端(modeling/app)**:参考 [1.1.1 B端 PC API](#111-b端-pc-api) 和 [1.1.2 B端移动 APP API](#112-b端移动-app-api)
|
|
144
|
+
- **C端(h5)**:参考 [1.1.3 C端 H5 API](#113-c端-h5-api)
|
|
145
|
+
|
|
146
|
+
**命名规范**:
|
|
147
|
+
- 类名:
|
|
148
|
+
- PC 端:`{模块名}Controller`
|
|
149
|
+
- APP 端:`{模块名}AppController`
|
|
150
|
+
- H5 端:`H5{模块名}Controller`
|
|
151
|
+
- 方法名:动词开头,如 `create`, `update`, `delete`, `get`, `list`
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
#### 1.2.2 DataApi 接口
|
|
156
|
+
|
|
157
|
+
**适用场景**:提供表格数据查询,支持分页、排序、字段定义等功能
|
|
158
|
+
|
|
159
|
+
**包路径规范**(根据端选择):
|
|
160
|
+
```
|
|
161
|
+
**.controller.modeling.dataapi # B端 PC 端
|
|
162
|
+
**.controller.app.dataapi # B端移动 APP 端
|
|
163
|
+
**.controller.h5.dataapi # C端 H5 端
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**开发规范**:
|
|
167
|
+
- **继承**:`extends DataApiController`
|
|
168
|
+
- **类注解**:
|
|
169
|
+
- `@PubService(value = "/xxxDataApi", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
170
|
+
- `@Tag(name = "PC-{模块名}-API")`
|
|
171
|
+
- **必须实现的方法**:
|
|
172
|
+
- `projectFilter()` - 是否启用项目过滤
|
|
173
|
+
- `loadFields()` - 定义字段结构,返回 `FieldsSetting`
|
|
174
|
+
- `loadData(LoadDataParams options)` - 加载数据,返回 `ListDataResult`
|
|
175
|
+
|
|
176
|
+
**字段类型**:`FieldType.String`, `FieldType.Int`, `FieldType.Decimal`, `FieldType.DateTime` 等
|
|
177
|
+
|
|
178
|
+
**参考示例**:
|
|
179
|
+
```java
|
|
180
|
+
@PubService(value = "/checkInMeterReadingDataApi", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.RENTAL_CARETAKER)
|
|
181
|
+
@Tag(name = "PC-房态入住抄表-API")
|
|
182
|
+
public class CheckInMeterReadingDataApiController extends DataApiController {
|
|
183
|
+
|
|
184
|
+
@Override
|
|
185
|
+
public boolean projectFilter() {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@Override
|
|
190
|
+
public FieldsSetting loadFields() {
|
|
191
|
+
FieldsSetting fieldsSetting = new FieldsSetting();
|
|
192
|
+
String groupName = "group_name";
|
|
193
|
+
fieldsSetting.setIdField("primaryKeyField");
|
|
194
|
+
fieldsSetting.setFields(new ArrayList<>());
|
|
195
|
+
|
|
196
|
+
// 添加字段定义
|
|
197
|
+
fieldsSetting.getFields().add(new DataApiField("fieldName", groupName, "字段显示名", FieldType.String));
|
|
198
|
+
|
|
199
|
+
return fieldsSetting;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@Override
|
|
203
|
+
public ListDataResult loadData(LoadDataParams options) {
|
|
204
|
+
ListDataResult listDataResult = new ListDataResult();
|
|
205
|
+
// 查询数据逻辑
|
|
206
|
+
listDataResult.setTotal(total);
|
|
207
|
+
listDataResult.setData(dataList);
|
|
208
|
+
return listDataResult;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
#### 1.2.3 OptionDataApi 接口
|
|
216
|
+
|
|
217
|
+
**适用场景**:提供下拉选项、枚举值等选项数据
|
|
218
|
+
|
|
219
|
+
**包路径规范**(根据端选择):
|
|
220
|
+
```
|
|
221
|
+
**.controller.modeling.dataapi # B端 PC 端
|
|
222
|
+
**.controller.app.dataapi # B端移动 APP 端
|
|
223
|
+
**.controller.h5.dataapi # C端 H5 端
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**说明**:OptionDataApi 也放在 `dataapi` 包下
|
|
227
|
+
|
|
228
|
+
**开发规范**:
|
|
229
|
+
- **继承**:`extends Controller`
|
|
230
|
+
- **实现接口**:`implements OptionDataApi`
|
|
231
|
+
- **类注解**:
|
|
232
|
+
- `@PubService(value = "/xxxOption", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
233
|
+
- `@Tag(name = "{模块名}-API")`
|
|
234
|
+
- **必须实现的方法**:
|
|
235
|
+
- `load()` - 返回 `List<OptionItem>`
|
|
236
|
+
|
|
237
|
+
**OptionItem 结构**:
|
|
238
|
+
- `setText(String text)` - 显示文本
|
|
239
|
+
- `setValue(Object value)` - 选项值
|
|
240
|
+
- `setDefault(boolean isDefault)` - 是否默认选中
|
|
241
|
+
|
|
242
|
+
**参考示例**:
|
|
243
|
+
```java
|
|
244
|
+
@Tag(name = "设备预警类型-API")
|
|
245
|
+
@PubService(value = "/deviceAlarmTypeOption", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.RENTAL_DEVICE)
|
|
246
|
+
public class DeviceAlarmTypeOptionDataApi extends Controller implements OptionDataApi {
|
|
247
|
+
|
|
248
|
+
@Override
|
|
249
|
+
@Operation(summary = "设备预警类型", description = "设备预警类型")
|
|
250
|
+
public List<OptionItem> load() {
|
|
251
|
+
// 获取参数
|
|
252
|
+
String param = PageParameter.getPageParams().get("paramName");
|
|
253
|
+
|
|
254
|
+
// 构建选项列表
|
|
255
|
+
return enumValues.stream().map(item -> {
|
|
256
|
+
OptionItem optionItem = new OptionItem();
|
|
257
|
+
optionItem.setText(item.getDesc());
|
|
258
|
+
optionItem.setValue(item.getCode());
|
|
259
|
+
optionItem.setDefault(false); // 可选
|
|
260
|
+
return optionItem;
|
|
261
|
+
}).collect(Collectors.toList());
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
#### 1.2.4 资源化过滤 API
|
|
269
|
+
|
|
270
|
+
**适用场景**:提供基于用户权限的资源过滤功能
|
|
271
|
+
|
|
272
|
+
**包路径规范**(根据端选择):
|
|
273
|
+
```
|
|
274
|
+
**.controller.modeling.filter # B端 PC 端资源过滤
|
|
275
|
+
**.controller.app.filter # B端移动 APP 端资源过滤
|
|
276
|
+
**.controller.h5.filter # C端 H5 端资源过滤
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**特别说明**:
|
|
280
|
+
- **modeling.filter**:PC 端的数据权限过滤
|
|
281
|
+
- **app.filter**:移动 APP 端的数据权限过滤(B端业务人员)
|
|
282
|
+
- **h5.filter**:H5 端的数据权限过滤(C端客户)
|
|
283
|
+
- 不同端使用相应的权限控制注解
|
|
284
|
+
|
|
285
|
+
**开发规范**:
|
|
286
|
+
- **继承**:`extends BaseResourceFilterController`
|
|
287
|
+
- **类注解**:
|
|
288
|
+
- `@PubService(value = "/xxxResourceFilterApp", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
289
|
+
- `@Tag(name = "{模块名}-APP-资源化过滤-API")`
|
|
290
|
+
- **必须实现的方法**:
|
|
291
|
+
- `getMainTable()` - 返回主表名称
|
|
292
|
+
- `getWhereSql()` - 返回过滤 SQL 条件
|
|
293
|
+
|
|
294
|
+
**参考示例**:
|
|
295
|
+
```java
|
|
296
|
+
@Tag(name = "设备-APP-资源化过滤-API")
|
|
297
|
+
@PubService(value = "/deviceResourceFilterApp", prefix = RequestPrefix.API, businessCode = BusinessUnitCodeConstant.RENTAL_DEVICE_DOOR_LOCK_APP)
|
|
298
|
+
public class DeviceResourceFilterAppController extends BaseResourceFilterController {
|
|
299
|
+
|
|
300
|
+
@Autowired
|
|
301
|
+
private UserDataPermissionFacade userDataPermissionFacade;
|
|
302
|
+
|
|
303
|
+
@Override
|
|
304
|
+
public String getMainTable() {
|
|
305
|
+
return TableUtils.getTableName(DeviceEntity.class);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
@Override
|
|
309
|
+
public String getWhereSql() {
|
|
310
|
+
return userDataPermissionFacade.getUserResourceFilterSql(
|
|
311
|
+
UserDataPermissionFilterModeEnum.ORGANIZATION_AND_PROJECT,
|
|
312
|
+
null,
|
|
313
|
+
"rental_Resource.BUGUID",
|
|
314
|
+
"rental_deviceroom.ProjGUID",
|
|
315
|
+
Lists.newArrayList()
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 二、跨系统调用 API(Pub API)
|
|
324
|
+
|
|
325
|
+
### 2.1 概述
|
|
326
|
+
|
|
327
|
+
**适用场景**:系统间调用、第三方系统集成、无需用户登录的开放接口
|
|
328
|
+
|
|
329
|
+
**包路径规范**:
|
|
330
|
+
```
|
|
331
|
+
**.controller.pub
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 2.2 开发规范
|
|
335
|
+
|
|
336
|
+
- **继承**:`extends Controller`
|
|
337
|
+
- **类注解**:
|
|
338
|
+
- `@PubService(value = "/xxxOpenRmi", prefix = RequestPrefix.SHARE, businessCode = BusinessUnitCodeConstant.XXX)`
|
|
339
|
+
- `@Tag(name = "{模块名}-openAPI")`
|
|
340
|
+
- **方法注解**:
|
|
341
|
+
- `@PubAction(value = "/methodName", method = RequestMethod.POST)`
|
|
342
|
+
- `@Operation(summary = "方法描述", description = "详细说明")`
|
|
343
|
+
- `@ApiResponses(value = {...})`
|
|
344
|
+
- **权限控制**:无需添加权限注解
|
|
345
|
+
|
|
346
|
+
**注意事项**:
|
|
347
|
+
- 使用 `RequestPrefix.SHARE` 而非 `RequestPrefix.API`
|
|
348
|
+
- 命名建议使用 `{模块}ShareController` 或 `{模块}OpenRmiController`
|
|
349
|
+
- 需做好接口安全校验(如签名验证、IP白名单等)
|
|
350
|
+
|
|
351
|
+
### 2.3 参考示例
|
|
352
|
+
|
|
353
|
+
```java
|
|
354
|
+
@Tag(name = "设备管理-预充值-openAPI")
|
|
355
|
+
@PubService(value = "/deviceRechargeOpenRmi", prefix = RequestPrefix.SHARE, businessCode = BusinessUnitCodeConstant.RENTAL_DEVICE)
|
|
356
|
+
public class DeviceRechargeShareController extends Controller {
|
|
357
|
+
|
|
358
|
+
@Operation(summary = "预充值回调接口", description = "预充值回调接口")
|
|
359
|
+
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "成功", content =
|
|
360
|
+
{@Content(mediaType = "application/json", schema = @Schema(implementation = void.class))})}
|
|
361
|
+
)
|
|
362
|
+
@PubAction(value = "/rechargeNotify", method = RequestMethod.POST)
|
|
363
|
+
public void rechargeNotify(@RequestBody @Validated DeviceRechargeNotifyCommand command) {
|
|
364
|
+
log.info("设备预充值回调参数:{}", command);
|
|
365
|
+
// 业务逻辑
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 三、通用规范
|
|
373
|
+
|
|
374
|
+
### 3.1 命名规范
|
|
375
|
+
|
|
376
|
+
| 类型 | 规范 | 示例 |
|
|
377
|
+
|------|------|------|
|
|
378
|
+
| B端 PC Controller | `{模块名}Controller` | `CheckInController` |
|
|
379
|
+
| B端 APP Controller | `{模块名}AppController` | `CheckInAppController` |
|
|
380
|
+
| C端 H5 Controller | `H5{模块名}Controller` | `H5CheckInController` |
|
|
381
|
+
| DataApi Controller | `{模块名}DataApiController` | `CheckInMeterReadingDataApiController` |
|
|
382
|
+
| OptionDataApi | `{模块名}OptionDataApi` | `DeviceAlarmTypeOptionDataApi` |
|
|
383
|
+
| 资源过滤 Controller | `{模块名}ResourceFilterAppController` | `DeviceResourceFilterAppController` |
|
|
384
|
+
| Share Controller | `{模块名}ShareController` | `DeviceRechargeShareController` |
|
|
385
|
+
| Service 路径 | `/小驼峰模块名` | `/checkIn`, `/checkInApp`, `/h5CheckIn` |
|
|
386
|
+
| Action 路径 | `/动词+名词` | `/deleteCheckIn`, `/getCheckInInfoById` |
|
|
387
|
+
|
|
388
|
+
### 3.2 注解使用规范
|
|
389
|
+
|
|
390
|
+
#### 必需注解:
|
|
391
|
+
- **类级别**:`@PubService`, `@Tag`
|
|
392
|
+
- **方法级别**:`@PubAction`, `@Operation`(建议)
|
|
393
|
+
|
|
394
|
+
#### 权限注解(根据类型选择):
|
|
395
|
+
- **B端 PC API**:`@ActionRight` 或 `@ActionRights`
|
|
396
|
+
- **B端移动 APP API**:`@ActionRight` 或 `@ActionRights`(与 PC 端相同)
|
|
397
|
+
- **C端 H5 API**:`@IdentityUserPermission()` + `@AuthOpenApi(model = UserType.Customer)`
|
|
398
|
+
- **Pub API**:无需权限注解
|
|
399
|
+
|
|
400
|
+
#### 文档注解(建议):
|
|
401
|
+
- `@ApiResponses` - 响应说明
|
|
402
|
+
- `@Schema` - 数据模型定义
|
|
403
|
+
- `@Content` - 内容类型定义
|
|
404
|
+
|
|
405
|
+
### 3.3 参数验证
|
|
406
|
+
|
|
407
|
+
- 使用 `@Valid` 或 `@Validated` 进行参数校验
|
|
408
|
+
- DTO/Command 类使用 JSR-303 注解(`@NotNull`, `@NotBlank`, `@Size` 等)
|
|
409
|
+
|
|
410
|
+
### 3.4 日志规范
|
|
411
|
+
|
|
412
|
+
- 重要操作需记录日志:`log.info("操作描述, 参数:{}", param)`
|
|
413
|
+
- 异常需记录:`log.error("错误描述", exception)`
|
|
414
|
+
|
|
415
|
+
### 3.5 返回值规范
|
|
416
|
+
|
|
417
|
+
- 查询接口:返回具体的 DTO 对象或 List
|
|
418
|
+
- 新增接口:返回主键 ID(UUID)
|
|
419
|
+
- 修改/删除接口:可返回 void 或 Boolean
|
|
420
|
+
- 分页查询:使用 `PagedResultDTO` 或 `ListDataResult`
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## 四、包结构总览
|
|
425
|
+
|
|
426
|
+
```
|
|
427
|
+
com.mysoft.rental.{module}.controller
|
|
428
|
+
├── modeling # B端 PC 端
|
|
429
|
+
│ ├── bizapi # 普通业务 API
|
|
430
|
+
│ ├── dataapi # DataApi 和 OptionDataApi
|
|
431
|
+
│ └── filter # 资源化过滤 API
|
|
432
|
+
├── app # B端移动 APP(企业内部业务人员)
|
|
433
|
+
│ ├── bizapi # 普通业务 API
|
|
434
|
+
│ ├── dataapi # DataApi 和 OptionDataApi
|
|
435
|
+
│ └── filter # 资源化过滤 API
|
|
436
|
+
├── h5 # C端 H5/小程序(面向客户)
|
|
437
|
+
│ ├── bizapi # 普通业务 API
|
|
438
|
+
│ ├── dataapi # DataApi 和 OptionDataApi
|
|
439
|
+
│ └── filter # 资源化过滤 API
|
|
440
|
+
└── pub # 跨系统调用 API(无需登录)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### 4.1 包结构说明
|
|
444
|
+
|
|
445
|
+
#### 按端划分(一级包):
|
|
446
|
+
|
|
447
|
+
| 包名 | 端类型 | 使用对象 | 权限体系 |
|
|
448
|
+
|------|--------|----------|----------|
|
|
449
|
+
| **modeling** | B端 PC | 企业内部业务人员(PC端) | `@ActionRight` |
|
|
450
|
+
| **app** | B端 APP | 企业内部业务人员(移动端) | `@ActionRight` |
|
|
451
|
+
| **h5** | C端 H5 | 终端客户/用户 | `@IdentityUserPermission()` + `@AuthOpenApi` |
|
|
452
|
+
| **pub** | 开放接口 | 跨系统调用 | 无需权限注解 |
|
|
453
|
+
|
|
454
|
+
#### 按类型划分(二级包):
|
|
455
|
+
|
|
456
|
+
| 包名 | 接口类型 | 说明 |
|
|
457
|
+
|------|----------|------|
|
|
458
|
+
| **bizapi** | 普通业务 API | 标准的 CRUD 操作接口 |
|
|
459
|
+
| **dataapi** | DataApi / OptionDataApi | 表格数据展示、下拉选项等 |
|
|
460
|
+
| **filter** | 资源化过滤 API | 基于用户权限的数据过滤 |
|
|
461
|
+
|
|
462
|
+
### 4.2 包路径组合规范
|
|
463
|
+
|
|
464
|
+
根据端和类型的组合,包路径如下:
|
|
465
|
+
|
|
466
|
+
| 场景 | 包路径 | Tag 命名 | 示例 |
|
|
467
|
+
|------|--------|----------|------|
|
|
468
|
+
| B端 PC 业务接口 | `**.controller.modeling.bizapi` | `PC-{模块}` | `CheckInController` |
|
|
469
|
+
| B端 PC DataApi | `**.controller.modeling.dataapi` | `PC-{模块}-API` | `CheckInDataApiController` |
|
|
470
|
+
| B端 PC 资源过滤 | `**.controller.modeling.filter` | `PC-{模块}-资源化过滤-API` | `DeviceResourceFilterController` |
|
|
471
|
+
| B端 APP 业务接口 | `**.controller.app.bizapi` | `APP-{模块}` | `CheckInAppController` |
|
|
472
|
+
| B端 APP DataApi | `**.controller.app.dataapi` | `APP-{模块}-API` | `CheckInAppDataApiController` |
|
|
473
|
+
| B端 APP 资源过滤 | `**.controller.app.filter` | `{模块}-APP-资源化过滤-API` | `DeviceResourceFilterAppController` |
|
|
474
|
+
| C端 H5 业务接口 | `**.controller.h5.bizapi` | `H5-{模块}` | `H5CheckInController` |
|
|
475
|
+
| C端 H5 DataApi | `**.controller.h5.dataapi` | `H5-{模块}-API` | `H5CheckInDataApiController` |
|
|
476
|
+
| C端 H5 资源过滤 | `**.controller.h5.filter` | `H5-{模块}-资源化过滤-API` | `H5ResourceFilterController` |
|
|
477
|
+
| 跨系统调用 | `**.controller.pub` | `{模块}-openAPI` | `DeviceRechargeShareController` |
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## 五、检查清单
|
|
482
|
+
|
|
483
|
+
在提交代码前,请确认:
|
|
484
|
+
|
|
485
|
+
- [ ] 类和方法名称符合命名规范
|
|
486
|
+
- [ ] 包路径正确
|
|
487
|
+
- [ ] 继承了正确的父类或实现了正确的接口
|
|
488
|
+
- [ ] 添加了必需的注解(@PubService, @Tag, @PubAction)
|
|
489
|
+
- [ ] 权限控制注解正确添加
|
|
490
|
+
- [ ] RequestPrefix 使用正确(API 或 SHARE)
|
|
491
|
+
- [ ] 添加了 Swagger 文档注解(@Operation, @ApiResponses)
|
|
492
|
+
- [ ] 参数校验注解完整
|
|
493
|
+
- [ ] 关键操作添加了日志记录
|
|
494
|
+
- [ ] 返回值类型符合规范
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## 六、常见问题
|
|
499
|
+
|
|
500
|
+
### Q1: 什么时候使用 RequestPrefix.API vs RequestPrefix.SHARE?
|
|
501
|
+
- **API**:需要用户登录的接口(B端、C端)
|
|
502
|
+
- **SHARE**:跨系统调用、无需登录的接口
|
|
503
|
+
|
|
504
|
+
### Q2: DataApi 和普通 API 的区别?
|
|
505
|
+
- **DataApi**:用于表格数据展示,支持字段配置、分页、排序等
|
|
506
|
+
- **普通 API**:标准的业务接口,CRUD 操作
|
|
507
|
+
|
|
508
|
+
### Q3: 多个权限如何配置?
|
|
509
|
+
- 使用 `@ActionRights` 包含多个 `@ActionRight`
|
|
510
|
+
|
|
511
|
+
### Q4: C端和B端权限控制的区别?
|
|
512
|
+
- **B端**:使用 `@ActionRight` 进行功能权限控制
|
|
513
|
+
- **C端**:使用 `@IdentityUserPermission()` 进行身份认证
|
|
514
|
+
|
|
515
|
+
### Q5: modeling、app、h5 三个包的区别?
|
|
516
|
+
- **modeling 包**:B端 PC 端接口,供企业内部业务人员在 PC 管理后台使用
|
|
517
|
+
- 权限体系:`@ActionRight`
|
|
518
|
+
- Tag 命名:`PC-xxx`
|
|
519
|
+
- 子包:`bizapi`、`dataapi`、`filter`
|
|
520
|
+
|
|
521
|
+
- **app 包**:B端移动 APP 接口,供企业内部业务人员在移动端使用(如管家、运营人员等)
|
|
522
|
+
- 权限体系:与 PC 端相同,使用 `@ActionRight`
|
|
523
|
+
- Tag 命名:`APP-xxx`
|
|
524
|
+
- 子包:`bizapi`、`dataapi`、`filter`
|
|
525
|
+
|
|
526
|
+
- **h5 包**:C端 H5/小程序接口,面向终端用户/客户
|
|
527
|
+
- 权限体系:客户认证体系,使用 `@IdentityUserPermission()`
|
|
528
|
+
- Tag 命名:`H5-xxx`
|
|
529
|
+
- 子包:`bizapi`、`dataapi`、`filter`
|
|
530
|
+
- 需添加:`@AuthOpenApi(model = UserType.Customer)`
|
|
531
|
+
|
|
532
|
+
### Q6: bizapi、dataapi、filter 三个子包的区别?
|
|
533
|
+
- **bizapi**:普通业务接口,如增删改查操作
|
|
534
|
+
- **dataapi**:数据 API 接口,包括 DataApi(表格数据展示)和 OptionDataApi(下拉选项)
|
|
535
|
+
- **filter**:资源化过滤接口,提供基于用户权限的数据过滤
|
|
536
|
+
|
|
537
|
+
**注意**:这三个子包可以出现在 modeling、app、h5 任何一个端包下
|
|
538
|
+
|
|
539
|
+
### Q7: 如何选择正确的包路径?
|
|
540
|
+
按照"端(一级包)+ 类型(二级包)"的组合方式选择:
|
|
541
|
+
|
|
542
|
+
**第一步:确定端(一级包)**
|
|
543
|
+
- 问:谁来调用这个接口?
|
|
544
|
+
- PC 端管理后台 → `modeling`
|
|
545
|
+
- 移动 APP(业务人员)→ `app`
|
|
546
|
+
- H5/小程序(客户)→ `h5`
|
|
547
|
+
- 跨系统调用 → `pub`
|
|
548
|
+
|
|
549
|
+
**第二步:确定类型(二级包)**
|
|
550
|
+
- 问:这是什么类型的接口?
|
|
551
|
+
- 普通 CRUD 业务 → `bizapi`
|
|
552
|
+
- 表格/选项数据 → `dataapi`
|
|
553
|
+
- 资源权限过滤 → `filter`
|
|
554
|
+
|
|
555
|
+
**示例**:
|
|
556
|
+
- PC 端入住单管理接口 → `modeling.bizapi`
|
|
557
|
+
- 移动 APP 设备资源过滤 → `app.filter`
|
|
558
|
+
- H5 端订单列表数据 → `h5.dataapi`
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## 七、相关文档
|
|
563
|
+
|
|
564
|
+
- Spring MVC 文档
|
|
565
|
+
- Swagger/OpenAPI 规范
|
|
566
|
+
- 公司框架开发手册
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
**文档版本**:v1.2
|
|
571
|
+
**最后更新**:2026-01-11
|
|
572
|
+
**更新说明**:
|
|
573
|
+
- v1.2: 完善包结构总览,明确 modeling/app/h5 三个端包下都可以有 bizapi/dataapi/filter 三个子包
|
|
574
|
+
- v1.1: 补充 B端移动 APP API 相关规范,明确 app 包和 h5 包的区别
|
|
575
|
+
- v1.0: 初始版本
|
|
576
|
+
|
|
577
|
+
**维护人**:开发团队
|
|
578
|
+
|