# MICA-Server 开发规范 > 本文档是 mica-server 项目的权威开发规范,所有开发人员必须严格遵守。 --- ## 一、技术栈与版本 ### 1.1 核心技术栈 | 类别 | 技术 | 版本 | 说明 | |------|------|------|------| | **JDK** | Java | 1.8 | 禁止使用 Java 9+ 特性 | | **框架** | Spring Boot | 2.6.7 | 统一版本 | | **ORM** | MyBatis-Plus | 3.5.1 | 禁止手写原生 SQL(除非性能优化) | | **构建工具** | Maven | 3.6+ | 统一使用 Maven | | **数据库** | MySQL | 8.0+ | HikariCP 连接池 | | **注册/配置中心** | Nacos | 2.x | 服务注册与配置管理 | ### 1.2 工具库使用优先级 1. **优先使用**: `com.witsoft.common-utils` 中 utils 包封装的类和方法 2. **其次使用**: **Hutool** 工具库 3. **再次使用**: **Apache Commons** 系列 4. **禁止**: 重复造轮子 --- ## 二、代码规范 ### 2.1 命名规范 #### 类命名 - **类名**: UpperCamelCase 风格,必须为名词 - 正确:`UserController`, `UserService` - 例外:领域模型 `DO`/`BO`/`DTO`/`VO` 等后缀 - **抽象类**: 使用 `Abstract` 或 `Base` 开头 - 例如:`AbstractService`, `BaseController` - **异常类**: 使用 `Exception` 结尾 - 例如:`BizException`, `ValidationException` - **测试类**: 以被测试类名开头,以 `Test` 结尾 - 例如:`UserServiceTest` #### 方法和变量命名 - **方法名/变量名**: lowerCamelCase 风格 - 正确:`queryUserList`, `localName`, `getUserName` - 禁止:拼音与英文混合、直接使用中文 - **Service/DAO 层方法前缀**: - 获取单个/多个对象:`query` (如 `queryUser`, `queryUserList`) - 插入:`insert` 或 `save` (如 `insertUser`, `saveOrder`) - 删除:`delete` 或 `batchDelete` (如 `deleteUser`, `batchDeleteOrders`) - 修改:`update` (如 `updateUser`, `updateOrderStatus`) #### 常量命名 - **常量名**: UPPER_CASE_UNDERSCORE 风格,力求语义完整 - 正确:`MAX_USER_COUNT`, `DEFAULT_PAGE_SIZE` - 禁止:不规范的缩写 (如 `AbsClass` 代替 `AbstractClass`) - **常量类组织**: 按功能分类,禁止一个常量类维护所有常量 - 例如:`CacheConsts`, `ConfigConsts`, `UserConsts` #### 包命名 - **包名**: 统一使用小写,点分隔符之间有且仅有一个单词 - 正确:`com.witsoft.mica.service`, `com.witsoft.util` - 禁止:`com.witsoft.mica.services` (复数) #### 其他命名规则 - **数组定义**: `String[] args` (中括号是数组类型的一部分) - **布尔类型变量**: 禁止加 `is` 前缀 (避免序列化错误) - 正确:`boolean success`, 方法名 `getSuccess()` - 错误:`boolean isSuccess`, 方法名 `isSuccess()` ### 2.2 代码格式 #### 大括号使用 ```java // 空代码块 if (flag == 0) {} // 非空代码块 if (flag == 1) { System.out.println("world"); } else { System.out.println("ok"); } ``` **规则**: - 左大括号前不换行 - 左大括号后换行 - 右大括号前换行 - 右大括号后还有 `else` 等代码则不换行 - 右大括号表示终止则必须换行 #### 缩进与空格 - **缩进**: 4 个空格,禁止使用 tab 字符 - **单行字符数**: 不超过 200 个,超出需换行 - **运算符**: 左右必须有一个空格 - **关键词**: `if`/`for`/`while` 等与括号之间必须有一个空格 - **方法参数**: 多个参数逗号后必须加空格 - 例如:`method("aa", "bb", "cc")` #### 换行规则 - 第二行相对第一行缩进 4 个空格,从第三行开始不再继续缩进 - 运算符与下文一起换行 - 方法调用的点符号与下文一起换行 - 多个参数超长时,逗号后换行 #### 文件编码 - **IDE 编码**: UTF-8 - **换行符**: Unix 格式 (LF),禁止使用 Windows 格式 (CRLF) ### 2.3 OOP 规约 1. **静态访问**: 直接用类名访问静态变量/方法,禁止通过对象引用访问 ```java // 正确 User user = UserService.getDefaultUser(); // 错误 User user = new UserService().getDefaultUser(); ``` 2. **覆写方法**: 必须加 `@Override` 注解 3. **可变参数**: - 相同参数类型、相同业务含义才可使用 - 必须放置在参数列表最后 - 避免使用 `Object` 类型 ```java public User getUsers(String type, Integer... ids) ``` 4. **接口签名**: - 原则上不允许修改方法签名 - 接口过时必须加 `@Deprecated` 注解,并说明新接口 5. **equals 方法**: 使用常量或确定有值的对象调用 ```java // 正确 "test".equals(object); // 错误 object.equals("test"); // 可能 NPE ``` 6. **序列化**: - 新增属性时不修改 `serialVersionUID` - 完全不兼容升级时修改 `serialVersionUID` 7. **toString 方法**: POJO 类必须编写,继承的 POJO 需调用 `super.toString()` ### 2.4 注释规范 #### 类注释模板 ```java /** * @menu : 类描述 * @Description : 类描述 * @ModifyBrief : * @Author : git 账号 * @Date : 创建时间 * @Version : 3.0 * @Param : * @Return : */ ``` #### 方法注释模板 ```java /** * @Description : 方法描述 * @ModifyBrief : * @Author : git 账号 * @Date : 创建时间 * @Version : 3.0 * @Param : 参数说明 * @Return : 返回值说明 */ ``` #### 注释规则 1. **所有公共接口和类**必须包含 Javadoc 2. **注释语言**: 中文描述业务背景,技术术语保留英文 (如 NPE、DTO、API) 3. **禁止**生成 "Gets the value of X" 这类无意义的 getter/setter 注释 4. **复杂算法**必须在代码块上方解释核心逻辑 5. **禁止使用 HTML 标签** 6. **代码内注释**: 复杂逻辑必须包含行内注释,解释"为什么这样做"而非"做了什么" 7. **代码与注释比例**: 约 5:1,行注释使用 `// xxxxxx` --- ## 三、异常处理规范 ### 3.1 异常捕获 1. **禁止**: 捕获 `Exception` 或 `Throwable` 后不做任何处理 (吞掉异常) 2. **规范**: 必须捕获具体的异常类 3. **日志**: 捕获异常时,调用 `GlobalException.getExceptionMessage(e)` ### 3.2 异常示例 ```java // 正确 try { userService.queryUser(userId); } catch (UserNotFoundException e) { log.error("用户不存在:userId={}", userId, e); throw new BizException("用户不存在"); } // 错误 - 禁止吞掉异常 try { userService.queryUser(userId); } catch (Exception e) { // 什么都不做 } ``` --- ## 四、数据库规范 ### 4.1 建表规约 #### 表名命名 - **不使用复数名词** - **业务表前缀**: `mica_` - **命名规则**: 小写字母或数字,下划线间隔 - 正确:`mica_user_info`, `mica_order_detail` - 禁止:`mica_users`, `1_table`, `table__name` #### 标准字段 (所有业务表必须包含) | 字段名 | 类型 | 长度 | 是否 NULL | 主键 | 注释 | |--------|------|------|-----------|------|------| | `id` | varchar | 50 | 否 | 是 | 自然主键 | | `ecid` | varchar | 100 | 否 | 否 | 企业编码 (多租户) | | `create_time` | datetime | 3 | 是 | 否 | 创建时间 | | `created_by` | varchar | 50 | 是 | 否 | 创建人 | | `update_time` | datetime | 3 | 是 | 否 | 修改时间 | | `updated_by` | varchar | 50 | 是 | 否 | 修改人 | | `delete_time` | datetime | 3 | 是 | 否 | 删除时间 | | `deleted_by` | varchar | 50 | 是 | 否 | 删除人 | | `delete_mark` | tinyint | 1 | 默认 0 | 否 | 删除标志 0:未删除 1:已删除 | #### 字段命名 - **小写字母或数字**,下划线间隔 - **禁止数字开头** - **禁止两个下划线中间只有数字** - **及时更新字段注释**: 修改字段含义或追加状态时 #### 索引命名 - **唯一索引**: `uk_字段名` (如 `uk_user_name`) - **普通索引**: `idx_字段名` (如 `idx_create_time`) #### 数据类型 - **小数**: 必须使用 `decimal`,禁止使用 `float` 和 `double` - **字符串**: - `varchar` 长度不超过 5000 - 超过 5000 使用 `text` 类型,独立成表,用主键对应 ### 4.2 索引规约 1. **唯一特性字段**: 即使组合字段也必须建立唯一索引 2. **关联查询**: 超过 3 个表禁止 join,被关联字段必须有索引 3. **varchar 索引**: 必须指定索引长度 (一般 20 即可达到 90% 区分度) ### 4.3 SQL 规约 1. **COUNT 统计**: 使用 `count(*)`,禁止使用 `count(列名)` 或 `count(常量)` 2. **NULL 判断**: 使用 `ISNULL()` 函数 - `NULL <> NULL` 返回 `NULL` - `NULL = NULL` 返回 `NULL` 3. **IN 操作**: 能避免则避免,可用 `EXISTS` 替换,集合元素控制在 1000 个内 4. **数据订正**: 删除/修改前先 `SELECT` 确认 ### 4.4 ORM 规约 1. **查询字段**: 禁止使用 `*`,必须明确写明需要的字段 2. **参数传递**: 使用 `#{}`,禁止使用 `${}` (防止 SQL 注入) 3. **返回结果**: 禁止直接使用 `HashMap` 或 `Hashtable` 4. **更新接口**: 只更新有改动的字段,禁止全字段更新 5. **事务控制**: - 不要滥用 `@Transactional` - 考虑缓存回滚、消息补偿等回滚方案 --- ## 五、统一响应格式 所有 Controller 层方法返回必须遵循以下 JSON 结构: ```json { "code": 200, "msg": "操作成功", "data": [], "extra": {}, "success": true } ``` --- ## 六、项目结构规范 ### 6.1 标准分层结构 ``` com.witsoft.mica.xxx/ ├── controller/ # REST 接口层 ├── domain/ # DTO / VO / 查询参数 ├── entity/ # 数据库实体 (DO) ├── mapper/ # MyBatis-Plus Mapper └── service/ # 业务逻辑层 ├── XxxService.java └── impl/ └── XxxServiceImpl.java ``` ### 6.2 各层职责 - **Controller**: 参数校验、调用 Service、返回统一响应 - **Service**: 业务逻辑、事务控制、数据填充 - **Mapper**: 数据持久化 (仅简单 CRUD,复杂查询用 XML) - **Entity**: 数据库实体映射 (DO) - **Domain**: - DTO: 数据传输对象 - VO: 展示对象 - Query: 查询参数对象 --- ## 七、开发注意事项 ### 7.1 代码复用 1. **复用优先**: 逻辑雷同时提取公共方法,避免重复代码 2. **工具类优先**: 优先使用已有工具类方法 ### 7.2 物料数据规范 1. **业务表仅存物料 id**: 物料相关字段仅存 `material_id` 2. **关联查询填充**: 编码、名称、规格、单位等通过关联查询填充 3. **填充在 Service 层**: 关联数据填充逻辑统一在 Service 层处理 ### 7.3 字典使用 1. **优先使用 DictService**: 字典取值优先使用 `DictService` 公共方法 2. **禁止手写**: 不手写字典查询逻辑 ### 7.4 Java 8 兼容性 1. **禁止 List.of()**: Java 8 不兼容 2. **使用**: `Collections.emptyList()` 替代 ### 7.5 版本管理 1. **首个版本直接改 DDL**: v1.0 脚本直接修改建表语句 2. **不需要 ALTER TABLE**: 初始版本不需要写迁移脚本 --- ## 八、Git 提交约定 ### 8.1 提交规范 1. **禁止 Agent commit**: Agent 不做任何 commit 操作,只允许查看、修改代码 2. **Commit Message**: 提示 commit 时必须附带 commit message,让用户可直接复制运行 3. **用户手动提交**: 如需提交代码,由用户手动执行 commit ### 8.2 配置文件 - **`application.yml` / `application-local.yml`**: 由用户自行提交 - **Agent 绝不碰**: 这两个配置文件的版本管理 --- ## 九、部署约定 ### 9.1 部署规范 1. **禁止自动部署**: Agent 不做任何自动部署操作 2. **用户手动决定**: 代码修改后由用户手动决定何时部署 ### 9.2 数据库脚本管理 所有数据库脚本必须按顺序编号,并在 MEMORY.md 中记录执行状态: ``` ✅ 00-init.sql - 基础表结构 ✅ 10-system.sql - 系统数据 ✅ 20-master-data-init.sql - 基础数据 ... ``` --- ## 十、物料近似查询规范 (2026-05-29 产品决策) ### 10.1 searchSimilar() 优先级 产品决定**不查询规格字段**,按以下优先级分步查询: 1. **名称精确匹配** (`material_name = keyword`) — 优先级最高 2. **名称前缀匹配** (`material_name LIKE 'keyword%'`) 3. **名称模糊匹配** (`material_name LIKE '%keyword%'`) 4. **编码模糊匹配** (`material_code LIKE '%keyword%'`) — 兜底 ### 10.2 去重原则 已在前置层级匹配的物料不再在后置层级重复出现。 ### 10.3 旧方法保留 保留旧 `searchByNameLike()` 方法不动,保持向后兼容。 --- ## 附录:快速参考 ### 命名速查表 | 类型 | 规范 | 示例 | |------|------|------| | 类名 | UpperCamelCase | `UserController` | | 方法名 | lowerCamelCase | `queryUserList` | | 变量名 | lowerCamelCase | `userName` | | 常量名 | UPPER_CASE_UNDERSCORE | `MAX_COUNT` | | 包名 | 小写单数 | `com.witsoft.util` | | 表名 | 小写 + 下划线 | `mica_user_info` | | 字段名 | 小写 + 下划线 | `user_name` | | 唯一索引 | `uk_字段名` | `uk_user_name` | | 普通索引 | `idx_字段名` | `idx_create_time` | ### Service 方法前缀速查 | 操作 | 前缀 | 示例 | |------|------|------| | 查询单个 | `query` | `queryUser` | | 查询列表 | `query` | `queryUserList` | | 插入 | `insert`/`save` | `insertUser` | | 删除 | `delete` | `deleteUser` | | 批量删除 | `batchDelete` | `batchDeleteUsers` | | 更新 | `update` | `updateUser` | --- **版本**: 1.0 **最后更新**: 2026-08-04 **维护者**: 后端开发团队