270 lines
7.6 KiB
TypeScript
270 lines
7.6 KiB
TypeScript
import { create } from 'zustand';
|
|
import { invoke } from '@tauri-apps/api/core';
|
|
import {
|
|
MaterialSegmentView,
|
|
MaterialSegmentQuery,
|
|
MaterialSegmentViewMode,
|
|
SegmentActionRequest,
|
|
SegmentActionType,
|
|
} from '../types/materialSegmentView';
|
|
|
|
interface MaterialSegmentViewState {
|
|
// 数据状态
|
|
currentView: MaterialSegmentView | null;
|
|
viewMode: MaterialSegmentViewMode;
|
|
isLoading: boolean;
|
|
error: string | null;
|
|
|
|
// 查询状态
|
|
currentQuery: MaterialSegmentQuery | null;
|
|
|
|
// UI状态
|
|
selectedSegmentIds: Set<string>;
|
|
expandedGroups: Set<string>;
|
|
|
|
// Actions
|
|
loadProjectSegmentView: (projectId: string) => Promise<void>;
|
|
loadProjectSegmentViewWithQuery: (query: MaterialSegmentQuery) => Promise<void>;
|
|
setViewMode: (mode: MaterialSegmentViewMode) => void;
|
|
updateQuery: (updates: Partial<MaterialSegmentQuery>) => void;
|
|
clearQuery: () => void;
|
|
|
|
// 选择管理
|
|
selectSegment: (segmentId: string) => void;
|
|
deselectSegment: (segmentId: string) => void;
|
|
selectAllSegments: () => void;
|
|
clearSelection: () => void;
|
|
|
|
// 分组管理
|
|
expandGroup: (groupId: string) => void;
|
|
collapseGroup: (groupId: string) => void;
|
|
toggleGroup: (groupId: string) => void;
|
|
expandAllGroups: () => void;
|
|
collapseAllGroups: () => void;
|
|
|
|
// 片段操作
|
|
executeSegmentAction: (request: SegmentActionRequest) => Promise<void>;
|
|
|
|
// 工具方法
|
|
refreshCurrentView: () => Promise<void>;
|
|
clearError: () => void;
|
|
}
|
|
|
|
export const useMaterialSegmentViewStore = create<MaterialSegmentViewState>((set, get) => ({
|
|
// 初始状态
|
|
currentView: null,
|
|
viewMode: MaterialSegmentViewMode.ByClassification,
|
|
isLoading: false,
|
|
error: null,
|
|
currentQuery: null,
|
|
selectedSegmentIds: new Set(),
|
|
expandedGroups: new Set(),
|
|
|
|
// 加载项目的MaterialSegment聚合视图
|
|
loadProjectSegmentView: async (projectId: string) => {
|
|
set({ isLoading: true, error: null });
|
|
try {
|
|
const view = await invoke<MaterialSegmentView>('get_project_segment_view', { projectId });
|
|
set({
|
|
currentView: view,
|
|
isLoading: false,
|
|
currentQuery: { project_id: projectId }
|
|
});
|
|
} catch (error) {
|
|
const errorMessage = typeof error === 'string' ? error : '加载MaterialSegment视图失败';
|
|
set({ error: errorMessage, isLoading: false });
|
|
throw new Error(errorMessage);
|
|
}
|
|
},
|
|
|
|
// 根据查询条件加载MaterialSegment聚合视图
|
|
loadProjectSegmentViewWithQuery: async (query: MaterialSegmentQuery) => {
|
|
set({ isLoading: true, error: null });
|
|
try {
|
|
const view = await invoke<MaterialSegmentView>('get_project_segment_view_with_query', { query });
|
|
set({
|
|
currentView: view,
|
|
isLoading: false,
|
|
currentQuery: query
|
|
});
|
|
} catch (error) {
|
|
const errorMessage = typeof error === 'string' ? error : '加载MaterialSegment视图失败';
|
|
set({ error: errorMessage, isLoading: false });
|
|
throw new Error(errorMessage);
|
|
}
|
|
},
|
|
|
|
// 设置视图模式
|
|
setViewMode: (mode: MaterialSegmentViewMode) => {
|
|
const currentQuery = get().currentQuery;
|
|
set({ viewMode: mode });
|
|
|
|
// 如果有当前查询,重新加载数据以应用新的视图模式
|
|
if (currentQuery) {
|
|
console.log('视图模式切换到:', mode === MaterialSegmentViewMode.ByClassification ? '按分类' : '按模特');
|
|
// 视图模式是前端状态,不需要传递给后端,只需要重新加载当前数据
|
|
get().loadProjectSegmentViewWithQuery(currentQuery);
|
|
}
|
|
},
|
|
|
|
// 更新查询条件
|
|
updateQuery: (updates: Partial<MaterialSegmentQuery>) => {
|
|
const currentQuery = get().currentQuery;
|
|
if (!currentQuery) return;
|
|
|
|
const newQuery = { ...currentQuery, ...updates };
|
|
get().loadProjectSegmentViewWithQuery(newQuery);
|
|
},
|
|
|
|
// 清除查询条件
|
|
clearQuery: () => {
|
|
const currentQuery = get().currentQuery;
|
|
if (!currentQuery) return;
|
|
|
|
const baseQuery: MaterialSegmentQuery = {
|
|
project_id: currentQuery.project_id,
|
|
};
|
|
get().loadProjectSegmentViewWithQuery(baseQuery);
|
|
},
|
|
|
|
// 选择片段
|
|
selectSegment: (segmentId: string) => {
|
|
set(state => ({
|
|
selectedSegmentIds: new Set([...state.selectedSegmentIds, segmentId])
|
|
}));
|
|
},
|
|
|
|
// 取消选择片段
|
|
deselectSegment: (segmentId: string) => {
|
|
set(state => {
|
|
const newSelection = new Set(state.selectedSegmentIds);
|
|
newSelection.delete(segmentId);
|
|
return { selectedSegmentIds: newSelection };
|
|
});
|
|
},
|
|
|
|
// 选择所有片段
|
|
selectAllSegments: () => {
|
|
const view = get().currentView;
|
|
if (!view) return;
|
|
|
|
const allSegmentIds = new Set<string>();
|
|
|
|
// 根据当前视图模式收集所有片段ID
|
|
if (get().viewMode === MaterialSegmentViewMode.ByClassification) {
|
|
view.by_classification.forEach(group => {
|
|
group.segments.forEach(segment => {
|
|
allSegmentIds.add(segment.segment.id);
|
|
});
|
|
});
|
|
} else {
|
|
view.by_model.forEach(group => {
|
|
group.segments.forEach(segment => {
|
|
allSegmentIds.add(segment.segment.id);
|
|
});
|
|
});
|
|
}
|
|
|
|
set({ selectedSegmentIds: allSegmentIds });
|
|
},
|
|
|
|
// 清除选择
|
|
clearSelection: () => {
|
|
set({ selectedSegmentIds: new Set() });
|
|
},
|
|
|
|
// 展开分组
|
|
expandGroup: (groupId: string) => {
|
|
set(state => ({
|
|
expandedGroups: new Set([...state.expandedGroups, groupId])
|
|
}));
|
|
},
|
|
|
|
// 折叠分组
|
|
collapseGroup: (groupId: string) => {
|
|
set(state => {
|
|
const newExpanded = new Set(state.expandedGroups);
|
|
newExpanded.delete(groupId);
|
|
return { expandedGroups: newExpanded };
|
|
});
|
|
},
|
|
|
|
// 切换分组展开状态
|
|
toggleGroup: (groupId: string) => {
|
|
const expandedGroups = get().expandedGroups;
|
|
if (expandedGroups.has(groupId)) {
|
|
get().collapseGroup(groupId);
|
|
} else {
|
|
get().expandGroup(groupId);
|
|
}
|
|
},
|
|
|
|
// 展开所有分组
|
|
expandAllGroups: () => {
|
|
const view = get().currentView;
|
|
if (!view) return;
|
|
|
|
const allGroupIds = new Set<string>();
|
|
|
|
if (get().viewMode === MaterialSegmentViewMode.ByClassification) {
|
|
view.by_classification.forEach(group => {
|
|
allGroupIds.add(group.category);
|
|
});
|
|
} else {
|
|
view.by_model.forEach(group => {
|
|
allGroupIds.add(group.model_id);
|
|
});
|
|
}
|
|
|
|
set({ expandedGroups: allGroupIds });
|
|
},
|
|
|
|
// 折叠所有分组
|
|
collapseAllGroups: () => {
|
|
set({ expandedGroups: new Set() });
|
|
},
|
|
|
|
// 执行片段操作
|
|
executeSegmentAction: async (request: SegmentActionRequest) => {
|
|
set({ isLoading: true, error: null });
|
|
try {
|
|
// 根据操作类型调用相应的后端命令
|
|
switch (request.action_type) {
|
|
case SegmentActionType.Reclassify:
|
|
// TODO: 实现重新分类逻辑
|
|
break;
|
|
case SegmentActionType.EditModel:
|
|
// TODO: 实现编辑模特关联逻辑
|
|
break;
|
|
case SegmentActionType.Delete:
|
|
// TODO: 实现删除逻辑
|
|
break;
|
|
case SegmentActionType.ViewDetails:
|
|
// TODO: 实现查看详情逻辑
|
|
break;
|
|
}
|
|
|
|
// 刷新当前视图
|
|
await get().refreshCurrentView();
|
|
set({ isLoading: false });
|
|
} catch (error) {
|
|
const errorMessage = typeof error === 'string' ? error : '执行操作失败';
|
|
set({ error: errorMessage, isLoading: false });
|
|
throw new Error(errorMessage);
|
|
}
|
|
},
|
|
|
|
// 刷新当前视图
|
|
refreshCurrentView: async () => {
|
|
const currentQuery = get().currentQuery;
|
|
if (!currentQuery) return;
|
|
|
|
await get().loadProjectSegmentViewWithQuery(currentQuery);
|
|
},
|
|
|
|
// 清除错误
|
|
clearError: () => {
|
|
set({ error: null });
|
|
},
|
|
}));
|