blob: 31482cc0e279dd4f6f7ff0489642e395a476458b [file] [log] [blame]
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
import type { Section } from './types';
// 分区状态类型
export interface CategoryState {
sections: Section[];
loading: boolean;
error: string | null;
selectedCategoryId: number | null;
}
// 初始状态
const initialState: CategoryState = {
sections: [],
loading: false,
error: null,
selectedCategoryId: null,
};
// 创建categorySlice
const categorySlice = createSlice({
name: 'category',
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;
},
// 设置分区列表
setSections: (state, action: PayloadAction<Section[]>) => {
state.sections = action.payload;
state.loading = false;
state.error = null;
},
// 添加单个分区
addSection: (state, action: PayloadAction<Section>) => {
state.sections.push(action.payload);
},
// 更新分区
updateSection: (state, action: PayloadAction<Section>) => {
const index = state.sections.findIndex(section => section.id === action.payload.id);
if (index !== -1) {
state.sections[index] = action.payload;
}
},
// 删除分区
removeSection: (state, action: PayloadAction<number>) => {
state.sections = state.sections.filter(section => section.id !== action.payload);
// 如果删除的是当前选中的分区,清空选中状态
if (state.selectedCategoryId === action.payload) {
state.selectedCategoryId = null;
}
},
// 设置选中的分区ID
setSelectedCategoryId: (state, action: PayloadAction<number | null>) => {
state.selectedCategoryId = action.payload;
},
// 向分区添加作品ID
addArtworkToSection: (state, action: PayloadAction<{ sectionId: number; artworkId: number }>) => {
const { sectionId, artworkId } = action.payload;
const section = state.sections.find(s => s.id === sectionId);
if (section && !section.childrenid.includes(artworkId)) {
section.childrenid.push(artworkId);
}
},
// 从分区移除作品ID
removeArtworkFromSection: (state, action: PayloadAction<{ sectionId: number; artworkId: number }>) => {
const { sectionId, artworkId } = action.payload;
const section = state.sections.find(s => s.id === sectionId);
if (section) {
section.childrenid = section.childrenid.filter(id => id !== artworkId);
}
},
// 重新排序分区
reorderSections: (state, action: PayloadAction<Section[]>) => {
state.sections = action.payload;
},
// 重置分区状态
resetCategoryState: () => {
return initialState;
},
// 初始化分区数据
initializeSections: (state, action: PayloadAction<Section[]>) => {
state.sections = action.payload;
state.loading = false;
state.error = null;
},
},
});
// 导出actions
export const {
setLoading,
setError,
setSections,
addSection,
updateSection,
removeSection,
setSelectedCategoryId,
addArtworkToSection,
removeArtworkFromSection,
reorderSections,
resetCategoryState,
initializeSections,
} = categorySlice.actions;
// 选择器函数
export const selectSections = (state: { category: CategoryState }): Section[] =>
state.category.sections;
export const selectCategoryLoading = (state: { category: CategoryState }): boolean =>
state.category.loading;
export const selectCategoryError = (state: { category: CategoryState }): string | null =>
state.category.error;
export const selectSelectedCategoryId = (state: { category: CategoryState }): number | null =>
state.category.selectedCategoryId;
// 根据ID获取分区
export const selectSectionById = (sectionId: number) => (state: { category: CategoryState }) => {
return state.category.sections.find(section => section.id === sectionId);
};
// 获取分区数量
export const selectSectionCount = (state: { category: CategoryState }) => state.category.sections.length;
// 获取包含特定作品的分区
export const selectSectionsByArtworkId = (artworkId: number) => (state: { category: CategoryState }) => {
return state.category.sections.filter(section => section.childrenid.includes(artworkId));
};
// 获取选中的分区
export const selectSelectedSection = (state: { category: CategoryState }) => {
const { sections, selectedCategoryId } = state.category;
if (selectedCategoryId === null) return null;
return sections.find(section => section.id === selectedCategoryId) || null;
};
// 获取分区名称映射
export const selectSectionNameMap = (state: { category: CategoryState }) => {
return state.category.sections.reduce((acc, section) => {
acc[section.id] = section.name;
return acc;
}, {} as Record<number, string>);
};
export default categorySlice.reducer;