430 lines
12 KiB
JavaScript
430 lines
12 KiB
JavaScript
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 {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,
|
||
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({
|
||
name: 'user',
|
||
id: '1001',
|
||
userAvatar: '',
|
||
userNickname: 'user',
|
||
account: '1234567890'
|
||
})
|
||
|
||
// 收入信息
|
||
const salaryInfo = reactive({
|
||
hostSalary: 0.00,
|
||
currentSalary: 0.00
|
||
})
|
||
|
||
// 任务信息
|
||
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 () => {
|
||
const userProfile = getUserProfile();
|
||
if (!userProfile) {
|
||
const res = await getMemberProfile()
|
||
if (res.status && res.body) {
|
||
userInfo.id = res.body.account
|
||
userInfo.userNickname = res.body.userNickname
|
||
userInfo.userAvatar = res.body.userAvatar
|
||
}
|
||
} else {
|
||
userInfo.id = userProfile.account
|
||
userInfo.userNickname = userProfile.userNickname
|
||
userInfo.userAvatar = userProfile.userAvatar
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取团队信息
|
||
*/
|
||
const fetchTeamInfo = async () => {
|
||
if (!needsTeamInfo) return
|
||
|
||
const teamInfo = getTeamInfo()
|
||
if (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.00
|
||
}
|
||
} catch (error) {
|
||
console.error('Failed to fetch bank balance:', error)
|
||
salaryInfo.currentSalary = 0.00
|
||
// 可以显示错误提示
|
||
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
|
||
}
|
||
}
|