优化API请求,移除时间戳参数以简化链接生成,更新二维码提示信息,调整区域选择按钮样式,提升用户交互体验

This commit is contained in:
zyh
2025-11-06 22:50:44 +08:00
parent e2a9fef1d0
commit e8c9e80002
8 changed files with 59 additions and 24 deletions

View File

@@ -6,7 +6,7 @@ import http from '@/plugins/http'
// 获取链接状态
export function getLinkStatus(code) {
return http.get(`/api/link/status?t=${Date.now()}`, {
return http.get('/api/link/status', {
params: { code }
})
}
@@ -34,12 +34,12 @@ export function pollLoginStatus(code) {
// 获取游戏界面数据
export function getGameInterface(code) {
return http.get(`/api/link/${code}/game-interface?t=${Date.now()}`)
return http.get(`/api/link/${code}/game-interface`)
}
// 获取二维码图片(可选,用于代理二维码避免混合内容问题)
export function getQRCode(code) {
return http.get(`/api/link/qr.png?t=${Date.now()}`, {
return http.get('/api/link/qr.png', {
params: { code },
responseType: 'blob'
})

View File

@@ -21,7 +21,7 @@
<!-- 二维码区域 -->
<div v-else-if="qrInfo && countdown > 0" class="qr-container">
<div class="qr-section">
<div class="qr-title">回验证码扫码</div>
<div class="qr-title">请尽快完成扫码!</div>
<div class="qr-wrapper">
<img :src="qrInfo.url" class="qr-code" alt="扫码登录" @error="$emit('qrImageError', $event)" @load="$emit('qrImageLoad', $event)" />
</div>

View File

@@ -33,8 +33,10 @@
@click="confirmSelection"
class="confirm-btn"
:disabled="!selectedRegion || submitting"
:class="{ 'loading': submitting }"
>
确认选择
<span v-if="submitting" class="loading-spinner"></span>
<span>{{ submitting ? '正在连接...' : '确认选择' }}</span>
</button>
</div>
@@ -44,6 +46,7 @@
@click="selectRegionOption('Q')"
class="option-btn qq-option"
:class="{ 'selected': selectedRegion === 'QQ区' }"
:disabled="submitting"
>
<div class="option-icon qq-icon">
<svg viewBox="0 0 24 24" width="32" height="32" fill="currentColor">
@@ -57,6 +60,7 @@
@click="selectRegionOption('V')"
class="option-btn wx-option"
:class="{ 'selected': selectedRegion === '微信区' }"
:disabled="submitting"
>
<div class="option-icon wx-icon">
<svg viewBox="0 0 24 24" width="32" height="32" fill="currentColor">
@@ -241,6 +245,10 @@ export default {
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
display: flex;
align-items: center;
gap: 8px;
justify-content: center;
}
.confirm-btn:hover:not(:disabled) {
@@ -253,6 +261,27 @@ export default {
cursor: not-allowed;
}
.confirm-btn.loading {
opacity: 0.8;
cursor: wait;
}
/* Loading Spinner */
.loading-spinner {
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* 选择区域按钮 */
.region-options {
flex: 1;
@@ -278,11 +307,16 @@ export default {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.option-btn:hover {
.option-btn:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.option-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.option-icon {
width: 60px;
height: 60px;

View File

@@ -112,7 +112,7 @@ export function usePlayState() {
state.status = 'LOGGED_IN'
state.assets = {
qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${new Date().getTime()}` : null,
qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${Date.now()}` : null,
...(gameData.assets || {})
}

View File

@@ -61,7 +61,7 @@ export function useTimers() {
} catch (error) {
console.error('轮询错误:', error)
}
}, 1000)
}, 3000) // 修改轮询间隔从1秒改为3秒
}
const startProgressPolling = (code, onProgressUpdate) => {

View File

@@ -5,19 +5,17 @@ export const LINK_CONFIG = {
// 基础域名 - 生产环境需要修改为实际域名
BASE_URL: import.meta.env.VITE_BASE_URL || 'http://localhost:5173',
// 游戏页面路径
GAME_PATH: '/play',
// 游戏页面路径(已缩短为空,新生成的链接使用短格式,旧链接 /play/:code 仍然兼容)
GAME_PATH: '',
// 机器编号参数名
CODE_PARAM: 'code',
// 链接地址模板
getLinkUrl: (codeNo) => {
// 生成随机参数:时间戳 + 随机字符串
const timestamp = Date.now()
const random = Math.random().toString(36).substring(2, 8)
const randomParam = `${timestamp}${random}`
return `${LINK_CONFIG.BASE_URL}${LINK_CONFIG.GAME_PATH}/${codeNo}?t=${randomParam}`
// 如果 GAME_PATH 为空,直接拼接;否则添加斜杠
const path = LINK_CONFIG.GAME_PATH ? `${LINK_CONFIG.GAME_PATH}/${codeNo}` : `/${codeNo}`
return `${LINK_CONFIG.BASE_URL}${path}`
}
}

View File

@@ -15,8 +15,9 @@ const NotFound = () => import('@/views/NotFound.vue')
export const routes = [
{ path: '/login', name: 'Login', component: Login, meta: { public: true, title: '登录' } },
{ path: '/play/:code', name: 'Play', component: Play, meta: { public: true, title: '上号任务' } },
{ path: '/play', name: 'PlayLegacy', component: Play, meta: { public: true, title: '上号任务' } },
// 保留旧的 /play/:code 路由用于兼容旧链接
{ path: '/play/:code', name: 'PlayLegacy', component: Play, meta: { public: true, title: '上号任务' } },
{ path: '/play', name: 'PlayLegacyNoCode', component: Play, meta: { public: true, title: '上号任务' } },
{
path: '/',
component: AdminLayout,
@@ -41,6 +42,8 @@ export const routes = [
{ path: 'announcements', name: 'Announcements', component: AnnouncementList, meta: { title: '公告管理' } },
],
},
// 新的短链接路由放在最后NotFound之前用于新生成的链接
{ path: '/:code', name: 'Play', component: Play, meta: { public: true, title: '上号任务' } },
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound, meta: { public: true, title: '未找到' } },
]

View File

@@ -325,18 +325,18 @@ export default {
midRewardUrl: gameData.midRewardUrl,
endRewardUrl: gameData.endRewardUrl,
qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${new Date().getTime()}` : null,
qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${Date.now()}` : null,
// 保留原有的assets数据如果存在
...(gameData.assets || {})
}
}else{
state.assets = {
homepageUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/首次主页.png?t=${new Date().getTime()}` : null,
firstRewardUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/首次赏金.png?t=${new Date().getTime()}` : null,
midRewardUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/中途赏金.png?t=${new Date().getTime()}` : null,
endRewardUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/结束赏金.png?t=${new Date().getTime()}` : null,
homepageUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/首次主页.png?t=${Date.now()}` : null,
firstRewardUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/首次赏金.png?t=${Date.now()}` : null,
midRewardUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/中途赏金.png?t=${Date.now()}` : null,
endRewardUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/结束赏金.png?t=${Date.now()}` : null,
qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${new Date().getTime()}` : null,
qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${Date.now()}` : null,
// 保留原有的assets数据如果存在
...(gameData.assets || {})
@@ -791,7 +791,7 @@ export default {
} catch (error) {
console.error('轮询错误:', error)
}
}, 1000)
}, 3000) // 修改轮询间隔从1秒改为3秒
}
// 开始进度轮询