import { ref, reactive, onMounted } from 'vue' import { useRouter } from 'vue-router' import { getBankBalance, getMemberProfile, getTeamMemberWorkStatistics, getTeamEntry, } from '../api/wallet.js' import { connectApplication, parseAccessOrigin, parseHeader, setHttpHeaders, isInApp, } from '../utils/appBridge.js' import { appConnectionManager, isAppConnected, getAppHeaderInfo, } from '../utils/appConnectionManager.js' import { checkAndRedirect } from '../utils/routeGuard.js' import { getTeamInfo, getUserId, getUserProfile, setTeamInfo } from '../utils/userStore.js' import { showError } from '../utils/toast.js' /** * 页面初始化公共组合式函数 * 适用于: HOST_CENTER, COIN_SELLER, AGENCY_CENTER, BD_CENTER, APPLY 等页面 * * @param {Object} options 配置选项 * @param {boolean} options.needsBankBalance 是否需要获取银行余额 (默认: true) * @param {boolean} options.needsWorkStatistics 是否需要获取工作统计 (默认: true) * @param {boolean} options.needsRouteGuard 是否需要路由守卫检查 (默认: true) * @param {boolean} options.forceRefresh 是否强制刷新数据 (默认: false) * @param {Function} options.onDataLoaded 数据加载完成后的回调函数 * @param {Function} options.onConnectionSuccess APP连接成功后的回调函数 * @param {Function} options.onConnectionFailed APP连接失败后的回调函数 */ export function usePageInitialization(options = {}) { const { needsBankBalance = true, needsWorkStatistics = true, needsTeamInfo = false, needsRouteGuard = true, forceRefresh = false, // 强制刷新数据 onDataLoaded, onConnectionSuccess, onConnectionFailed, } = options const router = useRouter() // 响应式状态 const loading = ref(false) const appConnected = ref(false) const headerInfo = ref({}) const userProfile = ref(null) // 用户信息 const userInfo = reactive({ id: '-', account: '-', userNickname: 'user', name: 'user', userAvatar: '', }) // 收入信息 const salaryInfo = reactive({ hostSalary: 0.0, currentSalary: 0.0, }) // 任务信息 const taskInfo = reactive({ anchorType: 'Chat', minutesProgress: 0, minutesTotal: 120, giftTask: 0, }) /** * 连接APP并获取认证信息(优化版 - 仅专注连接) */ const connectToApp = async () => { console.group('🔗 APP Connection Process') console.debug('🚀 Starting APP connection...') try { // 检查是否在APP环境中 if (!isInApp()) { console.debug('🌐 Browser environment detected') appConnected.value = true console.groupEnd() // 触发连接成功回调 if (onConnectionSuccess) { onConnectionSuccess({ environment: 'browser' }) } return { success: true, environment: 'browser' } } // 检查是否已经连接且未过期 if (isAppConnected()) { console.debug('✅ APP already connected and valid') appConnected.value = true // 使用缓存的头部信息 const cachedHeaderInfo = getAppHeaderInfo() if (cachedHeaderInfo) { headerInfo.value = cachedHeaderInfo console.debug('🔧 Using cached HTTP headers') } console.groupEnd() // 触发连接成功回调 if (onConnectionSuccess) { onConnectionSuccess({ environment: 'app', fromCache: true }) } return { success: true, environment: 'app', fromCache: true } } // 检查是否有正在进行的连接 if (appConnectionManager.isConnecting()) { console.debug('⏳ Connection already in progress, waiting...') await appConnectionManager.getConnectionPromise() appConnected.value = true console.debug('✅ Connected via existing process') console.groupEnd() // 触发连接成功回调 if (onConnectionSuccess) { onConnectionSuccess({ environment: 'app', fromCache: true }) } return { success: true, environment: 'app', fromCache: true } } // 建立新的APP连接 console.debug('📱 Establishing new APP connection...') const connectionResult = await new Promise((resolve, reject) => { const connectionPromise = new Promise((connectResolve, connectReject) => { connectApplication(async (access) => { try { const result = parseAccessOrigin(access) if (result.success) { // 解析头部信息 headerInfo.value = parseHeader(result.data) // 设置HTTP请求头 console.debug('🔧 Setting HTTP headers...') await setHttpHeaders(headerInfo.value) // 标记连接成功 appConnected.value = true appConnectionManager.setConnected(headerInfo.value) console.debug('🎉 APP connection established successfully') connectResolve({ success: true, environment: 'app', fromCache: false }) } else { console.error('❌ Failed to parse access origin:', result.error) appConnectionManager.reset() connectReject(new Error(result.error)) } } catch (error) { console.error('❌ Connection process failed:', error) appConnectionManager.reset() connectReject(error) } }) }) // 设置连接状态 appConnectionManager.setConnecting(connectionPromise) connectionPromise.then(resolve).catch(reject) }) console.debug('✅ Connection completed successfully') console.groupEnd() // 触发连接成功回调 if (onConnectionSuccess) { onConnectionSuccess(connectionResult) } return connectionResult } catch (error) { console.error('❌ Connection failed:', error) appConnected.value = false console.groupEnd() // 触发连接失败回调 if (onConnectionFailed) { onConnectionFailed(error) } // 连接失败的特殊处理 if (error.message && error.message.includes('parse access')) { router.push({ path: '/not_app', query: { message: error.message } }) } return { success: false, error: error.message } } } const fetchUserInfo = async () => { if (!forceRefresh) { const userProfile = getUserProfile() if (userProfile) { // 使用缓存数据 userInfo.id = userProfile.account userInfo.account = userProfile.account userInfo.userNickname = userProfile.userNickname userInfo.userAvatar = userProfile.userAvatar return } } // 强制从服务器获取数据 const res = await getMemberProfile() if (res.status && res.body) { userInfo.id = res.body.account userInfo.account = res.body.account userInfo.userNickname = res.body.userNickname userInfo.userAvatar = res.body.userAvatar } } /** * 获取团队信息 */ const fetchTeamInfo = async () => { if (!needsTeamInfo) return // 如果不是强制刷新,则尝试使用缓存 if (!forceRefresh) { const teamInfo = getTeamInfo() if (teamInfo) { console.log('teamInfo:', teamInfo) return teamInfo } } try { console.debug('🏢 Fetching team information...') const response = await getTeamEntry() if (response && response.status && response.body) { console.debug('✅ Team information retrieved successfully') // 缓存团队信息 setTeamInfo(response.body.teamProfile || response.body) } else { console.warn('⚠️ Team entry response invalid or empty') setTeamInfo(null) } } catch (error) { console.debug('🔴 Team info fetch error:', error) // 处理特定错误码 if (error.response && error.response.body && error.response.body.errorCode) { const errorCode = error.response.body.errorCode switch (errorCode) { case 6025: console.debug('🚫 User is not a team member (6025)') break case 6010: console.debug('🚫 Team not found or disbanded (6010)') break default: console.debug('❌ Other team error:', errorCode, error.response.body.message) } } // 静默处理错误,不向上抛出 setTeamInfo(null) } } /** * 获取银行余额 */ const fetchBankBalance = async () => { if (!needsBankBalance) return loading.value = true try { const response = await getBankBalance() if (response.status && typeof response.body === 'number') { // 格式化余额显示,保留2位小数 salaryInfo.currentSalary = response.body.toFixed(2) } else { salaryInfo.currentSalary = 0.0 } } catch (error) { console.error('Failed to fetch bank balance:', error) salaryInfo.currentSalary = 0.0 // 可以显示错误提示 showError('Failed to load balance. Please try again.') } finally { loading.value = false } } /** * 获取工作统计数据 */ const fetchWorkStatistics = async () => { if (!needsWorkStatistics) return try { const response = await getTeamMemberWorkStatistics('DAILY', getUserId()) if (response.status && response.body) { // 更新任务信息 taskInfo.anchorType = 'Chat' // 固定值 const ownTime = Number(response.body.ownTime) || 0 const otherTime = Number(response.body.otherTime) || 0 const totalTime = ownTime + otherTime taskInfo.minutesProgress = totalTime >= taskInfo.minutesTotal ? taskInfo.minutesTotal : totalTime taskInfo.giftTask = response.body.acceptGiftValue || 0 // acceptGiftValue } } catch (error) { console.error('获取工作统计失败:', error) } } /** * 数据初始化函数 */ const initializePageData = async () => { console.debug('📊 Starting data initialization...') try { const dataPromises = [] dataPromises.push(fetchUserInfo()) if (needsTeamInfo) { dataPromises.push(fetchTeamInfo()) } if (needsBankBalance) { dataPromises.push(fetchBankBalance()) } if (needsWorkStatistics) { dataPromises.push(fetchWorkStatistics()) } // 等待所有数据加载完成 await Promise.all(dataPromises) // 使用路由守卫进行身份检查和重定向 if (needsRouteGuard) { await checkAndRedirect(router, getUserId()) } // 触发数据加载完成回调 if (onDataLoaded) { onDataLoaded({ userProfile: userProfile.value, userInfo: userInfo, salaryInfo: salaryInfo, taskInfo: taskInfo, }) } console.debug('✅ Data initialization completed') } catch (error) { console.error('❌ Data initialization failed:', error) } } /** * 处理头像图片加载失败 */ const handleImageError = () => { // 图片加载失败时,清空userAvatar,显示占位符 userInfo.userAvatar = '' } /** * 获取头像占位符(用户名首字母) */ const getAvatarPlaceholder = () => { if (userInfo.name && userInfo.name.length > 0) { return userInfo.name.charAt(0).toUpperCase() } return 'U' // 默认显示 'U' } /** * 页面挂载时的初始化逻辑 */ const initializePage = async () => { console.debug('📄 Page initialization started') try { // 第一步:仅进行APP连接 const connectionResult = await connectToApp() // 第二步:根据连接结果决定是否初始化数据 if (connectionResult.success) { console.debug('🔗 Connection successful, initializing data...') await initializePageData() } else { console.warn('⚠️ Connection failed, skipping data initialization') } } catch (error) { console.error('❌ Page initialization failed:', error) } } // 自动在 onMounted 时初始化 onMounted(initializePage) // 返回所有需要的状态和方法 return { // 状态 loading, appConnected, headerInfo, userProfile, userInfo, salaryInfo, taskInfo, // 方法 connectToApp, initializePageData, fetchUserInfo, fetchTeamInfo, fetchBankBalance, fetchWorkStatistics, handleImageError, getAvatarPlaceholder, initializePage, // 手动初始化方法(如果需要重新初始化) reinitialize: initializePage, } }