mirror of
https://github.com/Funkoala14/CreatorCenter_OOIN.git
synced 2025-06-09 08:58:14 +08:00
250 lines
7.6 KiB
JavaScript
250 lines
7.6 KiB
JavaScript
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
||
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获取
|
||
const mockCreators = [
|
||
{
|
||
id: 1,
|
||
name: 'name',
|
||
avatar: 'https://api.dicebear.com/7.x/micah/svg?seed=1',
|
||
category: 'Phones & Electronics',
|
||
ecommerceLevel: 'L2',
|
||
exposureLevel: 'KOC-1',
|
||
followers: '162.2k',
|
||
gmv: '$534.1k',
|
||
soldPercentage: '18.1%',
|
||
avgViews: '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',
|
||
ecommerceLevel: 'L3',
|
||
exposureLevel: 'KOL-3',
|
||
followers: '162.2k',
|
||
gmv: '$534.1k',
|
||
soldPercentage: '18.1%',
|
||
avgViews: '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',
|
||
ecommerceLevel: 'L4',
|
||
exposureLevel: 'KOC-2',
|
||
followers: '162.2k',
|
||
gmv: '$534.1k',
|
||
soldPercentage: '18.1%',
|
||
avgViews: '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',
|
||
ecommerceLevel: 'L1',
|
||
exposureLevel: 'KOC-2',
|
||
followers: '162.2k',
|
||
gmv: '$534.1k',
|
||
soldPercentage: '18.1%',
|
||
avgViews: '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',
|
||
ecommerceLevel: 'L5',
|
||
exposureLevel: 'KOL-2',
|
||
followers: '162.2k',
|
||
gmv: '$534.1k',
|
||
soldPercentage: '18.1%',
|
||
avgViews: '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',
|
||
ecommerceLevel: 'New tag',
|
||
exposureLevel: 'New tag',
|
||
followers: '162.2k',
|
||
gmv: '$534.1k',
|
||
soldPercentage: '18.1%',
|
||
avgViews: '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.ecommerceLevel)
|
||
);
|
||
}
|
||
|
||
// 如果有选定的曝光评级,进行筛选
|
||
if (filters.exposureRatings.length > 0) {
|
||
filteredCreators = filteredCreators.filter((creator) =>
|
||
filters.exposureRatings.includes(creator.exposureLevel)
|
||
);
|
||
}
|
||
|
||
// 筛选观看量范围
|
||
if (filters.viewsRange.length === 2) {
|
||
const minViews = filters.viewsRange[0];
|
||
const maxViews = filters.viewsRange[1];
|
||
|
||
filteredCreators = filteredCreators.filter((creator) => {
|
||
// 将带k的字符串转换为数字
|
||
const viewsStr = creator.avgViews;
|
||
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 = {
|
||
creators: [],
|
||
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
|
||
error: null,
|
||
selectedCreators: [],
|
||
selectedCreator: null,
|
||
};
|
||
|
||
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 = [];
|
||
},
|
||
selectCreator: (state, action) => {
|
||
const id = action.payload;
|
||
state.selectedCreator = state.creators.find((creator) => creator.id.toString() === id.toString());
|
||
},
|
||
clearCreator: (state) => {
|
||
state.selectedCreator = null;
|
||
},
|
||
},
|
||
extraReducers: (builder) => {
|
||
builder
|
||
.addCase(fetchCreators.pending, (state) => {
|
||
state.status = 'loading';
|
||
})
|
||
.addCase(fetchCreators.fulfilled, (state, action) => {
|
||
state.status = 'succeeded';
|
||
state.creators = action.payload;
|
||
})
|
||
.addCase(fetchCreators.rejected, (state, action) => {
|
||
console.log(action);
|
||
state.status = 'failed';
|
||
state.error = action.error.message;
|
||
});
|
||
},
|
||
});
|
||
|
||
export const { toggleCreatorSelection, selectAllCreators, clearCreatorSelection, selectCreator, clearCreator } =
|
||
creatorsSlice.actions;
|
||
|
||
export default creatorsSlice.reducer;
|