# Game Interface 接口新增完成时间 ## ✅ 修改完成 在 `/api/link/{codeNo}/game-interface` 接口响应中新增了 `completedAt`(完成时间)和 `status`(任务状态)字段。 ## 📦 修改的文件 1. **GameInterfaceResponse.java** - 响应DTO - 新增 `status` 字段(任务状态) - 新增 `completedAt` 字段(完成时间) 2. **QrProxyController.java** - 控制器 - 设置 `status` 字段 - 仅当任务完成时设置 `completedAt` 字段 ## 📊 接口响应示例 ### 任务进行中(NEW / USING / LOGGED_IN) ```json { "codeNo": "MYNM5JHA", "totalPoints": 1000, "quantity": 100, "times": 10, "region": "Q", "regionDesc": "QQ区", "machineId": "rr3", "completedPoints": null, "status": "LOGGED_IN", "completedAt": null, "qrCodeUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/qr.png", "homepageUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/homepage.png", "firstRewardUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/first-reward.png", "midRewardUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/mid-reward.png", "endRewardUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/end-reward.png", "progressDisplayFormat": "percent" } ``` ### 任务已完成(COMPLETED)✨ ```json { "codeNo": "MYNM5JHA", "totalPoints": 1000, "quantity": 100, "times": 10, "region": "Q", "regionDesc": "QQ区", "machineId": "rr3", "completedPoints": 1000, "status": "COMPLETED", "completedAt": 1730644245, "qrCodeUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/qr.png", "homepageUrl": "https://uzi1.cn/api/link/completion/MYNM5JHA/homepage.png", "firstRewardUrl": "https://uzi1.cn/api/link/completion/MYNM5JHA/first-reward.png", "midRewardUrl": "https://uzi1.cn/api/link/completion/MYNM5JHA/mid-reward.png", "endRewardUrl": "https://uzi1.cn/api/link/completion/MYNM5JHA/end-reward.png", "progressDisplayFormat": "percent" } ``` ## 🎯 新增字段说明 ### status(任务状态) | 字段名 | 类型 | 说明 | 示例 | |--------|------|------|------| | `status` | String | 任务当前状态 | `"COMPLETED"` | **可能的值**: - `NEW`: 新建 - `USING`: 使用中 - `LOGGED_IN`: 已登录 - `COMPLETED`: 已完成 ✨ - `REFUNDED`: 已退款 - `EXPIRED`: 已过期 --- ### completedAt(完成时间戳) | 字段名 | 类型 | 说明 | 示例 | |--------|------|------|------| | `completedAt` | Long | 任务完成时间戳(秒级) | `1730644245` | **特点**: - ✅ 仅当 `status` 为 `COMPLETED` 时有值 - ✅ 使用 Unix 时间戳(秒级,10位数字) - ✅ 其他状态下为 `null` - ✅ 可直接用于前端时间处理 --- ## 🔧 实现逻辑 ```java // 设置状态 response.setStatus(linkTask.getStatus()); // 设置完成时间戳-秒级(仅当任务完成时) if ("COMPLETED".equals(linkTask.getStatus()) && linkTask.getUpdatedAt() != null) { // 转换为秒级时间戳 long epochSecond = linkTask.getUpdatedAt() .atZone(java.time.ZoneId.systemDefault()) .toEpochSecond(); response.setCompletedAt(epochSecond); } ``` ## 💡 前端使用示例 ### JavaScript/TypeScript ```javascript // 获取游戏界面数据 fetch(`/api/link/${codeNo}/game-interface`) .then(res => res.json()) .then(data => { console.log('任务状态:', data.status); // 判断任务是否完成 if (data.status === 'COMPLETED' && data.completedAt) { console.log('完成时间戳:', data.completedAt); // 将秒级时间戳转换为毫秒(JavaScript Date需要毫秒) const completedTime = new Date(data.completedAt * 1000); console.log('格式化时间:', completedTime.toLocaleString('zh-CN')); // 输出: 2025/11/3 20:30:45 // 计算完成了多久 const now = new Date(); const diffMs = now - completedTime; const diffMins = Math.floor(diffMs / 60000); console.log(`${diffMins} 分钟前完成`); // 显示完成图片 document.getElementById('homepage').src = data.homepageUrl; document.getElementById('firstReward').src = data.firstRewardUrl; document.getElementById('midReward').src = data.midRewardUrl; document.getElementById('endReward').src = data.endRewardUrl; } else { console.log('任务进行中...'); } }); ``` ### Vue/React 组件示例 ```javascript // Vue 3 Composition API import { ref, computed } from 'vue'; const gameData = ref(null); // 格式化完成时间 const formattedCompletedTime = computed(() => { if (gameData.value?.completedAt) { // 秒级时间戳转毫秒 const date = new Date(gameData.value.completedAt * 1000); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); } return null; }); // 计算完成多久 const completedAgo = computed(() => { if (gameData.value?.completedAt) { // 秒级时间戳转毫秒 const completedTime = new Date(gameData.value.completedAt * 1000); const now = new Date(); const diffMs = now - completedTime; const diffMins = Math.floor(diffMs / 60000); if (diffMins < 1) return '刚刚完成'; if (diffMins < 60) return `${diffMins} 分钟前`; const diffHours = Math.floor(diffMins / 60); if (diffHours < 24) return `${diffHours} 小时前`; const diffDays = Math.floor(diffHours / 24); return `${diffDays} 天前`; } return null; }); ``` ## 📱 UI 显示建议 ### 完成状态显示 ```html