增加文档说明

This commit is contained in:
lpd
2026-01-19 18:34:10 +08:00
parent 0cbb63432e
commit 2863c963ca
8 changed files with 5883 additions and 2 deletions

1464
doc/前端开发文档.md Normal file

File diff suppressed because it is too large Load Diff

866
doc/后端开发文档.md Normal file
View File

@@ -0,0 +1,866 @@
# 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 操作
```
### 架构设计原则
1. **依赖倒置**: Controller 依赖 Service 接口,而非实现
2. **单一职责**: 每层只负责自己的职责
3. **开闭原则**: 通过接口扩展,而非修改
4. **非严格分层**: 允许跨层访问(如 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/ |
#### 配置数据库
1. 创建数据库:
```sql
CREATE DATABASE lyzsys CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
2. 导入 SQL 脚本(位置:`sql/` 目录)
3. 修改配置文件 `lyzsys-server/src/main/resources/application.yaml`
### 快速开始
#### 1. 克隆项目
```bash
git clone https://github.com/your-org/lyzsys.git
cd lyzsys/lyzsys_backend
```
#### 2. 导入 IDE
将项目导入 IntelliJ IDEA
```
File → Open → 选择 lyzsys_backend 目录
```
等待 Maven 依赖下载完成。
#### 3. 启动 Redis
```bash
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
```
#### 注释规范
**类注释**:
```java
/**
* 用户 Controller
*
* @author 芋道源码
*/
@RestController
@RequestMapping("/system/user")
public class UserController {
}
```
**方法注释**:
```java
/**
* 创建用户
*
* @param createReqVO 创建信息
* @return 用户 ID
*/
@PostMapping("/create")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO createReqVO) {
return success(userService.createUser(createReqVO));
}
```
#### 代码规范
1. **使用 Lombok 简化代码**:
```java
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDO extends TenantBaseDO {
private Long id;
private String username;
}
```
2. **使用 MapStruct 进行对象转换**:
```java
@Mapper
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
UserDO convert(UserCreateReqVO bean);
UserRespVO convert(UserDO bean);
}
```
3. **异常处理**:
```java
// 使用全局异常处理器
throw new ServiceException(USER_USERNAME_EXISTS);
// 或使用工具方法
throw exception(USER_USERNAME_EXISTS);
```
### 接口开发
#### Controller 层
```java
@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 层
```java
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 层
```java
@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));
}
}
```
---
## 核心功能
### 认证授权
#### 认证流程
1. **登录认证**:
```
用户输入用户名密码 → 后端验证 → 生成 JWT Token → 返回 Token
```
2. **Token 验证**:
```
请求携带 Token → 后端解析 Token → 验证有效性 → 允许访问
```
3. **Token 刷新**:
```
Token 即将过期 → 使用刷新令牌 → 获取新 Token
```
#### 权限模型
**RBAC (基于角色的访问控制)**:
```
用户 (User)
角色 (Role)
权限 (Permission)
资源 (Resource)
```
**数据权限**:
- 全部数据权限
- 本部门数据权限
- 本部门及以下数据权限
- 仅本人数据权限
- 自定义数据权限
### 多租户
#### 租户隔离
1. **数据库隔离**: 通过 `tenant_id` 字段隔离
2. **自动过滤**: MyBatis Plus 拦截器自动添加租户条件
3. **租户上下文**: `TenantContextHolder` 管理当前租户
#### 使用示例
```java
// 继承租户基类
@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)
#### 流程定义
```java
@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();
}
}
```
#### 流程实例
```java
@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 缓存
```java
// 使用 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;
}
}
```
#### 缓存注解
```java
@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 消息队列
```java
@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 定时任务
```java
@Component
public class DemoJob extends QuartzJobBean {
@Autowired
private UserService userService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// 定时清理过期用户
userService.cleanExpiredUsers();
}
}
```
### 文件管理
#### 文件上传
```java
@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 操作
#### 导入
```java
@PostMapping("/import")
public CommonResult<Integer> importUsers(@RequestParam("file") MultipartFile file) {
List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);
return success(userService.importUsers(list));
}
```
#### 导出
```java
@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. 打包项目
```bash
cd lyzsys_backend
mvn clean package -DskipTests
```
#### 2. 上传文件
`lyzsys-server/target/lyzsys-server.jar` 上传到服务器
#### 3. 启动应用
```bash
java -jar lyzsys-server.jar --spring.profiles.active=prod
```
### Docker 部署
#### 1. 构建镜像
```bash
docker build -t lyzsys/lyzsys-server:latest .
```
#### 2. 运行容器
```bash
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
```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
```
---
## 附录
### 常见问题
#### Q1: 如何添加新的业务模块?
1.`lyzsys-module-xxx` 目录下创建新模块
2. 按照标准模块结构创建包和类
3.`lyzsys-server/pom.xml` 中添加模块依赖
4.`application.yaml` 中配置模块扫描路径
#### Q2: 如何自定义异常?
1.`module-system/enums/ErrorCodeConstants.java` 中添加错误码
2. 使用 `throw exception(ERROR_CODE)` 抛出异常
3. 全局异常处理器会自动处理并返回统一格式
#### Q3: 如何实现数据权限?
1.`@Table` 注解中配置 `dataPermission` 属性
2. 使用 `@DataPermission` 注解标记需要数据权限的方法
3. 框架会自动添加数据权限过滤条件
### 参考资源
- [Spring Boot 官方文档](https://spring.io/projects/spring-boot)
- [MyBatis Plus 官方文档](https://baomidou.com/)
- [Flowable 官方文档](https://www.flowable.com/open-source/docs)
- [Redis 官方文档](https://redis.io/documentation)
- [芋道源码文档](https://doc.iocoder.cn/)
---
**文档版本**: v1.0.0
**最后更新**: 2025-01-19
**维护团队**: Lyzsys 开发团队

804
doc/常见问题.md Normal file
View File

@@ -0,0 +1,804 @@
# Lyzsys 常见问题 (FAQ)
## 📖 目录
- [快速导航](#快速导航)
- [后端开发问题](#后端开发问题)
- [前端开发问题](#前端开发问题)
- [部署运维问题](#部署运维问题)
- [性能优化问题](#性能优化问题)
- [功能定制问题](#功能定制问题)
- [故障排查问题](#故障排查问题)
---
## 快速导航
### 新手入门
- [如何快速开始?](#如何快速开始)
- [项目运行需要什么环境?](#项目运行需要什么环境)
- [如何获取项目源码?](#如何获取项目源码)
### 开发相关
- [如何添加新的业务模块?](#如何添加新的业务模块)
- [如何修改前端页面?](#如何修改前端页面)
- [如何自定义接口?](#如何自定义接口)
- [如何实现权限控制?](#如何实现权限控制)
### 部署相关
- [如何部署到生产环境?](#如何部署到生产环境)
- [如何配置数据库连接?](#如何配置数据库连接)
- [如何配置 SSL 证书?](#如何配置-ssl-证书)
- [如何进行性能优化?](#如何进行性能优化)
---
## 后端开发问题
### Q1: 如何快速开始?
**A**: 按照以下步骤操作:
1. **克隆项目**
```bash
git clone https://github.com/your-org/lyzsys.git
cd lyzsys/lyzsys_backend
```
2. **导入数据库**
```bash
mysql -u root -p < sql/lyzsys.sql
```
3. **修改配置**
```yaml
# application.yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/lyzsys
username: root
password: your_password
```
4. **启动项目**
```bash
mvn spring-boot:run
```
5. **访问系统**
- 后端地址: http://localhost:48080
- API 文档: http://localhost:48080/doc.html
### Q2: 如何添加新的业务模块?
**A**: 按照以下步骤创建新模块:
1. **创建模块目录**
```
lyzsys-module-xxx/
├── src/
│ └── main/
│ ├── java/
│ └── resources/
└── pom.xml
```
2. **创建模块 pom.xml**
```xml
<parent>
<groupId>cn.iocoder</groupId>
<artifactId>lyzsys-backend</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>lyzsys-module-xxx</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- 依赖其他模块 -->
</dependencies>
```
3. **创建标准包结构**
```
cn.iocoder.lyzsys.module.xxx/
├── api/
├── controller/
│ ├── admin/
│ └── app/
├── service/
├── dal/
│ ├── dataobject/
│ ├── mysql/
│ └── redis/
├── convert/
└── enums/
```
4. **在主 pom.xml 中添加模块**
```xml
<modules>
<module>lyzsys-module-xxx</module>
</modules>
```
5. **在 lyzsys-server 中引入**
```xml
<dependency>
<groupId>cn.iocoder</groupId>
<artifactId>lyzsys-module-xxx</artifactId>
</dependency>
```
### Q3: 如何实现权限控制?
**A**: Lyzsys 提供了多层次的权限控制:
#### 1. 接口权限
使用 `@PreAuthorize` 注解:
```java
@PostMapping("/create")
@PreAuthorize("@ss.hasPermission('system:user:create')")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO reqVO) {
return success(userService.createUser(reqVO));
}
```
#### 2. 数据权限
使用 `@DataScope` 注解:
```java
@DataScope(deptAlias = "d", userAlias = "u")
public List<UserDO> getUserList() {
return userMapper.selectList();
}
```
#### 3. 前端权限
使用权限指令:
```vue
<!-- 有权限时显示 -->
<el-button v-hasPermi="['system:user:create']">创建</el-button>
<!-- 有角色时显示 -->
<el-button v-hasRole="['admin']">管理员操作</el-button>
```
### Q4: 如何使用代码生成器?
**A**: 代码生成器使用步骤:
1. **访问代码生成**
- 登录系统后,进入「基础设施」→「代码生成」
2. **导入数据库表**
- 点击「导入」按钮
- 选择要生成的表
3. **配置生成信息**
- 基本信息:模块名、业务名、功能名
- 生成信息:包路径、模块名、业务名
- 字段信息:字段显示、查询条件、必填项
4. **生成代码**
- 点击「生成代码」按钮
- 下载代码压缩包
5. **导入项目**
- 解压代码到对应模块
- 创建菜单和权限
### Q5: 如何实现文件上传?
**A**: 文件上传实现步骤:
#### 1. 配置文件存储
```yaml
lyzsys:
upload:
base-url: http://your-domain.com
storage:
minio:
endpoint: http://localhost:9000
access-key: your_access_key
secret-key: your_secret_key
bucket-name: lyzsys
```
#### 2. 后端上传
```java
@PostMapping("/upload")
public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file) {
String url = fileService.uploadFile(file);
return success(url);
}
```
#### 3. 前端上传
```vue
<el-upload
:action="uploadUrl"
:headers="uploadHeaders"
:on-success="handleSuccess"
>
<el-button type="primary">上传文件</el-button>
</el-upload>
```
### Q6: 如何使用 Redis 缓存?
**A**: Redis 缓存使用方法:
#### 1. 使用 Spring Cache
```java
@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);
}
```
#### 2. 使用 RedisTemplate
```java
@Autowired
private 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;
}
```
---
## 前端开发问题
### Q7: 如何修改前端页面?
**A**: 前端页面修改步骤:
1. **找到页面文件**
- 页面文件位于 `src/views/` 目录
- 按照模块分类,如 `src/views/system/user/`
2. **修改页面内容**
```vue
<template>
<div class="user-list">
<!-- 页面内容 -->
</div>
</template>
<script setup lang="ts">
// 脚本逻辑
</script>
<style scoped lang="scss">
// 样式
</style>
```
3. **热更新**
- 修改后自动热更新,无需重启
4. **构建测试**
```bash
pnpm build:prod
```
### Q8: 如何调用后端 API
**A**: API 调用方法:
#### 1. 定义 API
```typescript
// src/api/system/user/index.ts
import request from '@/utils/request'
export function getUserPage(params: UserPageReqVO) {
return request.get({ url: '/system/user/page', params })
}
export function createUser(data: UserCreateReqVO) {
return request.post({ url: '/system/user/create', data })
}
```
#### 2. 调用 API
```vue
<script setup lang="ts">
import { ref } from 'vue'
import { getUserPage } from '@/api/system/user'
const loading = ref(false)
const tableData = ref([])
async function fetchUsers() {
loading.value = true
try {
const { data } = await getUserPage({
pageNo: 1,
pageSize: 10
})
tableData.value = data.list
} finally {
loading.value = false
}
}
</script>
```
### Q9: 如何实现国际化?
**A**: 国际化实现步骤:
#### 1. 添加语言文件
```typescript
// src/locales/zh-CN/common.ts
export default {
title: 'Lyzsys 管理系统',
logout: '退出登录'
}
```
```typescript
// src/locales/en/common.ts
export default {
title: 'Lyzsys Admin',
logout: 'Logout'
}
```
#### 2. 使用翻译
```vue
<template>
<h1>{{ $t('common.title') }}</h1>
</template>
<script setup lang="ts">
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
const title = t('common.title')
</script>
```
### Q10: 如何自定义主题?
**A**: 主题定制方法:
#### 1. 修改主题色
```scss
// styles/variables.scss
$primary-color: #409eff;
$success-color: #67c23a;
$warning-color: #e6a23c;
$danger-color: #f56c6c;
```
#### 2. 动态切换主题
```typescript
import { useAppStore } from '@/store/modules/app'
const appStore = useAppStore()
// 切换暗黑模式
function toggleDarkMode() {
appStore.setDarkMode(!appStore.getDarkMode)
}
```
### Q11: 如何使用 Element Plus 组件?
**A**: Element Plus 组件使用:
#### 1. 表格组件
```vue
<el-table :data="tableData" border>
<el-table-column prop="name" label="姓名" />
<el-table-column prop="email" label="邮箱" />
<el-table-column label="操作">
<template #default="{ row }">
<el-button link @click="handleEdit(row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
```
#### 2. 表单组件
```vue
<el-form :model="form" :rules="rules" ref="formRef">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-form-item>
</el-form>
```
#### 3. 对话框组件
```vue
<el-dialog v-model="visible" title="提示">
<span>这是一段内容</span>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="visible = false">确定</el-button>
</template>
</el-dialog>
```
---
## 部署运维问题
### Q12: 如何部署到生产环境?
**A**: 生产部署步骤:
#### 后端部署
1. **打包项目**
```bash
mvn clean package -DskipTests
```
2. **上传到服务器**
```bash
scp lyzsys-server.jar user@server:/opt/lyzsys/
```
3. **启动服务**
```bash
java -jar lyzsys-server.jar --spring.profiles.active=prod
```
#### 前端部署
1. **构建项目**
```bash
pnpm build:prod
```
2. **部署到 Nginx**
```bash
scp -r dist/* user@server:/var/www/lyzsys/
```
3. **配置 Nginx**
```nginx
server {
listen 80;
server_name your-domain.com;
root /var/www/lyzsys;
location / {
try_files $uri $uri/ /index.html;
}
location /admin-api/ {
proxy_pass http://localhost:48080/admin-api/;
}
}
```
### Q13: 如何配置数据库连接?
**A**: 数据库连接配置:
```yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/lyzsys?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
# 连接池配置
hikari:
minimum-idle: 5
maximum-pool-size: 20
idle-timeout: 30000
connection-timeout: 30000
```
### Q14: 如何配置 SSL 证书?
**A**: SSL 证书配置步骤:
1. **获取证书**
```bash
certbot certonly --standalone -d your-domain.com
```
2. **配置 Nginx**
```nginx
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
```
### Q15: 如何进行备份和恢复?
**A**: 备份恢复方法:
#### 数据库备份
```bash
# 备份
mysqldump -u root -p lyzsys > lyzsys_backup.sql
# 恢复
mysql -u root -p lyzsys < lyzsys_backup.sql
```
#### 文件备份
```bash
# 备份
tar -czf lyzsys_backup.tar.gz /var/www/lyzsys
# 恢复
tar -xzf lyzsys_backup.tar.gz -C /
```
---
## 性能优化问题
### Q16: 如何进行性能优化?
**A**: 性能优化建议:
#### 后端优化
1. **数据库优化**
- 添加索引
- 优化 SQL
- 使用缓存
2. **代码优化**
- 批量操作
- 异步处理
- 减少数据库查询
3. **JVM 优化**
```bash
java -Xms2g -Xmx2g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-jar lyzsys-server.jar
```
#### 前端优化
1. **代码分割**
```typescript
const UserList = defineAsyncComponent(() => import('./views/system/user/index.vue'))
```
2. **资源优化**
- 压缩代码
- 使用 CDN
- 图片优化
3. **缓存优化**
- 浏览器缓存
- 本地存储
- Service Worker
### Q17: 如何处理高并发?
**A**: 高并发处理方案:
1. **水平扩展**
- 应用集群
- 负载均衡
- 数据库主从
2. **缓存策略**
- Redis 缓存
- 本地缓存
- 缓存预热
3. **异步处理**
- 消息队列
- 异步任务
- 线程池
4. **限流降级**
- 接口限流
- 服务降级
- 熔断保护
---
## 功能定制问题
### Q18: 如何修改 Logo 和标题?
**A**: 品牌定制方法:
#### 1. 修改前端
```typescript
// src/config/index.ts
export default {
title: '你的系统名称',
logo: '/logo.png'
}
```
#### 2. 修改后端
```yaml
lyzsys:
info:
name: '你的系统名称'
version: '1.0.0'
```
### Q19: 如何集成第三方服务?
**A**: 第三方集成方法:
#### 1. 短信集成
```java
@Service
public class SmsServiceImpl implements SmsService {
@Autowired
private SmsClient smsClient;
public void sendSms(String mobile, String content) {
SmsSendReqDTO req = new SmsSendReqDTO();
req.setMobile(mobile);
req.setContent(content);
smsClient.send(req);
}
}
```
#### 2. 支付集成
```java
@Service
public class PayServiceImpl implements PayService {
@Autowired
private PayClient payClient;
public String createOrder(PayOrderCreateReqDTO req) {
return payClient.createOrder(req);
}
}
```
---
## 故障排查问题
### Q20: 如何查看错误日志?
**A**: 日志查看方法:
#### 后端日志
```bash
# 查看应用日志
tail -f logs/lyzsys.log
# 查看错误日志
grep ERROR logs/lyzsys.log
# 查看 Nginx 日志
tail -f /var/log/nginx/error.log
```
#### 前端日志
```javascript
// 浏览器控制台
console.log('日志信息')
console.error('错误信息')
// 网络请求
// Network 标签查看请求详情
```
### Q21: 常见错误及解决方案
#### 1. 数据库连接失败
**错误**: `Could not get JDBC Connection`
**解决方案**:
- 检查数据库是否启动
- 检查连接信息是否正确
- 检查防火墙是否开放端口
#### 2. Redis 连接失败
**错误**: `Unable to connect to Redis`
**解决方案**:
- 检查 Redis 是否启动
- 检查 Redis 密码是否正确
- 检查 Redis 地址是否正确
#### 3. 前端页面空白
**错误**: 页面无法显示
**解决方案**:
- 检查 Nginx 配置
- 检查前端路由配置
- 检查浏览器控制台错误
#### 4. API 请求失败
**错误**: `Network Error`
**解决方案**:
- 检查后端服务是否启动
- 检查 API 地址是否正确
- 检查跨域配置
---
**文档版本**: v1.0.0
**最后更新**: 2025-01-19
**维护团队**: Lyzsys 开发团队

697
doc/数据库设计.md Normal file
View File

@@ -0,0 +1,697 @@
# Lyzsys 数据库设计文档
## 📖 目录
- [数据库概述](#数据库概述)
- [设计规范](#设计规范)
- [核心表设计](#核心表设计)
- [索引设计](#索引设计)
- [数据字典](#数据字典)
- [多租户设计](#多租户设计)
- [数据库优化](#数据库优化)
- [数据库管理](#数据库管理)
---
## 数据库概述
### 技术选型
| 特性 | 说明 |
|------|------|
| 数据库 | MySQL 5.7+ / 8.0+ |
| 字符集 | utf8mb4 |
| 排序规则 | utf8mb4_unicode_ci |
| 引擎 | InnoDB |
| 时区 | Asia/Shanghai |
### 支持的数据库
- MySQL 5.7、8.0+
- PostgreSQL 9.6+
| Oracle 11g+
| SQL Server 2012+
| H2 2.x (开发测试)
### 数据库特点
1. **多数据库支持**: 通过 MyBatis Plus 实现
2. **租户隔离**: 支持多租户数据隔离
3. **逻辑删除**: 支持软删除
4. **数据权限**: 支持行级数据权限
5. **审计日志**: 完整的创建、更新日志
---
## 设计规范
### 命名规范
#### 数据库命名
- 格式: `lyzsys`
- 示例: `lyzsys`
#### 表命名
- 格式: `{模块}_{业务}_{实体}`
- 规则: 小写字母 + 下划线
- 示例:
- `system_users` - 系统用户表
- `system_roles` - 系统角色表
- `mall_orders` - 商城订单表
- `bpm_process_instance` - 工作流实例表
#### 字段命名
- 格式: 小写字母 + 下划线
- 规则: 使用有意义的单词组合
- 示例:
- `user_id` - 用户 ID
- `user_name` - 用户名
- `create_time` - 创建时间
- `update_time` - 更新时间
#### 索引命名
- 主键索引: `PRIMARY`
- 唯一索引: `uniq_{字段名}`
- 普通索引: `idx_{字段名}`
- 示例:
- `uniq_username` - 用户名唯一索引
- `idx_dept_id` - 部门 ID 普通索引
### 字段类型
#### 整数类型
| 类型 | 字节 | 范围 | 用途 |
|------|------|------|------|
| TINYINT | 1 | -128 ~ 127 | 状态、标识 |
| SMALLINT | 2 | -32768 ~ 32767 | 枚举值 |
| INT | 4 | -21亿 ~ 21亿 | 数量、序号 |
| BIGINT | 8 | 极大数值 | 主键、外键 |
#### 字符串类型
| 类型 | 长度 | 用途 |
|------|------|------|
| CHAR | 0-255 | 固定长度字符串 |
| VARCHAR | 0-65535 | 变长字符串 |
| TEXT | 0-65535 | 长文本 |
| LONGTEXT | 0-4294967295 | 超长文本 |
#### 日期时间类型
| 类型 | 格式 | 用途 |
|------|------|------|
| DATE | YYYY-MM-DD | 日期 |
| DATETIME | YYYY-MM-DD HH:MM:SS | 日期时间 |
| TIMESTAMP | 时间戳 | 时间戳 |
#### 小数类型
| 类型 | 用途 |
|------|------|
| DECIMAL(M,D) | 金额、精度数值 |
### 通用字段
每张表都包含以下通用字段:
```sql
-- 主键
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键'
-- 创建信息
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
creator VARCHAR(64) COMMENT '创建人'
-- 更新信息
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
updater VARCHAR(64) COMMENT '更新人'
-- 删除标记
deleted BIT NOT NULL DEFAULT FALSE COMMENT '是否删除'
-- 租户 ID (多租户表)
tenant_id BIGINT NOT NULL COMMENT '租户 ID'
```
---
## 核心表设计
### 系统管理模块
#### 1. 用户表 (system_users)
```sql
CREATE TABLE `system_users` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` VARCHAR(30) NOT NULL COMMENT '用户账号',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`nickname` VARCHAR(30) NOT NULL COMMENT '用户昵称',
`remark` VARCHAR(500) COMMENT '备注',
`dept_id` BIGINT NOT NULL COMMENT '部门ID',
`post_ids` VARCHAR(255) COMMENT '岗位编号数组',
`email` VARCHAR(50) COMMENT '用户邮箱',
`mobile` VARCHAR(11) COMMENT '手机号码',
`sex` TINYINT COMMENT '用户性别',
`avatar` VARCHAR(100) COMMENT '头像地址',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '帐号状态0正常 1停用',
`login_ip` VARCHAR(50) COMMENT '最后登录IP',
`login_date` DATETIME COMMENT '最后登录时间',
`tenant_id` BIGINT NOT NULL COMMENT '租户 ID',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_username` (`username`, `update_time`, `tenant_id`, `deleted`)
) ENGINE=InnoDB COMMENT='用户信息表';
```
#### 2. 角色表 (system_roles)
```sql
CREATE TABLE `system_roles` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`name` VARCHAR(30) NOT NULL COMMENT '角色名称',
`code` VARCHAR(100) NOT NULL COMMENT '角色权限字符串',
`sort` INT NOT NULL COMMENT '显示顺序',
`data_scope` TINYINT NOT NULL DEFAULT 1 COMMENT '数据范围1全部数据权限 2本部门及以下数据权限 3本部门数据权限 4仅本人数据权限',
`data_scope_dept_ids` VARCHAR(500) COMMENT '数据范围-部门数组',
`status` TINYINT NOT NULL COMMENT '角色状态0正常 1停用',
`type` TINYINT NOT NULL COMMENT '角色类型1系统内置 2自定义',
`remark` VARCHAR(500) COMMENT '备注',
`tenant_id` BIGINT NOT NULL COMMENT '租户 ID',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='角色信息表';
```
#### 3. 菜单表 (system_menu)
```sql
CREATE TABLE `system_menu` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
`name` VARCHAR(50) NOT NULL COMMENT '菜单名称',
`permission` VARCHAR(100) NOT NULL COMMENT '权限标识',
`type` TINYINT NOT NULL COMMENT '菜单类型1目录 2菜单 3按钮',
`sort` INT NOT NULL DEFAULT 0 COMMENT '显示顺序',
`parent_id` BIGINT NOT NULL DEFAULT 0 COMMENT '父菜单ID',
`path` VARCHAR(200) COMMENT '路由地址',
`icon` VARCHAR(100) COMMENT '菜单图标',
`component` VARCHAR(255) COMMENT '组件路径',
`component_name` VARCHAR(255) COMMENT '组件名',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '菜单状态0正常 1停用',
`visible` BIT NOT NULL DEFAULT TRUE COMMENT '是否可见',
`keep_alive` BIT NOT NULL DEFAULT FALSE COMMENT '是否缓存',
`always_show` BIT NOT NULL DEFAULT FALSE COMMENT '是否总是显示',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='菜单权限表';
```
#### 4. 部门表 (system_dept)
```sql
CREATE TABLE `system_dept` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '部门id',
`parent_id` BIGINT NOT NULL DEFAULT 0 COMMENT '父部门id',
`name` VARCHAR(30) NOT NULL COMMENT '部门名称',
`sort` INT NOT NULL DEFAULT 0 COMMENT '显示顺序',
`leader_user_id` BIGINT COMMENT '负责人',
`phone` VARCHAR(11) COMMENT '联系电话',
`email` VARCHAR(64) COMMENT '邮箱',
`status` TINYINT NOT NULL COMMENT '部门状态0正常 1停用',
`tenant_id` BIGINT NOT NULL COMMENT '租户 ID',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='部门表';
```
#### 5. 字典表 (system_dict_type)
```sql
CREATE TABLE `system_dict_type` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '字典主键',
`name` VARCHAR(100) NOT NULL COMMENT '字典名称',
`type` VARCHAR(100) NOT NULL COMMENT '字典类型',
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态0正常 1停用',
`remark` VARCHAR(500) COMMENT '备注',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_type` (`type`, `update_time`, `deleted`)
) ENGINE=InnoDB COMMENT='字典类型表';
```
### 基础设施模块
#### 6. 代码生成表 (infra_codegen_column)
```sql
CREATE TABLE `infra_codegen_column` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '编号',
`table_id` BIGINT NOT NULL COMMENT '表编号',
`column_name` VARCHAR(200) NOT NULL COMMENT '字段名',
`data_type` VARCHAR(100) NOT NULL COMMENT '字段类型',
`column_comment` VARCHAR(500) COMMENT '字段描述',
`nullable` BIT NOT NULL COMMENT '是否允许为空',
`pk` BIT NOT NULL COMMENT '是否主键',
`ordinal_position` INT NOT NULL COMMENT '排序',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='代码生成字段表';
```
#### 7. 定时任务表 (infra_job)
```sql
CREATE TABLE `infra_job` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '任务ID',
`name` VARCHAR(200) NOT NULL COMMENT '任务名称',
`status` TINYINT NOT NULL COMMENT '任务状态',
`handler_name` VARCHAR(200) NOT NULL COMMENT '处理器的名字',
`handler_param` VARCHAR(500) COMMENT '处理器的参数',
`cron_expression` VARCHAR(100) NOT NULL COMMENT 'Cron 表达式',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '重试次数',
`retry_interval` INT NOT NULL DEFAULT 0 COMMENT '重试间隔',
`monitor_timeout` INT NOT NULL DEFAULT 0 COMMENT '监控超时时间',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='定时任务表';
```
### 工作流模块
#### 8. 流程实例表 (bpm_process_instance)
```sql
CREATE TABLE `bpm_process_instance` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '编号',
`process_definition_id` VARCHAR(64) NOT NULL COMMENT '流程定义的编号',
`process_instance_id` VARCHAR(64) NOT NULL COMMENT '流程实例的编号',
`start_user_id` BIGINT NOT NULL COMMENT '发起人的用户编号',
`name` VARCHAR(255) COMMENT '流程实例的名字',
`business_key` VARCHAR(64) COMMENT '业务标识',
`status` TINYINT NOT NULL COMMENT '流程实例的状态',
`tenant_id` BIGINT NOT NULL COMMENT '租户 ID',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='流程实例表';
```
### 商城模块
#### 9. 商品表 (mall_product)
```sql
CREATE TABLE `mall_product` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '商品编号',
`name` VARCHAR(200) NOT NULL COMMENT '商品名称',
`sell_point` VARCHAR(500) COMMENT '卖点',
`description` VARCHAR(2000) COMMENT '商品详情',
`category_id` BIGINT NOT NULL COMMENT '分类编号',
`brand_id` BIGINT COMMENT '品牌编号',
`price` BIGINT NOT NULL COMMENT '价格,单位:分',
`stock` INT NOT NULL COMMENT '库存',
`pic_url` VARCHAR(500) COMMENT '商品主图',
`status` TINYINT NOT NULL COMMENT '商品状态',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='商品表';
```
#### 10. 订单表 (mall_order)
```sql
CREATE TABLE `mall_order` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '订单编号',
`user_id` BIGINT NOT NULL COMMENT '用户编号',
`order_no` VARCHAR(64) NOT NULL COMMENT '订单号',
`total_price` BIGINT NOT NULL COMMENT '订单总价,单位:分',
`status` TINYINT NOT NULL COMMENT '订单状态',
`pay_time` DATETIME COMMENT '付款时间',
`delivery_time` DATETIME COMMENT '发货时间',
`receiver_time` DATETIME COMMENT '收货时间',
`comment_time` DATETIME COMMENT '评论时间',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_order_no` (`order_no`)
) ENGINE=InnoDB COMMENT='订单表';
```
---
## 索引设计
### 索引类型
#### 1. 主键索引 (PRIMARY KEY)
每张表都有主键索引:
```sql
PRIMARY KEY (`id`)
```
#### 2. 唯一索引 (UNIQUE)
用于保证字段的唯一性:
```sql
UNIQUE KEY `uniq_username` (`username`, `update_time`, `tenant_id`, `deleted`)
```
#### 3. 普通索引 (INDEX)
用于提升查询性能:
```sql
KEY `idx_dept_id` (`dept_id`)
```
#### 4. 联合索引
用于多字段查询:
```sql
KEY `idx_user_id_status` (`user_id`, `status`)
```
### 索引规范
1. **主键索引**: 使用自增 BIGINT
2. **唯一索引**: 业务唯一字段
3. **普通索引**: 频繁查询的字段
4. **联合索引**: 多字段组合查询,遵循最左前缀原则
5. **索引数量**: 单表索引不超过 5 个
### 索引示例
```sql
-- 用户表索引
PRIMARY KEY (`id`)
UNIQUE KEY `uniq_username` (`username`, `update_time`, `tenant_id`, `deleted`)
KEY `idx_dept_id` (`dept_id`)
KEY `idx_status` (`status`)
-- 订单表索引
PRIMARY KEY (`id`)
UNIQUE KEY `uniq_order_no` (`order_no`)
KEY `idx_user_id` (`user_id`)
KEY `idx_status` (`status`)
KEY `idx_create_time` (`create_time`)
```
---
## 数据字典
### 通用数据字典
#### 1. 用户性别 (system_user_sex)
| 字典值 | 字典标签 | 颜色 |
|--------|----------|------|
| 1 | 男 | blue |
| 2 | 女 | pink |
| 3 | 未知 | gray |
#### 2. 用户状态 (system_common_status)
| 字典值 | 字典标签 | 颜色 |
|--------|----------|------|
| 0 | 启用 | success |
| 1 | 停用 | danger |
#### 3. 菜单类型 (system_menu_type)
| 字典值 | 字典标签 | 颜色 |
|--------|----------|------|
| 1 | 目录 | |
| 2 | 菜单 | |
| 3 | 按钮 | |
#### 4. 数据范围 (system_data_scope)
| 字典值 | 字典标签 |
|--------|----------|
| 1 | 全部数据权限 |
| 2 | 本部门及以下数据权限 |
| 3 | 本部门数据权限 |
| 4 | 仅本人数据权限 |
#### 5. 流程实例状态 (bpm_process_instance_status)
| 字典值 | 字典标签 | 颜色 |
|--------|----------|------|
| 1 | 进行中 | primary |
| 2 | 已结束 | success |
---
## 多租户设计
### 租户隔离策略
#### 1. 共享数据库、共享 Schema
所有租户共享同一个数据库,通过 `tenant_id` 字段隔离。
#### 2. 自动过滤
MyBatis Plus 拦截器自动添加租户条件:
```java
// 查询时自动添加租户条件
List<UserDO> users = userMapper.selectList();
// 实际 SQL
SELECT * FROM system_users
WHERE deleted = 0
AND tenant_id = 1
```
### 租户表设计
#### 租户表 (system_tenant)
```sql
CREATE TABLE `system_tenant` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '租户编号',
`name` VARCHAR(30) NOT NULL COMMENT '租户名',
`contact_user_id` BIGINT NOT NULL COMMENT '联系人的用户编号',
`contact_name` VARCHAR(30) NOT NULL COMMENT '联系人',
`contact_mobile` VARCHAR(11) COMMENT '联系手机',
`status` TINYINT NOT NULL COMMENT '租户状态',
`website` VARCHAR(256) COMMENT '绑定域名',
`package_id` BIGINT NOT NULL COMMENT '租户套餐编号',
`expire_time` DATETIME NOT NULL COMMENT '过期时间',
`account_count` INT NOT NULL COMMENT '账号数量',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='租户表';
```
#### 租户套餐表 (system_tenant_package)
```sql
CREATE TABLE `system_tenant_package` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '套餐编号',
`name` VARCHAR(30) NOT NULL COMMENT '套餐名',
`status` TINYINT NOT NULL COMMENT '套餐状态',
`remark` VARCHAR(500) COMMENT '备注',
`menu_ids` VARCHAR(500) NOT NULL COMMENT '关联的菜单编号',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`creator` VARCHAR(64) COMMENT '创建人',
`updater` VARCHAR(64) COMMENT '更新人',
`deleted` BIT NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='租户套餐表';
```
---
## 数据库优化
### SQL 优化
#### 1. 避免全表扫描
```sql
-- 不推荐
SELECT * FROM system_users
-- 推荐
SELECT id, username, nickname FROM system_users
```
#### 2. 使用索引
```sql
-- 不推荐
SELECT * FROM system_users WHERE SUBSTRING(username, 1, 3) = 'adm'
-- 推荐
SELECT * FROM system_users WHERE username LIKE 'adm%'
```
#### 3. 分页查询
```sql
-- 使用分页插件
SELECT * FROM system_users
LIMIT 10 OFFSET 0
```
### 表结构优化
#### 1. 字段类型选择
```sql
-- 不推荐
VARCHAR(1000) -- 过长
-- 推荐
VARCHAR(200) -- 合理长度
```
#### 2. 字段数量控制
单表字段数量不超过 50 个。
#### 3. 表分区
大表可以采用分区策略:
```sql
-- 按时间分区
CREATE TABLE `system_operate_log` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`create_time` DATETIME NOT NULL,
PRIMARY KEY (`id`, `create_time`)
) ENGINE=InnoDB
PARTITION BY RANGE (TO_DAYS(create_time)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01'))
);
```
---
## 数据库管理
### 数据库备份
#### 1. 逻辑备份
```bash
# 备份
mysqldump -u root -p lyzsys > lyzsys_backup.sql
# 恢复
mysql -u root -p lyzsys < lyzsys_backup.sql
```
#### 2. 物理备份
```bash
# 复制数据文件
cp -r /var/lib/mysql/lyzsys /backup/lyzsys
```
### 数据库监控
#### 1. 慢查询日志
```sql
-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
```
#### 2. 性能监控
```sql
-- 查看连接数
SHOW PROCESSLIST;
-- 查看状态
SHOW STATUS;
```
### 数据库维护
#### 1. 表优化
```sql
-- 优化表
OPTIMIZE TABLE system_users;
-- 分析表
ANALYZE TABLE system_users;
-- 修复表
REPAIR TABLE system_users;
```
#### 2. 索引优化
```sql
-- 查看索引使用情况
SHOW INDEX FROM system_users;
-- 删除无用索引
DROP INDEX idx_unused ON system_users;
```
---
**文档版本**: v1.0.0
**最后更新**: 2025-01-19
**维护团队**: Lyzsys 数据库团队

734
doc/架构设计.md Normal file
View File

@@ -0,0 +1,734 @@
# Lyzsys 架构设计文档
## 📖 目录
- [架构概述](#架构概述)
- [架构设计原则](#架构设计原则)
- [分层架构](#分层架构)
- [模块化设计](#模块化设计)
- [数据架构](#数据架构)
- [安全架构](#安全架构)
- [技术架构](#技术架构)
- [部署架构](#部署架构)
- [性能优化](#性能优化)
- [扩展性设计](#扩展性设计)
---
## 架构概述
### 整体架构
Lyzsys 采用**前后端分离**的**模块化单体架构**,基于**领域驱动设计DDD**思想进行模块划分,支持未来向微服务架构演进。
```
┌─────────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Web 浏览器 │ │ 移动 App │ │ 小程序 │ │
│ │ (Vue3) │ │ (UniApp) │ │ (UniApp) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 接入层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Nginx / │ │ API 网关 │ │ 负载均衡 │ │
│ │ CDN │ │ (可选) │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ lyzsys-server │ │
│ │ (Spring Boot 应用) │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ Controller │ │ Service │ │ DAL │ │ │
│ │ │ 层 │ │ 层 │ │ 层 │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│lyzsys-module-│ │lyzsys-module-xxx │ │lyzsys-module-│
│ system │ │ (业务模块) │ │ infra │
└──────────────┘ └──────────────────┘ └──────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│lyzsys- │ │lyzsys-framework │ │lyzsys- │
│dependencies │ │ (框架组件) │ │common │
└──────────────┘ └──────────────────┘ └──────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ MinIO │ │
│ │ (主数据库) │ │ (缓存) │ │ (文件存储) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 外部服务 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ AI 服务 │ │ 短信服务 │ │ 支付服务 │ │
│ │ (OpenAI等) │ │ (阿里云等) │ │ (微信等) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
### 架构特点
1. **前后端分离**: 前端和后端独立开发、部署、扩展
2. **模块化设计**: 业务模块独立,低耦合、高内聚
3. **分层架构**: 清晰的分层,职责明确
4. **微服务就绪**: 模块化设计便于微服务化改造
5. **多租户支持**: 原生支持 SaaS 多租户场景
6. **高可用**: 支持集群部署,无状态设计
---
## 架构设计原则
### 1. 单一职责原则 (SRP)
每个模块、每个类只负责一个职责。
**示例**:
- `UserController` 只负责接收 HTTP 请求
- `UserService` 只负责业务逻辑处理
- `UserMapper` 只负责数据库操作
### 2. 开闭原则 (OCP)
对扩展开放,对修改关闭。
**示例**:
- 通过实现接口扩展功能,而非修改原有代码
- 使用策略模式实现不同的支付方式
### 3. 里氏替换原则 (LSP)
子类可以替换父类。
**示例**:
- `UserServiceImpl` 可以替换 `UserService`
- `BaseMapperX` 可以替换 `BaseMapper`
### 4. 接口隔离原则 (ISP)
使用多个细粒度的接口,而非单一的总接口。
**示例**:
- `UserService``RoleService``MenuService` 各司其职
- 前端 API 按模块划分(`/system/user``/system/role`
### 5. 依赖倒置原则 (DIP)
高层模块不依赖低层模块,都依赖于抽象。
**示例**:
- Controller 依赖 Service 接口,而非实现
- Service 依赖 Mapper 接口,而非实现
### 6. 迪米特法则 (LoD)
最少知识原则,模块之间尽量少交互。
**示例**:
- 模块之间通过 API 接口交互
- 避免跨层调用(如 Controller 直接调用 Mapper
---
## 分层架构
### 应用分层
```
┌─────────────────────────────────────────────────────────────┐
│ Controller 层 │
│ • 接收 HTTP 请求 │
│ • 参数校验 │
│ • 调用 Service 层 │
│ • 返回响应 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Service 层 │
│ • 业务逻辑处理 │
│ • 事务控制 │
│ • 调用 DAL 层 │
│ • 返回处理结果 │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ DAL 层 │
│ • 数据访问 │
│ • 数据库操作 │
│ • 缓存操作 │
│ • 返回数据对象 │
└─────────────────────────────────────────────────────────────┘
```
### 层次交互规则
1. **自上而下调用**: Controller → Service → DAL
2. **跨层访问**: 允许 Service 直接调用多个 DAL
3. **禁止反向调用**: 下层不能调用上层
4. **同层交互**: 同层之间通过接口交互
### 分层示例
#### Controller 层
```java
@RestController
@RequestMapping("/system/user")
@Tag(name = "管理后台 - 用户")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/create")
@Operation(summary = "创建用户")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO reqVO) {
return success(userService.createUser(reqVO));
}
@GetMapping("/get")
@Operation(summary = "获取用户详情")
public CommonResult<UserRespVO> getUser(@RequestParam("id") Long id) {
return success(userService.getUser(id));
}
}
```
#### Service 层
```java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private DeptMapper deptMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createUser(UserCreateReqVO reqVO) {
// 业务逻辑
UserDO user = UserConvert.INSTANCE.convert(reqVO);
userMapper.insert(user);
return user.getId();
}
@Override
public UserRespVO getUser(Long id) {
UserDO user = userMapper.selectById(id);
DeptDO dept = deptMapper.selectById(user.getDeptId());
return UserConvert.INSTANCE.convert(user, dept);
}
}
```
#### DAL 层
```java
@Mapper
public interface UserMapper extends BaseMapperX<UserDO> {
default UserDO selectByUsername(String username) {
return selectOne("username", username);
}
default PageResult<UserDO> selectPage(UserPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<UserDO>()
.likeIfPresent(UserDO::getUsername, pageReqVO.getUsername())
.betweenIfPresent(UserDO::getCreateTime, pageReqVO.getCreateTime())
.orderByDesc(UserDO::getId));
}
}
```
---
## 模块化设计
### 模块划分
项目按照**领域驱动设计DDD**思想进行模块划分。
#### 基础模块
| 模块 | 职责 |
|------|------|
| lyzsys-dependencies | 依赖版本管理 |
| lyzsys-framework | 框架组件封装 |
| lyzsys-server | 应用启动入口 |
#### 业务模块
| 模块 | 领域 | 职责 |
|------|------|------|
| lyzsys-module-system | 系统管理 | 用户、角色、菜单、部门、字典等 |
| lyzsys-module-infra | 基础设施 | 代码生成、文件、配置、任务等 |
| lyzsys-module-bpm | 工作流 | 流程定义、流程实例、任务管理 |
| lyzsys-module-pay | 支付 | 支付订单、退款、回调 |
| lyzsys-module-member | 会员 | 会员、积分、等级 |
| lyzsys-module-mall | 商城 | 商品、订单、营销 |
| lyzsys-module-crm | CRM | 客户、商机、合同 |
| lyzsys-module-erp | ERP | 采购、销售、库存 |
| lyzsys-module-ai | AI | AI 聊天、绘图、知识库 |
| lyzsys-module-mp | 微信公众号 | 公众号管理、粉丝、消息 |
| lyzsys-module-iot | IoT | 设备、产品、数据采集 |
| lyzsys-module-report | 报表 | 报表设计、大屏设计 |
### 模块结构
每个业务模块都遵循统一的结构:
```
lyzsys-module-xxx/
├── api/ # 对外 API
│ ├── xxxApi.java
│ └── xxxApiImpl.java
├── controller/ # 控制器
│ ├── admin/ # 管理后台 API
│ │ ├── xxxController.java
│ │ └── vo/
│ │ ├── xxxReqVO.java
│ │ └── xxxRespVO.java
│ └── app/ # 用户 App API
│ └── xxxController.java
├── service/ # 服务层
│ ├── xxxService.java
│ └── xxxServiceImpl.java
├── dal/ # 数据访问层
│ ├── dataobject/ # 数据对象
│ │ └── xxxDO.java
│ ├── mysql/ # MySQL Mapper
│ │ └── xxxMapper.java
│ └── redis/ # Redis DAO
│ └── xxxRedisDAO.java
├── convert/ # 对象转换
│ └── xxxConvert.java
├── enums/ # 枚举
│ └── xxxEnum.java
└── framework/ # 框架配置
└── xxxConfiguration.java
```
### 模块交互
#### 模块间调用规则
1. **禁止直接依赖**: 模块之间不能直接依赖
2. **通过 API 调用**: 通过 API 接口进行调用
3. **事件驱动**: 通过消息队列进行异步通信
#### 示例
```java
// mall 模块调用 pay 模块
@DubboReference
private PayOrderApi payOrderApi;
public void createOrder(OrderCreateReqVO reqVO) {
// 创建订单
OrderDO order = createOrder(reqVO);
// 调用支付模块
PayOrderCreateReqDTO payReq = new PayOrderCreateReqDTO();
payReq.setOrderId(order.getId());
payOrderApi.createOrder(payReq);
}
```
---
## 数据架构
### 数据存储
```
┌─────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ MinIO │ │
│ │ (主数据库) │ │ (缓存) │ │ (文件存储) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 数据库设计
#### 表命名规范
- 格式: `{模块}_{业务}_{实体}`
- 示例: `system_users``system_roles``mall_orders`
#### 字段命名规范
- 小写字母 + 下划线
- 示例: `user_id``user_name``create_time`
#### 通用字段
每张表都包含以下通用字段:
```sql
id BIGINT 主键
create_time DATETIME 创建时间
update_time DATETIME 更新时间
creator VARCHAR(64) 创建人
updater VARCHAR(64) 更新人
deleted BIT 是否删除
tenant_id BIGINT 租户 ID (多租户表)
```
### 多租户数据隔离
#### 策略
- **共享数据库、共享 Schema**: 所有租户共享数据库,通过 `tenant_id` 隔离
- **自动过滤**: MyBatis Plus 拦截器自动添加租户条件
#### 实现
```java
@TableName("system_users")
public class UserDO extends TenantBaseDO {
private Long id;
private String username;
// tenant_id 由 TenantBaseDO 提供
}
// 查询时自动过滤
List<UserDO> users = userMapper.selectList();
// SQL: SELECT * FROM system_users WHERE deleted = 0 AND tenant_id = ?
```
### 缓存设计
#### 缓存策略
1. **本地缓存**: Caffeine本地缓存
2. **分布式缓存**: Redis分布式缓存
#### 缓存使用
```java
// 使用 Spring Cache
@Cacheable(value = "user", key = "#id")
public UserDO getUser(Long id) {
return userMapper.selectById(id);
}
// 使用 RedisTemplate
@Service
public class UserServiceImpl {
@Autowired
private 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;
}
}
```
---
## 安全架构
### 认证授权
#### 认证流程
```
1. 用户登录
2. 后端验证用户名密码
3. 生成 JWT Token
4. 返回 Token 给前端
5. 前端存储 Token
6. 后续请求携带 Token
7. 后端验证 Token
8. 允许访问
```
#### 授权模型
```
用户 (User)
角色 (Role)
权限 (Permission)
资源 (Resource)
```
### 数据权限
#### 权限范围
| 权限范围 | 说明 |
|---------|------|
| 全部数据权限 | 查看所有数据 |
| 本部门数据权限 | 只能查看本部门数据 |
| 本部门及以下数据权限 | 查看本部门及子部门数据 |
| 仅本人数据权限 | 只能查看自己的数据 |
| 自定义数据权限 | 自定义数据权限规则 |
#### 实现
```java
@DataScope(deptAlias = "d", userAlias = "u")
public List<UserDO> getUserList() {
return userMapper.selectList();
}
// SQL 自动添加
// AND (d.id = ? OR d.id IN (?, ?) OR u.id = ?)
```
### API 安全
#### 接口加密
```java
// 请求加密
@PostMapping("/create")
public CommonResult<Long> createUser(@RequestBody String encryptedData) {
// 解密
String json = decrypt(encryptedData);
UserCreateReqVO reqVO = JSON.parseObject(json, UserCreateReqVO.class);
// 业务处理
Long id = userService.createUser(reqVO);
// 加密返回
return success(encrypt(id));
}
```
#### 接口签名
```java
// 请求签名
@PostMapping("/create")
public CommonResult<Long> createUser(
@RequestHeader("X-Signature") String signature,
@RequestBody UserCreateReqVO reqVO
) {
// 验证签名
if (!verifySignature(signature, reqVO)) {
return error(401, "签名验证失败");
}
// 业务处理
return success(userService.createUser(reqVO));
}
```
---
## 技术架构
### 技术选型
#### 后端技术栈
| 技术 | 版本 | 用途 |
|------|------|------|
| Spring Boot | 2.7.18 | 应用框架 |
| Spring Security | 5.8.16 | 安全框架 |
| MyBatis Plus | 3.5.15 | ORM 框架 |
| Flowable | 6.8.0 | 工作流引擎 |
| Quartz | 2.3.2 | 定时任务 |
| Redisson | 3.52.0 | 分布式锁 |
| Knife4j | 3.0.3 | API 文档 |
#### 前端技术栈
| 技术 | 版本 | 用途 |
|------|------|------|
| Vue | 3.2+ | 前端框架 |
| TypeScript | 4.x | 类型系统 |
| Vite | 4.x | 构建工具 |
| Element Plus | 2.x | UI 组件库 |
| Pinia | 2.x | 状态管理 |
### 框架封装
#### Web 封装
- 全局异常处理
- 统一响应格式
- 请求日志记录
- 参数校验
#### 安全封装
- JWT 认证
- 权限注解
- 数据权限
- API 加密
#### 数据库封装
- BaseMapperX
- LambdaQueryWrapperX
- 分页插件
- 租户插件
---
## 部署架构
### 单机部署
```
┌─────────────────────────────────────────────────────────────┐
│ 服务器 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Nginx │ │ JDK 8 │ │ MySQL │ │
│ │ (前端) │ │ (后端) │ │ (数据库) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Redis │ │ MinIO │ │
│ │ (缓存) │ │ (文件存储) │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 集群部署
```
┌─────────────────────────────────────────────────────────────┐
│ 负载均衡 │
│ (Nginx / F5) │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 应用服务器 1 │ │ 应用服务器 2 │ │ 应用服务器 3 │
│ (后端服务) │ │ (后端服务) │ │ (后端服务) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└────────────────┼────────────────┘
┌─────────────────┐
│ MySQL 主从 │
│ Redis 集群 │
└─────────────────┘
```
### 容器化部署
```
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │
│ │ (后端服务) │ │ (后端服务) │ │ (后端服务) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ MinIO │ │
│ │ (StatefulSet)│ │ (StatefulSet)│ │ (Deployment)│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
---
## 性能优化
### 数据库优化
1. **索引优化**: 合理创建索引
2. **SQL 优化**: 避免全表扫描
3. **分页查询**: 使用分页插件
4. **读写分离**: 主从数据库配置
5. **连接池**: Druid 连接池优化
### 缓存优化
1. **本地缓存**: Caffeine 本地缓存
2. **分布式缓存**: Redis 缓存
3. **缓存预热**: 系统启动时加载热点数据
4. **缓存更新**: 定时更新缓存
### 接口优化
1. **批量操作**: 批量插入、批量更新
2. **异步处理**: 消息队列异步处理
3. **接口合并**: 减少请求次数
4. **压缩传输**: Gzip 压缩
### 前端优化
1. **代码分割**: 路由懒加载
2. **资源压缩**: Gzip、Brotli 压缩
3. **CDN 加速**: 静态资源 CDN
4. **浏览器缓存**: 合理设置缓存策略
---
## 扩展性设计
### 水平扩展
1. **应用集群**: 多台应用服务器
2. **数据库集群**: 主从、分库分表
3. **缓存集群**: Redis 集群
4. **文件存储**: 分布式文件系统
### 垂直扩展
1. **升级硬件**: CPU、内存、磁盘
2. **优化配置**: JVM、数据库参数
### 微服务化
1. **模块拆分**: 按业务模块拆分
2. **服务注册**: Nacos、Eureka
3. **服务调用**: Dubbo、Feign
4. **网关路由**: Spring Cloud Gateway
---
**文档版本**: v1.0.0
**最后更新**: 2025-01-19
**维护团队**: Lyzsys 架构团队

805
doc/部署指南.md Normal file
View File

@@ -0,0 +1,805 @@
# Lyzsys 部署指南
## 📖 目录
- [部署概述](#部署概述)
- [环境准备](#环境准备)
- [后端部署](#后端部署)
- [前端部署](#前端部署)
- [数据库部署](#数据库部署)
- [缓存部署](#缓存部署)
- [文件存储部署](#文件存储部署)
- [生产环境部署](#生产环境部署)
- [容器化部署](#容器化部署)
- [监控部署](#监控部署)
---
## 部署概述
### 部署架构
```
┌─────────────────────────────────────────────────────────────┐
│ 用户端 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PC 浏览器 │ │ 移动 App │ │ 小程序 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Nginx │
│ (反向代理 + 静态资源) │
└─────────────────────────────────────────────────────────────┘
┌─────────────┴─────────────┐
│ │
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ 前端静态资源 │ │ 后端 API 服务 │
│ (Vue3 SPA 应用) │ │ (Spring Boot 应用) │
└──────────────────────────┘ └──────────────────────────┘
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ MySQL │ │ Redis │ │ MinIO │
│ (主数据库) │ │ (缓存/会话) │ │ (文件存储) │
└──────────────────┘ └──────────────────┘ └──────────────────┘
```
### 部署方式
1. **传统部署**: 直接在服务器上部署
2. **Docker 部署**: 使用 Docker 容器部署
3. **Kubernetes 部署**: 使用 K8s 编排部署
---
## 环境准备
### 服务器要求
#### 最低配置
| 组件 | CPU | 内存 | 硬盘 |
|------|-----|------|------|
| 后端服务 | 2核 | 4GB | 20GB |
| MySQL | 1核 | 2GB | 50GB |
| Redis | 1核 | 1GB | 10GB |
| 前端 | 1核 | 1GB | 10GB |
#### 推荐配置
| 组件 | CPU | 内存 | 硬盘 |
|------|-----|------|------|
| 后端服务 | 4核 | 8GB | 50GB |
| MySQL | 4核 | 16GB | 500GB |
| Redis | 2核 | 4GB | 50GB |
| 前端 | 2核 | 2GB | 20GB |
### 软件要求
| 软件 | 版本 | 用途 |
|------|------|------|
| JDK | 8+ | 后端运行环境 |
| MySQL | 5.7+ / 8.0+ | 数据库 |
| Redis | 5.0+ | 缓存 |
| Nginx | 1.18+ | Web 服务器 |
| Node.js | 16+ | 前端构建 |
| Docker | 20.10+ | 容器化(可选) |
---
## 后端部署
### 方式一: JAR 包部署
#### 1. 打包项目
```bash
cd lyzsys_backend
mvn clean package -DskipTests
```
生成的 JAR 包位于 `lyzsys-server/target/lyzsys-server.jar`
#### 2. 上传文件
将 JAR 包上传到服务器:
```bash
scp lyzsys-server/target/lyzsys-server.jar user@server:/opt/lyzsys/
```
#### 3. 配置文件
创建配置文件 `application-prod.yaml`:
```yaml
spring:
# 数据源配置
datasource:
url: jdbc:mysql://mysql-server:3306/lyzsys?useSSL=false&serverTimezone=Asia/Shanghai
username: lyzsys
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
# Redis 配置
redis:
host: redis-server
port: 6379
database: 1
password: your_redis_password
# 项目配置
lyzsys:
web:
api-prefix: /admin-api
security:
mock-enable: false
upload:
base-url: http://your-domain.com
```
#### 4. 启动服务
```bash
# 启动服务
java -jar lyzsys-server.jar --spring.profiles.active=prod
# 后台启动
nohup java -jar lyzsys-server.jar --spring.profiles.active=prod > lyzsys.log 2>&1 &
# 指定内存启动
java -Xms512m -Xmx1024m -jar lyzsys-server.jar --spring.profiles.active=prod
```
#### 5. 创建系统服务
创建 `/etc/systemd/system/lyzsys.service`:
```ini
[Unit]
Description=Lyzsys Server
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/bin/java -jar /opt/lyzsys/lyzsys-server.jar --spring.profiles.active=prod
ExecStop=/bin/kill -15 $MAINPID
User=lyzsys
Group=lyzsys
WorkingDirectory=/opt/lyzsys
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
启动服务:
```bash
# 重载配置
systemctl daemon-reload
# 启动服务
systemctl start lyzsys
# 开机启动
systemctl enable lyzsys
# 查看状态
systemctl status lyzsys
```
### 方式二: Docker 部署
#### 1. 创建 Dockerfile
创建 `Dockerfile`:
```dockerfile
FROM openjdk:8-jre-slim
LABEL maintainer="lyzsys"
# 设置工作目录
WORKDIR /opt/lyzsys
# 复制 JAR 包
COPY lyzsys-server/target/lyzsys-server.jar app.jar
# 暴露端口
EXPOSE 48080
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
```
#### 2. 构建镜像
```bash
docker build -t lyzsys/lyzsys-server:latest .
```
#### 3. 运行容器
```bash
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=lyzsys \
-e SPRING_DATASOURCE_PASSWORD=your_password \
-e SPRING_DATA_REDIS_HOST=redis \
-e SPRING_DATA_REDIS_PASSWORD=your_redis_password \
lyzsys/lyzsys-server:latest
```
#### 4. 使用 Docker Compose
创建 `docker-compose.yml`:
```yaml
version: '3.8'
services:
lyzsys-server:
image: lyzsys/lyzsys-server:latest
container_name: lyzsys-server
ports:
- "48080:48080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/lyzsys
- SPRING_DATASOURCE_USERNAME=lyzsys
- SPRING_DATASOURCE_PASSWORD=your_password
- SPRING_DATA_REDIS_HOST=redis
- SPRING_DATA_REDIS_PASSWORD=your_redis_password
depends_on:
- mysql
- redis
restart: always
```
启动:
```bash
docker-compose up -d
```
---
## 前端部署
### 方式一: Nginx 部署
#### 1. 构建项目
```bash
cd lyzsys-ui-admin
# 安装依赖
pnpm install
# 构建生产版本
pnpm build:prod
```
生成的文件位于 `dist/` 目录
#### 2. 上传文件
`dist/` 目录上传到服务器:
```bash
scp -r dist/* user@server:/var/www/lyzsys/
```
#### 3. 配置 Nginx
创建 Nginx 配置 `/etc/nginx/conf.d/lyzsys.conf`:
```nginx
server {
listen 80;
server_name your-domain.com;
root /var/www/lyzsys;
index index.html;
# 前端路由
location / {
try_files $uri $uri/ /index.html;
}
# API 代理
location /admin-api/ {
proxy_pass http://localhost:48080/admin-api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1024;
}
```
#### 4. 重启 Nginx
```bash
nginx -t
nginx -s reload
```
### 方式二: Docker 部署
#### 1. 创建 Dockerfile
创建 `Dockerfile`:
```dockerfile
FROM nginx:alpine
# 复制构建文件
COPY dist/ /usr/share/nginx/html/
# 复制 Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]
```
#### 2. 构建镜像
```bash
docker build -t lyzsys/lyzsys-ui-admin:latest .
```
#### 3. 运行容器
```bash
docker run -d \
--name lyzsys-ui-admin \
-p 80:80 \
lyzsys/lyzsys-ui-admin:latest
```
---
## 数据库部署
### MySQL 部署
#### 1. 安装 MySQL
```bash
# CentOS/RHEL
yum install -y mysql-server
# Ubuntu/Debian
apt-get install -y mysql-server
```
#### 2. 配置 MySQL
编辑 `/etc/my.cnf`:
```ini
[mysqld]
# 基础配置
port = 3306
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 连接配置
max_connections = 500
max_connect_errors = 100
# 缓存配置
innodb_buffer_pool_size = 1G
query_cache_size = 128M
# 日志配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
```
#### 3. 创建数据库
```bash
mysql -u root -p
CREATE DATABASE lyzsys CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'lyzsys'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON lyzsys.* TO 'lyzsys'@'%';
FLUSH PRIVILEGES;
```
#### 4. 导入数据
```bash
mysql -u lyzsys -p lyzsys < lyzsys.sql
```
### Docker 部署 MySQL
```bash
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=root_password \
-e MYSQL_DATABASE=lyzsys \
-e MYSQL_USER=lyzsys \
-e MYSQL_PASSWORD=your_password \
-v /data/mysql:/var/lib/mysql \
mysql:8.0
```
---
## 缓存部署
### Redis 部署
#### 1. 安装 Redis
```bash
# CentOS/RHEL
yum install -y redis
# Ubuntu/Debian
apt-get install -y redis-server
```
#### 2. 配置 Redis
编辑 `/etc/redis/redis.conf`:
```ini
# 绑定地址
bind 0.0.0.0
# 端口
port 6379
# 密码
requirepass your_redis_password
# 持久化
save 900 1
save 300 10
save 60 10000
# 最大内存
maxmemory 1gb
maxmemory-policy allkeys-lru
```
#### 3. 启动 Redis
```bash
# 启动 Redis
redis-server /etc/redis/redis.conf
# 或使用 systemd
systemctl start redis
systemctl enable redis
```
### Docker 部署 Redis
```bash
docker run -d \
--name redis \
-p 6379:6379 \
-v /data/redis:/data \
redis:7-alpine \
redis-server --appendonly yes --requirepass your_redis_password
```
---
## 文件存储部署
### MinIO 部署
#### 1. Docker 部署 MinIO
```bash
docker run -d \
--name minio \
-p 9000:9000 \
-p 9001:9001 \
-e MINIO_ROOT_USER=admin \
-e MINIO_ROOT_PASSWORD=admin123 \
-v /data/minio:/data \
minio/minio server /data --console-address ":9001"
```
#### 2. 配置 MinIO
1. 访问 http://localhost:9001
2. 登录admin / admin123
3. 创建 Bucket: `lyzsys`
4. 创建 Access Key 和 Secret Key
5. 配置后端 `application.yaml`:
```yaml
lyzsys:
storage:
minio:
endpoint: http://localhost:9000
access-key: your_access_key
secret-key: your_secret_key
bucket-name: lyzsys
```
---
## 生产环境部署
### 安全配置
#### 1. 配置防火墙
```bash
# 开放必要端口
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=48080/tcp
firewall-cmd --reload
```
#### 2. 配置 SSL 证书
使用 Let's Encrypt 免费证书:
```bash
# 安装 certbot
yum install -y certbot
# 获取证书
certbot certonly --standalone -d your-domain.com
# 证书位置
# /etc/letsencrypt/live/your-domain.com/fullchain.pem
# /etc/letsencrypt/live/your-domain.com/privkey.pem
```
配置 Nginx SSL
```nginx
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# ... 其他配置
}
# HTTP 跳转 HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
```
### 性能优化
#### 1. MySQL 优化
```ini
# my.cnf
[mysqld]
innodb_buffer_pool_size = 4G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
```
#### 2. Redis 优化
```ini
# redis.conf
maxmemory 2gb
maxmemory-policy allkeys-lru
save ""
```
#### 3. JVM 优化
```bash
java -Xms2g -Xmx2g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/opt/lyzsys/logs/ \
-jar lyzsys-server.jar
```
---
## 容器化部署
### Docker Compose 完整部署
创建 `docker-compose.yml`:
```yaml
version: '3.8'
services:
# MySQL
mysql:
image: mysql:8.0
container_name: lyzsys-mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=lyzsys
- MYSQL_USER=lyzsys
- MYSQL_PASSWORD=your_password
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
restart: always
# Redis
redis:
image: redis:7-alpine
container_name: lyzsys-redis
command: redis-server --appendonly yes --requirepass your_redis_password
volumes:
- redis-data:/data
ports:
- "6379:6379"
restart: always
# MinIO
minio:
image: minio/minio
container_name: lyzsys-minio
environment:
- MINIO_ROOT_USER=admin
- MINIO_ROOT_PASSWORD=admin123
volumes:
- minio-data:/data
ports:
- "9000:9000"
- "9001:9001"
command: server /data --console-address ":9001"
restart: always
# 后端服务
backend:
image: lyzsys/lyzsys-server:latest
container_name: lyzsys-backend
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/lyzsys
- SPRING_DATASOURCE_USERNAME=lyzsys
- SPRING_DATASOURCE_PASSWORD=your_password
- SPRING_DATA_REDIS_HOST=redis
- SPRING_DATA_REDIS_PASSWORD=your_redis_password
ports:
- "48080:48080"
depends_on:
- mysql
- redis
restart: always
# 前端服务
frontend:
image: lyzsys/lyzsys-ui-admin:latest
container_name: lyzsys-frontend
ports:
- "80:80"
depends_on:
- backend
restart: always
volumes:
mysql-data:
redis-data:
minio-data:
```
启动:
```bash
docker-compose up -d
```
---
## 监控部署
### Spring Boot Admin
#### 1. 添加依赖
```xml
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
```
#### 2. 配置应用
```yaml
spring:
application:
name: lyzsys-admin-server
server:
port: 48081
```
#### 3. 客户端配置
```yaml
spring:
boot:
admin:
client:
url: http://localhost:48081
```
### SkyWalking
#### 1. 安装 SkyWalking
```bash
docker run -d \
--name skywalking \
-p 11800:11800 \
-p 12800:12800 \
apache/skywalking-oap-server
```
#### 2. 配置 Agent
```bash
java -javaagent:/path/to/skywalking-agent.jar \
-Dskywalking.agent.service_name=lyzsys \
-Dskywalking.collector.backend_service=localhost:11800 \
-jar lyzsys-server.jar
```
---
**文档版本**: v1.0.0
**最后更新**: 2025-01-19
**维护团队**: Lyzsys 运维团队

508
doc/项目介绍.md Normal file
View File

@@ -0,0 +1,508 @@
# Lyzsys 项目介绍
## 📖 目录
- [项目简介](#项目简介)
- [核心特性](#核心特性)
- [技术架构](#技术架构)
- [功能模块](#功能模块)
- [快速开始](#快速开始)
- [项目展示](#项目展示)
- [适用场景](#适用场景)
- [开源协议](#开源协议)
---
## 项目简介
Lyzsys 是一个**企业级后台管理系统**,基于 Spring Boot + Vue 3 技术栈构建采用前后端分离架构。项目集成了丰富的企业级功能包括权限管理、工作流、多租户、AI 集成等,适用于各类企业管理系统的快速开发。
### 项目定位
- **快速开发平台**: 提供完整的代码生成器和脚手架,快速构建业务系统
- **企业级框架**: 内置权限、工作流、多租户等企业通用功能
- **微服务就绪**: 模块化设计,便于未来微服务化改造
- **AI 集成**: 原生支持多个 AI 服务提供商,便于构建智能化应用
### 版本说明
| 版本 | JDK 8 + Spring Boot 2.7 | JDK 17/21 + Spring Boot 3.2 |
|------|-------------------------|----------------------------|
| 【完整版】lyzsys | `master` 分支 | `master-jdk17` 分支 |
| 【精简版】lyzsys-mini | `mini` 分支 | `mini-jdk17` 分支 |
- **完整版**: 包括系统功能、基础设施、工作流、商城、CRM、ERP、AI 等所有模块
- **精简版**: 只包括系统功能和基础设施,适用于简单场景
---
## 核心特性
### 🎯 技术特性
#### 1. 模块化架构
- **Maven 多模块**: 清晰的模块划分,便于维护和扩展
- **前后端分离**: 独立部署,提升开发效率
- **微服务就绪**: 模块化设计便于微服务化改造
#### 2. 权限管理
- **RBAC 权限模型**: 基于角色的访问控制
- **数据权限**: 支持全部、本部门、本部门及以下、仅本人等数据权限
- **按钮级权限**: 细粒度的功能权限控制
- **动态菜单**: 根据权限动态生成菜单
#### 3. 多租户支持
- **SaaS 多租户**: 原生支持多租户场景
- **租户隔离**: 数据库级别的租户隔离
- **租户套餐**: 灵活的租户权限配置
#### 4. 工作流引擎
- **Flowable 集成**: 强大的工作流引擎
- **双设计器**: BPMN 标准设计器 + 仿钉钉/飞书简易设计器
- **流程管理**: 支持会签、或签、驳回、转办、委派等复杂流程操作
#### 5. AI 集成
- **多 AI 支持**: 支持 OpenAI、通义千问、文心一言等多个 AI 服务
- **AI 聊天**: 内置 AI 对话功能
- **AI 绘图**: 支持 AI 图片生成
- **知识库**: AI 知识库管理和检索
#### 6. 开发效率
- **代码生成器**: 一键生成前后端代码、SQL 脚本、接口文档
- **在线表单**: 拖拽式表单设计器
- **报表设计**: 可视化报表和大屏设计器
- **API 文档**: 自动生成 Swagger/Knife4j 接口文档
### 🛡️ 安全特性
- **Spring Security**: 企业级安全框架
- **JWT 认证**: 无状态认证机制
- **密码加密**: BCrypt 加密存储
- **API 加密**: 支持请求/响应加密
- **XSS 防护**: 内置 XSS 过滤器
- **操作日志**: 完整的操作审计日志
### ⚡ 性能特性
- **Redis 缓存**: 高性能缓存支持
- **数据库优化**: MyBatis Plus 增强,支持分页、排序、筛选
- **分布式锁**: 基于 Redisson 的分布式锁
- **消息队列**: 异步处理提升性能
- **连接池**: Druid 监控的数据库连接池
---
## 技术架构
### 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ 前端应用 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ lyzsys-ui- │ │ lyzsys-ui- │ │ lyzsys-mall- │ │
│ │ admin-vue3 │ │ admin-uniapp │ │ uniapp │ │
│ │ (PC端管理) │ │ (移动端管理) │ │ (用户App) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ lyzsys-server │
│ (后端服务启动模块) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ lyzsys- │ │ lyzsys-module-xxx│ │lyzsys- │
│ framework │ │ (业务模块) │ │dependencies │
│ (框架组件) │ │ │ │ (依赖管理) │
└──────────────┘ └──────────────────┘ └──────────────┘
├─── lyzsys-common (通用组件)
├─── lyzsys-spring-boot-starter-web (Web 封装)
├─── lyzsys-spring-boot-starter-security (安全认证)
├─── lyzsys-spring-boot-starter-mybatis (数据库)
├─── lyzsys-spring-boot-starter-redis (缓存)
├─── lyzsys-spring-boot-starter-biz-tenant (多租户)
└─── ...
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ MySQL │ │ Redis │ │ MinIO │
│ (主数据库) │ │ (缓存数据库) │ │ (文件存储) │
└──────────────┘ └──────────────────┘ └──────────────┘
```
### 技术选型
#### 后端技术栈
| 技术 | 版本 | 说明 |
|------|------|------|
| Spring Boot | 2.7.18 | 应用开发框架 |
| Spring Security | 5.8.16 | 安全框架 |
| MyBatis Plus | 3.5.15 | ORM 增强框架 |
| Flowable | 6.8.0 | 工作流引擎 |
| Redisson | 3.52.0 | 分布式锁客户端 |
| Quartz | 2.3.2 | 定时任务 |
| Knife4j | 3.0.3 | API 文档 |
| MySQL | 5.7+ | 关系型数据库 |
| Redis | 5.0+ | 缓存数据库 |
#### 前端技术栈
| 技术 | 版本 | 说明 |
|------|------|------|
| Vue | 3.2+ | 渐进式 JavaScript 框架 |
| TypeScript | 4.x | JavaScript 超集 |
| Vite | 4.x | 构建工具 |
| Element Plus | 2.x | UI 组件库 |
| Pinia | 2.x | 状态管理 |
| Vue Router | 4.x | 路由管理 |
| ECharts | 5.x | 数据可视化 |
| WangEditor | 5.x | 富文本编辑器 |
---
## 功能模块
### 核心模块(必选)
#### 1. 系统功能模块 (lyzsys-module-system)
提供系统基础功能,是整个系统的基础。
| 功能 | 说明 |
|------|------|
| 用户管理 | 用户的增删改查、密码重置、导入导出 |
| 角色管理 | 角色权限分配、数据权限配置 |
| 菜单管理 | 动态菜单配置、按钮权限标识 |
| 部门管理 | 组织机构树形结构管理 |
| 岗位管理 | 用户岗位配置 |
| 字典管理 | 系统字典项维护 |
| 参数配置 | 系统动态参数配置 |
| 通知公告 | 系统通知发布管理 |
| 操作日志 | 用户操作审计日志 |
| 登录日志 | 登录成功/失败日志 |
| 在线用户 | 当前在线用户监控,支持踢出 |
| 租户管理 | SaaS 租户配置 |
| 租户套餐 | 租户权限套餐管理 |
#### 2. 基础设施模块 (lyzsys-module-infra)
提供技术基础设施功能。
| 功能 | 说明 |
|------|------|
| 代码生成 | 可视化代码生成,支持单表、树表、主子表 |
| 表单构建 | 拖拽式表单设计器 |
| 系统接口 | Swagger/Knife4j 接口文档 |
| 数据库文档 | Screw 自动生成数据库文档 |
| 文件管理 | 支持本地、MinIO、阿里云、腾讯云等存储 |
| 定时任务 | Quartz 在线定时任务管理 |
| API 日志 | 接口访问日志、异常日志 |
| MySQL 监控 | 数据库连接池监控 |
| Redis 监控 | Redis 使用情况监控 |
| 服务监控 | Spring Boot Admin 监控 |
| 链路追踪 | SkyWalking 链路追踪集成 |
| 日志中心 | 远程日志查看 |
| 服务保障 | 分布式锁、幂等、限流、熔断 |
| 消息队列 | Redis 消息队列支持 |
### 业务模块(可选)
#### 3. 工作流模块 (lyzsys-module-bpm)
基于 Flowable 的业务流程管理。
| 功能 | 说明 |
|------|------|
| 流程模型 | BPMN 2.0 流程建模 |
| 流程设计 | BPMN 设计器 + 简易设计器 |
| 流程实例 | 流程实例管理、发起、审批 |
| 任务管理 | 待办、已办、抄送任务 |
| 表单管理 | 流程表单配置 |
| 流程监听 | 流程事件监听配置 |
#### 4. 支付模块 (lyzsys-module-pay)
统一的支付接入平台。
| 功能 | 说明 |
|------|------|
| 应用管理 | 支付应用配置 |
| 支付渠道 | 微信支付、支付宝等渠道接入 |
| 支付订单 | 支付订单管理 |
| 退款订单 | 退款订单管理 |
| 回调通知 | 支付回调处理 |
#### 5. 会员模块 (lyzsys-module-member)
C 端会员管理功能。
| 功能 | 说明 |
|------|------|
| 会员管理 | 会员信息管理 |
| 会员标签 | 会员标签体系 |
| 会员等级 | 会员等级配置 |
| 会员分组 | 会员分组管理 |
| 积分签到 | 积分规则、签到记录 |
#### 6. 商城模块 (lyzsys-module-mall)
完整的电商系统。
| 功能 | 说明 |
|------|------|
| 商品管理 | 商品、分类、品牌管理 |
| 营销管理 | 优惠券、满减、秒杀等活动 |
| 订单管理 | 订单、售后、退款管理 |
| 购物车 | 购物车管理 |
| 收货地址 | 用户地址管理 |
| 物流管理 | 物流公司、物流跟踪 |
| 统计分析 | 销售统计、商品分析 |
#### 7. CRM 模块 (lyzsys-module-crm)
客户关系管理。
| 功能 | 说明 |
|------|------|
| 客户管理 | 客户信息管理 |
| 联系人 | 客户联系人管理 |
| 商机管理 | 销售商机跟进 |
| 合同管理 | 合同签订、管理 |
| 回款管理 | 回款计划、记录 |
| 产品管理 | CRM 产品管理 |
#### 8. ERP 模块 (lyzsys-module-erp)
企业资源计划。
| 功能 | 说明 |
|------|------|
| 采购管理 | 采购订单、入库单 |
| 销售管理 | 销售订单、出库单 |
| 库存管理 | 库存查询、库存预警 |
| 产品管理 | 产品、物料管理 |
| 供应商管理 | 供应商信息管理 |
#### 9. AI 模块 (lyzsys-module-ai)
AI 大模型集成。
| 功能 | 说明 |
|------|------|
| AI 聊天 | 对话式 AI 交互 |
| AI 绘图 | AI 图片生成 |
| 知识库 | AI 知识库管理 |
| API 管理 | AI API 密钥管理 |
#### 10. 报表模块 (lyzsys-module-report)
数据报表和大屏。
| 功能 | 说明 |
|------|------|
| 报表设计 | 可视化报表设计器 |
| 大屏设计 | 拖拽式大屏设计器 |
| 数据源 | 多种数据源支持 |
#### 11. 微信公众号 (lyzsys-module-mp)
微信公众号管理。
| 功能 | 说明 |
|------|------|
| 账号管理 | 公众号配置 |
| 粉丝管理 | 粉丝信息、标签管理 |
| 消息管理 | 消息发送、接收 |
| 自动回复 | 关注、关键词、消息回复 |
| 菜单管理 | 公众号菜单配置 |
| 素材管理 | 图片、视频等素材管理 |
| 图文管理 | 图文素材管理 |
#### 12. IoT 物联网 (lyzsys-module-iot)
物联网设备管理。
| 功能 | 说明 |
|------|------|
| 设备管理 | 设备注册、管理 |
| 产品管理 | IoT 产品定义 |
| 属性定义 | 设备属性配置 |
| 数据采集 | 设备数据采集 |
| 场景联动 | 设备场景规则 |
---
## 快速开始
### 环境要求
| 软件 | 版本要求 | 必需 |
|------|----------|------|
| JDK | 8+ | √ |
| MySQL | 5.7+ | √ |
| Redis | 5.0+ | √ |
| Node.js | 16+ | √ |
| Maven | 3.6+ | √ |
### 后端启动
```bash
# 1. 克隆项目
git clone https://github.com/your-org/lyzsys.git
cd lyzsys/lyzsys_backend
# 2. 导入数据库
mysql -u root -p < sql/lyzsys.sql
# 3. 修改配置
vi lyzsys-server/src/main/resources/application.yaml
# 配置数据库、Redis 连接信息
# 4. 启动后端
cd lyzsys-server
mvn spring-boot:run
```
访问: http://localhost:48080/doc.html
### 前端启动
```bash
# 1. 安装依赖
cd lyzsys-ui-admin
pnpm install
# 2. 启动开发服务器
pnpm dev
```
访问: http://localhost:5173
默认账号: `admin` / `admin123`
---
## 项目展示
### 系统功能
| 登录 & 首页 | 用户 & 应用 | 租户 & 套餐 | 部门 & 岗位 |
|------------|------------|------------|------------|
| ![登录](../.image/登录.jpg) | ![用户管理](../.image/用户管理.jpg) | ![租户管理](../.image/租户管理.jpg) | ![部门管理](../.image/部门管理.jpg) |
| 菜单 & 角色 | 审计日志 | 短信管理 | 字典 & 敏感词 |
|------------|------------|------------|------------|
| ![菜单管理](../.image/菜单管理.jpg) | ![操作日志](../.image/操作日志.jpg) | ![短信渠道](../.image/短信渠道.jpg) | ![字典类型](../.image/字典类型.jpg) |
### 工作流程
| 流程模型 | 我的流程 | 待办 & 已办 | OA 请假 |
|---------|---------|-----------|---------|
| ![流程模型](../.image/流程模型-列表.jpg) | ![我的流程](../.image/我的流程-列表.jpg) | ![任务列表](../.image/任务列表-待办.jpg) | ![OA请假](../.image/OA请假-列表.jpg) |
### 基础设施
| 代码生成 | 文档 | 文件 & 配置 | 定时任务 |
|---------|-----|------------|---------|
| ![代码生成](../.image/代码生成.jpg) | ![系统接口](../.image/系统接口.jpg) | ![文件配置](../.image/文件配置.jpg) | ![定时任务](../.image/定时任务.jpg) |
---
## 适用场景
### 适用行业
- **互联网**: SaaS 平台、内容管理、用户系统
- **制造业**: ERP、MES、设备管理
- **零售电商**: 商城系统、CRM、会员管理
- **金融服务**: 风控系统、审批流程
- **政府机构**: OA 系统、审批平台
- **教育培训**: 在线教育、学员管理
- **医疗健康**: HIS 系统、预约管理
### 适用场景
1. **企业内部系统**: OA、ERP、CRM、HR 等管理系统
2. **SaaS 平台**: 多租户 SaaS 应用开发
3. **电商系统**: 商城、订单、支付系统
4. **审批系统**: 工作流、审批流程定制
5. **AI 应用**: AI 对话、AI 知识库、AI 绘图
---
## 开源协议
本项目采用 **MIT 协议**开源,这意味着:
✅ 个人和企业可以 100% 免费使用
✅ 可以用于商业项目无需保留类作者、Copyright 信息
✅ 可以自由修改、分发、二次开发
✅ 无任何商业版本限制
> 严肃声明:现在、未来都不会有商业版本,所有代码全部开源!
---
## 相关资源
### 官方资源
- **在线文档**: https://doc.iocoder.cn
- **视频教程**: https://doc.iocoder.cn/video/
- **Gitee 仓库**: https://gitee.com/zhijiantianya/ruoyi-vue-pro
- **GitHub 仓库**: https://github.com/YunaiV/ruoyi-vue-pro
### 参考项目
本项目基于以下开源项目进行二次开发和优化:
- **RuoYi-Vue**: 优秀的后台管理系统框架
- **Yudao Framework**: 芋道源码框架
### 技术支持
- **文档中心**: 完整的开发文档和使用指南
- **视频教程**: 从零开始的视频教程
- **社区支持**: GitHub Issues、Gitee Issues
---
## 更新日志
### v1.0.0 (2025-01-19)
- 🎉 首次发布 Lyzsys 系统
- ✨ 完整的系统功能和基础设施
- ✨ 工作流模块 (BPM)
- ✨ 支付模块 (Pay)
- ✨ 会员模块 (Member)
- ✨ 商城模块 (Mall)
- ✨ CRM 模块
- ✨ ERP 模块
- ✨ AI 模块
- ✨ 微信公众号模块 (MP)
- ✨ IoT 物联网模块
- 🐛 修复已知问题
- 📝 完善开发文档
---
**项目**: Lyzsys 企业级后台管理系统
**版本**: v1.0.0
**更新**: 2025-01-19
**团队**: Lyzsys 开发团队

View File

@@ -8,12 +8,15 @@
<version>${revision}</version> <version>${revision}</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
<!-- Maven 依赖版本管理-->
<module>lyzsys-dependencies</module> <module>lyzsys-dependencies</module>
<!-- Java 框架拓展-->
<module>lyzsys-framework</module> <module>lyzsys-framework</module>
<!-- Server 主项目 --> <!-- Server 主项目 -->
<module>lyzsys-server</module> <module>lyzsys-server</module>
<!-- 各种 module 拓展 --> <!-- 各种 module 拓展 -->
<module>lyzsys-module-system</module> <module>lyzsys-module-system</module>
<!-- 基础设施的 Module 模块-->
<module>lyzsys-module-infra</module> <module>lyzsys-module-infra</module>
<!-- <module>lyzsys-module-member</module>--> <!-- <module>lyzsys-module-member</module>-->
<!-- <module>lyzsys-module-bpm</module>--> <!-- <module>lyzsys-module-bpm</module>-->
@@ -29,8 +32,8 @@
</modules> </modules>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<description>芋道项目基础脚手架</description> <description>项目基础脚手架</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url> <url>https://aaaaa.com</url>
<properties> <properties>
<revision>2025.12-jdk8-SNAPSHOT</revision> <revision>2025.12-jdk8-SNAPSHOT</revision>