9.0 KiB
9.0 KiB
完成图片保存功能说明
📋 功能概述
当游戏任务完成时,系统会自动保存4张关键截图到本地文件系统,并保留24小时。这些图片可以作为任务完成的证明和记录。
🎯 保存的图片
任务完成时会保存以下4张图片:
- 首次主页.png (homepage)
- 首次赏金.png (first-reward)
- 中途赏金.png (mid-reward)
- 结束赏金.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 示例:
{
"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. 获取单张图片
首次主页图片
GET /api/link/completion/{codeNo}/homepage.png
首次赏金图片
GET /api/link/completion/{codeNo}/first-reward.png
中途赏金图片
GET /api/link/completion/{codeNo}/mid-reward.png
结束赏金图片
GET /api/link/completion/{codeNo}/end-reward.png
响应示例:
- 成功:返回图片数据(image/png)
- 失败:404 Not Found
2. 获取所有图片URL列表
GET /api/link/completion/{codeNo}/images
响应示例:
{
"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 中配置:
# 完成图片存储配置
completion:
image:
storage:
path: "./completion-images" # 图片存储路径
retention-hours: 24 # 图片保留时间(小时)
配置项说明
| 配置项 | 说明 | 默认值 |
|---|---|---|
path |
图片存储路径,支持相对路径和绝对路径 | ./completion-images |
retention-hours |
图片保留时间(小时) | 24 |
生产环境建议
推荐配置绝对路径:
completion:
image:
storage:
path: "/data/gameplatform/completion-images"
磁盘空间预估:
- 单个任务:4张图片,约 800KB - 2MB
- 每天100个任务:约 80MB - 200MB
- 24小时滚动:约 80MB - 200MB
🔄 执行流程
1. 图片保存流程
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 中已配置公开访问权限:
.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. 数据库迁移
执行迁移脚本:
# 文件位置: 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. 创建存储目录
# 创建图片存储目录
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:
completion:
image:
storage:
path: "/data/gameplatform/completion-images"
4. 重启应用
systemctl restart gameplatform-server
5. 验证功能
查看日志确认功能正常:
tail -f logs/server.log | grep "完成图片"
🔍 故障排查
问题1:图片保存失败
可能原因:
- 存储目录不存在或无写权限
- 脚本端图片不存在
- 网络连接问题
排查步骤:
# 1. 检查目录权限
ls -la /data/gameplatform/completion-images
# 2. 检查磁盘空间
df -h
# 3. 查看详细日志
grep "完成图片保存失败" logs/server.log
问题2:图片无法访问
可能原因:
- 图片已被清理(超过24小时)
- 图片保存时失败
- 文件路径错误
排查步骤:
# 查找特定任务的图片
find /data/gameplatform/completion-images -name "*ABC123XYZ*"
# 检查数据库记录
SELECT code_no, completion_images, completion_images_saved_at
FROM link_task
WHERE code_no = 'ABC123XYZ';
问题3:磁盘空间不足
解决方案:
- 调整保留时间(减少到12小时)
- 增加磁盘空间
- 配置日志轮转和压缩
📝 注意事项
- 异步执行:图片保存是异步的,不会阻塞任务完成流程
- 容错机制:单张图片下载失败不影响其他图片
- 自动清理:超过24小时的图片会自动删除,无需手动维护
- 并发安全:使用日期文件夹隔离,避免并发冲突
- 存储规划:建议预留至少 500MB 磁盘空间
🎓 使用示例
前端获取完成图片
// 获取所有图片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);
});
// 直接显示图片
<img src="/api/link/completion/ABC123XYZ/homepage.png" alt="首次主页" />
查询数据库中的图片信息
-- 查询最近完成且有图片的任务
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;
🔮 未来优化方向
- CDN 集成:将图片上传到 CDN,提高访问速度
- 压缩优化:自动压缩图片,减少存储空间
- 备份机制:定期备份重要图片到对象存储
- 统计分析:添加图片访问统计和热度分析
- 批量下载:支持批量导出完成图片
最后更新时间: 2025-11-03
版本: v1.0.0