7.0 KiB
7.0 KiB
Game Interface API - 完成时间戳快速参考
📡 接口
GET /api/link/{codeNo}/game-interface
📊 响应字段(新增)
completedAt - 完成时间戳
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
completedAt |
Long |
秒级Unix时间戳 | 1730644245 |
status |
String |
任务状态 | "COMPLETED" |
💡 特点
- ✅ 秒级时间戳:10位数字,如
1730644245 - ✅ 仅完成时有值:只有
status === "COMPLETED"时才有值 - ✅ 其他状态为null:未完成的任务返回
null
🎯 响应示例
任务完成时
{
"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",
...
}
任务进行中
{
"codeNo": "MYNM5JHA",
"status": "LOGGED_IN",
"completedAt": null,
"completedPoints": null,
"homepageUrl": "https://uzi1.cn/api/link/image/MYNM5JHA/homepage.png",
...
}
🔧 前端使用(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'));
}
});
格式化时间
// 方法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
计算完成多久
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 组件示例
<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 |
🧪 快速测试
# 测试接口
curl "http://localhost:18080/api/link/MYNM5JHA/game-interface" | jq '.completedAt'
# 转换时间戳(Linux/Mac)
date -r 1730644245
# 或
date -d @1730644245
⚡ 常见时间处理库
JavaScript
# dayjs (推荐 - 轻量)
npm install dayjs
# moment.js (功能强大)
npm install moment
# date-fns (函数式)
npm install date-fns
使用 dayjs
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时间戳(秒级)
状态: ✅ 已完成