29 KiB
Lyzsys 后端开发文档
目录
项目概述
Lyzsys 是一个基于 Spring Boot 的企业级后台管理系统,采用模块化单体架构,支持多租户、工作流、权限管理、AI 集成等企业级功能。
核心特性
- 模块化架构: 基于 Maven 多模块的清晰分层设计
- 多租户支持: 原生支持 SaaS 多租户场景
- 权限管理: 基于 RBAC 的动态权限和数据权限
- 工作流引擎: 集成 Flowable 实现业务流程管理
- AI 集成: 支持多个 AI 服务提供商集成
- 微服务就绪: 模块化设计便于未来微服务化改造
技术栈
核心框架
| 技术 | 版本 | 说明 |
|---|---|---|
| Spring Boot | 2.7.18 | 应用开发框架 |
| Spring Security | 5.8.16 | 安全框架 |
| MyBatis Plus | 3.5.15 | ORM 增强框架 |
| Flowable | 6.8.0 | 工作流引擎 |
| Redisson | 3.52.0 | 分布式锁客户端 |
数据存储
| 技术 | 版本 | 说明 |
|---|---|---|
| MySQL | 5.7+ | 主数据库 |
| Redis | 5.0+ | 缓存数据库 |
| 支持数据库 | - | MySQL、PostgreSQL、Oracle、SQL Server、H2 等 |
工具库
| 技术 | 版本 | 说明 |
|---|---|---|
| Lombok | 1.18.34 | 简化 Java 代码 |
| MapStruct | 1.6.3 | 对象映射 |
| Jackson | 2.13.5 | JSON 处理 |
| Hibernate Validator | 6.2.5 | 参数校验 |
| Knife4j | 3.0.3 | API 文档 |
项目架构
整体架构
Lyzsys 后端采用模块化单体架构,基于 Controller-Service-DAL 三层架构模式:
┌─────────────────────────────────────────────────────────────┐
│ 前端应用 │
│ (lyzsys-ui-admin / lyzsys-ui-admin-uniapp) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ lyzsys-server │
│ (应用启动入口) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ lyzsys-framework│ │ lyzsys-module-xxx│ │lyzsys-dependencies│
│ (框架层) │ │ (业务模块) │ │ (依赖管理) │
└──────────────┘ └──────────────────┘ └──────────────┘
分层架构
每个业务模块都遵循标准的三层架构:
controller/ # 控制层 - 接收 HTTP 请求
├── admin/ # 管理后台 API
└── app/ # 用户 App API
│
▼
service/ # 服务层 - 业务逻辑处理
├── IxxxService.java # 服务接口
└── xxxServiceImpl.java # 服务实现
│
▼
dal/ # 数据访问层
├── dataobject/ # 数据对象 (DO)
├── mysql/ # MyBatis Mapper
└── redis/ # Redis 操作
架构设计原则
- 依赖倒置: Controller 依赖 Service 接口,而非实现
- 单一职责: 每层只负责自己的职责
- 开闭原则: 通过接口扩展,而非修改
- 非严格分层: 允许跨层访问(如 Service 直接调用多个 Mapper)
模块说明
Maven 模块分类
项目共有四类 Maven Module:
1. lyzsys-dependencies
作用: Maven 依赖版本管理 (BOM)
说明: 定义项目中所有 Maven 依赖的版本号,解决依赖冲突问题。
关键文件:
pom.xml: 依赖版本定义
2. lyzsys-framework
作用: Java 框架拓展
说明: 提供项目的基础框架能力,分为技术组件和业务组件。
技术组件:
| 模块 | 作用 |
|---|---|
| lyzsys-common | 基础 pojo 类、枚举、工具类 |
| lyzsys-spring-boot-starter-web | Web 封装,全局异常、访问日志 |
| lyzsys-spring-boot-starter-security | 认证授权,基于 Spring Security |
| lyzsys-spring-boot-starter-mybatis | 数据库操作,基于 MyBatis Plus |
| lyzsys-spring-boot-starter-redis | 缓存操作,基于 Spring Data Redis + Redisson |
| lyzsys-spring-boot-starter-mq | 消息队列,基于 Redis 实现 |
| lyzsys-spring-boot-starter-job | 定时任务,基于 Quartz 实现 |
| lyzsys-spring-boot-starter-protection | 服务保障,幂等、分布式锁、限流、熔断 |
| lyzsys-spring-boot-starter-excel | Excel 导入导出,基于 EasyExcel |
| lyzsys-spring-boot-starter-monitor | 服务监控,链路追踪、日志服务 |
| lyzsys-spring-boot-starter-websocket | WebSocket 封装,支持 Token 认证 |
业务组件:
| 模块 | 作用 |
|---|---|
| lyzsys-spring-boot-starter-biz-tenant | SaaS 多租户 |
| lyzsys-spring-boot-starter-biz-data-permission | 数据权限 |
| lyzsys-spring-boot-starter-biz-ip | 地区 & IP 库 |
3. lyzsys-module-xxx
作用: 业务功能模块
核心模块:
| 模块 | 说明 | 是否必须 |
|---|---|---|
| lyzsys-module-system | 系统功能模块 | √ |
| lyzsys-module-infra | 基础设施模块 | √ |
| lyzsys-module-ai | AI 大模型集成 | × |
| lyzsys-module-bpm | 业务流程管理 | × |
| lyzsys-module-crm | 客户关系管理 | × |
| lyzsys-module-erp | 企业资源规划 | × |
| lyzsys-module-iot | 物联网平台 | × |
| lyzsys-module-mall | 商城系统 | × |
| lyzsys-module-member | 会员中心 | × |
| lyzsys-module-mp | 微信公众号 | × |
| lyzsys-module-pay | 支付系统 | × |
| lyzsys-module-report | 报表系统 | × |
4. lyzsys-server
作用: 管理后台 + 用户 App 的服务端
说明: 后端 Server 的主项目,通过引入需要的 lyzsys-module-xxx 业务模块,提供 RESTful API。
模块标准结构
每个业务模块采用统一的目录结构:
lyzsys-module-xxx/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── cn/iocoder/lyzsys/module/xxx/
│ │ │ ├── api/ # 对外 API 接口
│ │ │ │ ├── xxxApi.java
│ │ │ │ └── xxxApiImpl.java
│ │ │ ├── controller/ # 控制层
│ │ │ │ ├── admin/ # 管理后台 Controller
│ │ │ │ │ ├── xxxController.java
│ │ │ │ │ └── vo/ # 视图对象
│ │ │ │ │ ├── xxxReqVO.java
│ │ │ │ │ └── xxxRespVO.java
│ │ │ │ └── app/ # 用户 App Controller
│ │ │ ├── service/ # 服务层
│ │ │ │ ├── xxxService.java
│ │ │ │ └── xxxServiceImpl.java
│ │ │ ├── dal/ # 数据访问层
│ │ │ │ ├── dataobject/ # 数据对象
│ │ │ │ │ └── xxxDO.java
│ │ │ │ ├── mysql/ # MyBatis Mapper
│ │ │ │ │ └── xxxMapper.java
│ │ │ │ └── redis/ # Redis 操作
│ │ │ │ └── xxxRedisDAO.java
│ │ │ ├── convert/ # 对象转换器
│ │ │ │ └── xxxConvert.java
│ │ │ ├── enums/ # 枚举类
│ │ │ │ └── xxxEnum.java
│ │ │ └── framework/ # 模块框架配置
│ │ └── resources/
│ │ └── mapper/ # MyBatis XML
│ └── test/
│ └── java/
└── pom.xml
开发指南
环境准备
必需软件
| 软件 | 版本要求 | 下载地址 |
|---|---|---|
| JDK | 8+ | https://www.oracle.com/java/technologies/downloads/ |
| MySQL | 5.7+ | https://dev.mysql.com/downloads/mysql/ |
| Redis | 5.0+ | https://redis.io/download |
| Maven | 3.6+ | https://maven.apache.org/download.cgi |
| IDE | IntelliJ IDEA 推荐 | https://www.jetbrains.com/idea/ |
配置数据库
- 创建数据库:
CREATE DATABASE lyzsys CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
导入 SQL 脚本(位置:
sql/目录) -
修改配置文件
lyzsys-server/src/main/resources/application.yaml
快速开始
1. 克隆项目
git clone https://github.com/your-org/lyzsys.git
cd lyzsys/lyzsys_backend
2. 导入 IDE
将项目导入 IntelliJ IDEA:
File → Open → 选择 lyzsys_backend 目录
等待 Maven 依赖下载完成。
3. 启动 Redis
redis-server
4. 运行主类
找到 lyzsys-server/src/main/java/cn/iocoder/lyzsys/server/LyzsysServerApplication.java
右键 → Run 'LyzsysServerApplication'
5. 访问应用
- 应用地址: http://localhost:48080
- API 文档: http://localhost:48080/doc.html
- 用户名: admin
- 密码: admin123
开发规范
命名规范
包命名: 全小写,使用点分隔
cn.iocoder.lyzsys.module.system.controller.admin
类命名: 大驼峰
UserController, UserService, UserDO
方法命名: 小驼峰
getUserById(), createUser(), deleteUser()
变量命名: 小驼峰
userName, userAge, isAdmin
常量命名: 全大写,下划线分隔
MAX_SIZE, DEFAULT_PAGE_SIZE, ERROR_CODE
注释规范
类注释:
/**
* 用户 Controller
*
* @author 芋道源码
*/
@RestController
@RequestMapping("/system/user")
public class UserController {
}
方法注释:
/**
* 创建用户
*
* @param createReqVO 创建信息
* @return 用户 ID
*/
@PostMapping("/create")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO createReqVO) {
return success(userService.createUser(createReqVO));
}
代码规范
- 使用 Lombok 简化代码:
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDO extends TenantBaseDO {
private Long id;
private String username;
}
- 使用 MapStruct 进行对象转换:
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
UserDO convert(UserCreateReqVO bean);
UserRespVO convert(UserDO bean);
}
- 异常处理:
// 使用全局异常处理器
throw new ServiceException(USER_USERNAME_EXISTS);
// 或使用工具方法
throw exception(USER_USERNAME_EXISTS);
接口开发
Controller 层
@Tag(name = "管理后台 - 用户")
@RestController
@RequestMapping("/system/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/create")
@Operation(summary = "创建用户")
@PreAuthorize("@ss.hasPermission('system:user:create')")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO createReqVO) {
return success(userService.createUser(createReqVO));
}
@GetMapping("/get")
@Operation(summary = "获取用户详情")
@Parameter(name = "id", description = "用户 ID", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<UserRespVO> getUser(@RequestParam("id") Long id) {
return success(userService.getUser(id));
}
}
Service 层
public interface UserService {
Long createUser(UserCreateReqVO createReqVO);
UserRespVO getUser(Long id);
void deleteUser(Long id);
}
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createUser(UserCreateReqVO createReqVO) {
// 1. 参数校验
validateUserExists(null, createReqVO.getUsername());
// 2. 插入用户
UserDO user = UserConvert.INSTANCE.convert(createReqVO);
user.setPassword(encodePassword(createReqVO.getPassword()));
userMapper.insert(user);
// 3. 返回 ID
return user.getId();
}
@Override
public UserRespVO getUser(Long id) {
UserDO user = userMapper.selectById(id);
return UserConvert.INSTANCE.convert(user);
}
}
Mapper 层
@Mapper
public interface UserMapper extends BaseMapperX<UserDO> {
default UserDO selectByUsername(String username) {
return selectOne("username", username);
}
default List<UserDO> selectListByDeptIds(Collection<Long> deptIds) {
return selectList(new LambdaQueryWrapperX<UserDO>()
.in(UserDO::getDeptId, deptIds));
}
default PageResult<UserDO> selectPage(UserPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<UserDO>()
.likeIfPresent(UserDO::getUsername, pageReqVO.getUsername())
.likeIfPresent(UserDO::getMobile, pageReqVO.getMobile())
.betweenIfPresent(UserDO::getCreateTime, pageReqVO.getCreateTime())
.orderByDesc(UserDO::getId));
}
}
核心功能
认证授权
认证流程
- 登录认证:
用户输入用户名密码 → 后端验证 → 生成 JWT Token → 返回 Token
- Token 验证:
请求携带 Token → 后端解析 Token → 验证有效性 → 允许访问
- Token 刷新:
Token 即将过期 → 使用刷新令牌 → 获取新 Token
权限模型
RBAC (基于角色的访问控制):
用户 (User)
↓
角色 (Role)
↓
权限 (Permission)
↓
资源 (Resource)
数据权限:
- 全部数据权限
- 本部门数据权限
- 本部门及以下数据权限
- 仅本人数据权限
- 自定义数据权限
多租户
租户隔离
- 数据库隔离: 通过
tenant_id字段隔离 - 自动过滤: MyBatis Plus 拦截器自动添加租户条件
- 租户上下文:
TenantContextHolder管理当前租户
使用示例
// 继承租户基类
@TableName("system_user")
public class UserDO extends TenantBaseDO {
private Long id;
private String username;
// tenant_id 由 TenantBaseDO 提供
}
// 查询自动过滤租户
List<UserDO> users = userMapper.selectList();
// SQL: SELECT * FROM system_user WHERE tenant_id = ?
工作流 (Flowable)
流程定义
@Service
public class ProcessDefinitionService {
public String createProcessDefinition(ProcessDefinitionCreateReqVO createReqVO) {
// 1. 校验流程模型
validateProcessModel(createReqVO.getModelId());
// 2. 部署流程定义
Deployment deployment = repositoryService.createDeployment()
.name(createReqVO.getName())
.addBytes(createReqVO.getBpmnBytes())
.deploy();
// 3. 返回流程定义 ID
return deployment.getId();
}
}
流程实例
@Service
public class ProcessInstanceService {
public String startProcessInstance(ProcessInstanceStartReqVO startReqVO) {
// 1. 启动流程实例
ProcessInstance instance = runtimeService.startProcessInstanceByKey(
startReqVO.getProcessDefinitionKey(),
startReqVO.getBusinessKey()
);
// 2. 完成第一个任务
taskService.complete(instance.getId());
// 3. 返回实例 ID
return instance.getId();
}
}
缓存管理
Redis 缓存
// 使用 RedisTemplate
@Service
@RequiredArgsConstructor
public class UserServiceImpl {
private final RedisTemplate<String, UserDO> redisTemplate;
public UserDO getUser(Long id) {
String key = "user:" + id;
UserDO user = redisTemplate.opsForValue().get(key);
if (user == null) {
user = userMapper.selectById(id);
redisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);
}
return user;
}
}
缓存注解
@Cacheable(value = "user", key = "#id")
public UserDO getUser(Long id) {
return userMapper.selectById(id);
}
@CachePut(value = "user", key = "#user.id")
public UserDO updateUser(UserDO user) {
userMapper.updateById(user);
return user;
}
@CacheEvict(value = "user", key = "#id")
public void deleteUser(Long id) {
userMapper.deleteById(id);
}
消息队列
Redis 消息队列
@Component
@RequiredArgsConstructor
public class SmsProducer {
private final RedisTemplate<String, Object> redisTemplate;
public void sendSmsSendMessage(Long userId, String mobile, String content) {
SmsSendMessage message = new SmsSendMessage()
.setUserId(userId)
.setMobile(mobile)
.setContent(content);
redisTemplate.convertAndSend("sms_send", message);
}
}
@Component
@RequiredArgsConstructor
public class SmsSendConsumer {
private final SmsService smsService;
@RedisStreamListener(stream = "sms_send", consumerGroup = "sms_send_group")
public void consumeSmsSendMessage(SmsSendMessage message) {
smsService.sendSms(message.getMobile(), message.getContent());
}
}
定时任务
Quartz 定时任务
@Component
public class DemoJob extends QuartzJobBean {
@Autowired
private UserService userService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// 定时清理过期用户
userService.cleanExpiredUsers();
}
}
文件管理
文件上传
@RestController
@RequestMapping("/infra/file")
public class FileController {
@PostMapping("/upload")
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file) {
// 1. 上传文件
String url = fileService.uploadFile(file);
// 2. 返回 URL
return success(url);
}
}
文件存储
支持多种存储方式:
- 本地存储
- 阿里云 OSS
- 腾讯云 COS
- MinIO
- FTP / SFTP
Excel 操作
导入
@PostMapping("/import")
public CommonResult<Integer> importUsers(@RequestParam("file") MultipartFile file) {
List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);
return success(userService.importUsers(list));
}
导出
@GetMapping("/export")
public void exportUsers(HttpServletResponse response, UserPageReqVO pageReqVO) {
List<UserDO> list = userService.getUserList(pageReqVO);
ExcelUtils.write(response, "用户数据.xls", "用户列表", UserRespVO.class,
BeanConvertUtils.convertList(list, UserRespVO.class));
}
部署指南
本地部署
1. 打包项目
cd lyzsys_backend
mvn clean package -DskipTests
2. 上传文件
将 lyzsys-server/target/lyzsys-server.jar 上传到服务器
3. 启动应用
java -jar lyzsys-server.jar --spring.profiles.active=prod
Docker 部署
1. 构建镜像
docker build -t lyzsys/lyzsys-server:latest .
2. 运行容器
docker run -d \
--name lyzsys-server \
-p 48080:48080 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/lyzsys \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=password \
-e SPRING_DATA_REDIS_HOST=redis \
lyzsys/lyzsys-server:latest
配置说明
application.yaml
spring:
# 数据源配置
datasource:
url: jdbc:mysql://127.0.0.1:3306/lyzsys?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
# Redis 配置
redis:
host: 127.0.0.1
port: 6379
database: 1
password:
timeout: 0
# 项目配置
lyzsys:
info:
base-package: cn.iocoder.lyzsys
web:
api-prefix: /admin-api
security:
mock-enable: true
upload:
base-url: http://127.0.0.1:48080
Demo 示例模块
模块简介
lyzsys-module-demo 是一个完整的业务模块示例,展示了如何在 Lyzsys 系统中快速创建一个新的业务模块。该模块实现了项目管理的完整 CRUD 功能,包括增删改查和 Excel 导出。
功能特性
- ✅ 完整的 CRUD 接口(增删改查)
- ✅ 分页查询支持
- ✅ 批量删除功能
- ✅ Excel 导出功能
- ✅ 业务字段唯一性校验
- ✅ 权限控制
- ✅ 前后端完整实现
模块结构
lyzsys-module-demo/
├── pom.xml # Maven 配置
└── src/main/java/cn/iocoder/lyzsys/module/demo/
├── controller/admin/project/ # 控制器层
│ ├── ProjectController.java # 项目控制器
│ └── vo/ # VO 对象
│ ├── ProjectPageReqVO.java # 分页查询请求
│ ├── ProjectRespVO.java # 响应 VO
│ └── ProjectSaveReqVO.java # 保存请求 VO
├── service/project/ # 服务层
│ ├── ProjectService.java # 服务接口
│ └── ProjectServiceImpl.java # 服务实现
├── dal/ # 数据访问层
│ ├── dataobject/project/ # 数据对象
│ │ └── ProjectDO.java # 项目实体类
│ └── mysql/project/ # Mapper 接口
│ └── ProjectMapper.java # 项目 Mapper
└── enums/ # 枚举类
└── ErrorCodeConstants.java # 错误码常量
核心代码示例
实体类(ProjectDO)
@TableName("demo_project")
@Data
@EqualsAndHashCode(callSuper = true)
public class ProjectDO extends BaseDO {
@TableId
private Long id;
// 遵循命名规范:第一个单词不能只有一个字母
private String projectName; // ✅ 正确(而非 pName)
private String projectCode; // ✅ 正确(而非 pCode)
private LocalDateTime establishDate; // ✅ 正确(而非 eDate)
}
Controller 示例
@Tag(name = "管理后台 - 项目管理")
@RestController
@RequestMapping("/demo/project")
public class ProjectController {
@PostMapping("/create")
@Operation(summary = "创建项目")
@PreAuthorize("@ss.hasPermission('demo:project:create')")
public CommonResult<Long> createProject(@Valid @RequestBody ProjectSaveReqVO createReqVO) {
return success(projectService.createProject(createReqVO));
}
// 其他 CRUD 方法...
}
数据库设计
CREATE TABLE `demo_project` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '项目ID',
`project_name` varchar(100) NOT NULL COMMENT '项目名称',
`project_code` varchar(50) NOT NULL COMMENT '项目编号',
`establish_date` datetime NULL COMMENT '立项时间',
-- 标准字段
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='项目管理表';
菜单配置
Demo 模块的菜单结构:
项目管理(一级菜单,sort: 1)
└── 项目列表(二级菜单,sort: 1)
├── 项目查询(demo:project:query)
├── 项目新增(demo:project:create)
├── 项目修改(demo:project:update)
├── 项目删除(demo:project:delete)
└── 项目导出(demo:project:export)
前端实现
前端代码位置:
- API 接口:
src/api/demo/project/index.ts - 列表页面:
src/views/demo/project/index.vue - 表单组件:
src/views/demo/project/ProjectForm.vue
作为参考模板
Demo 模块可以作为新业务模块开发的参考模板,包含了:
- 标准的代码结构 - 遵循项目分层架构
- 完整的业务逻辑 - 包括校验、异常处理等
- 规范的命名方式 - 遵循驼峰命名规范
- 权限控制示例 - 展示如何配置权限
- 前后端联调 - 完整的前后端交互流程
详细开发指南请参考:
开发规范
为确保代码质量和团队协作效率,Lyzsys 项目制定了一系列开发规范。
核心规范文档
-
编码规范 - 必读 ⭐⭐⭐⭐⭐
- 驼峰命名规范(重要:第一个单词不能只有一个字母)
- 菜单结构规范
- 代码结构规范
- 数据库设计规范
- API 接口规范
- 前端开发规范
-
新模块开发指南 - 实战教程 ⭐⭐⭐⭐⭐
- 快速开始
- 创建后端模块(完整步骤)
- 创建前端页面
- 配置菜单权限
- 以 Demo 模块为参考示例
关键规范要点
命名规范核心原则
⚠️ 重要:所有字段名、类名的驼峰命名中,第一个单词不能只有一个字母
// ✅ 正确示例
private String projectId; // 而非 pId
private String projectName; // 而非 pName
private String establishDate; // 而非 eDate
// ❌ 错误示例
private String pId; // 单字母开头,可能导致 MyBatis Plus 映射问题
private String mType; // 单字母开头
菜单结构规范
业务功能菜单优先展示,系统管理功能放在最后:
1-90. 业务菜单(项目管理、客户管理等)
98. 系统管理
99. 基础设施
权限标识格式
格式:{模块名}:{业务}:{操作}
示例:
demo:project:query # 查询
demo:project:create # 新增
demo:project:update # 修改
demo:project:delete # 删除
demo:project:export # 导出
开发流程建议
- 阅读规范文档 → 了解编码规范和开发流程
- 参考 Demo 模块 → 理解标准的实现方式
- 按照开发指南 → 逐步创建新模块
- 代码评审 → 确保符合规范要求
附录
常见问题
Q1: 如何添加新的业务模块?
推荐方式:参考 新模块开发指南,以 Demo 模块为模板创建新模块。
快速步骤:
- 创建 Maven 模块和目录结构
- 编写数据库表(遵循命名规范)
- 按照 Demo 模块的结构创建后端代码
- 创建前端页面和 API 接口
- 配置菜单和权限
Q2: 如何自定义异常?
- 在
module-system/enums/ErrorCodeConstants.java中添加错误码 - 使用
throw exception(ERROR_CODE)抛出异常 - 全局异常处理器会自动处理并返回统一格式
Q3: 如何实现数据权限?
- 在
@Table注解中配置dataPermission属性 - 使用
@DataPermission注解标记需要数据权限的方法 - 框架会自动添加数据权限过滤条件
参考资源
文档版本: v1.0.0 最后更新: 2025-01-19 维护团队: Lyzsys 开发团队