完成主页, 作品页,作品编辑页
> 未对接后端接口
Change-Id: I5d62663602656da4940707e00f76bfe09d824c2c
diff --git a/src/feature/home/categorySlice.ts b/src/feature/home/categorySlice.ts
new file mode 100644
index 0000000..31482cc
--- /dev/null
+++ b/src/feature/home/categorySlice.ts
@@ -0,0 +1,167 @@
+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;
\ No newline at end of file