diff --git a/src/store/index.js b/src/store/index.js index 07f99bd3..cbdaebb6 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -6,6 +6,7 @@ import industryReducer from './slices/industrySlice'; import stockReducer from './slices/stockSlice'; import authModalReducer from './slices/authModalSlice'; import subscriptionReducer from './slices/subscriptionSlice'; +import deviceReducer from './slices/deviceSlice'; // ✅ 设备检测状态管理 import posthogMiddleware from './middleware/posthogMiddleware'; import { eventsApi } from './api/eventsApi'; // ✅ RTK Query API @@ -17,6 +18,7 @@ export const store = configureStore({ stock: stockReducer, // ✅ 股票和事件数据管理 authModal: authModalReducer, // ✅ 认证弹窗状态管理 subscription: subscriptionReducer, // ✅ 订阅信息状态管理 + device: deviceReducer, // ✅ 设备检测状态管理(移动端/桌面端) [eventsApi.reducerPath]: eventsApi.reducer, // ✅ RTK Query 事件 API }, middleware: (getDefaultMiddleware) => diff --git a/src/store/slices/deviceSlice.js b/src/store/slices/deviceSlice.js new file mode 100644 index 00000000..f92406da --- /dev/null +++ b/src/store/slices/deviceSlice.js @@ -0,0 +1,52 @@ +// src/store/slices/deviceSlice.js +import { createSlice } from '@reduxjs/toolkit'; + +/** + * 检测当前设备是否为移动设备 + * + * 判断逻辑: + * 1. User Agent 检测(移动设备标识) + * 2. 屏幕宽度检测(<= 768px) + * 3. 触摸屏检测(支持触摸事件) + * + * @returns {boolean} true 表示移动设备,false 表示桌面设备 + */ +const detectIsMobile = () => { + const userAgent = navigator.userAgent || navigator.vendor || window.opera; + const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i; + const isMobileUA = mobileRegex.test(userAgent); + const isMobileWidth = window.innerWidth <= 768; + const hasTouchScreen = 'ontouchstart' in window || navigator.maxTouchPoints > 0; + + return isMobileUA || (isMobileWidth && hasTouchScreen); +}; + +const initialState = { + isMobile: detectIsMobile(), +}; + +const deviceSlice = createSlice({ + name: 'device', + initialState, + reducers: { + /** + * 更新屏幕尺寸状态 + * + * 使用场景: + * - 监听 window resize 事件时调用 + * - 屏幕方向变化时调用(orientationchange) + */ + updateScreenSize: (state) => { + state.isMobile = detectIsMobile(); + }, + }, +}); + +// Actions +export const { updateScreenSize } = deviceSlice.actions; + +// Selectors +export const selectIsMobile = (state) => state.device.isMobile; + +// Reducer +export default deviceSlice.reducer;