Files
lyzsys_backend/doc/编码规范.md

16 KiB
Raw Permalink Blame History

Lyzsys 项目编码规范

目录


1. 命名规范

1.1 驼峰命名规范

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

为什么要遵循这个规范?

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

正确示例

// 字段命名
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;  // 而不是 k1Coefficientk1 是业务术语)

错误示例

// 错误:单字母开头
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,                 -- 父级ID0表示顶级
  '/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年 维护者:开发团队