# Lyzsys 项目编码规范

## 目录

- [1. 命名规范](#1-命名规范)
- [2. 菜单结构规范](#2-菜单结构规范)
- [3. 代码结构规范](#3-代码结构规范)
- [4. 数据库设计规范](#4-数据库设计规范)
- [5. API 接口规范](#5-api-接口规范)
- [6. 前端开发规范](#6-前端开发规范)

---

## 1. 命名规范

### 1.1 驼峰命名规范

**核心原则**：所有字段名、类名、文件名、变量名的驼峰命名中，**第一个单词不能只有一个字母**。

#### 为什么要遵循这个规范？

1. **MyBatis Plus 兼容性**：MyBatis Plus 在映射单字母开头的驼峰字段时可能出现问题
2. **代码可读性**：完整单词更具可读性，便于理解业务含义
3. **避免错误**：减少字段读取错误和调试困难

#### 正确示例 ✅

```java
// 字段命名
private String projectId;        // 而不是 pId
private String projectName;      // 而不是 pName
private String projectCode;      // 而不是 pCode
private LocalDateTime establishDate;  // 而不是 eDate

// 特殊情况：如果首字母缩写必须使用，请用完整单词
private String majorType;        // 而不是 mType
private BigDecimal leaderRatio;  // 而不是 lRatio
private Double kOneCoefficient;  // 而不是 k1Coefficient（k1 是业务术语）
```

#### 错误示例 ❌

```java
// 错误：单字母开头
private String pId;              // ❌ 应该是 projectId
private String mType;            // ❌ 应该是 majorType
private String lRatio;           // ❌ 应该是 leaderRatio
private String k1Coefficient;    // ❌ 应该是 kOneCoefficient
```

### 1.2 Java 类命名规范

#### 实体类（DO）

```java
// 格式：{业务名称}DO
ProjectDO.java           // 项目实体
UserDO.java              // 用户实体
OrderDO.java             // 订单实体
```

#### VO 类

```java
// 分页查询请求
{业务名称}PageReqVO.java
ProjectPageReqVO.java

// 响应 VO
{业务名称}RespVO.java
ProjectRespVO.java

// 保存请求 VO（新增和修改共用）
{业务名称}SaveReqVO.java
ProjectSaveReqVO.java

// 简单响应 VO（下拉选项等）
{业务名称}SimpleRespVO.java
ProjectSimpleRespVO.java
```

#### Mapper 接口

```java
// 格式：{业务名称}Mapper
ProjectMapper.java
```

#### Service 层

```java
// 接口：{业务名称}Service
ProjectService.java

// 实现：{业务名称}ServiceImpl
ProjectServiceImpl.java
```

#### Controller 层

```java
// 格式：{业务名称}Controller
ProjectController.java
```

### 1.3 数据库命名规范

#### 表名

```sql
-- 格式：{模块前缀}_{业务名称}（全小写，下划线分隔）
demo_project          -- demo 模块的项目表
system_user           -- system 模块的用户表
infra_config          -- infra 模块的配置表
```

#### 字段名

```sql
-- 使用下划线分隔的小写单词
project_name          -- 项目名称（对应 Java 中的 projectName）
project_code          -- 项目编号
establish_date        -- 立项时间

-- 标准字段（所有表必备）
id                    -- 主键
creator               -- 创建者
create_time           -- 创建时间
updater               -- 更新者
update_time           -- 更新时间
deleted               -- 删除标记
tenant_id             -- 租户ID（多租户表必备）
```

### 1.4 包名规范

```
cn.iocoder.lyzsys.module.{模块名}.{分层}

示例：
cn.iocoder.lyzsys.module.demo.controller.admin.project
cn.iocoder.lyzsys.module.demo.service.project
cn.iocoder.lyzsys.module.demo.dal.dataobject.project
cn.iocoder.lyzsys.module.demo.dal.mysql.project
```

### 1.5 前端命名规范

#### Vue 组件名

```javascript
// 页面组件（defineOptions name）
DemoProject           // 项目列表页
DemoProjectForm       // 项目表单组件

// 文件名（kebab-case）
index.vue             // 列表页
ProjectForm.vue       // 表单组件
```

#### API 文件

```typescript
// 文件路径
src/api/demo/project/index.ts

// 接口命名（驼峰）
export const getProjectPage = () => {}
export const createProject = () => {}
export const updateProject = () => {}
export const deleteProject = () => {}
```

---

## 2. 菜单结构规范

### 2.1 菜单层级规范

**原则**：业务功能菜单优先展示，系统管理功能放在最后。

#### 推荐的菜单顺序

```
1. 业务菜单（sort: 1-90）
   ├── 项目管理（一级菜单，sort: 1）
   │   └── 项目列表（二级菜单，sort: 1）
   ├── 客户管理（一级菜单，sort: 2）
   │   └── 客户列表（二级菜单，sort: 1）
   └── ...

98. 系统管理（sort: 98）
    ├── 用户管理
    ├── 角色管理
    ├── 菜单管理
    └── ...

99. 基础设施（sort: 99）
    ├── 代码生成
    ├── 文件管理
    └── ...
```

### 2.2 菜单配置规范

#### 一级菜单（目录）

```sql
INSERT INTO `system_menu` (
  `id`, `name`, `permission`, `type`, `sort`, `parent_id`,
  `path`, `icon`, `component`, `component_name`,
  `status`, `visible`, `keep_alive`, `always_show`,
  `creator`, `create_time`, `updater`, `update_time`, `deleted`
) VALUES (
  3000,              -- ID（建议按模块分配段，如 demo: 3000-3999）
  '项目管理',         -- 名称
  '',                -- 权限标识（一级菜单为空）
  1,                 -- 类型：1=目录
  1,                 -- 排序（业务菜单建议 1-90）
  0,                 -- 父级ID（0表示顶级）
  '/demo',           -- 路由路径
  'ep:files',        -- 图标
  NULL,              -- 组件路径（目录为NULL）
  NULL,              -- 组件名称（目录为NULL）
  0,                 -- 状态：0=正常
  b'1',              -- 是否可见
  b'1',              -- 是否缓存
  b'1',              -- 是否总是显示
  '1',               -- 创建者
  NOW(),             -- 创建时间
  '1',               -- 更新者
  NOW(),             -- 更新时间
  b'0'               -- 是否删除
);
```

#### 二级菜单（菜单页面）

```sql
INSERT INTO `system_menu` (...) VALUES (
  3001,                           -- ID
  '项目列表',                      -- 名称
  '',                             -- 权限标识（菜单页面为空）
  2,                              -- 类型：2=菜单
  1,                              -- 排序
  3000,                           -- 父级ID（对应一级菜单ID）
  'project',                      -- 路由路径
  'ep:document',                  -- 图标
  'demo/project/index',           -- 组件路径
  'DemoProject',                  -- 组件名称（对应 Vue defineOptions name）
  0, b'1', b'1', b'1',
  '1', NOW(), '1', NOW(), b'0'
);
```

#### 三级菜单（按钮权限）

```sql
-- 查询权限
INSERT INTO `system_menu` (...) VALUES (
  3002, '项目查询', 'demo:project:query', 3, 1, 3001,
  '', '', '', NULL, 0, b'1', b'1', b'1',
  '1', NOW(), '1', NOW(), b'0'
);

-- 新增权限
INSERT INTO `system_menu` (...) VALUES (
  3003, '项目新增', 'demo:project:create', 3, 2, 3001,
  '', '', '', NULL, 0, b'1', b'1', b'1',
  '1', NOW(), '1', NOW(), b'0'
);

-- 修改权限
INSERT INTO `system_menu` (...) VALUES (
  3004, '项目修改', 'demo:project:update', 3, 3, 3001,
  '', '', '', NULL, 0, b'1', b'1', b'1',
  '1', NOW(), '1', NOW(), b'0'
);

-- 删除权限
INSERT INTO `system_menu` (...) VALUES (
  3005, '项目删除', 'demo:project:delete', 3, 4, 3001,
  '', '', '', NULL, 0, b'1', b'1', b'1',
  '1', NOW(), '1', NOW(), b'0'
);

-- 导出权限
INSERT INTO `system_menu` (...) VALUES (
  3006, '项目导出', 'demo:project:export', 3, 5, 3001,
  '', '', '', NULL, 0, b'1', b'1', b'1',
  '1', NOW(), '1', NOW(), b'0'
);
```

### 2.3 权限标识规范

```
格式：{模块名}:{业务}:{操作}

示例：
demo:project:query      -- demo模块，项目业务，查询操作
demo:project:create     -- demo模块，项目业务，新增操作
demo:project:update     -- demo模块，项目业务，修改操作
demo:project:delete     -- demo模块，项目业务，删除操作
demo:project:export     -- demo模块，项目业务，导出操作
```

### 2.4 菜单 ID 分配规范

为避免 ID 冲突，建议按模块分配 ID 段：

| 模块 | ID 范围 | 说明 |
|-----|---------|------|
| system | 1-999 | 系统核心模块 |
| infra | 1000-1999 | 基础设施模块 |
| member | 2000-2999 | 会员模块 |
| demo | 3000-3999 | Demo 示例模块 |
| bpm | 4000-4999 | 工作流模块 |
| mall | 5000-5999 | 商城模块 |
| ... | ... | 其他业务模块 |

---

## 3. 代码结构规范

### 3.1 模块目录结构

```
lyzsys-module-{模块名}/
├── pom.xml                                    # Maven 配置
└── src/main/java/cn/iocoder/lyzsys/module/{模块名}/
    ├── controller/                            # 控制器层
    │   └── admin/                             # 管理后台接口
    │       └── {业务}/                        # 业务模块
    │           ├── {业务}Controller.java      # 控制器
    │           └── vo/                        # VO 对象
    │               ├── {业务}PageReqVO.java   # 分页请求
    │               ├── {业务}RespVO.java      # 响应 VO
    │               └── {业务}SaveReqVO.java   # 保存请求
    ├── service/                               # 服务层
    │   └── {业务}/
    │       ├── {业务}Service.java             # 服务接口
    │       └── {业务}ServiceImpl.java         # 服务实现
    ├── dal/                                   # 数据访问层
    │   ├── dataobject/                        # 数据对象
    │   │   └── {业务}/
    │   │       └── {业务}DO.java              # 实体类
    │   └── mysql/                             # Mapper 接口
    │       └── {业务}/
    │           └── {业务}Mapper.java          # Mapper
    ├── convert/                               # 对象转换（可选）
    │   └── {业务}Convert.java
    ├── enums/                                 # 枚举类
    │   └── ErrorCodeConstants.java            # 错误码
    └── api/                                   # 对外 API（可选）
        └── {业务}Api.java
```

### 3.2 分层职责

#### Controller 层

- 接收 HTTP 请求
- 参数校验（使用 @Valid）
- 权限控制（使用 @PreAuthorize）
- 调用 Service 层
- 返回统一响应

#### Service 层

- 业务逻辑处理
- 数据校验
- 事务控制
- 调用 Mapper 层

#### DAL 层

- 数据访问
- SQL 操作
- 不包含业务逻辑

---

## 4. 数据库设计规范

### 4.1 表设计规范

#### 标准字段（所有表必备）

```sql
CREATE TABLE `{表名}` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  -- 业务字段
  ...
  -- 标准字段
  `creator` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updater` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='表注释';
```

#### 多租户表额外字段

```sql
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
```

### 4.2 字段类型规范

| Java 类型 | MySQL 类型 | 说明 |
|-----------|-----------|------|
| Long | bigint | ID、数量等 |
| String | varchar | 字符串 |
| Integer | int | 状态、类型等 |
| LocalDateTime | datetime | 日期时间 |
| LocalDate | date | 日期 |
| BigDecimal | decimal | 金额、精确数值 |
| Boolean | bit(1) | 布尔值 |

### 4.3 索引规范

```sql
-- 主键索引
PRIMARY KEY (`id`)

-- 唯一索引（业务唯一字段）
UNIQUE KEY `uk_project_code` (`project_code`)

-- 普通索引（常用查询字段）
KEY `idx_project_name` (`project_name`)

-- 组合索引（多字段联合查询）
KEY `idx_tenant_status` (`tenant_id`, `status`)
```

---

## 5. API 接口规范

### 5.1 RESTful 风格

| 操作 | HTTP 方法 | URL | 说明 |
|-----|----------|-----|------|
| 查询列表 | GET | /{模块}/{业务}/page | 分页查询 |
| 查询详情 | GET | /{模块}/{业务}/get | 根据ID查询 |
| 新增 | POST | /{模块}/{业务}/create | 创建 |
| 修改 | PUT | /{模块}/{业务}/update | 更新 |
| 删除 | DELETE | /{模块}/{业务}/delete | 删除 |
| 批量删除 | DELETE | /{模块}/{业务}/delete-list | 批量删除 |
| 导出 | GET | /{模块}/{业务}/export-excel | 导出Excel |

### 5.2 统一响应格式

```java
// 成功响应
{
  "code": 0,
  "data": {...},
  "msg": ""
}

// 失败响应
{
  "code": 1001,
  "data": null,
  "msg": "错误信息"
}

// 分页响应
{
  "code": 0,
  "data": {
    "list": [...],
    "total": 100
  },
  "msg": ""
}
```

### 5.3 接口注解规范

```java
@Tag(name = "管理后台 - 项目管理")
@RestController
@RequestMapping("/demo/project")
@Validated
public class ProjectController {

    @PostMapping("/create")
    @Operation(summary = "创建项目")
    @PreAuthorize("@ss.hasPermission('demo:project:create')")
    public CommonResult<Long> createProject(@Valid @RequestBody ProjectSaveReqVO createReqVO) {
        // ...
    }
}
```

---

## 6. 前端开发规范

### 6.1 目录结构

```
src/
├── api/                          # API 接口
│   └── {模块}/
│       └── {业务}/
│           └── index.ts          # API 定义
└── views/                        # 页面
    └── {模块}/
        └── {业务}/
            ├── index.vue         # 列表页
            └── {业务}Form.vue    # 表单组件
```

### 6.2 组件规范

#### 列表页面

```vue
<template>
  <!-- 搜索工作栏 -->
  <ContentWrap>
    <el-form>...</el-form>
  </ContentWrap>

  <!-- 列表 -->
  <ContentWrap>
    <el-table>...</el-table>
    <Pagination />
  </ContentWrap>

  <!-- 表单弹窗 -->
  <{业务}Form ref="formRef" @success="getList" />
</template>

<script lang="ts" setup>
defineOptions({ name: '{模块}{业务}' })
// ...
</script>
```

#### 表单组件

```vue
<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle">
    <el-form>...</el-form>
    <template #footer>
      <el-button type="primary" @click="submitForm">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
defineOptions({ name: '{模块}{业务}Form' })
defineExpose({ open })
// ...
</script>
```

### 6.3 权限控制

```vue
<!-- 按钮权限 -->
<el-button
  v-hasPermi="['demo:project:create']"
  type="primary"
  @click="openForm('create')"
>
  新增
</el-button>

<!-- 路由权限在菜单配置中控制 -->
```

---

## 7. 最佳实践

### 7.1 代码注释

```java
/**
 * 项目管理 Service 接口
 *
 * @author lyzsys
 */
public interface ProjectService {

    /**
     * 创建项目
     *
     * @param createReqVO 项目信息
     * @return 项目编号
     */
    Long createProject(ProjectSaveReqVO createReqVO);
}
```

### 7.2 异常处理

```java
// 使用统一的业务异常
throw exception(PROJECT_NOT_EXISTS);
throw exception(PROJECT_CODE_DUPLICATE);
```

### 7.3 日志规范

```java
@Slf4j
public class ProjectServiceImpl implements ProjectService {

    @Override
    public Long createProject(ProjectSaveReqVO createReqVO) {
        log.info("[createProject] 创建项目，项目编号：{}", createReqVO.getProjectCode());
        // ...
    }
}
```

---

## 8. 检查清单

在提交代码前，请检查：

- [ ] 所有字段命名遵循驼峰规范，无单字母开头
- [ ] 菜单配置完整（一级、二级、按钮权限）
- [ ] 业务菜单排序在系统管理之前
- [ ] 权限标识格式正确（{模块}:{业务}:{操作}）
- [ ] 数据库表包含标准字段
- [ ] API 接口遵循 RESTful 风格
- [ ] 代码注释完整
- [ ] 前端权限控制正确

---

**文档版本**：v1.0
**最后更新**：2024年
**维护者**：开发团队
