Files
laravel_swoole/docs/README_SYSTEM.md
2026-02-08 22:38:13 +08:00

793 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# System 基础模块文档
## 概述
System 基础模块提供了完整的系统管理功能,包括系统配置、数据字典、操作日志、任务管理、城市数据和文件上传等功能。
## 控制器结构
```
app/Http/Controllers/System/
├── Admin/ # 后台管理控制器
│ ├── Config.php # 系统配置控制器
│ ├── Log.php # 操作日志控制器
│ ├── Dictionary.php # 数据字典控制器
│ ├── Task.php # 任务管理控制器
│ ├── City.php # 城市数据控制器
│ └── Upload.php # 文件上传控制器
└── Api/ # 公共API控制器
├── Config.php # 系统配置API
├── Dictionary.php # 数据字典API
├── City.php # 城市数据API
└── Upload.php # 文件上传API
```
### Admin 控制器
**命名空间**: `App\Http\Controllers\System\Admin`
**路由前缀**: `/admin`
**中间件**: `auth.check:admin` (后台管理认证)
### Api 控制器
**命名空间**: `App\Http\Controllers\System\Api`
**路由前缀**: `/api`
**中间件**: `auth:api` (API认证部分接口为公开接口)
## 技术栈
- PHP 8.1+
- Laravel 11
- Redis 缓存
- Intervention Image (图像处理)
## 数据库表结构
### system_configs (系统配置表)
- `id`: 主键
- `group`: 配置分组system, site, upload
- `key`: 配置键(唯一)
- `value`: 配置值JSON格式
- `type`: 数据类型string, number, boolean, array, image, file
- `name`: 配置名称
- `description`: 配置描述
- `options`: 可选值JSON数组
- `sort`: 排序
- `status`: 状态0:禁用, 1:启用)
- `created_at`, `updated_at`: 时间戳
### system_dictionaries (数据字典分类表)
- `id`: 主键
- `name`: 字典名称
- `code`: 字典编码(唯一)
- `description`: 描述
- `sort`: 排序
- `status`: 状态
- `created_at`, `updated_at`: 时间戳
### system_dictionary_items (数据字典项表)
- `id`: 主键
- `dictionary_id`: 字典ID
- `label`: 显示标签
- `value`: 实际值
- `sort`: 排序
- `status`: 状态
- `created_at`, `updated_at`: 时间戳
### system_logs (操作日志表)
- `id`: 主键
- `user_id`: 用户ID
- `username`: 用户名
- `module`: 模块
- `action`: 操作
- `method`: 请求方法
- `url`: 请求URL
- `ip`: IP地址
- `user_agent`: 用户代理
- `request_data`: 请求数据JSON
- `response_data`: 响应数据JSON
- `duration`: 执行时间(毫秒)
- `status_code`: 状态码
- `created_at`: 创建时间
### system_tasks (任务表)
- `id`: 主键
- `name`: 任务名称
- `code`: 任务编码(唯一)
- `command`: 命令
- `description`: 描述
- `cron_expression`: Cron表达式
- `status`: 状态0:禁用, 1:启用, 2:运行中, 3:失败)
- `last_run_at`: 最后运行时间
- `next_run_at`: 下次运行时间
- `run_count`: 运行次数
- `fail_count`: 失败次数
- `last_message`: 最后运行消息
- `sort`: 排序
- `created_at`, `updated_at`: 时间戳
### system_cities (城市表)
- `id`: 主键
- `name`: 城市名称
- `code`: 城市编码
- `level`: 级别1:省, 2:市, 3:区县)
- `parent_id`: 父级ID
- `adcode`: 行政区划编码
- `sort`: 排序
- `status`: 状态
- `created_at`, `updated_at`: 时间戳
## Admin API 接口文档
### 系统配置管理
#### 获取配置列表
- **接口**: `GET /admin/configs`
- **参数**:
- `page`: 页码默认1
- `page_size`: 每页数量默认20
- `keyword`: 搜索关键词
- `group`: 配置分组
- `status`: 状态
- `order_by`, `order_direction`: 排序
#### 获取所有配置分组
- **接口**: `GET /admin/configs/groups`
#### 按分组获取配置
- **接口**: `GET /admin/configs/all`
- **参数**:
- `group`: 配置分组(可选)
#### 获取配置详情
- **接口**: `GET /admin/configs/{id}`
#### 创建配置
- **接口**: `POST /admin/configs`
- **参数**:
```json
{
"group": "site",
"key": "site_name",
"name": "网站名称",
"description": "网站显示的名称",
"type": "string",
"value": "\"我的网站\"",
"options": null,
"sort": 1,
"status": 1
}
```
- **数据类型说明**:
- `string`: 字符串
- `number`: 数字
- `boolean`: 布尔值
- `array`: 数组
- `image`: 图片
- `file`: 文件
#### 更新配置
- **接口**: `PUT /admin/configs/{id}`
#### 删除配置
- **接口**: `DELETE /admin/configs/{id}`
#### 批量删除配置
- **接口**: `POST /admin/configs/batch-delete`
- **参数**:
```json
{
"ids": [1, 2, 3]
}
```
#### 批量更新配置状态
- **接口**: `POST /admin/configs/batch-status`
- **参数**:
```json
{
"ids": [1, 2, 3],
"status": 1
}
```
### 操作日志管理
#### 获取日志列表
- **接口**: `GET /admin/logs`
- **参数**:
- `page`, `page_size`
- `keyword`: 搜索关键词(用户名/模块/操作)
- `module`: 模块
- `action`: 操作
- `user_id`: 用户ID
- `start_date`: 开始日期
- `end_date`: 结束日期
- `order_by`, `order_direction`
#### 获取日志详情
- **接口**: `GET /admin/logs/{id}`
#### 删除日志
- **接口**: `DELETE /admin/logs/{id}`
#### 批量删除日志
- **接口**: `POST /admin/logs/batch-delete`
- **参数**:
```json
{
"ids": [1, 2, 3]
}
```
#### 清理日志
- **接口**: `POST /admin/logs/clear`
- **参数**:
```json
{
"days": 30
}
```
- **说明**: 删除指定天数之前的日志记录
#### 获取日志统计
- **接口**: `GET /admin/logs/statistics`
- **参数**:
- `start_date`: 开始日期
- `end_date`: 结束日期
- **返回**:
```json
{
"code": 200,
"message": "success",
"data": {
"total_count": 1000,
"module_stats": [
{
"module": "user",
"count": 500
}
],
"user_stats": [
{
"user_id": 1,
"username": "admin",
"count": 800
}
]
}
}
```
### 数据字典管理
#### 获取字典列表
- **接口**: `GET /admin/dictionaries`
- **参数**:
- `page`, `page_size`, `keyword`, `status`, `order_by`, `order_direction`
#### 获取所有字典
- **接口**: `GET /admin/dictionaries/all`
#### 获取字典详情
- **接口**: `GET /admin/dictionaries/{id}`
#### 创建字典
- **接口**: `POST /admin/dictionaries`
- **参数**:
```json
{
"name": "用户状态",
"code": "user_status",
"description": "用户状态字典",
"sort": 1,
"status": 1
}
```
#### 更新字典
- **接口**: `PUT /admin/dictionaries/{id}`
#### 删除字典
- **接口**: `DELETE /admin/dictionaries/{id}`
#### 批量删除字典
- **接口**: `POST /admin/dictionaries/batch-delete`
#### 批量更新字典状态
- **接口**: `POST /admin/dictionaries/batch-status`
### 数据字典项管理
#### 获取字典项列表
- **接口**: `GET /admin/dictionary-items`
- **参数**:
- `page`, `page_size`
- `dictionary_id`: 字典ID必需
- `keyword`: 搜索关键词
- `status`, `order_by`, `order_direction`
#### 创建字典项
- **接口**: `POST /admin/dictionary-items`
- **参数**:
```json
{
"dictionary_id": 1,
"label": "正常",
"value": "1",
"sort": 1,
"status": 1
}
```
#### 更新字典项
- **接口**: `PUT /admin/dictionary-items/{id}`
#### 删除字典项
- **接口**: `DELETE /admin/dictionary-items/{id}`
#### 批量删除字典项
- **接口**: `POST /admin/dictionary-items/batch-delete`
#### 批量更新字典项状态
- **接口**: `POST /admin/dictionary-items/batch-status`
### 任务管理
#### 获取任务列表
- **接口**: `GET /admin/tasks`
- **参数**:
- `page`, `page_size`, `keyword`, `status`, `order_by`, `order_direction`
#### 获取所有任务
- **接口**: `GET /admin/tasks/all`
#### 获取任务详情
- **接口**: `GET /admin/tasks/{id}`
#### 创建任务
- **接口**: `POST /admin/tasks`
- **参数**:
```json
{
"name": "清理临时文件",
"code": "cleanup_temp_files",
"command": "cleanup:temp",
"description": "每天清理过期临时文件",
"cron_expression": "0 2 * * *",
"sort": 1,
"status": 1
}
```
- **Cron表达式说明**:
- 格式:`分 时 日 月 周`
- 示例:`0 2 * * *` (每天凌晨2点执行)
- 示例:`*/5 * * * *` (每5分钟执行一次)
#### 更新任务
- **接口**: `PUT /admin/tasks/{id}`
#### 删除任务
- **接口**: `DELETE /admin/tasks/{id}`
#### 批量删除任务
- **接口**: `POST /admin/tasks/batch-delete`
#### 批量更新任务状态
- **接口**: `POST /admin/tasks/batch-status`
#### 手动执行任务
- **接口**: `POST /admin/tasks/{id}/run`
- **说明**: 立即执行指定任务
#### 获取任务统计
- **接口**: `GET /admin/tasks/statistics`
- **返回**:
```json
{
"code": 200,
"message": "success",
"data": {
"total": 10,
"enabled": 8,
"disabled": 2,
"running": 0,
"failed": 0
}
}
```
### 城市数据管理
#### 获取城市列表
- **接口**: `GET /admin/cities`
- **参数**:
- `page`, `page_size`, `keyword`, `level`, `parent_id`, `status`
- `order_by`, `order_direction`
#### 获取城市树
- **接口**: `GET /admin/cities/tree`
- **说明**: 从缓存中获取完整的三级城市树
#### 获取城市详情
- **接口**: `GET /admin/cities/{id}`
#### 获取子级城市
- **接口**: `GET /admin/cities/{id}/children`
- **说明**: 获取指定城市的下级城市
#### 获取所有省份
- **接口**: `GET /admin/cities/provinces`
#### 获取指定省份的城市
- **接口**: `GET /admin/cities/{provinceId}/cities`
#### 获取指定城市的区县
- **接口**: `GET /admin/cities/{cityId}/districts`
#### 创建城市
- **接口**: `POST /admin/cities`
- **参数**:
```json
{
"name": "北京市",
"code": "110000",
"level": 1,
"parent_id": 0,
"adcode": "110000",
"sort": 1,
"status": 1
}
```
- **级别说明**:
- `1`: 省级
- `2`: 市级
- `3`: 区县级
#### 更新城市
- **接口**: `PUT /admin/cities/{id}`
#### 删除城市
- **接口**: `DELETE /admin/cities/{id}`
#### 批量删除城市
- **接口**: `POST /admin/cities/batch-delete`
#### 批量更新城市状态
- **接口**: `POST /admin/cities/batch-status`
### 文件上传管理
#### 单文件上传
- **接口**: `POST /admin/upload`
- **参数**:
- `file`: 文件multipart/form-data最大10MB
- `directory`: 存储目录默认uploads
- `compress`: 是否压缩图片默认false
- `quality`: 图片质量1-100默认80
- `width`: 压缩宽度(可选)
- `height`: 压缩高度(可选)
- **返回**:
```json
{
"code": 200,
"message": "上传成功",
"data": {
"url": "http://example.com/uploads/2024/01/xxx.jpg",
"path": "uploads/2024/01/xxx.jpg",
"name": "xxx.jpg",
"size": 102400,
"mime_type": "image/jpeg"
}
}
```
#### 多文件上传
- **接口**: `POST /admin/upload/multiple`
- **参数**:
- `files`: 文件数组multipart/form-data
- 其他参数同单文件上传
- **返回**: 文件数组
#### Base64上传
- **接口**: `POST /admin/upload/base64`
- **参数**:
```json
{
"base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
"directory": "uploads",
"file_name": "image.jpg"
}
```
#### 删除文件
- **接口**: `POST /admin/upload/delete`
- **参数**:
```json
{
"path": "uploads/2024/01/xxx.jpg"
}
```
#### 批量删除文件
- **接口**: `POST /admin/upload/batch-delete`
- **参数**:
```json
{
"paths": [
"uploads/2024/01/xxx.jpg",
"uploads/2024/01/yyy.jpg"
]
}
```
## Public API 接口文档
### 系统配置 API
#### 获取所有配置
- **接口**: `GET /api/system/configs`
- **认证**: 公开接口(无需认证)
- **返回**:
```json
{
"code": 200,
"message": "success",
"data": {
"site_name": "我的网站",
"site_logo": "/uploads/logo.png"
}
}
```
#### 按分组获取配置
- **接口**: `GET /api/system/configs/group`
- **参数**:
- `group`: 配置分组
- **认证**: 公开接口
#### 根据键获取配置
- **接口**: `GET /api/system/configs/key`
- **参数**:
- `key`: 配置键
- **认证**: 公开接口
### 数据字典 API
#### 获取所有字典
- **接口**: `GET /api/system/dictionaries`
- **认证**: 公开接口
- **返回**:
```json
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"code": "user_status",
"name": "用户状态",
"items": [...]
}
]
}
```
#### 根据编码获取字典项
- **接口**: `GET /api/system/dictionaries/code`
- **参数**:
- `code`: 字典编码
- **认证**: 公开接口
- **返回**:
```json
{
"code": 200,
"message": "success",
"data": {
"code": "user_status",
"items": [
{"label": "正常", "value": "1"},
{"label": "禁用", "value": "0"}
]
}
}
```
#### 获取字典详情
- **接口**: `GET /api/system/dictionaries/{id}`
- **认证**: 公开接口
### 城市数据 API
#### 获取城市树
- **接口**: `GET /api/system/cities/tree`
- **认证**: 公开接口
- **说明**: 从缓存中获取完整的三级城市树
#### 获取所有省份
- **接口**: `GET /api/system/cities/provinces`
- **认证**: 公开接口
#### 获取指定省份的城市
- **接口**: `GET /api/system/cities/{provinceId}/cities`
- **认证**: 公开接口
#### 获取指定城市的区县
- **接口**: `GET /api/system/cities/{cityId}/districts`
- **认证**: 公开接口
#### 获取城市详情
- **接口**: `GET /api/system/cities/{id}`
- **认证**: 公开接口
### 文件上传 API
#### 单文件上传
- **接口**: `POST /api/system/upload`
- **认证**: 需要认证(`auth:api`
- **参数**: 同Admin上传接口
#### 多文件上传
- **接口**: `POST /api/system/upload/multiple`
- **认证**: 需要认证(`auth:api`
- **参数**: 同Admin上传接口
#### Base64上传
- **接口**: `POST /api/system/upload/base64`
- **认证**: 需要认证(`auth:api`
- **参数**: 同Admin上传接口
## 缓存机制
### 城市数据缓存
- **缓存键**: `city:tree`
- **过期时间**: 永久(手动清除)
- **更新时机**: 城市数据增删改时自动清除
### 系统配置缓存
- **缓存键**: `config:all` 或 `config:group:{group}`
- **过期时间**: 60分钟
- **更新时机**: 配置数据增删改时自动清除
### 数据字典缓存
- **缓存键**: `dictionary:all` 或 `dictionary:code:{code}`
- **过期时间**: 60分钟
- **更新时机**: 字典数据增删改时自动清除
## 服务层说明
### ConfigService
提供系统配置的CRUD操作和缓存管理。
**主要方法**:
- `getList()`: 获取配置列表
- `getByGroup()`: 按分组获取配置
- `getConfigValue()`: 获取配置值
- `create()`: 创建配置
- `update()`: 更新配置
- `delete()`: 删除配置
### LogService
提供操作日志的记录、查询和清理功能。
**主要方法**:
- `getList()`: 获取日志列表
- `getStatistics()`: 获取统计数据
- `clearLogs()`: 清理过期日志
- `record()`: 记录日志(由中间件自动调用)
### DictionaryService
提供数据字典和字典项的管理功能。
**主要方法**:
- `getList()`: 获取字典列表
- `getItemsByCode()`: 按编码获取字典项
- `create()`: 创建字典
- `createItem()`: 创建字典项
- `update()`: 更新字典
- `updateItem()`: 更新字典项
### TaskService
提供任务的管理和执行功能。
**主要方法**:
- `getList()`: 获取任务列表
- `run()`: 手动执行任务
- `getStatistics()`: 获取任务统计
- `updateStatus()`: 更新任务状态
### CityService
提供城市数据的管理和缓存功能。
**主要方法**:
- `getList()`: 获取城市列表
- `getCachedTree()`: 从缓存获取城市树
- `getProvinces()`: 获取省份列表
- `getCities()`: 获取城市列表
- `getDistricts()`: 获取区县列表
### UploadService
提供文件上传和删除功能。
**主要方法**:
- `upload()`: 单文件上传
- `uploadMultiple()`: 多文件上传
- `uploadBase64()`: Base64上传
- `delete()`: 删除文件
- `compressImage()`: 图片压缩
## 初始化数据
```bash
# 执行迁移
php artisan migrate
# 填充初始数据
php artisan db:seed --class=SystemSeeder
```
初始数据包括:
- 基础系统配置
- 常用数据字典
- 全国省市区数据
## 注意事项
1. **Swoole环境注意事项**:
- 文件上传时注意临时文件清理
- 使用Redis缓存避免内存泄漏
- 图片压缩使用协程安全的方式
2. **安全注意事项**:
- 文件上传必须验证文件类型和大小
- 敏感操作必须记录日志
- 配置数据不要存储密码等敏感信息
3. **性能优化**:
- 城市数据使用Redis缓存
- 大量日志数据定期清理
- 图片上传时进行压缩处理
4. **文件上传**:
- 限制文件上传大小
- 验证文件MIME类型
- 定期清理临时文件
## 扩展建议
1. **日志告警**: 添加日志异常告警功能
2. **配置加密**: 敏感配置数据加密存储
3. **多语言**: 支持配置数据的多语言
4. **任务监控**: 添加任务执行监控和通知
5. **CDN集成**: 文件上传支持CDN分发
## 常见问题
### Q: 如何清除城市数据缓存?
A: 调用 `CityService::clearCache()` 方法或运行 `php artisan cache:forget city:tree`。
### Q: 图片上传后如何压缩?
A: 上传时设置 `compress=true` 和 `quality` 参数,系统会自动压缩。
### Q: 如何配置定时任务?
A: 在Admin后台创建任务设置Cron表达式系统会自动调度执行。
### Q: 数据字典如何使用?
A: 通过Public API获取字典数据前端根据数据渲染下拉框等组件。
### Q: 日志数据过多如何处理?
A: 定期使用 `/admin/logs/clear` 接口清理过期日志,或在后台设置自动清理任务。