Files
game_server/API_COMPLETION_TIMESTAMP.md

306 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Game Interface API - 完成时间戳快速参考
## 📡 接口
```
GET /api/link/{codeNo}/game-interface
```
## 📊 响应字段(新增)
### completedAt - 完成时间戳
| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| `completedAt` | `Long` | 秒级Unix时间戳 | `1730644245` |
| `status` | `String` | 任务状态 | `"COMPLETED"` |
## 💡 特点
-**秒级时间戳**10位数字`1730644245`
-**仅完成时有值**:只有 `status === "COMPLETED"` 时才有值
-**其他状态为null**:未完成的任务返回 `null`
## 🎯 响应示例
### 任务完成时
```json
{
"codeNo": "MYNM5JHA",
"status": "COMPLETED",
"completedAt": 1730644245,
"completedPoints": 1000,
"totalPoints": 1000,
"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",
...
}
```
### 任务进行中
```json
{
"codeNo": "MYNM5JHA",
"status": "LOGGED_IN",
"completedAt": null,
"completedPoints": null,
"homepageUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/homepage.png",
...
}
```
## 🔧 前端使用JavaScript
### 基础用法
```javascript
fetch(`/api/link/${codeNo}/game-interface`)
.then(res => res.json())
.then(data => {
if (data.status === 'COMPLETED' && data.completedAt) {
// 秒级时间戳需要 * 1000 转换为毫秒
const completedTime = new Date(data.completedAt * 1000);
console.log('完成时间:', completedTime.toLocaleString('zh-CN'));
}
});
```
### 格式化时间
```javascript
// 方法1: 原生 JavaScript
const formatTimestamp = (timestamp) => {
const date = new Date(timestamp * 1000); // 秒转毫秒
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
};
console.log(formatTimestamp(1730644245));
// 输出: 2025/11/03 20:30:45
// 方法2: 使用 dayjs
import dayjs from 'dayjs';
console.log(dayjs.unix(1730644245).format('YYYY-MM-DD HH:mm:ss'));
// 输出: 2025-11-03 20:30:45
// 方法3: 使用 moment
import moment from 'moment';
console.log(moment.unix(1730644245).format('YYYY-MM-DD HH:mm:ss'));
// 输出: 2025-11-03 20:30:45
```
### 计算完成多久
```javascript
const getTimeAgo = (timestamp) => {
const completedTime = new Date(timestamp * 1000);
const now = new Date();
const diffSeconds = Math.floor((now - completedTime) / 1000);
if (diffSeconds < 60) return `${diffSeconds} 秒前`;
const diffMins = Math.floor(diffSeconds / 60);
if (diffMins < 60) return `${diffMins} 分钟前`;
const diffHours = Math.floor(diffMins / 60);
if (diffHours < 24) return `${diffHours} 小时前`;
const diffDays = Math.floor(diffHours / 24);
return `${diffDays} 天前`;
};
console.log(getTimeAgo(1730644245));
// 输出: 5 分钟前
```
## 🎨 Vue 组件示例
```vue
<template>
<div v-if="gameData">
<!-- 状态徽章 -->
<div class="status-badge" :class="statusClass">
{{ statusText }}
</div>
<!-- 完成信息仅完成时显示 -->
<div v-if="gameData.status === 'COMPLETED'" class="completion-info">
<div class="completion-time">
<span class="label">完成时间:</span>
<span class="value">{{ formattedCompletedTime }}</span>
</div>
<div class="time-ago">{{ completedAgo }}</div>
<div class="points">
完成点数: {{ gameData.completedPoints }} / {{ gameData.totalPoints }}
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const gameData = ref(null);
// 状态类名
const statusClass = computed(() => {
const classMap = {
'NEW': 'status-new',
'USING': 'status-using',
'LOGGED_IN': 'status-logged-in',
'COMPLETED': 'status-completed',
'REFUNDED': 'status-refunded',
'EXPIRED': 'status-expired'
};
return classMap[gameData.value?.status] || 'status-default';
});
// 状态文本
const statusText = computed(() => {
const textMap = {
'NEW': '等待开始',
'USING': '使用中',
'LOGGED_IN': '游戏中',
'COMPLETED': '已完成',
'REFUNDED': '已退款',
'EXPIRED': '已过期'
};
return textMap[gameData.value?.status] || '未知';
});
// 格式化完成时间
const formattedCompletedTime = computed(() => {
if (gameData.value?.completedAt) {
const date = new Date(gameData.value.completedAt * 1000);
return date.toLocaleString('zh-CN');
}
return '';
});
// 完成多久前
const completedAgo = computed(() => {
if (!gameData.value?.completedAt) return '';
const completedTime = new Date(gameData.value.completedAt * 1000);
const now = new Date();
const diffSeconds = Math.floor((now - completedTime) / 1000);
if (diffSeconds < 60) return `${diffSeconds} 秒前`;
const diffMins = Math.floor(diffSeconds / 60);
if (diffMins < 60) return `${diffMins} 分钟前`;
const diffHours = Math.floor(diffMins / 60);
if (diffHours < 24) return `${diffHours} 小时前`;
const diffDays = Math.floor(diffHours / 24);
return `${diffDays} 天前`;
});
// 加载数据
const loadGameData = async (codeNo) => {
const res = await fetch(`/api/link/${codeNo}/game-interface`);
gameData.value = await res.json();
};
</script>
<style scoped>
.status-badge {
display: inline-block;
padding: 6px 16px;
border-radius: 20px;
font-weight: 600;
font-size: 14px;
}
.status-completed {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.completion-info {
margin-top: 16px;
padding: 16px;
background: #f8f9fa;
border-radius: 8px;
}
.completion-time {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.time-ago {
color: #6c757d;
font-size: 13px;
}
</style>
```
## 🔍 时间戳对照表
| 时间戳 | 日期时间(北京时间) |
|--------|---------------------|
| `1730644245` | 2025-11-03 20:30:45 |
| `1730640000` | 2025-11-03 19:20:00 |
| `1730635200` | 2025-11-03 18:00:00 |
## 🧪 快速测试
```bash
# 测试接口
curl "http://localhost:18080/api/link/MYNM5JHA/game-interface" | jq '.completedAt'
# 转换时间戳Linux/Mac
date -r 1730644245
# 或
date -d @1730644245
```
## ⚡ 常见时间处理库
### JavaScript
```bash
# dayjs (推荐 - 轻量)
npm install dayjs
# moment.js (功能强大)
npm install moment
# date-fns (函数式)
npm install date-fns
```
### 使用 dayjs
```javascript
import dayjs from 'dayjs';
// 格式化
dayjs.unix(1730644245).format('YYYY-MM-DD HH:mm:ss');
// 相对时间
import relativeTime from 'dayjs/plugin/relativeTime';
import 'dayjs/locale/zh-cn';
dayjs.extend(relativeTime);
dayjs.locale('zh-cn');
dayjs.unix(1730644245).fromNow(); // "5分钟前"
```
---
**更新时间**: 2025-11-03
**格式**: Unix时间戳秒级
**状态**: ✅ 已完成