import { initTrackAll, trackEvent, restoreQuickSaveEnv } from "../tracking/TrackAll"; import { createSelector, createSlice } from "@reduxjs/toolkit"; import { routes } from "@db/routes"; import { ROUTE_PATH, ROUTE_TYPE_CUSTOM, ROUTE_TYPE_FULL, ROUTE_TYPE_IN, ROUTE_TYPE_OUTLINK, ROUTE_TYPE_POP, ROUTE_TYPE_POP_OR_FULL, SIDE_TYPE_NOMAL } from "@constants/routes"; import { REQ_STATUS } from "@api/config"; import { buildReqReducer, reqBindSMS, reqChangeEmail, reqChangeInfo, reqChangePass, reqChangePhone, reqCustomLeaveMsg, reqCustomService, reqFavoGet, reqForgetPass, reqGameCardInfo, reqGameInfo, reqGetRoutes, reqLogin, reqLogout, reqRegister, reqRegisterGold, reqSendCode, reqSMSLogin, reqUpdateFavoInfo, reqFreeWithdraw, reqFreeWithdrawMission, reqFreeWithdrawClaim, reqHolidaysGiftInfo, reqFreeBonusGiftInfo, reqHolidaysActInfo, reqGetPwaBonus, reqCheckinCheck, reqProtectCheck, reqEnterGameInterval, reqCountryCode, reqVerifyOldCode, reqChangeBindPhone, reqChangeLimitInfo, reqResetLoginState } from "@features/api"; import { toast } from 'react-toastify'; import { getFinger2DeviceId, getHttpMsg, getTimestampDays, localStorageGet, localStorageRemove, localStorageSet, parseNYTimeToTimestamp } from "@utils/helpers"; import { LOCAL_ACTIVITY_C, LOCAL_BALANCE_POPUP_TS, LOCAL_CUSTOM_LOCK, LOCAL_DEFAULT_COUNTRY, LOCAL_GAME_URL, LOCAL_LAST_LOGIN_TYPE, LOCAL_REGISTER_DATE_TS, LOCAL_SIGN, LOCAL_VISTOR_ID, LOCAL_GOOGLE_REDIRECT_JUMPAPK, LOCAL_GOOGLE_REDIRECT_APK_ENV, LOCAL_RESET_LOGIN_STATES } from "@constants/localkey"; import { APP_LOGIN_TYPE } from "@constants/app"; import { v4 as uuidv4 } from 'uuid'; import { VIPStatus } from "@constants/vip"; import SsqHelp from "@utils/SsqHelp"; const generateNavs = (routes) => { const navs = []; const allNavs = []; const allTopNavs = []; for (let i = 0; i < routes.length; i++) { let route = routes[i]; if (!route.side) continue; allNavs.push(route); if (route.side === SIDE_TYPE_NOMAL) allTopNavs.push(route); let block = route.block != null ? route.block : 0; let temp = navs[block]; if (temp == null) temp = []; temp.push(route); navs[block] = temp; } return { navs, allNavs, allTopNavs }; }; const generateRoutes = (routes, asyncRoutes = []) => { const allMap = {}; const inRoutes = []; const popRoutes = []; //路由等级 //ppath parent path const _generate = (list, plevel, ppath) => { Object.keys(list).forEach((key) => { let route = list[key]; if (route) { if (allMap[route.path] == null) { //level route.plv = plevel; route.ppath = ppath; route.lv = plevel + key + "_"; if (route.path === "#/pay") { route.component = "deposit"; } if (route.path === "#/saque") { route.component = "withdraw"; } allMap[route.path] = route; let type = route.type; if (type === ROUTE_TYPE_IN || type === ROUTE_TYPE_FULL) inRoutes.push(route); else if (type === ROUTE_TYPE_POP_OR_FULL) popRoutes.push(route); else if (type === ROUTE_TYPE_POP) popRoutes.push(route); else if (type === ROUTE_TYPE_CUSTOM) popRoutes.push(route); } let subs = route.subs; if (subs != null) _generate(subs, route.lv, route.path); } }); }; const allroutes = [...routes, ...asyncRoutes]; _generate(allroutes, "", ""); const gnavs = generateNavs(allroutes); return { allMap, inRoutes, popRoutes, blockNavs: gnavs.navs, allNavs: gnavs.allNavs, allTopNavs: gnavs.allTopNavs }; }; const parseThemeStypes = (data) => { if (data != null) { for (const key in data) { let item = data[key]; if (item != null) { if (typeof item == "string") { if (item.indexOf(";") !== -1) { data[key] = item.split(";"); } } } } } return data; }; const parseStyles = (data) => { let styles = {}; if (data != null) { for (let i = 0; i < data.length; i++) { let item = data[i]; if (item) { let styleid = item.styleid; let style = item.style; let json = {}; if (style != null && style !== "") { try { const parsed = typeof style === "string" ? JSON.parse(style) : style; if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) { json = parsed; json['dark'] = parseThemeStypes(json['dark']); json['light'] = parseThemeStypes(json['light']); } } catch (e) { // A malformed optional theme must not abort route initialization. } } styles[styleid] = { styleid, style: json }; } } } return styles; }; const parseBlocks = (data) => { let blocks = {}; if (data != null) { for (let i = 0; i < data.length; i++) { let item = data[i]; if (item) { blocks[item.block] = item; } } } return blocks; }; const parseGoogleRedirectH5Conf = (conf) => { if (!conf) return null; let redirectConf = conf.googleRedirectH5 || conf.google_redirect_h5 || conf.redirectH5 || conf.redirect_h5 || null; if (typeof redirectConf === "string") { try { redirectConf = JSON.parse(redirectConf); } catch (e) { redirectConf = null; } } if (!redirectConf || typeof redirectConf !== "object") return null; if (redirectConf.enabled != null) redirectConf.enabled = Number(redirectConf.enabled) !== 0 && redirectConf.enabled !== false; if (redirectConf.source_channels == null && redirectConf.sourceChannels != null) { redirectConf.source_channels = redirectConf.sourceChannels; } if (typeof redirectConf.source_channels === "string") { redirectConf.source_channels = redirectConf.source_channels .split(",") .map((item) => Number(item.trim())) .filter((item) => !Number.isNaN(item)); } return redirectConf; }; const parseGoogleRedirectH5BonusConf = (conf) => { if (!conf) return null; let bonusConf = conf.googleRedirectH5Bonus || conf.google_redirect_h5_bonus || null; if (typeof bonusConf === "string") { try { bonusConf = JSON.parse(bonusConf); } catch (e) { bonusConf = null; } } if (!bonusConf || typeof bonusConf !== "object") return null; bonusConf.show = Number(bonusConf.show) || 0; bonusConf.claimed = Number(bonusConf.claimed) || 0; if (bonusConf.amount != null) bonusConf.amount = Number(bonusConf.amount) || 0; if (bonusConf.expire_in != null) bonusConf.expire_in = Number(bonusConf.expire_in) || 0; return bonusConf; }; const getLocalGoogleRedirectDebugParams = () => { if (typeof window === "undefined") return null; const host = window.location.hostname; if (host !== "localhost" && host !== "127.0.0.1" && host !== "0.0.0.0") return null; const params = new URLSearchParams(window.location.search || ""); return params.get("gdebug") === "1" ? params : null; }; const applyGoogleRedirectDebugConf = (googleRedirectH5, googleRedirectJumpApk, googleRedirectH5Bonus) => { const params = getLocalGoogleRedirectDebugParams(); if (!params) return { googleRedirectH5, googleRedirectJumpApk, googleRedirectH5Bonus }; const jumpApkMode = Number(params.get("gd_jumpapk")) || 0; if (jumpApkMode === 1 || jumpApkMode === 2 || jumpApkMode === 3) { const rewardAmount = params.get("gd_reward") || googleRedirectH5?.reward_amount || googleRedirectH5?.rewardAmount || 10; const rewardCurrency = params.get("gd_currency") || googleRedirectH5?.reward_currency || googleRedirectH5?.rewardCurrency || global.DOLLAR || "$"; const defaultBonusUrl = `${window.location.origin}${window.location.pathname}?gdebug=1&gd_bonus=1&gd_sk=debug_sk&gd_amount=${params.get("gd_amount") || 1000}&gd_claim_success=1`; googleRedirectJumpApk = jumpApkMode; googleRedirectH5 = { ...(googleRedirectH5 || {}), enabled: true, reward_amount: rewardAmount, reward_currency: rewardCurrency, target_h5_url: params.get("gd_h5") || googleRedirectH5?.target_h5_url || googleRedirectH5?.targetH5Url || googleRedirectH5?.h5_url || defaultBonusUrl, support_url: params.get("gd_support") || googleRedirectH5?.support_url || googleRedirectH5?.tg_support_url || "" }; localStorageSet(LOCAL_GOOGLE_REDIRECT_JUMPAPK, `${jumpApkMode}`); } const bonusMode = params.get("gd_bonus"); if (bonusMode === "1" || bonusMode === "claimed") { googleRedirectH5Bonus = { ...(googleRedirectH5Bonus || {}), show: 1, claimed: bonusMode === "claimed" ? 1 : Number(params.get("gd_claimed")) || 0, amount: Number(params.get("gd_amount")) || 1000, s_k: params.get("gd_sk") || googleRedirectH5Bonus?.s_k || "debug_sk", expire_in: Number(params.get("gd_expire")) || 600 }; } return { googleRedirectH5, googleRedirectJumpApk, googleRedirectH5Bonus }; }; const reducerRoutes = (state, action) => { let json = action.payload; if (json && Number(json.code) === 0) { // _dmr=1 路径首次响应仅用于把 conf.s_p 中的 env 还原到本地(cookie/LS), // 此时本次请求未带恢复后的 sign,user 必为空;若继续更新 state 会让 isLogin=0 // 触发 CHashRouter 的登录守卫,把用户从 #/freewithdraw 跳到 #/signin。 // 这里截获首次响应:只跑 restoreQuickSaveEnv,由其内部 signRestored 分支 // 触发二次 reqGetRoutes(带 sign);同时把 status 回退到 LOADING, // 让 App 继续显示 LoadingFull,阻塞 Layout / CHashRouter 挂载避免提前触发登录守卫。 if (window.__dmig_pending_reload) { // 迁移落地(到 H5):清除 APK 环境标记。APK 与 H5 同源(localStorage 共享), // 若不清,H5 仍会被 isJumpApkEnv() 判成 APK 而弹引导。APK 启动带 jumpapk(无 __dmig_pending_reload), // 不会进这里,所以不影响 APK 正常弹引导(三个 mode 都靠 isJumpApkEnv 这道闸)。 localStorageSet(LOCAL_GOOGLE_REDIRECT_APK_ENV, ""); restoreQuickSaveEnv(json.conf); state.status = REQ_STATUS.LOADING; return; } let data = json.data == null ? [] : json.data; let generData = generateRoutes(state.routes, data); let styles = parseStyles(json.styles); let blocks = parseBlocks(json.blocks); let user = json.user; let isLogin = 0; let userInfo = {}; let hasPhone = 0; if (user) { if (typeof user == "object") { isLogin = 1; userInfo = user; let sign = user.sign; if (sign != null) localStorageSet(LOCAL_SIGN, sign); if (user.Phone !== "" && user.Phone.startsWith(user.RegisterLocation)) { hasPhone = 1; } //同步lang if (user.DefaultLanguage != null) global.i18n.setLocalLangFromS(user.DefaultLanguage); checkChannel(user); updateRegisterDate(user.RegisterDate); //设置ssq gameUserID SsqHelp.setGameId(user.GameID, user.Channel); } } let conf = json.conf; restoreQuickSaveEnv(conf); let hallServerUrl = ''; let promoteInstall = 0; let guest = 0; let upgradeBonus = 0; let registerBonus = 0; let recommendGame = ""; let popWheel = 0; let popBindPhone = 0; let firstBonus = 0; let openRelief = 0; let accountLogin = 1; let loginOpen = ""; let registerOpen = ""; let serviceLink = ""; let landscapeGames = []; let area = global.getLocalAreaID(); //sport 配置 let bbConf = null; let popFirst = 0; let showInstall = 0; let download = {}; let vipConfig = []; let popPwaBonus = 0; let outLimit = null; let withdrawChannel = null; let freeChannel = null; let slotsPartner = []; let sharePop = null; let googleRedirectH5 = null; let googleRedirectJumpApk = 0; let googleRedirectH5Bonus = null; //fb/ins浏览器延迟跳转默认浏览器(仅在提款/充值时拦截) let jumplater = 0; let fbGuideWeight = {}; let isAutoEnterGame = 1; let jumpToH5 = 0; if (conf) { if (!!conf.hall) hallServerUrl = conf.hall; if (!!conf.DOLLAR) global.DOLLAR = conf.DOLLAR; if (!!conf.currency) global.currency = conf.currency; global.pf = conf.pf; //平台配置 if (!!conf.pf && !!conf.pf.id) { let { type, id } = conf.pf; initTrackAll(type, id, isLogin ? userInfo.UserID : null); } //promoteInstall if (!!conf.promoteInstall) promoteInstall = conf.promoteInstall; //guest if (!!conf.guest) guest = conf.guest; //绑定手机奖励 if (!!conf.upgradeBonus) upgradeBonus = conf.upgradeBonus; ///初始注册奖励 if (!!conf.registerBonus) registerBonus = conf.registerBonus; ///领取注册奖励后进入的游戏 if (!!conf.recommendGame) recommendGame = conf.recommendGame; //客服地址 if (!!conf.serviceLink) serviceLink = conf.serviceLink; //弹出转盘 if (!!conf.popWheel) popWheel = conf.popWheel; //弹出绑定电话奖励,并显示浮标 if (!!conf.popBindPhone) popBindPhone = hasPhone ? 0 : conf.popBindPhone; //显示首冲浮标 if (!!conf.firstBonus) firstBonus = conf.firstBonus; //显示救济浮标 if (!!conf.openRelief) openRelief = conf.openRelief; //sport 配置 if (!!conf.bb) { bbConf = conf.bb; if (userInfo != null) userInfo.bb = bbConf; } if (!!conf.loginOpen) loginOpen = conf.loginOpen; if (!!conf.registerOpen) registerOpen = conf.registerOpen; if (!!conf.popFirst) popFirst = conf.popFirst; if (!!conf.showInstall) showInstall = conf.showInstall; //download 配置 if (!!conf.download) download = conf.download; if (!!conf.vipConfig) vipConfig = conf.vipConfig; if (!!conf.LandscapeGames) landscapeGames = conf.LandscapeGames; // adjust相关配置 if (!!conf.AdjustToken && !!conf.AdjustConfig) global.tracker.initAdjust(conf.AdjustToken, conf.AdjustConfig); if (!!conf.popPwaBonus) popPwaBonus = conf.popPwaBonus; if (!!conf.outLimit) outLimit = conf.outLimit; if (!!conf.withdrawChannel) withdrawChannel = conf.withdrawChannelNew; if (!!conf.freeChannel) freeChannel = conf.freeChannel; if (!!conf.slotsPartner) slotsPartner = conf.slotsPartner; if (!!conf.sharePop) sharePop = conf.sharePop; googleRedirectH5 = parseGoogleRedirectH5Conf(conf); googleRedirectH5Bonus = parseGoogleRedirectH5BonusConf(conf); if (conf.jumpapk === 1 || conf.jumpapk === "1" || conf.jumpapk === 2 || conf.jumpapk === "2" || conf.jumpapk === 3 || conf.jumpapk === "3") { googleRedirectJumpApk = Number(conf.jumpapk); localStorageSet(LOCAL_GOOGLE_REDIRECT_JUMPAPK, conf.jumpapk); } else { localStorageSet(LOCAL_GOOGLE_REDIRECT_JUMPAPK, ""); } if (conf.jumplater != null) jumplater = Number(conf.jumplater) || 0; if (conf.weight1234 != null) fbGuideWeight = conf.weight1234; // 注册后自动进游戏 if (conf.isAutoEnterGame != null) isAutoEnterGame = conf.isAutoEnterGame; // 强制引导开关 if (conf.jumpios != null) jumpToH5 = conf.jumpios; // 内置客服JS if (!!conf.servicejs) SsqHelp.setServicejs(conf.servicejs); } ({ googleRedirectH5, googleRedirectJumpApk, googleRedirectH5Bonus } = applyGoogleRedirectDebugConf(googleRedirectH5, googleRedirectJumpApk, googleRedirectH5Bonus)); Object.assign(state, { routes: state.routes, asyncRoutes: data, styles, blocks, ...generData, isLogin: isLogin, userInfo, hallServerUrl, promoteInstall, guest, upgradeBonus, recommendGame, serviceLink, registerBonus, popWheel, popBindPhone, firstBonus, openRelief, bbConf, accountLogin, area, loginOpen, registerOpen, popFirst, showInstall, download, vipConfig, landscapeGames, popPwaBonus, outLimit, withdrawChannel, freeChannel, slotsPartner, sharePop, googleRedirectH5, googleRedirectJumpApk, googleRedirectH5Bonus, jumplater, fbGuideWeight, isAutoEnterGame, jumpToH5 }); } }; const routesStatus = (state, status, arg) => { state.status = status; }; const getMsg = (payload) => { return getHttpMsg(payload); }; //检查渠道 const checkChannel = (userInfo) => { if (userInfo != null && userInfo.Channel != null) { let Channel = parseInt(userInfo.Channel); let localC = localStorageGet(LOCAL_ACTIVITY_C, ""); if (localC != null && localC !== "") { localC = parseInt(localC); if (Channel !== localC) { localStorageSet(LOCAL_ACTIVITY_C, Channel + ""); let search = window.location.search || ""; const params = new URLSearchParams(search); // 移除参数c和bfp params.delete('c'); params.delete('bfp'); search = params.toString(); let url = `${window.location.origin}${search !== "" ? "?" + search : ""}`; window.location.replace(url); } } } }; const updateRegisterDate = (date) => { const local = Number(localStorageGet(LOCAL_REGISTER_DATE_TS, "0")); if (local > 0) return; const ts = parseNYTimeToTimestamp(date); localStorageSet(LOCAL_REGISTER_DATE_TS, ts); const days = getTimestampDays(ts); if (days === 0) { //注册首日不弹Balance 弹窗 localStorageSet(LOCAL_BALANCE_POPUP_TS, Date.now()); } } const parseLogin = (state, action, arg, isShowMsg = true) => { let payload = action.payload; let code = payload.code; let msg = getMsg(payload); //success if (Number(code) === 200) { let data = payload.data; if (data.bb == null) { if (state.userInfo != null) data.bb = state.userInfo.bb; } if (arg) { if (arg.DefaultLanguage != null) data.lang = arg.DefaultLanguage; else { if (state.userInfo != null && state.userInfo.lang != null) data.lang = state.userInfo.lang; } } state.userInfo = data; state.isLogin = 1; state.serverKick = 0; if (!!data.recommendGame) state.recommendGame = data.recommendGame; let sign = data.sign; if (sign != null) localStorageSet(LOCAL_SIGN, sign); if (isShowMsg) toast.success(msg, { toastId: "login" }); if (!!data.reg) { //新注册的 trackEvent("CompleteRegistration", { external_id: data.UserID, event_id: "reg_" + data.UserID }); } checkChannel(data); updateRegisterDate(data.RegisterDate); localStorageRemove(LOCAL_RESET_LOGIN_STATES); //设置ssq gameUserID SsqHelp.setGameId(data.GameID, data.Channel); } else { if (isShowMsg) toast.error(msg, { toastId: "login" }); } if (arg) { let callback = arg.callback; if (callback != null) callback(code, payload.data); } }; const reducerLogin = (state, action, arg) => { parseLogin(state, action, arg); }; const loginStatus = (state, status, arg) => { state.loginStatus.login = status; }; const reducerReg = (state, action, arg) => { parseLogin(state, action, arg, false); }; const regStatus = (state, status, arg) => { state.loginStatus.register = status; }; const reducerRegGold = (state, action, arg) => { let payload = action.payload; //payload:{"data":{"user":{"InsureScore":10,"Registed":1,"message":"Success"}},"result":"","msg":"success","code":200} //payload:{"data":[],"msg":"Fail","code":301} let code = payload.code; let msg = getMsg(payload); if (Number(code) === 200) { let data = payload.data || {}; let user = data.user; if (!!user) { if (user.InsureScore != null) { state.userInfo.InsureScore = Number(user.InsureScore); } if (user.Registed != null) { state.userInfo.Registed = Number(user.Registed); } } } else { toast.error(msg, { toastId: "regGold" }); } }; const regGoldStatus = (state, status, arg) => { state.loginStatus.regGold = status; }; const reducerLogout = (state, action, arg) => { let payload = action.payload; let code = payload.code; let msg = getMsg(payload); if (Number(code) === 200) { state.userInfo = {}; state.isLogin = 0; localStorageSet(LOCAL_SIGN, ""); //清理ssq gameUserID SsqHelp.setGameId(null, null); toast.success(msg, { toastId: "logout" }); } else { toast.error(msg, { toastId: "logout" }); } }; const logoutStatus = (state, status, arg) => { state.loginStatus.logout = status; }; //login //modify const reducerChangePass = (state, action, arg) => { parseLogin(state, action, arg); }; const changePassStatus = (state, status, arg) => { state.modifyStatus.password = status; }; const reducerChangeInfo = (state, action, arg) => { parseLogin(state, action, arg); }; const changeInfoStatus = (state, status, arg) => { state.modifyStatus.info = status; }; const reducerChangePhone = (state, action, arg) => { parseLogin(state, action, arg); }; const changePhoneStatus = (state, status, arg) => { state.modifyStatus.phone = status; }; const reducerChangeEmail = (state, action, arg) => { parseLogin(state, action, arg); }; const changeEmailStatus = (state, status, arg) => { state.modifyStatus.phone = status; }; //modify //gameinfo const parseVipUpgrade = (state, prevLv, vip, preFreeBonus = -1) => { if (prevLv >= vip) return; state.vipUpgrade = { prevLv, preFreeBonus, active: true, //是否显示VIP升级弹窗 } // const vipConfig = state.vipConfig || {}; // let predicts = []; // let benefits = getDiffBenefits(vipConfig[prevLv], vipConfig[vip], prevLv == 0); // if (benefits.length === 0) { // if (vipConfig[vip + 1]) { // /// 预告 // predicts = getDiffBenefits(vipConfig[vip], vipConfig[vip + 1]); // } // } // let active = predicts.length > 0 || benefits.length > 0; // let freeBonus = state.userInfo?.InsureScore || 0; // if (preFreeBonus < freeBonus && prevLv == 0) { // /// 刚升级成vip 并且之前的freebonus <100 才显示freeBonus这个选项 // let index = Math.min(2, benefits.length); // benefits.splice(index, 0, { // key: VIPBenefits.FreeBonus, // from: freeBonus, // to: freeBonus // }) // } // //需要预览的权益 预览后如果还有则自动再次打开弹窗 // let previews = getPreviewBenefits(benefits); // state.vipUpgrade = { // prevLv, // previews, //需要预览的vip权益 [暂时弃用,预览需求已取消] // benefits, //升级变化的vip权益 [非vip变成vip 直接展示所有权益] // predicts, //预测再次提升的权益变化 [如果升级没有权益变化,则预告再升一级会有什么变化] // active, //是否显示VIP升级弹窗 // } } const reducerGameInfo = (state, action, arg) => { const prevLv = state.userInfo?.vip || 0; const insureScore = state.userInfo?.InsureScore || 0; parseLogin(state, action, arg, false); const vip = state.userInfo?.vip || 0; parseVipUpgrade(state, prevLv, vip, insureScore); }; const gameInfoStatus = (state, status, arg) => { state.gameInfoStatus = status; }; //gameinfo //custom const reducerCustom = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { state.customerInfo = payload.data; } }; const customStatus = (state, status, arg) => { state.customServiceStatus = status; }; const reducerCustomLeaveMsg = (state, action, arg) => { let payload = action.payload; if (payload != null) { if (payload && payload.code === 200) { localStorageSet(LOCAL_CUSTOM_LOCK, Date.now()); toast.success(global.i18n.t("customer.TopTip_succeed"), { toastId: "customLeaveMsg" }); } else { toast.error(global.i18n.t("customer.TopTip_fail"), { toastId: "customLeaveMsg" }); } } if (arg && arg.callback != null) { arg.callback(payload); } }; const customLeaveMsgStatus = (state, status, arg) => { state.customLeaveMsgStatus = status; }; const reducerUpdateFavoInfo = (state, action, arg) => { let payload = action.payload; let msg = getHttpMsg(payload); if (payload && payload.code === 200) { if (msg != null && msg !== "") { toast.success(msg, { toastId: "updateFavoInfo" }); } } else { if (msg != null && msg !== "") { toast.error(msg, { toastId: "updateFavoInfo" }); } } }; const reducerFavoGet = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; let favorites = []; if (data != null) { for (let i = 0; i < data.length; i++) { let item = data[i]; if (item) favorites.push(item.id); } } state.favorites = favorites; } }; const reducerFreeWithdraw = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; state.freeWithdrawInfo = data; global.freeTxTotal = data.total; if (arg === true && data?.InsureScore) {//同步InsureScore state.userInfo.InsureScore = data?.InsureScore; } } }; const reducerFreeWithdrawMission = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; state.freeWithdrawMission = data; } }; const reducerFreeWithdrawClaim = (state, action, arg) => { let payload = action.payload; let msg = getHttpMsg(payload); if (payload && payload.code === 200) { toast.success(global.i18n?.t("withdraw.tip.success") ?? "", { toastId: "freeWithdrawClaim" }); setTimeout(() => { global.dispatch(reqGameInfo()); global.dispatch(reqFreeWithdrawMission()); }, 1); } else { toast.error(msg, { toastId: "freeWithdrawClaim" }); } if (arg && arg.callback != null) { arg.callback(payload); } }; const reducerFreeBonusGiftInfo = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; state.freeBonusGiftInfo = data; } }; const reducerHolidaysGiftInfo = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; state.holidaysGiftInfo = data; } }; const reducerHolidaysActInfo = (state, action, arg) => { let payload = action.payload; //payload = JSON.parse(`{"data":{"status":1,"start_time":"2026-02-24 00:00:00.000","end_time":"2026-03-23 00:00:00.000","logo_url":"","button_url":"","button_light_url":"","lunzi_url":"","dipan_url":"","free_times":1,"slots":[777,1,177,2,77,4,32,7,16],"user":{"left_times":1,"total_times":1},"recharge_rules":[{"amount":19.99,"times":1,"gear":{"id":"1016","money":19.99,"favorable_price":19.99,"give":0,"recommend":0,"gear":"[{\\"name\\":\\"cashapp\\",\\"value\\":1,\\"status\\":1},{\\"name\\":\\"applepay\\",\\"value\\":4,\\"status\\":1}]","gift_id":402}},{"amount":39.99,"times":2,"gear":{"id":"1041","money":39.99,"favorable_price":39.99,"give":0,"recommend":1,"gear":"[{\\"name\\":\\"cashapp\\",\\"value\\":1,\\"status\\":1},{\\"name\\":\\"applepay\\",\\"value\\":4,\\"status\\":1}]","gift_id":402}},{"amount":59.99,"times":3,"gear":{"id":"1052","money":59.99,"favorable_price":59.99,"give":0,"recommend":0,"gear":"[{\\"name\\":\\"cashapp\\",\\"value\\":1,\\"status\\":1},{\\"name\\":\\"paypal\\",\\"value\\":2,\\"status\\":1},{\\"name\\":\\"applepay\\",\\"value\\":4,\\"status\\":1}]","gift_id":402}}],"now":"2026-03-29 22:28:14"},"result":"","msg":"success","code":200}`) if (payload && payload.code === 200) { let data = payload.data; state.holidaysActInfo = data; } }; const updateFreeWithdrawClaimStatus = (state, status, arg) => { state.freeTxClaimStatus = status; }; export const getFreeWithdrawClaimStatus = (state) => { return state.main.freeTxClaimStatus; }; const reducerGameCardInfo = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; if (data != null) { let id = Number(data.id); let level_info = data.level_info; let level = level_info != null ? 1 : 0; let local = parseInt(localStorageGet(LOCAL_GAME_URL + id, 0)); if (local > 0) level = local; state.gameCardInfo[id] = { ...data, level: level }; } } }; const gameCardInfoStatus = (state, status, arg) => { state.gameCardInfoStatus = status; }; //send code const reducerSendCode = (state, action, arg) => { let payload = action.payload; let msg = getHttpMsg(payload); if (payload && payload.code === 200) { toast.success(msg, { toastId: "sendCode" }); state.otpTimeStamp = Date.now(); const phone = arg.phone; if (!!phone) { if (!state.otpTsMap) state.otpTsMap = {}; state.otpTsMap[phone] = Date.now(); } } else { toast.error(msg, { toastId: "sendCode" }); } }; const sendCodeStatus = (state, status, arg) => { state.loginStatus.send_code = status; const phone = arg?.phone; if (!!phone) { if (!state.loginStatus.sendCodeMaps) { state.loginStatus.sendCodeMaps = {}; } state.loginStatus.sendCodeMaps[phone] = status; } }; //bind phone const reducerBindSMS = (state, action, arg) => { let payload = action.payload; state.oldUserInfo = null; if (Number(payload.code) === 301 && payload.data && payload.data.UserID) { // 已有账号 state.oldUserInfo = payload.data; } else if (Number(payload.code) === 200) { toast.success(global.i18n.t("bindPhone.success"), { toastId: "login" }); } parseLogin(state, action, arg, Number(payload.code) !== 200); }; const bindSMSStatus = (state, status, arg) => { state.loginStatus.bind = status; }; //sms login const reducerSMSLogin = (state, action, arg) => { parseLogin(state, action, arg); }; const smsLoginStatus = (state, status, arg) => { state.loginStatus.smslogin = status; }; //custom //pwa bonus const reducerGetPwaBonus = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { toast.success(global.i18n?.t("popPwaBonus.claim_success") ?? "", { toastId: "popPwaBonus" }); state.popPwaBonus = 0; } else { toast.error(global.i18n?.t("popPwaBonus.claim_failed") ?? "", { toastId: "popPwaBonus" }); } if (arg && arg.callback != null) { arg.callback(payload); } } const updateVipStatus = (state, arg) => { let { lastRecharge, levelDown, levelDownWarn, levelDownDay, expired, expireWarn, expireDay, alpha, trialEnd, vip = -1 } = arg; if (vip === -1) { vip = state.userInfo?.vip || 0; } let leftDays = 0; let status = VIPStatus.Active; if (Number(vip) === 0) { status = VIPStatus.Trial; if (trialEnd) { /// 非vip用户 体验已到期 status = VIPStatus.TrialEnd; } } else { // vip 用户 if (expired) { status = VIPStatus.Frozen; } else if (levelDown) { status = VIPStatus.LevelDown; } } switch (status) { case VIPStatus.Active: if (lastRecharge >= levelDownWarn) { status = VIPStatus.LevelDownWarn; leftDays = levelDownDay - lastRecharge; } break; case VIPStatus.LevelDown: if (lastRecharge >= expireWarn) { status = VIPStatus.FrozenWarn; leftDays = expireDay - lastRecharge; } break; default: break; } const vipConfig = state.vipConfig || []; state.vipStatus = { status, curAlpha: alpha, fullAlpha: vipConfig[vip]?.Alpha || 1, leftDays, levelDownDay, expireDay, } } const reducerCheckinCheck = (state, action, arg) => { let payload = action.payload; if (payload != null && payload.code === 200) { let data = payload.data; if (data) { updateVipStatus(state, { vip: data.vip, alpha: parseFloat(data.Alpha), lastRecharge: data.LastRechargeDays, levelDown: data.vip_level_down, levelDownDay: parseFloat(data.vip_level_down_days), levelDownWarn: parseFloat(data.level_down_warning_day), expired: data.vip_expire, expireDay: parseFloat(data.vip_expire_days), expireWarn: parseFloat(data.vip_expire_warning_day), trialEnd: data.new_user_thirty_days_without_recharge, }) } } } const reducerProtectCheck = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { let data = payload.data; if (data != null && data[0] != null) { data = data[0]; updateVipStatus(state, { vip: data.vip, alpha: parseFloat(data.Alpha), lastRecharge: data.last_recharge_days, levelDown: data.vip_level_down, levelDownDay: parseFloat(data.vip_level_down_days), levelDownWarn: parseFloat(data.level_down_warning_day), expired: data.vip_expire, expireDay: parseFloat(data.vip_expire_days), expireWarn: parseFloat(data.vip_expire_warning_day), trialEnd: data.new_user_thirty_days_without_recharge, }) } } } const getPwaBonusStatus = (state, status, arg) => { state.pwaBonusStatus = status; } //pwa bonus const reducerGameInterval = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { //console.log("game interval", payload.data); } } const reducerCountryCode = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200 && payload.data) { const phone_code = payload.data.phone_code || global.getLocalAreaID(); if (phone_code) { localStorageSet(LOCAL_DEFAULT_COUNTRY, phone_code) } } } const reducerVerifyCode = (state, action, arg) => { let payload = action.payload; let msg = getHttpMsg(payload); if (!payload || payload.code !== 200) { toast.error(msg, { toastId: "verify_old_code" }); } }; const setVerifyCodeStatus = (state, status, arg) => { state.verifyCodeStatus = status; }; const reducerChangeBindPhone = (state, action, arg) => { let payload = action.payload; let msg = getHttpMsg(payload); if (payload && payload.code === 200) { if (!!state.userInfo) { const country = arg.country || ''; const phone = arg.newPhone; if (phone) state.userInfo.Phone = country + phone; } } else { toast.error(msg, { toastId: "change_bind_phone" }); } }; const reducerChangeLimitInfo = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { const data = payload.data; if (!!data) { // phone_ttl — 手机号修改后剩余锁定时长(秒),0 表示可修改 const phone_ttl = data.phone_ttl || 0; const phone_ts = phone_ttl === 0 ? 0 : Date.now() + phone_ttl * 1000; state.changeLimit = { phone_ts, }; } } } const setChangeBindPhoneStatus = (state, status, arg) => { state.changeBindPhoneStatus = status; }; const reducerResetLogin = (state, action, arg) => { let payload = action.payload; if (payload && payload.code === 200) { onLogout(state, false); localStorageSet(LOCAL_RESET_LOGIN_STATES, "1"); } } const onLogout = (state, open_signin = true) => { state.isLogin = 0; state.userInfo = { UserID: open_signin ? 0 : -1 }; } export const Main = createSlice({ name: 'main', initialState: { status: REQ_STATUS.NONE, routes: routes, asyncRoutes: [], styles: {}, blocks: {}, ...generateRoutes(routes), loginStatus: { login: REQ_STATUS.NONE, register: REQ_STATUS.NONE, regGold: REQ_STATUS.NONE, logout: REQ_STATUS.NONE, bind: REQ_STATUS.NONE, send_code: REQ_STATUS.NONE, smslogin: REQ_STATUS.NONE, sendCodeMaps: {}, }, userInfo: null, oldUserInfo: null, isLogin: 0, modifyStatus: { info: REQ_STATUS.NONE, password: REQ_STATUS.NONE, phone: REQ_STATUS.NONE, email: REQ_STATUS.NONE }, gameInfoStatus: REQ_STATUS.NONE, customLeaveMsgStatus: REQ_STATUS.NONE, customServiceStatus: REQ_STATUS.NONE, freeTxClaimStatus: REQ_STATUS.NONE, verifyCodeStatus: REQ_STATUS.NONE, changeBindPhoneStatus: REQ_STATUS.NONE, //客服 customerInfo: [], //大厅服务器 hallServerUrl: '', //收藏列表 favorites: [], // 免费提现信息 freeWithdrawInfo: {}, //免费提现任务 freeWithdrawMission: {}, freeBonusGiftInfo: {}, holidaysGiftInfo: {}, holidaysActInfo: {}, //当前游戏id gameID: 0, //服务器踢 serverKick: 0, //安装提示 promoteInstall: 0, //服务器返回777打开充值 openPay: 0, gameCardInfoStatus: REQ_STATUS.NONE, //游戏卡信息 gameCardInfo: {}, //otp 时间戳 otpTimeStamp: 0, //是否是guest登录 guest: 0, //绑定奖励 upgradeBonus: 0, //初始注册奖励 registerBonus: 0, //领取注册奖励后进入的游戏 recommendGame: "", //客服地址 serviceLink: "", //sport conf bbConf: null, accountLogin: 0, area: 0, loginOpen: "", registerOpen: "", popFirst: 0, showInstall: 0, download: {}, landscapeGames: [], popPwaBonus: 0, outLimit: null, withdrawChannel: null, freeChannel: null, slotsPartner: [], pwaBonusStatus: REQ_STATUS.NONE, sharePop: null, googleRedirectH5: null, googleRedirectJumpApk: 0, googleRedirectH5Bonus: null, //fb/ins浏览器延迟跳转:0=关闭 1=组件级拦截(提款表单/支付下单时) 2=路由级拦截(进入 #/freewithdraw 或 #/paymentmethods 时) jumplater: 0, vipUpgrade: null, vipStatus: { status: VIPStatus.Trial, alpha: 0, leftDays: 0 }, fbGuideWeight: {}, }, reducers: { logout: (state, action) => { onLogout(state); }, updateUserInfo: (state, action) => { parseLogin(state, action, {}, false); }, updateUserScore: (state, action) => { let score = action.payload; if (score != null) { if (state.userInfo) state.userInfo.Score = Number(score); } }, updateAddScore: (state, action) => { let score = action.payload; if (score != null) { if (state.userInfo) state.userInfo.Score = state.userInfo.Score + Number(score); } }, updateUserBalance: (state, action) => { const score = Number(action.payload); if (!Number.isFinite(score) || !state.userInfo) return; if ((state.userInfo.vip || 0) > 0) { state.userInfo.Score = score; } else { state.userInfo.InsureScore = score; if (state.freeWithdrawInfo) { state.freeWithdrawInfo.InsureScore = score; } } }, updateGameLike: (state, action) => { let payload = action.payload; let id = payload.id; let like = payload.like; let favorites = state.favorites; let index = favorites.indexOf(id); if (like) { if (index === -1) { favorites.push(id); state.favorites = favorites; } } else { let index = favorites.indexOf(id); if (index !== -1) { favorites.splice(index, 1); state.favorites = favorites; } } }, onSliceChangeUser: (state, action) => { state.favorites = []; }, updateCurrGame: (state, action) => { state.gameID = action.payload; }, updateServerKick: (state, action) => { state.serverKick = action.payload; }, updateOpenPay: (state, action) => { state.openPay = action.payload; }, updateGameRoute: (state, action) => { let route = state.allMap[ROUTE_PATH.GAME + "/*"]; if (route != null) { let type = action.payload; route.type = type; } }, updateGameCardInfo: (state, action) => { let { data, level } = action.payload; if (data != null) { if (level == null) level = 0; let id = data.id; state.gameCardInfo[id] = { ...data, level }; } }, updateAreaID: (state, action) => { let areaID = action.payload; global.setLocalAreaID(areaID); }, updateHolidaysGiftSpinTimes: (state, action) => { let { left_times } = action.payload; if (left_times != null) { state.holidaysGiftInfo.user.left_times = left_times; } }, updateHolidaysActSpinTimes: (state, action) => { let { left_times } = action.payload; if (left_times != null) { state.holidaysActInfo.user.left_times = left_times; } }, changeOldAccount: (state, action) => { localStorageSet(LOCAL_LAST_LOGIN_TYPE, APP_LOGIN_TYPE.SMS); localStorageSet(LOCAL_SIGN, state.oldUserInfo.sign); window.location.reload(); }, viewedVipBenefits: (state, action) => { const key = action.payload; if (!key || !state.vipUpgrade) return; let previews = state.vipUpgrade.previews; if (!previews || !previews[key]) return; delete previews[key]; state.vipUpgrade.active = Object.keys(previews).length > 0; }, clearVIPUpgrade: (state, action) => { state.vipUpgrade = null; }, clearGoogleRedirectH5Bonus: (state) => { state.googleRedirectH5Bonus = null; }, testVipUpgrade: (state, action) => { const { prevLv, vip } = action.payload; parseVipUpgrade(state, prevLv, vip); } }, extraReducers: (builder) => { // Add reducers for additional action types here, and handle loading state as needed buildReqReducer(builder, reqGetRoutes, reducerRoutes, routesStatus); buildReqReducer(builder, reqLogin, reducerLogin, loginStatus); buildReqReducer(builder, reqRegister, reducerReg, regStatus); buildReqReducer(builder, reqRegisterGold, reducerRegGold, regGoldStatus); buildReqReducer(builder, reqLogout, reducerLogout, logoutStatus); buildReqReducer(builder, reqChangePass, reducerChangePass, changePassStatus); buildReqReducer(builder, reqChangeInfo, reducerChangeInfo, changeInfoStatus); buildReqReducer(builder, reqChangePhone, reducerChangePhone, changePhoneStatus); buildReqReducer(builder, reqChangeEmail, reducerChangeEmail, changeEmailStatus); buildReqReducer(builder, reqGameInfo, reducerGameInfo, gameInfoStatus); buildReqReducer(builder, reqCustomService, reducerCustom, customStatus); buildReqReducer(builder, reqCustomLeaveMsg, reducerCustomLeaveMsg, customLeaveMsgStatus); buildReqReducer(builder, reqUpdateFavoInfo, reducerUpdateFavoInfo, null); buildReqReducer(builder, reqFavoGet, reducerFavoGet, null); buildReqReducer(builder, reqGameCardInfo, reducerGameCardInfo, gameCardInfoStatus); buildReqReducer(builder, reqSendCode, reducerSendCode, sendCodeStatus); buildReqReducer(builder, reqBindSMS, reducerBindSMS, bindSMSStatus); buildReqReducer(builder, reqSMSLogin, reducerSMSLogin, smsLoginStatus); buildReqReducer(builder, reqForgetPass, reducerChangePass, changePassStatus); buildReqReducer(builder, reqFreeWithdraw, reducerFreeWithdraw, null); buildReqReducer(builder, reqFreeWithdrawMission, reducerFreeWithdrawMission, null); buildReqReducer(builder, reqFreeWithdrawClaim, reducerFreeWithdrawClaim, updateFreeWithdrawClaimStatus); buildReqReducer(builder, reqFreeBonusGiftInfo, reducerFreeBonusGiftInfo, null); buildReqReducer(builder, reqHolidaysGiftInfo, reducerHolidaysGiftInfo, null); buildReqReducer(builder, reqHolidaysActInfo, reducerHolidaysActInfo, null); buildReqReducer(builder, reqGetPwaBonus, reducerGetPwaBonus, getPwaBonusStatus); buildReqReducer(builder, reqCheckinCheck, reducerCheckinCheck); buildReqReducer(builder, reqProtectCheck, reducerProtectCheck); buildReqReducer(builder, reqEnterGameInterval, reducerGameInterval); buildReqReducer(builder, reqCountryCode, reducerCountryCode, null); buildReqReducer(builder, reqVerifyOldCode, reducerVerifyCode, setVerifyCodeStatus); buildReqReducer(builder, reqChangeBindPhone, reducerChangeBindPhone, setChangeBindPhoneStatus); buildReqReducer(builder, reqChangeLimitInfo, reducerChangeLimitInfo, null); buildReqReducer(builder, reqResetLoginState, reducerResetLogin, null); }, }); export const { logout, updateUserInfo, updateUserScore, updateAddScore, updateUserBalance, updateGameLike, updateCurrGame, updateServerKick, updateOpenPay, updateGameRoute, updateGameCardInfo, updateAreaID, updateHolidaysGiftSpinTimes, changeOldAccount, updateHolidaysActSpinTimes, viewedVipBenefits, clearVIPUpgrade, clearGoogleRedirectH5Bonus, testVipUpgrade } = Main.actions; //数据获取 export const getFetchStatus = (state) => { return state.main.status; }; export const routesMap = (state) => { return state.main.allMap; }; export const routesIn = (state) => { return state.main.inRoutes; }; export const routesPop = (state) => { return state.main.popRoutes; }; export const nBlocks = (state) => { return state.main.blockNavs; }; export const allNavs = (state) => { return state.main.allNavs; }; export const allTopNavs = (state) => { return state.main.allTopNavs; }; const EMPTY_ROUTE = Object.freeze({}); const getRouteFromPath = (state, path) => { let allMap = routesMap(state); let route = allMap[path]; if (route == null) { //查看是否有可变路由 let paths = path.split("/"); paths[paths.length - 1] = "*"; let newpath = paths.join("/"); route = allMap[newpath]; } return route; }; export const getRoute = (path) => (state) => { let route = getRouteFromPath(state, path); if (route == null) return EMPTY_ROUTE; return route; }; export const getRouteChain = (path) => createSelector( [routesMap], (map) => { const list = []; const addRouteChain = (currentPath) => { const route = map[currentPath]; if (route != null) { list.unshift(route); if (route.ppath != null && route.ppath !== "") { addRouteChain(route.ppath); } } }; addRouteChain(path); return list; } ); export const getRouteStyles = (state) => { let styles = state.main.styles; return styles; }; export const getBlockColumn = (state) => { let blocks = state.main.blocks; return blocks; }; export const isFullRoute = (path) => (state) => { let route = getRouteFromPath(state, path); if (route) return route.type === ROUTE_TYPE_FULL; return false; }; export const isPopRoute = (path) => (state) => { let route = getRouteFromPath(state, path); if (route) return route.type === ROUTE_TYPE_POP; return false; }; export const isInRoute = (path) => (state) => { let route = getRouteFromPath(state, path); if (route) return route.type === ROUTE_TYPE_IN; return false; }; export const isOutRoute = (path) => (state) => { let route = getRouteFromPath(state, path); if (route) return route.type === ROUTE_TYPE_OUTLINK; return false; }; //login export const getLoginStatus = (state) => { return state.main.loginStatus.login; }; export const getRegStatus = (state) => { return state.main.loginStatus.register; }; export const getRegGoldStatus = (state) => { return state.main.loginStatus.regGold; }; export const getLogoutStatus = (state) => { return state.main.loginStatus.logout; }; export const getSendCodeStatus = (state) => { return state.main.loginStatus.send_code; }; export const getSendCodeMapStatus = (state) => { return state.main.loginStatus.sendCodeMaps; }; export const getBindSMSStatus = (state) => { return state.main.loginStatus.bind; }; export const getSMSLoginStatus = (state) => { return state.main.loginStatus.smslogin; }; export const getSendCodeTS = (state, phone) => { return state.main.otpTimeStamp; }; export const getSendCodeTSMap = (state, phone) => { return state.main.otpTsMap; }; //modify export const getChangeInfoStatus = (state) => { return state.main.modifyStatus.info; }; export const getChangePassStatus = (state) => { return state.main.modifyStatus.password; }; export const getChangePhoneStatus = (state) => { return state.main.modifyStatus.phone; }; export const getChangeEmailStatus = (state) => { return state.main.modifyStatus.email; }; export const isLogined = (state) => { return state.main.isLogin; }; export const getUserInfo = (state) => { return state.main.userInfo; }; export const getOldUserInfo = (state) => { return state.main.oldUserInfo; }; export const getUserVip = (state) => { let userInfo = state.main.userInfo; if (userInfo != null) return userInfo.vip || 0; return 0; }; export const getUserInsureScore = (state) => { if (state.main.freeWithdrawInfo) { return state.main.freeWithdrawInfo.InsureScore; } let userInfo = state.main.userInfo; if (userInfo != null) return userInfo.InsureScore; return 0; }; export const getUserID = (state) => { let uid = -1; let userInfo = state.main.userInfo; if (userInfo) { if (userInfo.UserID != null) uid = Number(userInfo.UserID); else uid = 0; } return uid; }; export const getCustomInfo = (state) => { return state.main.customerInfo; }; export const getCustomTypeInfo = (type) => (state) => { let item = null; let customerInfo = state.main.customerInfo; if (customerInfo) { for (let i = 0; i < customerInfo.length; i++) { let info = customerInfo[i]; if (info.StatusName === type) { item = info; break; } } } return item; }; export const getCustomStatus = (state) => { return state.main.customLeaveMsgStatus; }; export const getCustomServiceStatus = (state) => { return state.main.customServiceStatus; }; export const getHallServerUrl = (state) => { return state.main.hallServerUrl; }; export const getGameLikes = (state) => { return state.main.favorites; }; export const getGameLike = (id) => (state) => { let favorites = state.main.favorites; if (favorites.includes(id)) return 1; return 0; }; export const getKickState = (state) => { return state.main.serverKick; }; export const getPromoteInstall = (state) => { return state.main.promoteInstall; }; export const getPopWheel = (state) => { return state.main.popWheel; }; export const getOpenPay = (state) => { return state.main.openPay; }; export const getGameCardInfo = (id) => (state) => { id = Number(id); return state.main.gameCardInfo[id]; }; export const getIsGuest = (state) => { return state.main.guest; }; export const getIsBindPhone = (state) => { let phone = ""; if (state.main.userInfo != null) { phone = state.main.userInfo.Phone || ""; } return phone.length > 0; }; export const getBindPhone = (state) => { const userInfo = getUserInfo(state); return userInfo?.Phone; } export const getUpgradeBonus = (state) => { return state.main.upgradeBonus; }; export const getreRisterBonus = (state) => { return state.main.registerBonus; }; export const getreRecommendGame = (state) => { return state.main.recommendGame; }; export const getServiceLink = (state) => { return state.main.serviceLink; }; export const getPopBindPhone = (state) => { return state.main.popBindPhone; }; export const getFirstBonus = (state) => { return state.main.firstBonus; }; export const getOpenRelief = (state) => { return state.main.openRelief; }; export const getBBConf = (state) => { return state.main.bbConf; }; export const getAccountLogin = (state) => { return state.main.accountLogin; }; export const getArea = (state) => { return state.main.area; }; export const getUserBBToken = (state) => { let token = null; let userInfo = state.main.userInfo; if (userInfo) { if (userInfo.bb != null && userInfo.bb.token != null) token = userInfo.bb.token; } return token; }; export const getUserLang = (state) => { let lang = ""; let userInfo = state.main.userInfo; if (userInfo) { lang = userInfo.lang; } return lang; }; export const getUserNick = (state) => { let nick = ""; let userInfo = state.main.userInfo; if (userInfo) { nick = userInfo.NickName; } return nick; }; export const getUserRegisted = (state) => { let userInfo = state.main.userInfo; if (userInfo) { return Number(userInfo.Registed) === 1; } return false; }; export const getLoginOpen = (state) => { return state.main.loginOpen; }; export const getRegisterOpen = (state) => { return state.main.registerOpen; }; export const getPopFirst = (state) => { return state.main.popFirst; }; export const getShowInstall = (state) => { return state.main.showInstall; }; export const getDownloadConf = (state) => { return state.main.download; }; export const getVipConfig = (state) => { return state.main.vipConfig; }; export const getVipUpgrade = (state) => { return state.main.vipUpgrade; } const DefaultVipStatus = { status: VIPStatus.Trial, curAlpha: 0, fullAlpha: 0, leftDays: 0, levelDownDay: 0, expireDay: 0, } export const getVipStatus = (state) => { return state.main.vipStatus || DefaultVipStatus; } //数据获取 export default Main.reducer; export const getBFP = () => { return async (dispatch, getState) => { //Finger2 添加指纹 global.FF = await getFinger2DeviceId(); let bfp = ""; if (window.Capacitor?.isNativePlatform?.()) { bfp = window.AndroidAdjust?.getAdid(); } else { bfp = localStorageGet(LOCAL_VISTOR_ID, ""); } if (bfp != null && bfp !== "") { global.BFP = bfp; return bfp; } bfp = uuidv4(); localStorageSet(LOCAL_VISTOR_ID, bfp); global.BFP = bfp; return bfp; }; }; export const getFreeWithdraw = (state) => { return state.main.freeWithdrawInfo; }; export const getFreeWithdrawMission = (state) => { return state.main.freeWithdrawMission; }; export const getFreeBonusGiftInfo = (state) => { return state.main.freeBonusGiftInfo; }; export const checkFreeBonusGift = (state) => { const freeBonusGift = getFreeBonusGiftInfo(state); if (!freeBonusGift) return false; const list = freeBonusGift.list; if (!list || !Array.isArray(list)) return false; return list.length > 0; } export const getHolidaysGiftInfo = (state) => { return state.main.holidaysGiftInfo; }; export const getHolidaysActInfo = (state) => { return state.main.holidaysActInfo; }; export const checkHolidaysActInfo = (state) => { const holidayAct = getHolidaysActInfo(state); if (!holidayAct) return false; const list = holidayAct.recharge_rules; if (!list || !Array.isArray(list)) return false; return list.length > 0; } export const getLandscapeGames = (state) => { return state.main.landscapeGames; } export const getPopPwaBonus = (state) => { return state.main.popPwaBonus; } export const getPwaCliamStatus = (state) => { return state.main.pwaBonusStatus; } export const getOutLimit = (state) => { return state.main.outLimit; } export const getwithdrawChannel = state => state.main.withdrawChannel; export const getFreeChannel = state => state.main.freeChannel; export const getSlotsPartner = (state) => { return state.main.slotsPartner; } export const getSharePopConf = state => state.main.sharePop; export const getJumpLater = state => state.main.jumplater; export const getGoogleRedirectH5Conf = state => state.main.googleRedirectH5; export const getGoogleRedirectJumpApk = state => state.main.googleRedirectJumpApk; export const getGoogleRedirectH5BonusConf = state => state.main.googleRedirectH5Bonus; export const getFBGuideWeight = state => state.main.fbGuideWeight; export const getVerifyCodeStatus = state => state.main.verifyCodeStatus; export const getChangeBindPhoneStatus = state => state.main.changeBindPhoneStatus; export const getChangeLimitInfo = state => state.main.changeLimit; export const getIsAutoEnterGame = state => state.main.isAutoEnterGame; export const getJumpToH5 = state => state.main.jumpToH5;