Files
game_server/docs/完成图片保存功能说明.md

9.0 KiB
Raw Permalink Blame History

完成图片保存功能说明

📋 功能概述

当游戏任务完成时系统会自动保存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 示例:

{
  "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. 存储目录不存在或无写权限
  2. 脚本端图片不存在
  3. 网络连接问题

排查步骤:

# 1. 检查目录权限
ls -la /data/gameplatform/completion-images

# 2. 检查磁盘空间
df -h

# 3. 查看详细日志
grep "完成图片保存失败" logs/server.log

问题2图片无法访问

可能原因:

  1. 图片已被清理超过24小时
  2. 图片保存时失败
  3. 文件路径错误

排查步骤:

# 查找特定任务的图片
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 磁盘空间

🎓 使用示例

前端获取完成图片

// 获取所有图片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;

🔮 未来优化方向

  1. CDN 集成:将图片上传到 CDN提高访问速度
  2. 压缩优化:自动压缩图片,减少存储空间
  3. 备份机制:定期备份重要图片到对象存储
  4. 统计分析:添加图片访问统计和热度分析
  5. 批量下载:支持批量导出完成图片

最后更新时间: 2025-11-03
版本: v1.0.0