| import { createSlice, type PayloadAction } from '@reduxjs/toolkit'; |
| import type{ WorkListState, Artwork, Section } from './types'; |
| |
| // 初始状态 |
| const initialState: WorkListState = { |
| artworks: [], |
| searchTerm: '', |
| loading: false, |
| error: null, |
| }; |
| |
| // 创建slice |
| const workListSlice = createSlice({ |
| name: 'workList', |
| initialState, |
| reducers: { |
| // 设置加载状态 |
| setLoading: (state, action: PayloadAction<boolean>) => { |
| state.loading = action.payload; |
| if (action.payload) { |
| state.error = null; |
| } |
| }, |
| |
| // 设置错误信息 |
| setError: (state, action: PayloadAction<string>) => { |
| state.error = action.payload; |
| state.loading = false; |
| }, |
| |
| // 设置作品列表 |
| setArtworks: (state, action: PayloadAction<Artwork[]>) => { |
| state.artworks = action.payload; |
| state.loading = false; |
| state.error = null; |
| }, |
| |
| // 添加单个作品 |
| addArtwork: (state, action: PayloadAction<Artwork>) => { |
| state.artworks.push(action.payload); |
| }, |
| |
| // 更新作品 |
| updateArtwork: (state, action: PayloadAction<Artwork>) => { |
| const index = state.artworks.findIndex(artwork => artwork.id === action.payload.id); |
| if (index !== -1) { |
| state.artworks[index] = action.payload; |
| } |
| }, |
| |
| // 删除作品 |
| removeArtwork: (state, action: PayloadAction<number>) => { |
| state.artworks = state.artworks.filter(artwork => artwork.id !== action.payload); |
| }, |
| |
| // 设置搜索词 |
| setSearchTerm: (state, action: PayloadAction<string>) => { |
| state.searchTerm = action.payload; |
| }, |
| |
| // 清空搜索 |
| clearSearch: (state) => { |
| state.searchTerm = ''; |
| }, |
| |
| // 重置状态 |
| resetState: () => { |
| return initialState; |
| }, |
| |
| // 初始化数据(用于设置示例数据) |
| initializeArtworks: (state, action: PayloadAction<Artwork[]>) => { |
| state.artworks = action.payload; |
| state.loading = false; |
| state.error = null; |
| }, |
| }, |
| }); |
| |
| // 导出actions |
| export const { |
| setLoading, |
| setError, |
| setArtworks, |
| addArtwork, |
| updateArtwork, |
| removeArtwork, |
| setSearchTerm, |
| clearSearch, |
| resetState, |
| initializeArtworks, |
| } = workListSlice.actions; |
| |
| // 选择器函数 |
| export const selectArtworks = (state: { workList: WorkListState }) => state.workList.artworks; |
| export const selectSearchTerm = (state: { workList: WorkListState }) => state.workList.searchTerm; |
| export const selectWorkListLoading = (state: { workList: WorkListState }) => state.workList.loading; |
| export const selectWorkListError = (state: { workList: WorkListState }) => state.workList.error; |
| |
| // 过滤后的作品选择器 |
| export const selectFilteredArtworks = (state: { workList: WorkListState }) => { |
| const { artworks, searchTerm } = state.workList; |
| |
| if (!searchTerm.trim()) { |
| return artworks; |
| } |
| |
| return artworks.filter(artwork => |
| artwork.title.toLowerCase().includes(searchTerm.toLowerCase()) || |
| artwork.author.toLowerCase().includes(searchTerm.toLowerCase()) || |
| artwork.category.name.toLowerCase().includes(searchTerm.toLowerCase()) || |
| artwork.category.children.some(child => |
| child.toLowerCase().includes(searchTerm.toLowerCase()) |
| ) |
| ); |
| }; |
| |
| // 根据分区获取作品的选择器 |
| export const selectArtworksBySection = (sectionId: number) => (state: { |
| workList: WorkListState; |
| category: { sections: Section[] } |
| }) => { |
| const section = state.category.sections.find(s => s.id === sectionId); |
| const filteredArtworks = selectFilteredArtworks(state); |
| |
| if (!section) return []; |
| |
| return filteredArtworks.filter(artwork => section.childrenid.includes(artwork.id)); |
| }; |
| |
| export default workListSlice.reducer; |