# RuoYi-Cloud-Plus 编码规范 ## 命名规范 ### 类命名 - **实体类**:使用表名驼峰命名,如 `t_pt_room` → `PtRoom` - **业务对象**:实体名 + `Bo`,如 `PtRoomBo` - **视图对象**:实体名 + `Vo`,如 `PtRoomVo` - **传输对象**:`Remote` + 实体名 + `Dto`,如 `RemoteRoomDto` - **服务接口**:`I` + 实体名 + `Service`,如 `IPtRoomService` - **服务实现**:实体名 + `ServiceImpl`,如 `PtRoomServiceImpl` - **Mapper**:实体名 + `Mapper`,如 `PtRoomMapper` - **Controller**:实体名 + `Controller`,如 `PtRoomController` - **Dubbo接口**:`Remote` + 功能 + `Service`,如 `RemotePtRoomService` ### 方法命名 | 操作 | 前缀 | 示例 | |------|------|------| | 查询单个 | queryById / getById | `queryById(Long id)` | | 查询列表 | queryList / selectList | `queryList(Bo bo)` | | 分页查询 | queryPageList / selectPage | `queryPageList(Bo bo, PageQuery query)` | | 新增 | insertByBo / save | `insertByBo(Bo bo)` | | 修改 | updateByBo / update | `updateByBo(Bo bo)` | | 删除 | deleteByIds / remove | `deleteByIds(Collection ids)` | | 校验 | validateXxx | `validateUnique(Bo bo)` | ### 变量命名 - 使用驼峰命名法 - 布尔类型避免使用 `is` 开头(避免与 getter 冲突) - 常量使用全大写下划线分隔 ```java // 推荐 private String userName; private Boolean enabled; private static final String DEFAULT_STATUS = "0"; // 避免 private String user_name; private Boolean isEnabled; ``` ## 注解使用规范 ### 类级别注解顺序 ```java @Slf4j // 日志 @RequiredArgsConstructor // 构造器注入 @Service // Spring Bean @DubboService // Dubbo服务(如需要) public class XxxServiceImpl implements IXxxService { } ``` ### Controller 注解 ```java @Validated // 参数校验 @RequiredArgsConstructor // 构造器注入 @RestController // REST控制器 @RequestMapping("/room") // 请求路径 public class PtRoomController extends BaseController { } ``` ### 字段注解顺序 ```java @NotBlank(message = "名称不能为空", groups = {AddGroup.class, EditGroup.class}) @ExcelProperty(value = "名称") private String name; ``` ## 依赖注入规范 ### 推荐:构造器注入 ```java @Service @RequiredArgsConstructor public class PtRoomServiceImpl implements IPtRoomService { private final PtRoomMapper baseMapper; private final IPtAreaService areaService; } ``` ### 避免:字段注入 ```java // 不推荐 @Autowired private PtRoomMapper baseMapper; ``` ## 注释规范 ### 类注释 ```java /** * 房间定义对象 t_pt_room * * @author bing * @date 2024-08-09 */ ``` ### 方法注释 ```java /** * 查询房间列表 * * @param bo 查询条件 * @return 房间列表 */ List queryList(PtRoomBo bo); ``` ### 复杂逻辑注释 ```java // 1. 构建查询条件 PtUserAccountBo bo = new PtUserAccountBo(); bo.setCategory(TRAINEE_CATEGORY); // 2. 设置分页参数 PageQuery pageQuery = new PageQuery(); pageQuery.setPageNum(Math.max(queryDto.getPageNum(), 1)); // 3. 执行查询并转换结果 TableDataInfo result = userAccountService.queryPageList(bo, pageQuery); ``` ## 异常处理规范 ### 使用 R 对象包装返回 ```java public R selectTeacherById(Long userId) { PtUserAccountVo vo = userAccountService.queryById(userId); if (vo == null || !TEACHER_CATEGORY.equals(vo.getCategory())) { return R.fail("未找到对应的教师信息"); } return R.ok(convertToTeacherDto(vo)); } ``` ### 抛出自定义异常 ```java if (room == null) { throw new ServiceException("房间不存在"); } ``` ## 分页参数处理 ### 安全分页 ```java PageQuery pageQuery = new PageQuery(); pageQuery.setPageNum(queryDto.getPageNum() != null ? Math.max(queryDto.getPageNum(), 1) : 1); pageQuery.setPageSize(queryDto.getPageSize() != null ? Math.min(Math.max(queryDto.getPageSize(), 1), 500) : 10); ``` ### 分页返回值构建 ```java TableDataInfo pageData = TableDataInfo.build(); pageData.setRows(dtoList); pageData.setTotal(result.getTotal()); return pageData; ``` ## 空值处理 ### 集合判空 ```java import cn.hutool.core.collection.CollectionUtil; if (CollectionUtil.isEmpty(list)) { return Collections.emptyList(); } ``` ### 对象判空 ```java if (vo == null) { return null; } ``` ## 常量定义 ### 分类常量 ```java public class XxxConstants { /** 教师类型编码 */ public static final String TEACHER_CATEGORY = "1"; /** 学员类型编码 */ public static final String TRAINEE_CATEGORY = "2"; } ``` ### 枚举类 ```java @Getter @AllArgsConstructor public enum StatusEnum { NORMAL("0", "正常"), DISABLED("1", "停用"); private final String code; private final String desc; } ``` ## 日志使用 ```java @Slf4j @Service public class XxxServiceImpl { public void doSomething() { log.info("处理开始,参数:{}", param); log.debug("调试信息:{}", detail); log.error("处理失败", e); } } ```