CreatorCenter_OOIN/src/store/slices/creatorsSlice.js

356 lines
11 KiB
JavaScript
Raw Normal View History

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