import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import api from '../../services/api'; const mockVideos = [ { id: 1, title: 'Collagen + Biotin = your beauty routine’s new besties. For hair, skin, nails, and join...', picture: 'https://api.dicebear.com/7.x/micah/svg?seed=1', releaseTime: '2025-01-01', views: 1000, likes: 100, }, { id: 2, title: 'Collagen + Biotin = your beauty routine’s new besties. For hair, skin, nails, and join...', picture: 'https://api.dicebear.com/7.x/micah/svg?seed=2', releaseTime: '2025-01-01', views: 1000, likes: 100, }, { id: 3, title: 'Collagen + Biotin = your beauty routine’s new besties. For hair, skin, nails, and join...', picture: 'https://api.dicebear.com/7.x/micah/svg?seed=3', releaseTime: '2025-01-01', views: 1000, likes: 100, }, ]; // 模拟创作者数据,实际项目中会从API获取 export const mockCreators = [ { id: 1, name: 'name', avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=1', category: 'Phones & Electronics', e_commerce_level: 'L2', exposure_level: 'KOC-1', followers: '162.2k', gmv: '$534.1k', soldPercentage: '18.1%', avg_video_views: '1.9k', hasEcommerce: true, hasTiktok: true, verified: true, videos: mockVideos, videosWithProduct: mockVideos, }, { id: 2, name: 'name', avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=2', category: 'Womenswear & Underwear', e_commerce_level: 'L3', exposure_level: 'KOL-3', followers: '162.2k', gmv: '$534.1k', soldPercentage: '18.1%', avg_video_views: '1.9k', hasEcommerce: false, hasTiktok: true, verified: false, videos: mockVideos, videosWithProduct: mockVideos, }, { id: 3, name: 'name', avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=3', category: 'Sports & Outdoor', e_commerce_level: 'L4', exposure_level: 'KOC-2', followers: '162.2k', gmv: '$534.1k', soldPercentage: '18.1%', avg_video_views: '1.9k', hasEcommerce: true, hasTiktok: true, verified: false, videos: mockVideos, videosWithProduct: mockVideos, }, { id: 4, name: 'name', avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=4', category: 'Food & Beverage', e_commerce_level: 'L1', exposure_level: 'KOC-2', followers: '162.2k', gmv: '$534.1k', soldPercentage: '18.1%', avg_video_views: '1.9k', hasEcommerce: true, hasTiktok: true, hasInstagram: true, hasYoutube: true, verified: true, videos: mockVideos, videosWithProduct: mockVideos, }, { id: 5, name: 'name', avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=5', category: 'Health', e_commerce_level: 'L5', exposure_level: 'KOL-2', followers: '162.2k', gmv: '$534.1k', soldPercentage: '18.1%', avg_video_views: '1.9k', hasEcommerce: false, hasTiktok: true, hasInstagram: true, hasYoutube: true, verified: true, videos: mockVideos, videosWithProduct: mockVideos, }, { id: 6, name: 'name', avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=6', category: 'Kitchenware', e_commerce_level: 'New tag', exposure_level: 'New tag', followers: '162.2k', gmv: '$534.1k', soldPercentage: '18.1%', avg_video_views: '1.9k', hasEcommerce: true, hasTiktok: true, hasInstagram: true, hasYoutube: true, verified: false, videos: mockVideos, videosWithProduct: mockVideos, }, ]; // 模拟API获取数据的异步Thunk // export const fetchCreators = createAsyncThunk('creators/fetchCreators', async ({ path }, { getState }) => { // // 模拟API调用延迟 // await new Promise((resolve) => setTimeout(resolve, 500)); // // 获取当前的筛选条件 // const state = getState(); // const filters = state.filters; // // 应用筛选逻辑(实际项目中可能在服务器端进行) // let filteredCreators = [...mockCreators]; // // 如果有选定的类别,进行筛选 // if (filters.category.length > 0) { // filteredCreators = filteredCreators.filter((creator) => filters.category.includes(creator.category)); // } // // 如果有选定的电商评级,进行筛选 // if (filters.ecommerceRatings.length > 0) { // filteredCreators = filteredCreators.filter((creator) => // filters.ecommerceRatings.includes(creator.e_commerce_level) // ); // } // // 如果有选定的曝光评级,进行筛选 // if (filters.exposureRatings.length > 0) { // filteredCreators = filteredCreators.filter((creator) => // filters.exposureRatings.includes(creator.exposure_level) // ); // } // // 筛选观看量范围 // if (filters.viewsRange.length === 2) { // const minViews = filters.viewsRange[0]; // const maxViews = filters.viewsRange[1]; // filteredCreators = filteredCreators.filter((creator) => { // // 将带k的字符串转换为数字 // const viewsStr = creator.avg_video_views; // let views = parseFloat(viewsStr); // if (viewsStr.includes('k')) { // views *= 1000; // } else if (viewsStr.includes('M')) { // views *= 1000000; // } // return views >= minViews && views <= maxViews; // }); // } // return filteredCreators; // }); const initialState = { publicCreators: [], privateCreators: [], publicTiktokCreators: [], publicInstagramCreators: [], publicYoutubeCreators: [], privateTiktokCreators: [], privateInstagramCreators: [], privateYoutubeCreators: [], status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed' error: null, selectedCreators: [], selectedCreator: null, pagination: { current_page: 1, total_pages: 0, total_count: 0, has_next: false, has_prev: false, }, hasMore: true, isLoadingMore: false, }; export const fetchCreators = createAsyncThunk('creators/fetchCreators', async ({ path, page = 1 }, { getState }) => { const state = getState(); const filters = state.filters; const response = await api.get(`/daren_detail/public/creators`, { params: { page } }); return response; }); export const fetchPrivateCreators = createAsyncThunk( 'creators/fetchPrivateCreators', async ({ path, page = 1 }, { getState }) => { const state = getState(); const filters = state.filters; const queryParams = { pool_id: 1, page }; const response = await api.get(`/daren_detail/private/pools/creators`, { params: queryParams }); return response; } ); export const fetchCreatorDetail = createAsyncThunk( 'creators/fetchCreatorDetail', async ({ creatorId }, { getState }) => { const response = await api.get(`/daren_detail/creators/${creatorId}`); return response; } ); const creatorsSlice = createSlice({ name: 'creators', initialState, reducers: { toggleCreatorSelection: (state, action) => { const creatorId = action.payload; const isSelected = state.selectedCreators.includes(creatorId); if (isSelected) { state.selectedCreators = state.selectedCreators.filter((id) => id.toString() !== creatorId.toString()); } else { state.selectedCreators.push(creatorId); } }, selectAllCreators: (state) => { state.selectedCreators = state.creators.map((creator) => creator.id); }, clearCreatorSelection: (state) => { state.selectedCreators = []; }, clearCreator: (state) => { state.selectedCreator = null; }, resetCreators: (state) => { state.publicCreators = []; state.privateCreators = []; state.pagination = initialState.pagination; state.hasMore = true; state.isLoadingMore = false; }, }, extraReducers: (builder) => { builder .addCase(fetchCreators.pending, (state) => { if (state.creators.length === 0) { state.status = 'loading'; } else { state.isLoadingMore = true; } }) .addCase(fetchCreators.fulfilled, (state, action) => { state.status = 'succeeded'; state.isLoadingMore = false; const { data, pagination } = action.payload; if (pagination.current_page === 1) { state.publicCreators = data; } else { state.publicCreators = [...state.publicCreators, ...data]; } state.pagination = pagination; state.hasMore = pagination.has_next; }) .addCase(fetchCreators.rejected, (state, action) => { state.status = 'failed'; state.isLoadingMore = false; state.error = action.error.message; }) .addCase(fetchPrivateCreators.pending, (state) => { if (state.creators?.length === 0) { state.status = 'loading'; } else { state.isLoadingMore = true; } }) .addCase(fetchPrivateCreators.fulfilled, (state, action) => { state.status = 'succeeded'; state.isLoadingMore = false; const { data, pagination } = action.payload; if (pagination.current_page === 1) { state.privateCreators = data; } else { state.privateCreators = [...state.privateCreators, ...data]; } state.pagination = pagination; state.hasMore = pagination.has_next; }) .addCase(fetchPrivateCreators.rejected, (state, action) => { console.log('fetchPrivateCreators.rejected', action); state.status = 'failed'; state.isLoadingMore = false; state.error = action.error.message; }) .addCase(fetchCreatorDetail.pending, (state) => { state.status = 'loading'; }) .addCase(fetchCreatorDetail.fulfilled, (state, action) => { state.status = 'succeeded'; const { data, pagination } = action.payload; state.selectedCreator = data; }) .addCase(fetchCreatorDetail.rejected, (state, action) => { state.status = 'failed'; state.error = action.error.message; }); }, }); export const { toggleCreatorSelection, selectAllCreators, clearCreatorSelection, clearCreator, setCreators, resetCreators, } = creatorsSlice.actions; export default creatorsSlice.reducer;