16 KiB
16 KiB
Lyzsys 项目编码规范
目录
1. 命名规范
1.1 驼峰命名规范
核心原则:所有字段名、类名、文件名、变量名的驼峰命名中,第一个单词不能只有一个字母。
为什么要遵循这个规范?
- MyBatis Plus 兼容性:MyBatis Plus 在映射单字母开头的驼峰字段时可能出现问题
- 代码可读性:完整单词更具可读性,便于理解业务含义
- 避免错误:减少字段读取错误和调试困难
正确示例 ✅
// 字段命名
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 是业务术语)
错误示例 ❌
// 错误:单字母开头
private String pId; // ❌ 应该是 projectId
private String mType; // ❌ 应该是 majorType
private String lRatio; // ❌ 应该是 leaderRatio
private String k1Coefficient; // ❌ 应该是 kOneCoefficient
1.2 Java 类命名规范
实体类(DO)
// 格式:{业务名称}DO
ProjectDO.java // 项目实体
UserDO.java // 用户实体
OrderDO.java // 订单实体
VO 类
// 分页查询请求
{业务名称}PageReqVO.java
ProjectPageReqVO.java
// 响应 VO
{业务名称}RespVO.java
ProjectRespVO.java
// 保存请求 VO(新增和修改共用)
{业务名称}SaveReqVO.java
ProjectSaveReqVO.java
// 简单响应 VO(下拉选项等)
{业务名称}SimpleRespVO.java
ProjectSimpleRespVO.java
Mapper 接口
// 格式:{业务名称}Mapper
ProjectMapper.java
Service 层
// 接口:{业务名称}Service
ProjectService.java
// 实现:{业务名称}ServiceImpl
ProjectServiceImpl.java
Controller 层
// 格式:{业务名称}Controller
ProjectController.java
1.3 数据库命名规范
表名
-- 格式:{模块前缀}_{业务名称}(全小写,下划线分隔)
demo_project -- demo 模块的项目表
system_user -- system 模块的用户表
infra_config -- infra 模块的配置表
字段名
-- 使用下划线分隔的小写单词
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 组件名
// 页面组件(defineOptions name)
DemoProject // 项目列表页
DemoProjectForm // 项目表单组件
// 文件名(kebab-case)
index.vue // 列表页
ProjectForm.vue // 表单组件
API 文件
// 文件路径
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 菜单配置规范
一级菜单(目录)
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' -- 是否删除
);
二级菜单(菜单页面)
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'
);
三级菜单(按钮权限)
-- 查询权限
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 表设计规范
标准字段(所有表必备)
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='表注释';
多租户表额外字段
`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 索引规范
-- 主键索引
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 统一响应格式
// 成功响应
{
"code": 0,
"data": {...},
"msg": ""
}
// 失败响应
{
"code": 1001,
"data": null,
"msg": "错误信息"
}
// 分页响应
{
"code": 0,
"data": {
"list": [...],
"total": 100
},
"msg": ""
}
5.3 接口注解规范
@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 组件规范
列表页面
<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>
表单组件
<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 权限控制
<!-- 按钮权限 -->
<el-button
v-hasPermi="['demo:project:create']"
type="primary"
@click="openForm('create')"
>
新增
</el-button>
<!-- 路由权限在菜单配置中控制 -->
7. 最佳实践
7.1 代码注释
/**
* 项目管理 Service 接口
*
* @author lyzsys
*/
public interface ProjectService {
/**
* 创建项目
*
* @param createReqVO 项目信息
* @return 项目编号
*/
Long createProject(ProjectSaveReqVO createReqVO);
}
7.2 异常处理
// 使用统一的业务异常
throw exception(PROJECT_NOT_EXISTS);
throw exception(PROJECT_CODE_DUPLICATE);
7.3 日志规范
@Slf4j
public class ProjectServiceImpl implements ProjectService {
@Override
public Long createProject(ProjectSaveReqVO createReqVO) {
log.info("[createProject] 创建项目,项目编号:{}", createReqVO.getProjectCode());
// ...
}
}
8. 检查清单
在提交代码前,请检查:
- 所有字段命名遵循驼峰规范,无单字母开头
- 菜单配置完整(一级、二级、按钮权限)
- 业务菜单排序在系统管理之前
- 权限标识格式正确({模块}:{业务}:{操作})
- 数据库表包含标准字段
- API 接口遵循 RESTful 风格
- 代码注释完整
- 前端权限控制正确
文档版本:v1.0 最后更新:2024年 维护者:开发团队