원클릭으로
server-coding
Triflow 后端 Java 开发规范。包括 MyBatis-Flex 查询、实体与 DTO/VO 定义、分层架构、数据库命名、异常处理、数据转换等项目约定。在编写或修改 triflow-server 代码时必须遵循。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Triflow 后端 Java 开发规范。包括 MyBatis-Flex 查询、实体与 DTO/VO 定义、分层架构、数据库命名、异常处理、数据转换等项目约定。在编写或修改 triflow-server 代码时必须遵循。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Triflow App 移动端开发规范。包括 UniApp + Wot Design Uni + Alova 请求、API 路径前缀、z-paging 分页、UnoCSS 样式、跨端兼容性等项目约定。在编写或修改 triflow-app 代码时必须遵循。
Triflow 代码审查规范。对当前代码变更或指定文件/模块进行全面合规性检查,覆盖后端 Java、Web 前端、App 移动端的命名、架构、类型安全、数据库、API 等规范。使用此 skill 审查代码是否符合项目约定。
Triflow Web 前端开发规范。包括 Vue 3.5 + Element Plus + TypeScript 组件编写、API 类型定义、Pinia 状态管理、VXE Table、样式规范等项目约定。在编写或修改 triflow-web 代码时必须遵循。
| name | server-coding |
| description | Triflow 后端 Java 开发规范。包括 MyBatis-Flex 查询、实体与 DTO/VO 定义、分层架构、数据库命名、异常处理、数据转换等项目约定。在编写或修改 triflow-server 代码时必须遵循。 |
本 Skill 定义了 Triflow 后端 Java 代码的编写规范,所有代码变更必须遵守。
User::getUsername)进行类型安全查询xxxTableDef 静态字段(如 USER.STATUS)// ✅ 正确 - Mapper 层使用 Lambda 查询
default User selectByUsername(String username) {
QueryWrapper qw = QueryWrapper.create()
.from(User.class)
.eq(User::getUsername, username);
return this.selectOneByQuery(qw);
}
// ✅ 正确 - 条件查询带第三个参数控制是否生效
default QueryWrapper buildQueryWrapper(UserQueryDTO query) {
return QueryWrapper.create()
.from(User.class)
.eq(User::getStatus, query.getStatus(), query.getStatus() != null)
.like(User::getUsername, query.getUsername(), StringUtils.isNotBlank(query.getUsername()))
.orderBy(User::getCreateTime, false); // false = DESC
}
// ❌ 禁止 - Service 层直接构造 QueryWrapper
public User getByUsername(String username) {
return userMapper.selectOneByQuery(
QueryWrapper.create().from(User.class).eq(User::getUsername, username)
); // ❌ 应在 Mapper 层封装
}
PageQuery 基类query.buildPage() 构建分页对象paginateAs 直接返回 VO 类型// Service 层
public Page<UserVO> page(UserQueryDTO query) {
Page<UserVO> page = query.buildPage();
QueryWrapper qw = userMapper.buildQueryWrapper(query);
return userMapper.paginateAs(page, qw, UserVO.class);
}
@RelationOneToMany / @RelationManyToOne 等注解详细查询示例和模式见 QUERY.md
@Table 使用模块前缀命名(如 sys_user、cms_article),禁止 t_ 前缀@see 指向枚举类,禁止在注释中罗列状态值BaseEnum 接口@Data
@Table("sys_user") // ✅ 模块前缀
public class User implements BaseEntity {
@Id(keyType = KeyType.Auto)
private Long id;
/** 用户名(唯一) */
private String username;
/**
* 状态
* @see com.glowxq.triflow.base.system.enums.UserStatus
*/
private Integer status; // ✅ 用 @see 指向枚举
@Column(isLogicDelete = true)
private Integer deleted;
}
@Schema 注解@AutoMapper(target = Entity.class) 定义转换关系MapStructUtils.convert() 进行转换,禁止 BeanUtils / Hutool / 手写 Convert@Data
@Schema(description = "用户创建请求")
@AutoMapper(target = User.class)
public class UserCreateDTO implements BaseDTO {
@Schema(description = "用户名", example = "zhangsan", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "用户名不能为空")
private String username;
}
pojo/
├── vo/ # View Object - 返回给前端的展示对象
├── dto/ # Data Transfer Object - 接收前端参数
├── bo/ # Business Object - 业务层内部传递
└── query/ # Query Object - 分页/条件查询参数
详细实体规范、枚举定义、Excel VO、审计字段见 ENTITY.md
com.glowxq.triflow.{module}/
├── controller/ # HTTP 请求处理(继承 BaseApi)
├── service/ # 业务逻辑(禁止构造 QueryWrapper)
│ └── impl/
├── mapper/ # 数据访问(封装查询逻辑)
├── entity/ # 数据库实体
└── pojo/ # DTO / VO / BO
| 层级 | 职责 | 返回类型 |
|---|---|---|
| Controller | 参数校验、调用 Service、返回 ApiResult;必须继承 BaseApi | ApiResult<T> |
| Service | 业务逻辑、事务管理;禁止构造 QueryWrapper | Entity / VO / Page |
| Mapper | CRUD 和查询条件封装 | Entity / List |
路径结构:类级 @RequestMapping("/base/{module}/{resource}"),方法级用具体路径。
@Slf4j
@Tag(name = "用户管理")
@RestController
@RequestMapping("/base/system/user") // ✅ 类级定义完整前缀
@RequiredArgsConstructor
@OperationLog(module = ModuleEnum.System)
public class SysUserController extends BaseApi { // ✅ 继承 BaseApi
private final SysUserService userService;
@PostMapping("/page")
public ApiResult<List<UserVO>> page(@RequestBody UserQueryDTO query) { ... }
@GetMapping("/{id}")
public ApiResult<UserVO> detail(@PathVariable Long id) { ... }
@PostMapping
public ApiResult<Void> create(@RequestBody @Valid UserCreateDTO dto) { ... }
@PutMapping
public ApiResult<Void> update(@RequestBody @Valid UserUpdateDTO dto) { ... }
@DeleteMapping("/{id}")
public ApiResult<Void> delete(@PathVariable Long id) { ... }
@DeleteMapping("/batch")
public ApiResult<Void> deleteBatch(@RequestBody @Valid Ids ids) { ... }
@PostMapping("/export")
public void export(@RequestBody @Valid UserQueryDTO query, HttpServletResponse response) { ... }
}
return ApiResult.success(); // 无数据
return ApiResult.success(data); // 携带数据
return ApiResult.success(voList, page); // 分页(自动解析 total/totalPage/current/limit)
return ApiResult.error(ErrorCodeEnum.PARAM_MISSING); // 错误
| 位 | 含义 | 说明 |
|---|---|---|
| T | 类型 | 1:业务异常 2:告警异常 3:客户端异常 |
| MM | 模块 | 00-99 |
| CCC | 序号 | 000-999 |
Assert 断言工具(一行完成校验 + 异常抛出)throw new BusinessException / AlertsException / ClientException// ✅ 推荐 - Assert 断言
Assert.notNull(user, ErrorCodeEnum.USER_NOT_FOUND);
Assert.isTrue(age >= 18, ErrorCodeEnum.PARAM_INVALID, "年龄必须大于18");
// ❌ 不推荐 - if-throw
if (user == null) {
throw new BusinessException(ErrorCodeEnum.USER_NOT_FOUND);
}
cn.hutool.*)StringUtils(commons-lang3)CollectionUtils(commons-collections4)ObjectUtils(commons-lang3)MapStructUtils@AutoMapper(target = Entity.class)StrictTypeMapping,字段类型必须严格匹配// ✅ 使用 MapStructUtils
User user = MapStructUtils.convert(dto, User.class);
List<UserVO> voList = MapStructUtils.convert(users, UserVO.class);
// ❌ 禁止
BeanUtils.copyProperties(source, target);
@RequiredArgsConstructor + private final 构造器注入@Autowired 字段注入cn.*, com.*, io.*, org.*)java.*, javax.*, jakarta.*)import static ...)@author 和 @since 标签@SaCheckPermission / @SaCheckRoleLoginUtils.getLoginUser() 获取当前用户t_ 前缀sys_(系统)、cms_(内容)、ord_(订单)、file_(文件)、log_(日志)所有业务表必须包含:dept_id、tenant_id、create_time、update_time、create_by、update_by、deleted
snake_caseid(BIGINT AUTO_INCREMENT){关联表}_idis_ 前缀(包括布尔字段)uk_{字段名},普通索引:idx_{字段名}详细数据库规范、SQL 模板、关联表规范见 DATABASE.md
后端所有业务枚举实现 BaseEnum 接口,系统启动时 EnumRegistry 自动扫描注册。
| 接口 | 说明 |
|---|---|
GET /base/enums | 获取所有枚举名称 |
GET /base/enums/{enumClassName} | 获取枚举选项 |
GET /base/enums/batch/{names} | 批量获取枚举 |
前端通过 EnumSelect 组件或手动调用 API 获取枚举选项。