163 lines
4.8 KiB
Markdown
163 lines
4.8 KiB
Markdown
# ghb-base 开发规范(人工版)
|
||
|
||
> 给不用 AI 编码的开发者阅读。用 AI 写代码的看 `.claude/` 目录。
|
||
|
||
|
||
## 一、返回格式(不变式)
|
||
|
||
**所有接口必须用 `Result<T>` 包装:**
|
||
|
||
```java
|
||
// ✅ 正确
|
||
return Result.OK(data);
|
||
return Result.OK("操作成功", data);
|
||
return Result.error("参数错误");
|
||
|
||
// ❌ 禁止
|
||
return data;
|
||
return "success";
|
||
return Map.of(...);
|
||
```
|
||
|
||
**分页格式:** `{ code, message, data: { records, total, size, current } }`
|
||
|
||
**日期格式:** 统一 `yyyy-MM-dd HH:mm:ss`
|
||
|
||
**状态值:** 枚举中文值必须从 `contract/common/status-map.md` 取,不许硬编码前端文案同义替换("已拒绝"="拒绝"之类)。
|
||
|
||
|
||
## 二、分层规则
|
||
|
||
```
|
||
controller/ — 参数校验 + 调用 service + 返回 Result,不许写业务逻辑
|
||
service/ — 业务逻辑,事务管理
|
||
mapper/ — SQL(MyBatis XML 或 @Select),不许写业务逻辑
|
||
entity/ — 表映射,纯数据对象
|
||
```
|
||
|
||
**禁止:Controller 超过 20 行、Controller 里有 if/else 嵌套、Service 里直接操作 HttpServletRequest**
|
||
|
||
|
||
## 三、命名规则
|
||
|
||
| 元素 | 规则 | 示例 |
|
||
|------|------|------|
|
||
| 类名 | 大驼峰,名词 | `TaskController`,❌ `taskController` |
|
||
| 方法名 | 小驼峰,动词开头 | `getById()`,❌ `getbyid()` |
|
||
| 变量 | 小驼峰,有意义 | `taskList`,❌ `list` `data` |
|
||
| 包名 | 全小写 | `com.ghb.base.modules.business` |
|
||
| 表名 | 小写,下划线,单数 | `task_apply`,❌ `TaskApply` |
|
||
| 字段名 | 小写,下划线 | `create_time`,❌ `createdAt` |
|
||
| 主键 | 统一 `id` | ❌ `task_id` |
|
||
| 外键 | `关联表_id` | `user_id`,❌ `uid` |
|
||
| 布尔 | `del_flag` 或明确业务含义的 `is_` 前缀 | `del_flag`,❌ `deleted` |
|
||
|
||
**长度控制:** 类名/表名超过 3 个单词或 30 字符必须缩写。缩写必须一眼能认出含义:
|
||
|
||
| 完整 | 缩写 |
|
||
|------|------|
|
||
| department | dept |
|
||
| permission | perm |
|
||
| message | msg |
|
||
| enterprise | ent |
|
||
|
||
|
||
## 四、字段类型
|
||
|
||
| 场景 | 类型 |
|
||
|------|------|
|
||
| 金额 | `DECIMAL(15,2)`,❌ `FLOAT` `DOUBLE` |
|
||
| 时间 | `DATETIME`,❌ `VARCHAR` `TIMESTAMP` |
|
||
| 状态 | `VARCHAR(20)`,存英文枚举值 |
|
||
| 文本 | `VARCHAR(N)`(长度写死,不用 TEXT) |
|
||
|
||
**必有字段:** 每张表必须包含 `id` `create_by` `create_time` `update_by` `update_time`。每个字段必须有 `COMMENT`。
|
||
|
||
|
||
## 五、索引规则
|
||
|
||
| 场景 | 索引 |
|
||
|------|------|
|
||
| 外键 | 必须建索引 |
|
||
| WHERE 高频字段 | 必须建索引 |
|
||
| 唯一约束 | `uk_表名_字段` |
|
||
| 普通索引 | `idx_表名_字段` |
|
||
|
||
|
||
## 六、Git 规则
|
||
|
||
**分支:** `dev`(开发)/ `master`(生产)。新功能从 `dev` 拉,合回 `dev`。
|
||
|
||
**Commit 格式:**
|
||
```
|
||
<type>: <简短描述>
|
||
|
||
[AI: 模型名]
|
||
```
|
||
|
||
**Type:** feat / fix / refactor / docs / style / test / chore
|
||
|
||
**禁止:** `git push --force`、commit 只写 "update"、提交含硬编码密钥
|
||
|
||
|
||
## 七、安全规则
|
||
|
||
- 所有接口(除登录)必须验证 JWT Token
|
||
- 涉及租户数据的 SQL 必须带 `tenant_id` 条件
|
||
- 密码/密钥/Token 禁止硬编码、禁止 log 输出、禁止提交到 Git
|
||
- 文件上传限制大小(≤10MB)和类型(白名单)
|
||
- 用户输入必须做 XSS 过滤
|
||
- 日志不输出敏感信息(手机号脱敏 176****2303)
|
||
|
||
|
||
## 八、编码规则
|
||
|
||
- 所有源文件:UTF-8 无 BOM
|
||
- 禁止 GBK/GB2312
|
||
- `ghb-backend/.editorconfig` 和 `ghb-frontend/.editorconfig` 各一个,不要覆盖
|
||
- **Windows 终端重定向(`>` `>>`)会按 GBK 写入,不要用**
|
||
|
||
|
||
## 九、测试规则
|
||
|
||
**必须写测试:**
|
||
- 新增 Service 方法 → 单元测试
|
||
- 新增 Controller 接口 → 集成测试
|
||
- 涉及金额计算 → 单元测试(多组边界值)
|
||
- 涉及状态流转 → 单元测试(覆盖所有路径)
|
||
|
||
**错误码:** 200 成功 / 400 参数错误 / 401 未登录 / 403 无权限 / 500 服务器异常
|
||
|
||
|
||
## 十、前端规则
|
||
|
||
**样式铁律:**
|
||
- 颜色禁硬编码(`color: #333` ❌),走主题变量
|
||
- 字号/间距禁硬编码,走全局类或 Less 变量
|
||
- 所有文案必须走 i18n,不能写死中文
|
||
|
||
**命名规则:**
|
||
|
||
| 元素 | 规则 | 示例 |
|
||
|------|------|------|
|
||
| 组件文件 | kebab-case | `task-card.vue`,❌ `TaskCard.vue` |
|
||
| 组件 name | PascalCase | `TaskCard` |
|
||
| CSS 类名 | kebab-case | `.task-card`,❌ `.taskCard` |
|
||
| JS 变量 | 小驼峰 | `taskList`,❌ `task_list` |
|
||
|
||
**代码修改痕迹:** 所有新增或修改的代码块必须用 `// update-begin` / `// update-end` 包裹,注明 author/date/原因。
|
||
|
||
|
||
## 十一、提交前检查表
|
||
|
||
```
|
||
□ 接口变更 → contract/ 同步更新
|
||
□ 返回格式 → 全部用 Result 包装
|
||
□ 手写 SQL → 有 tenant_id 条件
|
||
□ 新增表 → create_time / update_time / COMMENT 完整
|
||
□ 金额字段 → DECIMAL 类型
|
||
□ 无硬编码魔法数字/裸色值
|
||
□ Commit 格式正确
|
||
□ 测试通过
|
||
```
|