# 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 (图像处理) - Laravel-S / Swoole (WebSocket 通知) - WebSocket (实时消息推送) ## 数据库表结构 ### system_setting (系统配置表) - `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`: 请求方法 (GET/POST/PUT/DELETE) - `url`: 请求URL - `ip`: IP地址 - `user_agent`: 用户代理 - `params`: 请求参数(JSON) - `result`: 响应结果(仅错误时记录) - `status_code`: HTTP状态码 - `status`: 状态 (success/error) - `error_message`: 错误信息 - `execution_time`: 执行时间(毫秒) - `created_at`: 创建时间 - `updated_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 } ``` ### 操作日志管理 操作日志模块通过中间件自动记录所有后台管理 API 请求,实现全自动化的日志记录功能。 #### 中间件说明 **LogRequestMiddleware** 位置: `app/Http/Middleware/LogRequestMiddleware.php` 功能: - 自动拦截所有经过的请求 - 记录请求和响应信息 - 计算请求执行时间 - 提取用户信息和操作详情 - 过滤敏感参数(password、token、secret、key) - 获取客户端真实 IP(支持代理) - 异常处理,记录失败不影响业务 使用方式: ```php // 在路由中应用 Route::middleware(['auth.check:admin', 'log.request'])->group(function () { // 需要记录日志的路由 }); ``` #### 日志记录规则 **自动记录的请求:** 所有经过 `log.request` 中间件的请求都会被自动记录,包括: - 用户管理操作 - 角色管理操作 - 权限管理操作 - 部门管理操作 - 系统配置操作 - 其他所有后台管理操作 **不记录的请求:** - 登录接口 (`POST /admin/auth/login`) - 健康检查接口 (`GET /up`) - 其他明确排除的路由 **敏感信息过滤:** 以下字段会被自动过滤,记录为 `******`: - `password` - `password_confirmation` - `token` - `secret` - `key` **错误日志处理:** - 成功请求 (HTTP 状态码 < 400): `status` = `success` - 失败请求 (HTTP 状态码 >= 400): `status` = `error` - 错误时记录响应内容和错误消息 - 同时写入 Laravel 日志文件 (`storage/logs/laravel.log`) #### 获取日志列表 - **接口**: `GET /admin/logs` - **参数**: ```json { "user_id": 1, "username": "admin", "module": "users", "action": "创建 users", "status": "success", "start_date": "2024-01-01", "end_date": "2024-12-31", "ip": "192.168.1.1", "page": 1, "page_size": 20 } ``` - **响应示例**: ```json { "code": 200, "message": "success", "data": { "list": [ { "id": 1, "user_id": 1, "username": "admin", "module": "users", "action": "创建 users", "method": "POST", "url": "http://example.com/admin/users", "ip": "192.168.1.1", "user_agent": "Mozilla/5.0...", "params": { "name": "test", "email": "test@example.com" }, "result": null, "status_code": 200, "status": "success", "error_message": null, "execution_time": 125, "created_at": "2024-01-01 12:00:00" } ], "total": 100, "page": 1, "page_size": 20 } } ``` #### 获取日志详情 - **接口**: `GET /admin/logs/{id}` - **响应示例**: ```json { "code": 200, "message": "success", "data": { "id": 1, "user_id": 1, "username": "admin", "module": "users", "action": "创建 users", "method": "POST", "url": "http://example.com/admin/users", "ip": "192.168.1.1", "user_agent": "Mozilla/5.0...", "params": { "name": "test", "email": "test@example.com" }, "result": null, "status_code": 200, "status": "success", "error_message": null, "execution_time": 125, "created_at": "2024-01-01 12:00:00", "user": { "id": 1, "name": "管理员", "username": "admin" } } } ``` #### 获取日志统计 - **接口**: `GET /admin/logs/statistics` - **参数**: ```json { "start_date": "2024-01-01", "end_date": "2024-12-31" } ``` - **响应示例**: ```json { "code": 200, "message": "success", "data": { "total": 1000, "success": 950, "error": 50 } } ``` #### 导出日志 - **接口**: `POST /admin/logs/export` - **参数**: 与获取日志列表相同的查询参数 - **响应**: Excel 文件下载 - **文件名格式**: `系统操作日志_YYYYMMDDHHmmss.xlsx` - **包含字段**: - ID - 用户名 - 模块 - 操作 - 请求方法 - URL - IP 地址 - 状态码 - 状态 - 错误信息 - 执行时间(ms) - 创建时间 #### 删除单条日志 - **接口**: `DELETE /admin/logs/{id}` - **响应示例**: ```json { "code": 200, "message": "删除成功", "data": null } ``` #### 批量删除日志 - **接口**: `POST /admin/logs/batch-delete` - **参数**: ```json { "ids": [1, 2, 3, 4, 5] } ``` - **响应示例**: ```json { "code": 200, "message": "批量删除成功", "data": null } ``` #### 清理历史日志 - **接口**: `POST /admin/logs/clear` - **参数**: ```json { "days": 30 } ``` - **说明**: 清理指定天数前的所有日志记录,默认清理 30 天前的数据 - **响应示例**: ```json { "code": 200, "message": "清理成功", "data": null } ``` ### 数据字典管理 数据字典模块提供了完整的字典管理功能,包括字典分类和字典项的 CRUD 操作。通过 WebSocket 实现了前后端缓存的实时同步更新。 #### 字典缓存更新机制 **概述** 字典缓存更新机制通过 WebSocket 实现前后端字典缓存的实时同步,确保在字典分类和字典项的增删改等操作后,前端字典缓存能够自动更新。 **技术实现** 1. **后端实现** 在 `app/Services/System/DictionaryService.php` 中添加了 WebSocket 通知功能: **通知方法:** - `notifyDictionaryUpdate` - 字典分类更新通知 - 触发时机:创建、更新、删除、批量删除、批量更新状态 - 消息类型:`dictionary_update` - `notifyDictionaryItemUpdate` - 字典项更新通知 - 触发时机:创建、更新、删除、批量删除、批量更新状态 - 消息类型:`dictionary_item_update` **WebSocket 消息格式:** 字典分类更新消息: ```json { "type": "dictionary_update", "data": { "action": "create|update|delete|batch_delete|batch_update_status", "resource_type": "dictionary", "data": { // 字典分类数据 }, "timestamp": 1234567890 } } ``` 字典项更新消息: ```json { "type": "dictionary_item_update", "data": { "action": "create|update|delete|batch_delete|batch_update_status", "resource_type": "dictionary_item", "data": { // 字典项数据 }, "timestamp": 1234567890 } } ``` 2. **前端实现** 创建了 `resources/admin/src/composables/useWebSocket.js` 来处理 WebSocket 连接和消息监听: **主要功能:** - 初始化 WebSocket 连接(检查用户登录状态、验证用户信息完整性) - 消息处理器:`handleDictionaryUpdate` 和 `handleDictionaryItemUpdate` - 缓存刷新:接收到更新通知后,自动刷新字典缓存并显示成功提示 **App.vue 集成:** ```javascript onMounted(async () => { // 初始化 WebSocket 连接 if (userStore.isLoggedIn()) { initWebSocket() } }) onUnmounted(() => { // 关闭 WebSocket 连接 closeWebSocket() }) ``` **工作流程:** ``` 用户操作(增删改字典) ↓ 后端 Controller 调用 Service ↓ Service 执行数据库操作 ↓ Service 清理后端缓存(Redis) ↓ Service 发送 WebSocket 广播通知 ↓ WebSocket 推送消息到所有在线客户端 ↓ 前端接收 WebSocket 消息 ↓ 触发相应的消息处理器 ↓ 刷新前端字典缓存 ↓ 显示成功提示 ``` **注意事项:** - WebSocket 仅在用户登录后建立连接 - 连接失败会自动重试(最多 5 次) - 页面卸载时会自动关闭连接 - WebSocket 通知功能依赖于 Laravel-S (Swoole) 环境 - 在普通 PHP 环境下运行时,WebSocket 通知会优雅降级(不发送通知,但不影响功能) #### 获取字典列表 - **接口**: `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}` - **过期时间**: 3600秒(1小时) - **更新时机**: - 字典数据增删改时自动清除后端缓存(Redis) - 通过 WebSocket 通知前端自动刷新缓存 **字典缓存同步流程:** 1. 后端执行字典操作(增删改) 2. 清理 Redis 缓存 3. 发送 WebSocket 广播通知 4. 前端接收通知并自动刷新缓存 5. 显示成功提示 ## 服务层说明 ### ConfigService 提供系统配置的CRUD操作和缓存管理。 **主要方法**: - `getList()`: 获取配置列表 - `getByGroup()`: 按分组获取配置 - `getConfigValue()`: 获取配置值 - `create()`: 创建配置 - `update()`: 更新配置 - `delete()`: 删除配置 ### LogService 提供操作日志的记录、查询和清理功能。 **主要方法**: - `getList()`: 获取日志列表 - `getById()`: 根据 ID 获取日志详情 - `getStatistics()`: 获取统计数据 - `getListQuery()`: 获取日志查询构建器 - `clearLogs()`: 清理过期日志 - `delete()`: 删除单条日志 - `batchDelete()`: 批量删除日志 - `record()`: 记录日志(由中间件自动调用) **特性**: - 自动记录所有经过中间件的请求 - 计算请求执行时间 - 过滤敏感参数 - 获取客户端真实 IP(支持代理) - 异常处理,记录失败不影响业务 ### DictionaryService 提供数据字典和字典项的管理功能,包括 WebSocket 通知机制。 **主要方法**: - `getList()`: 获取字典列表 - `getItemsByCode()`: 按编码获取字典项 - `create()`: 创建字典 - `createItem()`: 创建字典项 - `update()`: 更新字典 - `updateItem()`: 更新字典项 - `notifyDictionaryUpdate()`: 发送字典更新通知 - `notifyDictionaryItemUpdate()`: 发送字典项更新通知 **缓存机制**: - Redis 缓存字典数据(TTL: 3600秒) - WebSocket 实时通知前端更新 - 前端 Pinia + 本地存储持久化 ### 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 ``` 初始数据包括: - 基础系统配置 - 常用数据字典 - 全国省市区数据 ## 前端集成示例 ### 日志管理页面 ```vue ``` ## 注意事项 ### 1. Swoole环境注意事项 - 文件上传时注意临时文件清理 - 使用Redis缓存避免内存泄漏 - 图片压缩使用协程安全的方式 - WebSocket 通知依赖于 Laravel-S 环境 ### 2. 安全注意事项 - 文件上传必须验证文件类型和大小 - 敏感操作必须记录日志 - 配置数据不要存储密码等敏感信息 - 日志敏感信息已自动过滤 ### 3. 性能优化 - 城市数据使用Redis缓存 - 大量日志数据定期清理 - 图片上传时进行压缩处理 - 日志记录在请求处理后执行,不影响响应速度 ### 4. 文件上传 - 限制文件上传大小 - 验证文件MIME类型 - 定期清理临时文件 ### 5. 日志管理 - 定期清理历史日志(建议使用任务调度器) - 确保查询字段有索引 - 使用分页查询避免加载过多数据 ## 性能优化建议 ### 1. 定期清理日志 建议使用 Laravel 任务调度器定期清理历史日志: ```php // app/Console/Kernel.php protected function schedule(Schedule $schedule) { // 每天凌晨 2 点清理 90 天前的日志 $schedule->call(function () { app(LogService::class)->clearLogs(90); })->dailyAt('02:00'); } ``` ### 2. 数据库索引 确保以下字段有索引: - `system_logs`: `user_id`, `username`, `module`, `status`, `created_at` - `system_dictionaries`: `code`, `status` - `system_dictionary_items`: `dictionary_id`, `status` - `system_setting`: `group`, `key`, `status` ### 3. 分页查询 列表查询必须使用分页,避免一次加载过多数据。 ### 4. 异步记录 日志记录操作应放在请求处理后,不影响响应速度。 ### 5. 细粒度缓存更新 字典缓存当前实现为全量刷新,未来可以优化为增量更新: ```javascript // 只更新受影响的字典 async function handleDictionaryUpdate(data) { const { action, data: dictData } = data if (action === 'update' && dictData.code) { // 只更新特定的字典 await dictionaryStore.getDictionary(dictData.code, true) } else { // 全量刷新 await dictionaryStore.refresh(true) } } ``` ## 扩展建议 ### 1. 日志告警 添加日志异常告警功能,当出现大量错误日志时自动通知管理员。 ### 2. 配置加密 敏感配置数据加密存储,提高安全性。 ### 3. 多语言 支持配置数据的多语言,便于国际化部署。 ### 4. 任务监控 添加任务执行监控和通知,实时掌握任务运行状态。 ### 5. CDN集成 文件上传支持CDN分发,提高访问速度。 ### 6. WebSocket 权限控制 可以只向有权限的用户发送通知: ```php // 后端只向有字典管理权限的用户发送 $adminUserIds = User::whereHas('roles', function($query) { $query->where('name', 'admin'); })->pluck('id')->toArray(); $this->webSocketService->sendToUsers($adminUserIds, $message); ``` ### 7. 消息队列 对于高并发场景,可以使用消息队列异步发送 WebSocket 通知: ```php // 使用 Laravel 队列 UpdateDictionaryCacheJob::dispatch($action, $data); ``` ## 常见问题 ### Q1: 如何清除城市数据缓存? A: 调用 `CityService::clearCache()` 方法或运行 `php artisan cache:forget city:tree`。 ### Q2: 图片上传后如何压缩? A: 上传时设置 `compress=true` 和 `quality` 参数,系统会自动压缩。 ### Q3: 如何配置定时任务? A: 在Admin后台创建任务,设置Cron表达式,系统会自动调度执行。 ### Q4: 数据字典如何使用? A: 通过Public API获取字典数据,前端根据数据渲染下拉框等组件。 ### Q5: 日志数据过多如何处理? A: 定期使用 `/admin/logs/clear` 接口清理过期日志,或在后台设置自动清理任务。 ### Q6: 为什么某些请求没有被记录? A: 检查路由是否应用了 `log.request` 中间件,或者在中间件中是否被排除了。 ### Q7: 字典缓存未更新怎么办? A: 检查以下几点: - 确认 Laravel-S 服务是否启动:`php bin/laravels status` - 检查浏览器控制台是否有 WebSocket 错误 - 确认用户已登录且有 token - 手动刷新页面验证 API 是否正常 ### Q8: WebSocket 连接失败会影响功能吗? A: 不会。WebSocket 连接失败不影响页面正常使用,只是不会收到自动更新通知。字典数据仍会正常更新到数据库和 Redis 缓存,只是前端不会收到实时通知,需要手动刷新页面。 ## 测试建议 ### 1. 功能测试 1. 测试各种请求是否被正确记录 2. 测试敏感信息是否被正确过滤 3. 测试日志查询和筛选功能 4. 测试日志导出功能 5. 测试批量删除和清理功能 6. 测试字典 WebSocket 通知是否正确 ### 2. 性能测试 1. 测试日志记录对响应时间的影响 2. 测试大量日志数据的查询性能 3. 测试并发写入的性能 4. 测试 WebSocket 广播性能 ### 3. 集成测试(字典 WebSocket) 1. 启动后端服务(Laravel-S) 2. 启动前端开发服务器 3. 在浏览器中登录系统 4. 打开开发者工具的 Network -> WS 标签查看 WebSocket 消息 5. 执行字典增删改操作 6. 验证: - WebSocket 消息是否正确接收 - 缓存是否自动刷新 - 页面数据是否更新 - 提示消息是否显示 ### 4. 并发测试 1. 打开多个浏览器窗口并登录 2. 在一个窗口中进行字典操作 3. 验证所有窗口的缓存是否同步更新 ### 5. 边界测试 1. 测试异常情况下的日志记录 2. 测试超长参数的处理 3. 测试特殊字符的处理 4. 测试 WebSocket 断连重连机制 ## 文件清单 ### 核心文件 **控制器:** ``` app/Http/Controllers/System/Admin/Config.php app/Http/Controllers/System/Admin/Log.php app/Http/Controllers/System/Admin/Dictionary.php app/Http/Controllers/System/Admin/Task.php app/Http/Controllers/System/Admin/City.php app/Http/Controllers/System/Admin/Upload.php app/Http/Controllers/System/WebSocket.php ``` **中间件:** ``` app/Http/Middleware/LogRequestMiddleware.php ``` **请求验证:** ``` app/Http/Requests/LogRequest.php ``` **服务层:** ``` app/Services/System/ConfigService.php app/Services/System/LogService.php app/Services/System/DictionaryService.php app/Services/System/TaskService.php app/Services/System/CityService.php app/Services/System/UploadService.php app/Services/WebSocket/WebSocketService.php ``` **模型:** ``` app/Models/System/Config.php app/Models/System/Log.php app/Models/System/Dictionary.php app/Models/System/DictionaryItem.php app/Models/System/Task.php app/Models/System/City.php ``` **路由:** ``` routes/admin.php (后台管理路由) routes/api.php (公共 API 路由) ``` **前端:** ``` resources/admin/src/composables/useWebSocket.js resources/admin/src/App.vue (集成 WebSocket) ``` **文档:** ``` docs/README_SYSTEM.md (本文档) ``` ## 总结 System 基础模块提供了完整的系统管理功能,包括: ### 核心功能 - ✅ 系统配置管理(多分组、多类型支持) - ✅ 数据字典管理(分类 + 字典项) - ✅ 操作日志管理(自动记录、多维度查询、导出) - ✅ 任务管理(定时任务、手动执行、统计) - ✅ 城市数据管理(三级联动、缓存优化) - ✅ 文件上传管理(单文件、多文件、Base64、压缩) ### 高级特性 - ✅ WebSocket 实时通知(字典缓存自动更新) - ✅ Redis 缓存机制(性能优化) - ✅ 自动化日志记录(中间件拦截) - ✅ 敏感信息保护(自动过滤) - ✅ 数据导出功能(Excel 导出) - ✅ 批量操作支持 - ✅ 完整的 API 文档 ### 性能优化 - ✅ Redis 缓存(城市数据、系统配置、数据字典) - ✅ 日志异步记录(不影响响应速度) - ✅ 分页查询(避免加载过多数据) - ✅ 图片压缩(减少存储空间) - ✅ WebSocket 实时更新(减少不必要的请求) ### 安全特性 - ✅ 敏感信息过滤 - ✅ 文件类型验证 - ✅ 请求日志记录 - ✅ IP 地址记录 - ✅ 异常处理机制 System 模块现已完全集成到项目中,提供了完整的系统管理功能和优秀的用户体验。