# 完成图片保存功能说明 ## 📋 功能概述 当游戏任务完成时,系统会自动保存4张关键截图到本地文件系统,并保留24小时。这些图片可以作为任务完成的证明和记录。 ## 🎯 保存的图片 任务完成时会保存以下4张图片: 1. **首次主页.png** (homepage) 2. **首次赏金.png** (first-reward) 3. **中途赏金.png** (mid-reward) 4. **结束赏金.png** (end-reward) ## 🔧 技术实现 ### 1. 核心服务组件 #### **CompletionImageService** - 负责从脚本端下载图片并保存到本地文件系统 - 并发下载4张图片,提高效率 - 提供图片访问和清理功能 #### **GameCompletionDetectionService** - 在任务完成时触发图片保存 - 异步执行,不阻塞主流程 - 保存成功后更新数据库记录 #### **CompletionImageController** - 提供HTTP接口访问已保存的图片 - 支持单张图片访问和批量URL获取 #### **CompletionImageCleanupTask** - 定时清理任务(每小时执行) - 自动删除超过24小时的图片文件夹 ### 2. 文件存储结构 ``` completion-images/ ├── 20251103/ # 日期文件夹(yyyyMMdd) │ ├── ABC123XYZ/ # 链接编号(codeNo) │ │ ├── homepage.png │ │ ├── first-reward.png │ │ ├── mid-reward.png │ │ └── end-reward.png │ └── DEF456UVW/ │ └── ... └── 20251104/ └── ... ``` ### 3. 数据库字段 在 `link_task` 表中新增两个字段: | 字段名 | 类型 | 说明 | |--------|------|------| | `completion_images` | TEXT | JSON格式存储图片信息 | | `completion_images_saved_at` | DATETIME | 图片保存时间 | **completion_images JSON 示例:** ```json { "saveTime": "2025-11-03T10:30:45", "codeNo": "ABC123XYZ", "machineId": "f1", "dateFolder": "20251103", "images": { "homepage": "20251103/ABC123XYZ/homepage.png", "first-reward": "20251103/ABC123XYZ/first-reward.png", "mid-reward": "20251103/ABC123XYZ/mid-reward.png", "end-reward": "20251103/ABC123XYZ/end-reward.png" }, "totalCount": 4 } ``` ## 📡 API 接口 ### 1. 获取单张图片 **首次主页图片** ```http GET /api/link/completion/{codeNo}/homepage.png ``` **首次赏金图片** ```http GET /api/link/completion/{codeNo}/first-reward.png ``` **中途赏金图片** ```http GET /api/link/completion/{codeNo}/mid-reward.png ``` **结束赏金图片** ```http GET /api/link/completion/{codeNo}/end-reward.png ``` **响应示例:** - 成功:返回图片数据(image/png) - 失败:404 Not Found ### 2. 获取所有图片URL列表 ```http GET /api/link/completion/{codeNo}/images ``` **响应示例:** ```json { "homepage": "https://uzi1.cn/api/link/completion/ABC123XYZ/homepage.png", "firstReward": "https://uzi1.cn/api/link/completion/ABC123XYZ/first-reward.png", "midReward": "https://uzi1.cn/api/link/completion/ABC123XYZ/mid-reward.png", "endReward": "https://uzi1.cn/api/link/completion/ABC123XYZ/end-reward.png" } ``` ## ⚙️ 配置说明 在 `application.yml` 中配置: ```yaml # 完成图片存储配置 completion: image: storage: path: "./completion-images" # 图片存储路径 retention-hours: 24 # 图片保留时间(小时) ``` ### 配置项说明 | 配置项 | 说明 | 默认值 | |--------|------|--------| | `path` | 图片存储路径,支持相对路径和绝对路径 | `./completion-images` | | `retention-hours` | 图片保留时间(小时) | 24 | ### 生产环境建议 **推荐配置绝对路径:** ```yaml completion: image: storage: path: "/data/gameplatform/completion-images" ``` **磁盘空间预估:** - 单个任务:4张图片,约 800KB - 2MB - 每天100个任务:约 80MB - 200MB - 24小时滚动:约 80MB - 200MB ## 🔄 执行流程 ### 1. 图片保存流程 ```mermaid sequenceDiagram participant Detection as 完成检测服务 participant ImageService as 图片服务 participant ScriptClient as 脚本客户端 participant FileSystem as 文件系统 participant Database as 数据库 Detection->>Detection: 检测到任务完成 Detection->>ImageService: 异步保存图片 ImageService->>ScriptClient: 并发下载4张图片 ScriptClient-->>ImageService: 返回图片数据 ImageService->>FileSystem: 保存到本地 FileSystem-->>ImageService: 保存成功 ImageService->>Database: 更新图片信息 Database-->>ImageService: 更新完成 ``` ### 2. 清理流程 ``` 每小时第5分钟执行 ↓ 计算过期时间(当前时间 - 24小时) ↓ 查找过期的日期文件夹 ↓ 递归删除过期文件夹 ↓ 记录清理日志 ``` ## 🔒 安全配置 在 `SecurityConfig.java` 中已配置公开访问权限: ```java .pathMatchers(HttpMethod.GET, "/api/link/completion/**").permitAll() .pathMatchers(HttpMethod.HEAD, "/api/link/completion/**").permitAll() ``` **说明:** - 完成图片可以公开访问(无需认证) - 图片URL包含链接编号,具有一定的私密性 - 24小时后自动删除,减少泄露风险 ## 📊 监控和日志 ### 关键日志 **图片保存成功:** ``` INFO - 完成图片保存成功: codeNo=ABC123XYZ, imageInfo={...} ``` **图片保存失败:** ``` ERROR - 完成图片保存失败: codeNo=ABC123XYZ, error=... ``` **定时清理:** ``` INFO - === 完成图片清理任务完成:删除文件夹数=5, 耗时=234ms === ``` ### 监控指标 - 图片保存成功率 - 图片下载耗时 - 磁盘空间使用 - 清理任务执行情况 ## 🚀 部署步骤 ### 1. 数据库迁移 执行迁移脚本: ```bash # 文件位置: src/main/resources/db/migration/V20251103__add_completion_images_saved_at.sql mysql -u username -p database_name < V20251103__add_completion_images_saved_at.sql ``` 或者使用 Flyway 自动迁移(推荐)。 ### 2. 创建存储目录 ```bash # 创建图片存储目录 mkdir -p /data/gameplatform/completion-images # 设置权限 chown -R app_user:app_group /data/gameplatform/completion-images chmod 755 /data/gameplatform/completion-images ``` ### 3. 更新配置文件 修改 `application.yml`: ```yaml completion: image: storage: path: "/data/gameplatform/completion-images" ``` ### 4. 重启应用 ```bash systemctl restart gameplatform-server ``` ### 5. 验证功能 查看日志确认功能正常: ```bash tail -f logs/server.log | grep "完成图片" ``` ## 🔍 故障排查 ### 问题1:图片保存失败 **可能原因:** 1. 存储目录不存在或无写权限 2. 脚本端图片不存在 3. 网络连接问题 **排查步骤:** ```bash # 1. 检查目录权限 ls -la /data/gameplatform/completion-images # 2. 检查磁盘空间 df -h # 3. 查看详细日志 grep "完成图片保存失败" logs/server.log ``` ### 问题2:图片无法访问 **可能原因:** 1. 图片已被清理(超过24小时) 2. 图片保存时失败 3. 文件路径错误 **排查步骤:** ```bash # 查找特定任务的图片 find /data/gameplatform/completion-images -name "*ABC123XYZ*" # 检查数据库记录 SELECT code_no, completion_images, completion_images_saved_at FROM link_task WHERE code_no = 'ABC123XYZ'; ``` ### 问题3:磁盘空间不足 **解决方案:** 1. 调整保留时间(减少到12小时) 2. 增加磁盘空间 3. 配置日志轮转和压缩 ## 📝 注意事项 1. **异步执行**:图片保存是异步的,不会阻塞任务完成流程 2. **容错机制**:单张图片下载失败不影响其他图片 3. **自动清理**:超过24小时的图片会自动删除,无需手动维护 4. **并发安全**:使用日期文件夹隔离,避免并发冲突 5. **存储规划**:建议预留至少 500MB 磁盘空间 ## 🎓 使用示例 ### 前端获取完成图片 ```javascript // 获取所有图片URL fetch('/api/link/completion/ABC123XYZ/images') .then(res => res.json()) .then(urls => { console.log('首次主页:', urls.homepage); console.log('首次赏金:', urls.firstReward); console.log('中途赏金:', urls.midReward); console.log('结束赏金:', urls.endReward); }); // 直接显示图片 首次主页 ``` ### 查询数据库中的图片信息 ```sql -- 查询最近完成且有图片的任务 SELECT code_no, status, completed_points, completion_images_saved_at, JSON_EXTRACT(completion_images, '$.totalCount') as image_count FROM link_task WHERE status = 'COMPLETED' AND completion_images IS NOT NULL AND completion_images_saved_at > DATE_SUB(NOW(), INTERVAL 24 HOUR) ORDER BY completion_images_saved_at DESC LIMIT 10; ``` ## 🔮 未来优化方向 1. **CDN 集成**:将图片上传到 CDN,提高访问速度 2. **压缩优化**:自动压缩图片,减少存储空间 3. **备份机制**:定期备份重要图片到对象存储 4. **统计分析**:添加图片访问统计和热度分析 5. **批量下载**:支持批量导出完成图片 --- **最后更新时间:** 2025-11-03 **版本:** v1.0.0