# 游戏完成检测实现文档

## 📋 功能概述

实现了两种方式来自动检测游戏是否完成，并在检测到完成时自动更新链接状态为 `COMPLETED`，同时记录完成时的点数。

## 🔧 实现方案

### **方案1: 定时检查空闲设备**
- **触发方式**: 每1分钟自动执行
- **检查逻辑**: 
  1. 获取所有空闲设备列表
  2. 对每个空闲设备，查找是否有 `LOGGED_IN` 状态的链接任务使用该设备
  3. 如果找到，则将该链接任务标记为 `COMPLETED`，并记录当前点数

### **方案2: 选区请求时检查**
- **触发方式**: 用户发起选区请求时
- **检查逻辑**:
  1. 在分配新设备给用户前，先检查该设备是否空闲
  2. 如果设备空闲且有之前的 `LOGGED_IN` 状态链接任务，则标记为完成
  3. 然后继续正常的选区流程

## 🗄️ 数据库变更

### **1. link_task 表结构更新**

```sql
-- 添加完成时点数字段
ALTER TABLE `link_task` 
ADD COLUMN `completed_points` int UNSIGNED NULL DEFAULT NULL COMMENT '完成时的点数' 
AFTER `first_region_select_at`;

-- 更新状态枚举，添加 COMPLETED 状态
ALTER TABLE `link_task` 
MODIFY COLUMN `status` enum('NEW','USING','LOGGED_IN','COMPLETED','REFUNDED','EXPIRED') 
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NEW';
```

### **2. 状态流转图**

```
NEW (新建) 
  ↓
USING (使用中)
  ↓
LOGGED_IN (已登录)
  ↓
COMPLETED (正常完成) ← 新增状态
```

**终态状态**: `COMPLETED`, `REFUNDED`, `EXPIRED`

## 💻 代码实现

### **1. 核心服务类**

#### **DeviceStatusCheckService**
- 负责设备状态检查和链接任务更新逻辑
- 解析设备状态响应数据 (f0: 点数, f1: 状态)
- 更新相关链接任务为完成状态

#### **DeviceStatusCheckTask**
- 定时任务类，每分钟执行一次
- 获取空闲设备列表并逐个检查

### **2. API 接口更新**

#### **ScriptClient**
```java
// 新增方法：获取特定设备状态
public Mono<Map<String, Object>> getDeviceStatus(String machineId)
```

#### **DeviceStatusService**
```java
// 新增方法：解析特定设备状态
public Map<String, Object> parseDeviceStatusForMachine(String jsonResponse, String machineId)
```

#### **LinkTaskMapper**
```java
// 新增方法：根据设备ID和状态查询链接任务
List<LinkTask> findByMachineIdAndStatus(String machineId, String status);
```

### **3. 实体类更新**

#### **LinkTask**
```java
@TableField("completed_points")
private Integer completedPoints;  // 完成时的点数
```

## 📊 数据处理流程

### **设备状态数据格式**
```json
{
    "f0": {
        "val": "900",           // 当前点数
        "time": "2025-08-27 15:49:04"
    },
    "f1": {
        "val": "空闲",          // 设备状态
        "time": "2025-08-27 15:49:01"
    }
}
```

### **完成检测逻辑**
1. **获取设备状态**: 调用 `readAllMsg?文件名=判断分数` 接口
2. **解析状态**: 提取 f0(点数) 和 f1(状态) 信息
3. **判断空闲**: 检查 f1.val 是否为 "空闲"
4. **查找任务**: 根据 machine_id 和 status='LOGGED_IN' 查询链接任务
5. **更新状态**: 设置 status='COMPLETED', completed_points=f0.val

## 🔧 配置说明

### **定时任务配置**
- **执行频率**: 每60秒 (`@Scheduled(fixedRate = 60000)`)
- **启用方式**: 主应用类添加 `@EnableScheduling` 注解

### **日志记录**
- **定时检查**: `DEBUG` 级别，避免日志过多
- **状态更新**: `INFO` 级别，记录重要操作
- **异常处理**: `WARN/ERROR` 级别，不影响主流程

## 🚀 部署说明

### **1. 数据库迁移**
```bash
# 执行迁移脚本
mysql -u username -p database_name < docs/database_migration_add_completed_points.sql
```

### **2. 应用重启**
- 新增的定时任务会在应用启动后自动运行
- 选区请求的检查逻辑会立即生效

### **3. 验证方法**
1. **查看日志**: 观察定时任务执行日志
2. **数据库检查**: 验证 `completed_points` 字段是否正确填充
3. **API 测试**: 测试选区请求是否正常工作

## 📈 监控指标

### **关键日志**
- `=== 开始定时检查空闲设备 ===`
- `发现 X 个空闲设备: [设备列表]`
- `链接任务 X (代码: X) 已标记为完成，完成点数: X`

### **异常监控**
- 设备状态获取失败
- JSON 解析异常
- 数据库更新失败

## 🔄 扩展性

### **支持更多设备状态**
- 可扩展 DeviceStatusInfo 类添加更多状态字段
- 支持不同的完成判断条件

### **自定义检查频率**
- 通过配置文件调整定时任务执行频率
- 支持不同环境使用不同配置

### **完成通知**
- 可扩展添加完成通知功能 (邮件、短信、webhook等)
- 支持完成统计和报表功能

## ⚠️ 注意事项

1. **性能考虑**: 定时任务频率不宜过高，避免对系统造成压力
2. **异常处理**: 单个设备检查失败不应影响其他设备的检查
3. **数据一致性**: 使用事务确保状态更新的原子性
4. **日志管理**: 合理设置日志级别，避免日志过多影响性能
