luckyRollSlice.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import { createSlice, createDraftSafeSelector } from "@reduxjs/toolkit";
  2. import { REQ_STATUS } from "@api/config";
  3. import { buildReqReducer, reqLuckyRollExchange, reqLuckyRollFirstFree, reqLuckyRollGifts, reqLuckyRollInfo, reqLuckyRollLogs, reqLuckyRollSaturdayFree, reqLuckyRollStart, reqLuckyRollState, reqLuckyRollSwitchMode, reqLuckyRollVIPFreeClaim, reqLuckyRollVIPFreeInfo } from "@features/api";
  4. const reducerLuckyRollInfo = (state, action, arg) => {
  5. const payload = action.payload;
  6. if (payload?.code === 200 && payload?.data) {
  7. const data = payload.data;
  8. state.luckyRollInfo = data;
  9. let clientTime = Date.now();
  10. let serverTimeMs = data.server_time * 1000; // 服务器时间转毫秒
  11. state.timeDiff = serverTimeMs - clientTime;
  12. // state.luckyRollInfo.state.fragments = 3;
  13. } else {
  14. state.luckyRollInfo = {};
  15. }
  16. };
  17. const reducerLuckyRollState = (state, action, arg) => {
  18. const payload = action.payload;
  19. if (payload?.code === 200 && payload?.data) {
  20. const data = payload.data;
  21. state.luckyRollInfo.state = data;
  22. }
  23. };
  24. const reducerLuckyRollGifts = (state, action, arg) => {
  25. const payload = action.payload;
  26. if (payload?.code === 200 && payload?.data) {
  27. const data = payload.data;
  28. state.gifts = data;
  29. }
  30. };
  31. const reducerLuckyRollFirstFree = (state, action, arg) => {
  32. const payload = action.payload;
  33. if (payload?.code === 200 && payload?.data) {
  34. const data = payload.data;
  35. state.luckyRollInfo.state.has_received_first_free = true;
  36. state.luckyRollInfo.state.dice_count = data?.state?.dice_count;
  37. }
  38. };
  39. const reducerLuckyRollSwitchMode = (state, action, arg) => {
  40. const payload = action.payload;
  41. if (payload?.code === 200 && payload?.data) {
  42. const data = payload.data;
  43. state.luckyRollInfo = data;
  44. }
  45. };
  46. const reducerLuckyRollStart = (state, action, arg) => {
  47. const payload = action.payload;
  48. if (payload?.code === 200 && payload?.data) {
  49. // 手动调用action
  50. }
  51. };
  52. const reducerLuckyRollExchange = (state, action, arg) => {
  53. const payload = action.payload;
  54. if (payload?.code === 200 && payload?.data) {
  55. const data = payload.data;
  56. state.luckyRollInfo.state = data.state;
  57. // reqCollectionHandler覆盖
  58. }
  59. };
  60. const reducerLuckyRollLogs = (state, action, arg) => {
  61. const payload = action.payload;
  62. if (payload?.code === 200 && payload?.data?.logs) {
  63. const { logs: newLogs } = payload.data;
  64. // 直接替换
  65. state.logs = newLogs;
  66. }
  67. };
  68. const reducerLuckyRollSaturdayFree = (state, action, arg) => {
  69. const payload = action.payload;
  70. if (payload?.code === 200 && payload?.data) {
  71. const data = payload.data;
  72. if (data?.state?.normal?.saturday_claimed) {
  73. state.luckyRollInfo.state.saturday_claimed = true;
  74. state.luckyRollInfo.state.dice_count = data?.state?.normal?.dice_count;
  75. }
  76. }
  77. };
  78. const reducerLuckyRollVIPFreeInfo = (state, action, arg) => {
  79. const payload = action.payload;
  80. if (payload?.code === 200 && payload?.data) {
  81. const data = payload.data;
  82. state.vipFreeInfo = data;
  83. }
  84. };
  85. const reducerLuckyRollVIPFreeClaim = (state, action, arg) => {
  86. const payload = action.payload;
  87. if (payload?.code === 200 && payload?.data) {
  88. const data = payload.data;
  89. state.luckyRollInfo.state = data.state;
  90. state.vipFreeInfo.available = false;
  91. state.vipFreeInfo.claimed_today = 1;
  92. }
  93. };
  94. const switchModeStatus = (state, status, arg) => {
  95. state.switchModeStatus = status;
  96. };
  97. const firstFreeStatus = (state, status, arg) => {
  98. state.firstFreeStatus = status;
  99. };
  100. const rollStartStatus = (state, status, arg) => {
  101. state.rollStartStatus = status;
  102. };
  103. const exchangeStatus = (state, status, arg) => {
  104. state.exchangeStatus = status;
  105. };
  106. const saturdayFreeStatus = (state, status, arg) => {
  107. state.saturdayFreeStatus = status;
  108. };
  109. const vipFreeDiceStatus = (state, status, arg) => {
  110. state.vipFreeDiceStatus = status;
  111. };
  112. export const LuckyRoll = createSlice({
  113. name: 'luckyRoll',
  114. initialState: {
  115. luckyRollInfo: {},
  116. gifts: {},
  117. vipFreeInfo: {},
  118. logs: [],
  119. timeDiff: 0,
  120. firstFreeStatus: REQ_STATUS.NONE,
  121. switchModeStatus: REQ_STATUS.NONE,
  122. rollStartStatus: REQ_STATUS.NONE,
  123. exchangeStatus: REQ_STATUS.NONE,
  124. saturdayFreeStatus: REQ_STATUS.NONE,
  125. vipFreeDiceStatus: REQ_STATUS.NONE,
  126. },
  127. reducers: {
  128. updateDiceNum: (state, action) => {
  129. state.luckyRollInfo.state.dice_count = action.payload;
  130. },
  131. updateStateAfterRoll: (state, action) => {
  132. state.luckyRollInfo.state = action.payload.state;
  133. },
  134. },
  135. extraReducers: (builder) => {
  136. buildReqReducer(builder, reqLuckyRollInfo, reducerLuckyRollInfo, null);
  137. buildReqReducer(builder, reqLuckyRollState, reducerLuckyRollState, null);
  138. buildReqReducer(builder, reqLuckyRollGifts, reducerLuckyRollGifts, null);
  139. buildReqReducer(builder, reqLuckyRollFirstFree, reducerLuckyRollFirstFree, firstFreeStatus);
  140. buildReqReducer(builder, reqLuckyRollSwitchMode, reducerLuckyRollSwitchMode, switchModeStatus);
  141. buildReqReducer(builder, reqLuckyRollStart, reducerLuckyRollStart, rollStartStatus);
  142. buildReqReducer(builder, reqLuckyRollExchange, reducerLuckyRollExchange, exchangeStatus);
  143. buildReqReducer(builder, reqLuckyRollSaturdayFree, reducerLuckyRollSaturdayFree, saturdayFreeStatus);
  144. buildReqReducer(builder, reqLuckyRollLogs, reducerLuckyRollLogs, null);
  145. buildReqReducer(builder, reqLuckyRollVIPFreeInfo, reducerLuckyRollVIPFreeInfo, null);
  146. buildReqReducer(builder, reqLuckyRollVIPFreeClaim, reducerLuckyRollVIPFreeClaim, vipFreeDiceStatus);
  147. },
  148. });
  149. export const { updateDiceNum, updateStateAfterRoll } = LuckyRoll.actions;
  150. // 基础选择器(简单的值查找,不需要记忆化)
  151. export const selectLuckyRoll = state => state.luckyRoll;
  152. export const selectLuckyRollInfo = state => state.luckyRoll.luckyRollInfo;
  153. export const selectLuckyRollVIPFreeInfo = state => state.luckyRoll.vipFreeInfo;
  154. export const selectLuckyRollLogs = state => state.luckyRoll.logs;
  155. export const selectLuckyRollGifts = state => state.luckyRoll.gifts;
  156. export const selectTimeDiff = state => state.luckyRoll.timeDiff;
  157. export const selectFirstFreeStatus = state => state.luckyRoll.firstFreeStatus;
  158. export const selectSwitchModeStatus = state => state.luckyRoll.switchModeStatus;
  159. export const selectRollStartStatus = state => state.luckyRoll.rollStartStatus;
  160. export const selectExchangeStatus = state => state.luckyRoll.exchangeStatus;
  161. export const selectSaturdayFreeStatus = state => state.luckyRoll.saturdayFreeStatus;
  162. export const selectVipFreeDiceStatus = state => state.luckyRoll.vipFreeDiceStatus;
  163. // 记忆化选择器(返回新引用或需要计算)
  164. export const selectLuckyRollUserState = createDraftSafeSelector(
  165. [selectLuckyRoll],
  166. (luckyRoll) => luckyRoll?.luckyRollInfo?.state || {}
  167. );
  168. export const selectLuckyRollMode = createDraftSafeSelector(
  169. [selectLuckyRoll],
  170. (luckyRoll) => luckyRoll?.luckyRollInfo?.state?.mode || 'normal'
  171. );
  172. export const selectLuckyRollBoard = createDraftSafeSelector(
  173. [selectLuckyRoll],
  174. (luckyRoll) => luckyRoll?.luckyRollInfo?.board || []
  175. );
  176. export const selectLuckyRollPackages = createDraftSafeSelector(
  177. [selectLuckyRoll],
  178. (luckyRoll) => {
  179. const gifts = luckyRoll.gifts;
  180. const mode = luckyRoll?.luckyRollInfo?.state?.mode;
  181. if (!gifts || !mode) return [];
  182. return gifts[mode] || [];
  183. }
  184. );
  185. export const selectLuckyRollJackpot = createDraftSafeSelector(
  186. [selectLuckyRoll],
  187. (luckyRoll) => {
  188. const info = luckyRoll.luckyRollInfo;
  189. if (!info?.jackpot) return {};
  190. const mode = info.state?.mode || 'normal';
  191. const fragments = info.state?.fragments || 0;
  192. const amount = info.jackpot[`amount_${mode}`] || 0;
  193. return {
  194. pieces_required: 4 - fragments,
  195. pieces: fragments,
  196. amount: amount,
  197. };
  198. }
  199. );
  200. export const selectLuckyRollRedPoint = createDraftSafeSelector(
  201. [selectLuckyRoll],
  202. (luckyRoll) => {
  203. const info = luckyRoll.luckyRollInfo;
  204. if (!info) return {};
  205. return {
  206. vip: {
  207. mode: info?.vip_reward?.mode,
  208. isShow: info?.vip_reward?.available
  209. },
  210. saturday: {
  211. mode: "normal",
  212. isShow: info?.is_saturday && !info?.state?.saturday_claimed
  213. },
  214. isShow: info?.vip_reward?.available || (info?.is_saturday && !info?.state?.saturday_claimed)
  215. };
  216. }
  217. );
  218. // 复合选择器示例:如果需要结合多个基础选择器的数据
  219. export const selectLuckyRollWithDetails = createDraftSafeSelector(
  220. [selectLuckyRollInfo, selectLuckyRollGifts, selectTimeDiff],
  221. (info, gifts, timeDiff) => ({
  222. info,
  223. gifts,
  224. timeDiff,
  225. isDataLoaded: Object.keys(info).length > 0 && Object.keys(gifts).length > 0
  226. })
  227. );
  228. export default LuckyRoll.reducer;