import { createSlice, createDraftSafeSelector } from "@reduxjs/toolkit"; import { REQ_STATUS } from "@api/config"; import { buildReqReducer, reqLuckyRollExchange, reqLuckyRollFirstFree, reqLuckyRollGifts, reqLuckyRollInfo, reqLuckyRollLogs, reqLuckyRollSaturdayFree, reqLuckyRollStart, reqLuckyRollState, reqLuckyRollSwitchMode, reqLuckyRollVIPFreeClaim, reqLuckyRollVIPFreeInfo } from "@features/api"; const reducerLuckyRollInfo = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.luckyRollInfo = data; let clientTime = Date.now(); let serverTimeMs = data.server_time * 1000; // 服务器时间转毫秒 state.timeDiff = serverTimeMs - clientTime; // state.luckyRollInfo.state.fragments = 3; } else { state.luckyRollInfo = {}; } }; const reducerLuckyRollState = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.luckyRollInfo.state = data; } }; const reducerLuckyRollGifts = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.gifts = data; } }; const reducerLuckyRollFirstFree = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.luckyRollInfo.state.has_received_first_free = true; state.luckyRollInfo.state.dice_count = data?.state?.dice_count; } }; const reducerLuckyRollSwitchMode = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.luckyRollInfo = data; } }; const reducerLuckyRollStart = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { // 手动调用action } }; const reducerLuckyRollExchange = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.luckyRollInfo.state = data.state; // reqCollectionHandler覆盖 } }; const reducerLuckyRollLogs = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data?.logs) { const { logs: newLogs } = payload.data; // 直接替换 state.logs = newLogs; } }; const reducerLuckyRollSaturdayFree = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; if (data?.state?.normal?.saturday_claimed) { state.luckyRollInfo.state.saturday_claimed = true; state.luckyRollInfo.state.dice_count = data?.state?.normal?.dice_count; } } }; const reducerLuckyRollVIPFreeInfo = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.vipFreeInfo = data; } }; const reducerLuckyRollVIPFreeClaim = (state, action, arg) => { const payload = action.payload; if (payload?.code === 200 && payload?.data) { const data = payload.data; state.luckyRollInfo.state = data.state; state.vipFreeInfo.available = false; state.vipFreeInfo.claimed_today = 1; } }; const switchModeStatus = (state, status, arg) => { state.switchModeStatus = status; }; const firstFreeStatus = (state, status, arg) => { state.firstFreeStatus = status; }; const rollStartStatus = (state, status, arg) => { state.rollStartStatus = status; }; const exchangeStatus = (state, status, arg) => { state.exchangeStatus = status; }; const saturdayFreeStatus = (state, status, arg) => { state.saturdayFreeStatus = status; }; const vipFreeDiceStatus = (state, status, arg) => { state.vipFreeDiceStatus = status; }; export const LuckyRoll = createSlice({ name: 'luckyRoll', initialState: { luckyRollInfo: {}, gifts: {}, vipFreeInfo: {}, logs: [], timeDiff: 0, firstFreeStatus: REQ_STATUS.NONE, switchModeStatus: REQ_STATUS.NONE, rollStartStatus: REQ_STATUS.NONE, exchangeStatus: REQ_STATUS.NONE, saturdayFreeStatus: REQ_STATUS.NONE, vipFreeDiceStatus: REQ_STATUS.NONE, }, reducers: { updateDiceNum: (state, action) => { state.luckyRollInfo.state.dice_count = action.payload; }, updateStateAfterRoll: (state, action) => { state.luckyRollInfo.state = action.payload.state; }, }, extraReducers: (builder) => { buildReqReducer(builder, reqLuckyRollInfo, reducerLuckyRollInfo, null); buildReqReducer(builder, reqLuckyRollState, reducerLuckyRollState, null); buildReqReducer(builder, reqLuckyRollGifts, reducerLuckyRollGifts, null); buildReqReducer(builder, reqLuckyRollFirstFree, reducerLuckyRollFirstFree, firstFreeStatus); buildReqReducer(builder, reqLuckyRollSwitchMode, reducerLuckyRollSwitchMode, switchModeStatus); buildReqReducer(builder, reqLuckyRollStart, reducerLuckyRollStart, rollStartStatus); buildReqReducer(builder, reqLuckyRollExchange, reducerLuckyRollExchange, exchangeStatus); buildReqReducer(builder, reqLuckyRollSaturdayFree, reducerLuckyRollSaturdayFree, saturdayFreeStatus); buildReqReducer(builder, reqLuckyRollLogs, reducerLuckyRollLogs, null); buildReqReducer(builder, reqLuckyRollVIPFreeInfo, reducerLuckyRollVIPFreeInfo, null); buildReqReducer(builder, reqLuckyRollVIPFreeClaim, reducerLuckyRollVIPFreeClaim, vipFreeDiceStatus); }, }); export const { updateDiceNum, updateStateAfterRoll } = LuckyRoll.actions; // 基础选择器(简单的值查找,不需要记忆化) export const selectLuckyRoll = state => state.luckyRoll; export const selectLuckyRollInfo = state => state.luckyRoll.luckyRollInfo; export const selectLuckyRollVIPFreeInfo = state => state.luckyRoll.vipFreeInfo; export const selectLuckyRollLogs = state => state.luckyRoll.logs; export const selectLuckyRollGifts = state => state.luckyRoll.gifts; export const selectTimeDiff = state => state.luckyRoll.timeDiff; export const selectFirstFreeStatus = state => state.luckyRoll.firstFreeStatus; export const selectSwitchModeStatus = state => state.luckyRoll.switchModeStatus; export const selectRollStartStatus = state => state.luckyRoll.rollStartStatus; export const selectExchangeStatus = state => state.luckyRoll.exchangeStatus; export const selectSaturdayFreeStatus = state => state.luckyRoll.saturdayFreeStatus; export const selectVipFreeDiceStatus = state => state.luckyRoll.vipFreeDiceStatus; // 记忆化选择器(返回新引用或需要计算) export const selectLuckyRollUserState = createDraftSafeSelector( [selectLuckyRoll], (luckyRoll) => luckyRoll?.luckyRollInfo?.state || {} ); export const selectLuckyRollMode = createDraftSafeSelector( [selectLuckyRoll], (luckyRoll) => luckyRoll?.luckyRollInfo?.state?.mode || 'normal' ); export const selectLuckyRollBoard = createDraftSafeSelector( [selectLuckyRoll], (luckyRoll) => luckyRoll?.luckyRollInfo?.board || [] ); export const selectLuckyRollPackages = createDraftSafeSelector( [selectLuckyRoll], (luckyRoll) => { const gifts = luckyRoll.gifts; const mode = luckyRoll?.luckyRollInfo?.state?.mode; if (!gifts || !mode) return []; return gifts[mode] || []; } ); export const selectLuckyRollJackpot = createDraftSafeSelector( [selectLuckyRoll], (luckyRoll) => { const info = luckyRoll.luckyRollInfo; if (!info?.jackpot) return {}; const mode = info.state?.mode || 'normal'; const fragments = info.state?.fragments || 0; const amount = info.jackpot[`amount_${mode}`] || 0; return { pieces_required: 4 - fragments, pieces: fragments, amount: amount, }; } ); export const selectLuckyRollRedPoint = createDraftSafeSelector( [selectLuckyRoll], (luckyRoll) => { const info = luckyRoll.luckyRollInfo; if (!info) return {}; return { vip: { mode: info?.vip_reward?.mode, isShow: info?.vip_reward?.available }, saturday: { mode: "normal", isShow: info?.is_saturday && !info?.state?.saturday_claimed }, isShow: info?.vip_reward?.available || (info?.is_saturday && !info?.state?.saturday_claimed) }; } ); // 复合选择器示例:如果需要结合多个基础选择器的数据 export const selectLuckyRollWithDetails = createDraftSafeSelector( [selectLuckyRollInfo, selectLuckyRollGifts, selectTimeDiff], (info, gifts, timeDiff) => ({ info, gifts, timeDiff, isDataLoaded: Object.keys(info).length > 0 && Object.keys(gifts).length > 0 }) ); export default LuckyRoll.reducer;