import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react'; import MissionApiService from '@lofter-mission/core'; import { ActivityInfo, Mission, UserInfo } from '../types'; interface ActivityContextType { activityInfo: ActivityInfo | null; missions: Mission[]; userInfo: UserInfo | null; missionApi: MissionApiService | null; loading: boolean; error: string | null; refreshActivity: (silent?: boolean) => Promise<{ userInfo: UserInfo | null; activityInfo: ActivityInfo | null; missions: Mission[] }>; updateMissionProgress: (mission: Mission) => void; } const ActivityContext = createContext(undefined); interface ActivityProviderProps { activityCode: string; children: ReactNode; presetMissionApiService: MissionApiService; // 预设的missionApiService,是因为为了避免同时使用core 包和 react 包导致的重复请求 presetActivityInfo?: any; // 预设的活动信息,如果有则不发起请求 } export const ActivityProvider = ({ activityCode, children, presetMissionApiService, presetActivityInfo }: ActivityProviderProps): React.ReactElement => { const [activityInfo, setActivityInfo] = useState(presetActivityInfo || null); const [missions, setMissions] = useState([]); const [userInfo, setUserInfo] = useState(presetActivityInfo?.userInfo || null); const [missionApi, setMissionApi] = useState(null); const [loading, setLoading] = useState(!presetActivityInfo); // 如果有预设数据,不显示loading const [error, setError] = useState(null); const initializeActivity = async (): Promise => { try { setLoading(true); setError(null); let api = presetMissionApiService; if (!api) { api = new MissionApiService({ activityCode }); } setMissionApi(api); // 获取活动数据(包含所有信息) const activityData = await api.getProcessedActivityData(); console.log('activityData', activityData); setActivityInfo({ activityCode, ...activityData }); // 从活动数据中提取任务列表 - 直接使用 MissionItem 实例 if (activityData && activityData.missionActivity && activityData.missionActivity.tabList) { // 从所有 tab 中提取任务并合并,现在 tab.missions 已经是 MissionItem[] 类型 const allMissions: Mission[] = []; activityData.missionActivity.tabList.forEach((tab: any) => { if (tab.missions && Array.isArray(tab.missions)) { // 直接添加 MissionItem 实例,并为每个任务添加 tabName 信息 tab.missions.forEach((mission: Mission) => { // 为 MissionItem 实例添加 tabName 属性 (mission as any).tabName = tab.tabName; allMissions.push(mission); }); } }); console.log('allMissions', allMissions); setMissions(allMissions); } // 从活动数据中直接获取用户信息,避免重复请求 if (activityData && activityData.userInfo) { setUserInfo(activityData.userInfo as UserInfo); } } catch (err) { setError(err instanceof Error ? err.message : '获取活动数据失败'); console.error('Activity initialization failed:', err); } finally { setLoading(false); } }; // 从预设数据中提取任务列表 const initializeFromPresetData = () => { if (presetActivityInfo) { setMissionApi(presetMissionApiService); // 从预设活动数据中提取任务列表 if (presetActivityInfo.missionActivity && presetActivityInfo.missionActivity.tabList) { const allMissions: Mission[] = []; presetActivityInfo.missionActivity.tabList.forEach((tab: any) => { if (tab.missions && Array.isArray(tab.missions)) { tab.missions.forEach((mission: Mission) => { (mission as any).tabName = tab.tabName; allMissions.push(mission); }); } }); console.log('从预设数据提取的 allMissions', allMissions); setMissions(allMissions); } } }; useEffect(() => { if (presetActivityInfo) { // 如果有预设数据,直接使用,不发起请求 console.log('使用预设活动数据,不发起请求'); initializeFromPresetData(); } else { // 没有预设数据,发起请求 console.log('没有预设数据,发起请求'); initializeActivity(); } }, [activityCode, presetActivityInfo]); // 静默刷新方法 - 不显示loading状态 const silentRefreshActivity = async (): Promise<{ userInfo: UserInfo | null; activityInfo: ActivityInfo | null; missions: Mission[] }> => { try { setError(null); let api = presetMissionApiService; if (!api) { api = new MissionApiService({ activityCode }); } setMissionApi(api); // 获取活动数据(包含所有信息) const activityData = await api.getProcessedActivityData(); console.log('静默刷新 activityData', activityData); const newActivityInfo = { activityCode, ...activityData }; setActivityInfo(newActivityInfo); // 从活动数据中提取任务列表 - 直接使用 MissionItem 实例 let newMissions: Mission[] = []; if (activityData && activityData.missionActivity && activityData.missionActivity.tabList) { // 从所有 tab 中提取任务并合并,现在 tab.missions 已经是 MissionItem[] 类型 const allMissions: Mission[] = []; activityData.missionActivity.tabList.forEach((tab: any) => { if (tab.missions && Array.isArray(tab.missions)) { // 直接添加 MissionItem 实例,并为每个任务添加 tabName 信息 tab.missions.forEach((mission: Mission) => { // 为 MissionItem 实例添加 tabName 属性 (mission as any).tabName = tab.tabName; allMissions.push(mission); }); } }); console.log('静默刷新 allMissions', allMissions); newMissions = allMissions; setMissions(allMissions); } // 从活动数据中直接获取用户信息,避免重复请求 let newUserInfo: UserInfo | null = null; if (activityData && activityData.userInfo) { newUserInfo = activityData.userInfo as UserInfo; setUserInfo(newUserInfo); } return { userInfo: newUserInfo, activityInfo: newActivityInfo, missions: newMissions }; } catch (err) { setError(err instanceof Error ? err.message : '获取活动数据失败'); console.error('Silent refresh failed:', err); throw err; } }; const refreshActivity = async (silent?: boolean): Promise<{ userInfo: UserInfo | null; activityInfo: ActivityInfo | null; missions: Mission[] }> => { if (silent) { return await silentRefreshActivity(); } else { await initializeActivity(); return { userInfo, activityInfo, missions }; } }; const updateMissionProgress = (updatedMission: Mission): void => { setMissions((prev: Mission[]) => prev.map((mission: Mission) => mission.info.code === updatedMission.info.code ? updatedMission : mission ) ); }; const value: ActivityContextType = { activityInfo, missions, userInfo, missionApi, loading, error, refreshActivity, updateMissionProgress, }; return ( {children} ); }; export const useActivity = (): ActivityContextType => { const context = useContext(ActivityContext); if (context === undefined) { throw new Error('useActivity must be used within an ActivityProvider'); } return context; };