You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
9.2 KiB
293 lines
9.2 KiB
/** |
|
* 游戏状态管理 |
|
* 使用 Zustand + AsyncStorage 持久化 |
|
*/ |
|
|
|
import { create } from 'zustand'; |
|
// import { useShallow } from 'zustand/react/shallow'; |
|
import storageManager, { STORAGE_KEYS } from '@/utils/storageManager'; |
|
import gameService from '@/services/gameService'; |
|
import appConfig from '@/utils/config'; |
|
import useTenantStore from '@/stores/tenantStore'; |
|
import useMsgStore from '@/stores/msgStore'; |
|
import { filter, map, concat, cloneDeep, groupBy } from 'lodash-es'; |
|
import { GameMainKeysEnum, defaultHomeGameTabMenus } from '@/constants/game'; |
|
|
|
// 状态 |
|
interface State { |
|
appLoginPopType: number; |
|
receiveAwardPopType: number; |
|
appLoginPop: boolean; |
|
menuSort: Record<string, any>[]; |
|
rebateGameSort: Record<string, any>[]; |
|
originalGames: Record<string, any>[]; |
|
blockchainGames: Record<string, any>[]; |
|
homeHotGames: Record<string, any>[]; |
|
gamesTry: Record<string, any>[]; |
|
gamesTryPlayIds: number[]; |
|
smallClassGames: Record<string, any>; |
|
gameBigClass: Record<string, any>; |
|
activeMainMenuTab: string; // 当前选中的主菜单分类 |
|
activeSubMenuTab: string; // 当前选中的子菜单分类 |
|
} |
|
|
|
// 操作 |
|
interface Actions { |
|
setHomePageData: (data: Record<string, any>) => void; |
|
setOriginalGames: (data: Record<string, any>[]) => void; |
|
setBlockchainGames: (data: Record<string, any>[]) => void; |
|
setGamesTry: (data: Record<string, any>[]) => void; |
|
setHomeHotGames: (data: Record<string, any>[]) => void; |
|
setSmallClassGame: (data: Record<string, any>) => void; |
|
setGameBigClass: (data: Record<string, any>) => void; |
|
setActiveMenuTabs: (mainMenuKey: string, subMenuKey: string) => void; // 设置选中的游戏分类 |
|
setActiveMainMenuTab: (mainMenuKey: string) => void; // 设置选中的主菜单分类 |
|
setActiveSubMenuTab: (subMenuKey: string) => void; // 设置选中的子菜单分类 |
|
// requestHomePageData: (data?: Record<string, any>) => Promise<any>; |
|
} |
|
|
|
/** |
|
* 租户状态 Store |
|
*/ |
|
const useGameStore = create<State & Actions>()((set, get) => ({ |
|
// 初始状态 |
|
appLoginPopType: 0, |
|
receiveAwardPopType: 0, |
|
appLoginPop: false, |
|
menuSort: [], // 游戏主菜单 |
|
rebateGameSort: [], |
|
originalGames: [], // 原创游戏 |
|
blockchainGames: [], // 区块链游戏 |
|
homeHotGames: [], // 热门游戏 |
|
gamesTry: [], // 试玩游戏 |
|
gamesTryPlayIds: [], // 试玩游戏id列表 |
|
smallClassGames: {}, |
|
gameBigClass: {}, |
|
activeMainMenuTab: '103', // 默认选中推荐分类 |
|
activeSubMenuTab: '', // 默认无子菜单选中 |
|
|
|
// 保存首页数据 |
|
setHomePageData: (data: any) => { |
|
if (data) { |
|
const { setNotices, setBanners } = useMsgStore.getState(); |
|
|
|
// 设置注册弹窗 |
|
const appLoginPopType = data.appLoginPopType || 0; |
|
const receiveAwardPopType = data.receiveAwardPopType || 0; |
|
const appLoginPop = data.appLoginPop || false; |
|
|
|
// 菜单排序 |
|
const menuSort = filter( |
|
data.version_type, |
|
(item) => item.sort_v !== 0 && item.state == 1 |
|
).sort((a, b) => { |
|
return b.sort_v - a.sort_v; |
|
}); |
|
console.log(menuSort, 'menuSort 1'); |
|
// version_shuffle |
|
const rebateGameSort = data.version_shuffle || []; |
|
|
|
// 所有游戏销售状态 |
|
// gameStore.setGameAllStates(res.data.gameState); |
|
|
|
// 公告 |
|
setNotices(data.news?.data || []); |
|
|
|
// 轮播图 |
|
setBanners(data.banners?.data || []); |
|
|
|
set({ appLoginPopType, receiveAwardPopType, appLoginPop, menuSort, rebateGameSort }); |
|
|
|
// 原创游戏 |
|
get().setOriginalGames(data.originalGames); |
|
|
|
// 区块链游戏 |
|
get().setBlockchainGames(data.hsGames); |
|
|
|
// 试玩游戏 |
|
get().setGamesTry(data.gamesTry); |
|
|
|
// 首页热门游戏 |
|
get().setHomeHotGames(data.homeHotGames?.[1] || []); |
|
get().setSmallClassGame(data.homeHotGames); |
|
|
|
// 三方游戏 |
|
get().setGameBigClass(data.thirdGames); |
|
|
|
// 手动持久化 |
|
// storageManager.setItem(STORAGE_KEYS.TENANT_STORE, JSON.stringify({ tenantInfo: data })); |
|
} |
|
if (__DEV__) { |
|
console.log('💾 Tenant info saved:', data); |
|
} |
|
}, |
|
|
|
setOriginalGames: (list: Record<string, any>[]) => { |
|
const originalGames = map(list, (item: any) => ({ |
|
...item, |
|
isOriginal: true, |
|
})).sort((a: any, b: any) => a.hotVal - b.hotVal); |
|
set({ originalGames }); |
|
}, |
|
|
|
setBlockchainGames: (list: Record<string, any>[]) => { |
|
set({ blockchainGames: list || [] }); |
|
}, |
|
|
|
setGamesTry: (list: Record<string, any>[]) => { |
|
set({ gamesTry: list || [] }); |
|
storageManager.session.setItem(STORAGE_KEYS.GAME_TRY, list); |
|
const gamesTryPlayIds = concat( |
|
...map(list, (item) => map(item.subList, (subItem) => Number(subItem.play_id))) |
|
); |
|
set({ gamesTryPlayIds }); |
|
}, |
|
|
|
setHomeHotGames: (list: Record<string, any>[]) => { |
|
set({ homeHotGames: list || [] }); |
|
}, |
|
|
|
setSmallClassGame: (data: Record<string, any>) => { |
|
set({ |
|
smallClassGames: { |
|
[GameMainKeysEnum.HOT_ELECTRONIC]: data?.[2] || [], |
|
[GameMainKeysEnum.HOT_FISHING]: data?.[3] || [], |
|
[GameMainKeysEnum.HOT_CHESS]: data?.[5] || [], |
|
[GameMainKeysEnum.HOT_BLOCK_THIRD]: data?.[8] || [], |
|
}, |
|
}); |
|
}, |
|
|
|
setGameBigClass: (data: Record<string, any>) => { |
|
const groupByType = cloneDeep(groupBy(data, (item) => item.big_type)); |
|
console.log(groupByType, 'groupByType'); |
|
set({ |
|
gameBigClass: { |
|
[GameMainKeysEnum.CHESS]: groupByType?.[1] || [], |
|
[GameMainKeysEnum.ELECTRONIC]: groupByType?.[2] || [], |
|
[GameMainKeysEnum.FISHING]: groupByType?.[3] || [], |
|
[GameMainKeysEnum.LIVE]: groupByType?.[4] || [], |
|
[GameMainKeysEnum.SPORTS]: groupByType?.[5] || [], |
|
[GameMainKeysEnum.LOTTERY]: groupByType?.[7] || [], |
|
[GameMainKeysEnum.BLOCK_THIRD]: groupByType?.[10] || [], |
|
}, |
|
}); |
|
}, |
|
|
|
setActiveMenuTabs: (mainMenuKey: string, subMenuKey: string) => { |
|
set({ activeMainMenuTab: mainMenuKey, activeSubMenuTab: subMenuKey }); |
|
// 保存到 session storage,页面刷新后仍然保留 |
|
storageManager.session.setItem(STORAGE_KEYS.APP_ACTIVE_MAIN_MENU_TAB, mainMenuKey); |
|
storageManager.session.setItem(STORAGE_KEYS.APP_ACTIVE_SUB_MENU_TAB, subMenuKey); |
|
}, |
|
|
|
setActiveMainMenuTab: (mainMenuKey: string) => { |
|
set({ activeMainMenuTab: mainMenuKey }); |
|
// 保存到 session storage,页面刷新后仍然保留 |
|
storageManager.session.setItem(STORAGE_KEYS.APP_ACTIVE_MAIN_MENU_TAB, mainMenuKey); |
|
}, |
|
|
|
setActiveSubMenuTab: (subMenuKey: string) => { |
|
set({ activeSubMenuTab: subMenuKey }); |
|
// 保存到 session storage,页面刷新后仍然保留 |
|
storageManager.session.setItem(STORAGE_KEYS.APP_ACTIVE_SUB_MENU_TAB, subMenuKey); |
|
}, |
|
})); |
|
|
|
// 从 AsyncStorage 恢复状态的函数 |
|
export const restoreGameState = async () => { |
|
try { |
|
const stored = await storageManager.session.getItem(STORAGE_KEYS.TENANT_STORE); |
|
if (stored) { |
|
const state = JSON.parse(stored); |
|
useGameStore.setState(state); |
|
if (__DEV__) { |
|
console.log('✅ Tenant state restored from storage'); |
|
} |
|
} |
|
} catch (error) { |
|
console.error('Failed to restore tenant state:', error); |
|
} |
|
}; |
|
|
|
// 获取首页数据 |
|
export const requestHomePageData = async () => { |
|
try { |
|
const { tenantInfo } = useTenantStore.getState(); |
|
const params = { |
|
tid: tenantInfo?.tid, |
|
aseq: { |
|
aseq: appConfig.app.aseqId, |
|
}, |
|
version_type: { |
|
version_type: 3, // 1 是棋牌, 2 是网赚 3, 是综合彩票 |
|
}, |
|
news: { |
|
page_start: 1, |
|
num_per_page: 999, |
|
chan_con: 8, |
|
state: 1, |
|
message_id: '10,13', //10公告 13 跑马灯 |
|
sort_flag: 1, |
|
vip_level: 0, //userInfo.value.cust_level || 0, |
|
proxy: tenantInfo?.proxy, |
|
apply: 8, // 1 棋牌;2 网赚;3 综合彩票;3 老版彩票; (apply后端设置默认为1,为可选参数) |
|
language: 0, //Number(window.localStorage.getItem('languageNum') || '0'), |
|
}, |
|
game_news: { |
|
page_start: 1, |
|
num_per_page: 9999, |
|
state: 1, |
|
message_id: 17, |
|
sort_flag: 1, |
|
tid: tenantInfo?.tid, |
|
proxy: tenantInfo?.proxy, |
|
chan_con: 0, |
|
apply: 8, |
|
ma_id: 10, |
|
// vip_level: userInfo.value.cust_level || 0, |
|
vip_level: 0, |
|
type: 'MWEB', |
|
language: 0, |
|
}, |
|
banners: { |
|
page_start: 1, |
|
num_per_page: 999, |
|
chan_con: 8, |
|
state: 1, |
|
message_id: 12, |
|
sort_flag: 1, |
|
tid: tenantInfo?.tid, |
|
proxy: tenantInfo?.proxy, |
|
apply: 8, |
|
location: '1', |
|
type: 'MWEB', |
|
language: Number(window.localStorage.getItem('languageNum') || '0'), |
|
}, |
|
homeHotGames: { |
|
// cust_id: userInfo.value.cust_id || '0', |
|
cust_id: '0', |
|
}, |
|
proxyConfig: { |
|
proxy: tenantInfo?.proxy, |
|
}, |
|
hotGames: { |
|
size: 12, |
|
}, |
|
}; |
|
const { data } = await gameService.getHomePageData(params); |
|
|
|
// ✅ 直接调用 setHomePageData action |
|
useGameStore.getState().setHomePageData(data); |
|
|
|
if (__DEV__) { |
|
console.log('✅ Home-data info loaded:', data); |
|
} |
|
return Promise.resolve(data); |
|
} catch (error) { |
|
console.error('Failed to request home-data info:', error); |
|
return Promise.reject(error); |
|
} |
|
}; |
|
|
|
export default useGameStore;
|
|
|