# 前端链接访问示例
## 概述
当用户访问链接页面时(如 `https://你的域名/ABC12345`),前端需要自动请求后端获取链接的详细信息,并根据状态显示相应的内容。
## 接口说明
### 1. 获取链接状态(主要接口)
**推荐格式(路径参数):**
```
GET /api/link/{code}/status
```
**兼容格式(查询参数,兼容旧版):**
```
GET /api/link/status?code={code}
GET /api/link/status?codeNo={codeNo}
GET /api/link/status?linkId={linkId}
```
> 💡 **推荐使用路径参数格式**,因为复制粘贴时不容易丢失参数,更符合 RESTful 规范。查询参数格式保留用于兼容已生成的旧链接。
**响应示例:**
```json
{
"codeNo": "ABC12345",
"batchId": 123,
"status": "NEW",
"statusDesc": "新建",
"expireAt": "2024-01-15T16:30:00",
"isExpired": false,
"remainingSeconds": 3600,
"quantity": 50,
"times": 10,
"totalPoints": 500,
"region": null,
"machineId": null,
"loginAt": null,
"createdAt": "2024-01-15T12:00:00",
"updatedAt": "2024-01-15T12:00:00"
}
```
### 2. 检查链接是否存在
```
GET /api/link/{codeNo}/exists
```
**响应:** `true` 或 `false`
### 3. 检查链接是否有效
```
GET /api/link/{codeNo}/valid
```
**响应:** `true` 或 `false`
## 前端实现示例
### React 组件示例
```jsx
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
const LinkPage = () => {
const { codeNo } = useParams();
const [linkStatus, setLinkStatus] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetchLinkStatus();
}, [codeNo]);
const fetchLinkStatus = async () => {
try {
setLoading(true);
// 使用路径参数格式,更不容易丢失链接信息
const response = await fetch(`/api/link/${codeNo}/status`);
if (!response.ok) {
if (response.status === 404) {
setError('链接不存在');
} else {
setError('获取链接信息失败');
}
return;
}
const data = await response.json();
setLinkStatus(data);
} catch (err) {
setError('网络错误');
console.error('获取链接状态失败:', err);
} finally {
setLoading(false);
}
};
const formatTime = (seconds) => {
if (seconds <= 0) return '已过期';
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
if (hours > 0) {
return `${hours}小时${minutes}分钟`;
} else if (minutes > 0) {
return `${minutes}分钟${secs}秒`;
} else {
return `${secs}秒`;
}
};
if (loading) {
return
加载中...
;
}
if (error) {
return (
链接错误
{error}
链接编号: {codeNo}
);
}
if (!linkStatus) {
return 未找到链接信息
;
}
return (
游戏任务链接
链接编号: {linkStatus.codeNo}
状态:
{linkStatus.statusDesc}
任务信息:
打{linkStatus.times}次副本,每次{linkStatus.quantity}点
(总计{linkStatus.totalPoints}点)
过期时间:
{linkStatus.expireAt}
剩余时间:
{formatTime(linkStatus.remainingSeconds)}
{linkStatus.isExpired && (
)}
{!linkStatus.isExpired && linkStatus.status === 'NEW' && (
开始任务
点击下方按钮开始执行任务
)}
{linkStatus.status === 'USING' && (
)}
{linkStatus.status === 'LOGGED_IN' && (
任务完成
恭喜!任务已完成,奖励点数已发放
获得奖励: {linkStatus.totalPoints} 点
)}
扫码访问
使用手机扫描二维码访问
);
};
const startTask = () => {
// 实现开始任务的逻辑
console.log('开始任务');
};
export default LinkPage;
```
### Vue 组件示例
```vue
加载中...
链接错误
{{ error }}
链接编号: {{ codeNo }}
状态:
{{ linkStatus.statusDesc }}
任务信息:
打{{ linkStatus.times }}次副本,每次{{ linkStatus.quantity }}点
(总计{{ linkStatus.totalPoints }}点)
剩余时间:
{{ formatTime(linkStatus.remainingSeconds) }}
开始任务
扫码访问
```
## 路由配置
### React Router
```jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import LinkPage from './components/LinkPage';
function App() {
return (
} />
{/* 其他路由 */}
);
}
```
### Vue Router
```javascript
import { createRouter, createWebHistory } from 'vue-router';
import LinkPage from '@/components/LinkPage.vue';
const routes = [
{
path: '/:codeNo',
name: 'LinkPage',
component: LinkPage
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
```
## 使用流程
1. **用户访问链接**:`https://你的域名/ABC12345`
2. **前端自动请求**:调用 `/api/link/ABC12345/status` 获取链接信息(使用路径参数,更不容易丢失)
3. **显示相应内容**:根据链接状态显示不同的界面
4. **实时更新**:可以定时刷新状态,显示剩余时间等
## 接口格式说明
系统同时支持两种访问格式,保证新旧链接都能正常使用:
### 方式一:路径参数格式(推荐 ⭐)
```
GET /api/link/{code}/status
```
**示例:**
```javascript
fetch('/api/link/ABC12345/status')
```
**优势:**
- ✅ 复制粘贴时不会丢失参数
- ✅ 符合 RESTful 设计规范
- ✅ URL 结构更清晰
- ✅ 浏览器地址栏直接可见完整路径
### 方式二:查询参数格式(兼容旧版)
```
GET /api/link/status?code={code}
GET /api/link/status?codeNo={codeNo}
GET /api/link/status?linkId={linkId}
```
**示例:**
```javascript
fetch('/api/link/status?code=ABC12345')
fetch('/api/link/status?codeNo=ABC12345')
fetch('/api/link/status?linkId=123')
```
**说明:**
- 保留此格式用于兼容已生成的旧链接
- 支持 `code`、`codeNo`、`linkId` 三种参数名
- `linkId` 和 `code/codeNo` 至少提供一个即可
### 兼容性保证
- ✅ 两种格式返回完全相同的数据结构
- ✅ 旧链接继续有效,无需修改
- ✅ 新生成的链接推荐使用路径参数格式
## 注意事项
1. **错误处理**:处理链接不存在、已过期等情况
2. **加载状态**:显示加载中的状态,提升用户体验
3. **响应式设计**:确保在不同设备上都能正常显示
4. **缓存策略**:可以适当缓存链接状态,减少请求次数
5. **实时更新**:对于进行中的任务,可以定时刷新状态