import { reactive } from 'vue' import { useRoute, useRouter } from 'vue-router' import { ElMessage } from 'element-plus' import { getLinkStatus, selectRegion as selectRegionAPI, refreshLink as refreshLinkAPI, getGameInterface as getGameInterfaceAPI } from '@/api/play' export function usePlayState() { const route = useRoute() const router = useRouter() const state = reactive({ code: '', status: 'NEW', loading: true, submitting: false, needRefresh: false, region: null, regionDesc: null, qrInfo: null, assets: null, currentPoints: 0, totalPoints: null, // 修改:初始值改为null,等待从API获取真实数据 completedPoints: 0, progressDisplayFormat: '1', error: null, qrDelaySeconds: 0, isWaitingQr: false, qrRetryCount: 0, maxQrRetries: 3, qrRetryDelay: 2000, qrError: null, mecmachineId: null, machineId: null, qrCreatedAt: null, qrExpireAt: null, qrDelayTimeoutId: null, completedAt: null, isCompletedExpired: false }) const initializePage = async () => { try { await fetchStatus() } catch (error) { handleError(error) } finally { state.loading = false } } const fetchStatus = async () => { try { const response = await getLinkStatus(state.code) const data = response.data await updateStateFromResponse(data) // 如果是NEW状态,尝试获取游戏界面数据以获取totalPoints if (data.status === 'NEW') { try { const gameResponse = await getGameInterfaceAPI(state.code) const gameData = gameResponse.data console.log('NEW状态 - 游戏界面数据:', gameData) // 更新totalPoints和其他可用数据 if (gameData.totalPoints !== undefined && gameData.totalPoints !== null) { state.totalPoints = gameData.totalPoints console.log('从游戏界面获取到totalPoints:', state.totalPoints) } if (gameData.completedPoints !== undefined) { state.completedPoints = gameData.completedPoints } if (gameData.progressDisplayFormat) { state.progressDisplayFormat = String(gameData.progressDisplayFormat) } } catch (gameError) { // 游戏界面数据获取失败不影响主流程,只记录日志 console.log('NEW状态获取游戏界面数据失败(这是正常的):', gameError.message) } } } catch (error) { throw error } } const getGameInterface = async () => { try { console.log('调用游戏界面接口,code:', state.code) const response = await getGameInterfaceAPI(state.code) console.log('游戏界面接口响应:', response.data) return response } catch (error) { console.error('获取游戏界面数据失败:', error) ElMessage.error('获取游戏界面数据失败') throw error } } const handleLoggedInStatus = async () => { try { console.log('检测到LOGGED_IN状态,获取游戏界面数据') const gameResponse = await getGameInterface() const gameData = gameResponse.data console.log('游戏界面数据:', gameData) state.status = 'LOGGED_IN' state.assets = { qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${Date.now()}` : null, ...(gameData.assets || {}) } console.log('更新区域信息:', { gameDataRegion: gameData.region, originalStateRegion: state.region }) if (gameData.region) { state.region = gameData.region console.log('已设置 state.region =', state.region) } else { console.log('gameData.region 为空,未更新 state.region') } if (gameData.regionDesc) { state.regionDesc = gameData.regionDesc } if (gameData.mecmachineId) { state.mecmachineId = gameData.mecmachineId } if (gameData.machineId) { state.machineId = gameData.machineId } if (gameData.totalPoints) { state.totalPoints = gameData.totalPoints } else if (gameData.assets && gameData.assets.totalPoints) { state.totalPoints = gameData.assets.totalPoints } state.completedPoints = gameData.completedPoints || 0 if (gameData.progressDisplayFormat) { state.progressDisplayFormat = String(gameData.progressDisplayFormat) } state.currentPoints = 0 console.log('handleLoggedInStatus 执行完成,最终状态:', { status: state.status, region: state.region, totalPoints: state.totalPoints, completedPoints: state.completedPoints, mecmachineId: state.mecmachineId }) ElMessage.success('登录成功,正在进入游戏界面...') } catch (error) { console.error('获取游戏界面数据失败:', error) ElMessage.error('获取游戏数据失败,请稍后重试') } } const handleCompletedStatus = async () => { try { const gameResponse = await getGameInterfaceAPI(state.code) const gameData = gameResponse.data console.log('已完成状态 - 游戏界面数据:', gameData) state.status = 'COMPLETED' // 保存完成时间戳 if (gameData.completedAt) { state.completedAt = gameData.completedAt // 判断是否超过24小时 const now = Math.floor(Date.now() / 1000) // 当前时间戳(秒) const completedTime = gameData.completedAt const hoursPassed = (now - completedTime) / 3600 // 转换为小时 state.isCompletedExpired = hoursPassed > 24 console.log('完成时间判断:', { completedAt: completedTime, now: now, hoursPassed: hoursPassed.toFixed(2), isExpired: state.isCompletedExpired }) } // 更新区域和机器信息 if (gameData.region) { state.region = gameData.region } if (gameData.regionDesc) { state.regionDesc = gameData.regionDesc } if (gameData.mecmachineId) { state.mecmachineId = gameData.mecmachineId } if (gameData.machineId) { state.machineId = gameData.machineId } state.assets = { qrCodeUrl: gameData.mecmachineId ? `https://uzi1.cn/image/${gameData.mecmachineId}/二维码.png?t=${Date.now()}` : null } state.totalPoints = gameData.totalPoints || 50 state.completedPoints = gameData.completedPoints || state.totalPoints if (gameData.progressDisplayFormat) { state.progressDisplayFormat = String(gameData.progressDisplayFormat) } state.currentPoints = state.totalPoints console.log('已完成状态更新完成:', { status: state.status, totalPoints: state.totalPoints, completedPoints: state.completedPoints, currentPoints: state.currentPoints, completedAt: state.completedAt, isCompletedExpired: state.isCompletedExpired, assets: !!state.assets }) } catch (error) { console.error('获取已完成状态游戏数据失败:', error) state.status = 'COMPLETED' ElMessage.error('获取游戏数据失败,但订单已完成') } } const updateStateFromResponse = async (data, skipQrProcessing = false) => { if (data.status === 'LOGGED_IN') { await handleLoggedInStatus() return } if (data.status === 'COMPLETED') { await handleCompletedStatus() return } state.status = data.status state.needRefresh = data.needRefresh || false state.region = data.region state.regionDesc = data.regionDesc || null state.assets = data.assets state.mecmachineId = data.mecmachineId || null state.machineId = data.machineId || null if (data.qrCreatedAt) { state.qrCreatedAt = data.qrCreatedAt } if (data.qrExpireAt) { state.qrExpireAt = data.qrExpireAt } // 优先使用 data.totalPoints,确保在NEW状态也能获取到目标点数 if (data.totalPoints !== undefined && data.totalPoints !== null) { state.totalPoints = data.totalPoints } if (data.completedPoints !== undefined) { state.completedPoints = data.completedPoints } if (data.progressDisplayFormat) { state.progressDisplayFormat = String(data.progressDisplayFormat) } // 如果assets中有totalPoints,也更新 if (data.assets && data.assets.totalPoints !== undefined && data.assets.totalPoints !== null) { state.totalPoints = data.assets.totalPoints if (state.currentPoints === undefined) { state.currentPoints = 0 } } console.log('updateStateFromResponse:', { status: data.status, dataRegion: data.region, stateRegion: state.region, mecmachineId: data.mecmachineId, dataTotalPoints: data.totalPoints, stateTotalPoints: state.totalPoints, completedPoints: state.completedPoints, skipQrProcessing }) if (skipQrProcessing) { return } if (data.mecmachineId) { const qrUrl = `https://uzi1.cn/image/${data.mecmachineId}/二维码.png?t=${Date.now()}` state.qrInfo = { url: qrUrl, createdAt: data.qrCreatedAt, expireAt: data.qrExpireAt } } else if (data.qr) { state.qrInfo = data.qr } } const selectRegion = async (region) => { if (state.submitting) return state.submitting = true state.qrRetryCount = 0 try { const response = await selectRegionAPI({ code: state.code, region }) const data = response.data console.log('selectRegion 响应数据:', data) return data } catch (error) { handleError(error) throw error } finally { state.submitting = false } } const handleRefresh = async (clearAllTimers) => { try { const response = await refreshLinkAPI(state.code) const data = response.data if (clearAllTimers) { clearAllTimers() } state.needRefresh = false state.status = 'NEW' return data } catch (error) { handleError(error) throw error } } const handlePageRefresh = () => { window.location.reload() } const handleRetry = () => { state.error = null state.loading = true initializePage() } const handleError = (error) => { console.error('API错误:', error) const status = error?.response?.status if (status === 401) { console.log('检测到401错误,跳转到登录页面') router.replace({ name: 'Login', query: { redirect: route.fullPath } }) return } if (status === 400 || status === 403) { state.error = 'INVALID_CODE' } else if (status === 410) { state.error = 'EXPIRED' } else { state.error = 'NETWORK_ERROR' } } const formatTime = (seconds) => { const mins = Math.floor(seconds / 60) const secs = seconds % 60 return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}` } const getRegionName = () => { return state.region === 'Q' ? 'QQ区' : state.region === 'V' ? '微信区' : '' } const getCurrentUrl = () => { return window.location.href } const getGameStatus = () => { if (state.currentPoints >= state.totalPoints) { return '已打完' } else if (state.currentPoints > 0) { return '代练中' } else { return '空闲' } } const getStatusClass = () => { const status = getGameStatus() return { 'status-completed': status === '已打完', 'status-playing': status === '代练中', 'status-idle': status === '空闲' } } const getDisplayStatus = () => { if (state.status === 'COMPLETED') { return '已完成' } else if (state.status === 'LOGGED_IN') { return '代练中' } else { return '状态' } } const getStatusMessage = () => { if (state.status === 'COMPLETED') { return '代练已完成!感谢您的使用,订单已结束。' } else if (state.status === 'LOGGED_IN') { return '正在代练中,期间请勿操号,耐心等待代练完成......' } else { return '正在代练中,期间请勿操号,耐心等待代练完成......' } } const getStatusMessageClass = () => { if (state.status === 'COMPLETED') { return 'status-message-completed' } else { return '' } } const getProgressPercent = () => { if (!state.totalPoints) return 0 return Math.min(100, (state.currentPoints / state.totalPoints) * 100) } const getCurrentGameImage = () => { if (!state.machineId) return null const progress = getProgressPercent() const baseUrl = 'https://uzi1.cn/image' if (progress === 0) { return `${baseUrl}/${state.machineId}/首次主页.png` } else if (progress < 50) { return `${baseUrl}/${state.machineId}/首次赏金.png` } else if (progress < 100) { return `${baseUrl}/${state.machineId}/中途赏金.png` } else { return `${baseUrl}/${state.machineId}/结束赏金.png` } } const getErrorTitle = () => { const titles = { 'INVALID_CODE': '链接无效', 'EXPIRED': '链接已过期', 'REFUNDED': '订单已退单', 'NETWORK_ERROR': '网络错误' } return titles[state.error] || '出现错误' } const getErrorMessage = () => { const messages = { 'INVALID_CODE': '请联系商家获取有效链接', 'EXPIRED': '请联系商家重新获取链接', 'REFUNDED': '该订单已被退单,无法继续使用', 'NETWORK_ERROR': '网络连接失败,请检查网络后重试' } return messages[state.error] || '请稍后重试或联系客服' } return { state, initializePage, fetchStatus, updateStateFromResponse, handleLoggedInStatus, handleCompletedStatus, selectRegion, handleRefresh, handlePageRefresh, handleRetry, handleError, formatTime, getRegionName, getCurrentUrl, getGameStatus, getStatusClass, getDisplayStatus, getStatusMessage, getStatusMessageClass, getProgressPercent, getCurrentGameImage, getErrorTitle, getErrorMessage } }