import { create } from 'zustand'; import type { Project, GenerationRecord, OptimizeParams, OptimizeResult, Industry, MediaReference } from '../types'; import * as api from '../api'; import { useAuthStore } from './useAuthStore'; const emptyRecordsPage = (): api.GenerationRecordPageListOut => ({ page: 1, pageSize: 10, total: 0, items: [], }); interface AppState { projects: Project[]; records: api.GenerationRecordPageListOut; loading: boolean; // 生成配置状态 - 页面跳转时保留,刷新时重置 mediaType: string; countType: string; generationCount: number; selectedRatio: string; selectedResolution: string; width: number; height: number; videoDuration: number; videoAspectRatio: string; videoResolution: string; engineOptions: { ratios: string[]; resolutions: string[]; durations: number[]; }; enginesele: any; inputValue: string; currentMedia: MediaReference[]; fetchProjects: () => Promise; createProject: (name: string, industry: Industry) => Promise; deleteProject: (id: string) => Promise; fetchRecords: (params?: api.GetRecordsPageParams) => Promise; optimizePrompt: (projectId: string, params: OptimizeParams) => Promise; generateVideo: (recordId: string) => Promise; retryGeneration: (recordId: string) => Promise; updateRecordReferences: (recordId: string, references: MediaReference[]) => void; // 生成配置状态更新方法 setMediaType: (mediaType: string) => void; setCountType: (countType: string) => void; setGenerationCount: (generationCount: number) => void; setImageSettings: (ratio: string, resolution: string, width: number, height: number) => void; setVideoSettings: (duration: number, aspectRatio: string, resolution: string) => void; setEngineOptions: (options: { ratios: string[]; resolutions: string[]; durations: number[] }) => void; // 单独的 setter 方法 setSelectedRatio: (ratio: string) => void; setSelectedResolution: (resolution: string) => void; setWidth: (width: number) => void; setHeight: (height: number) => void; setVideoDuration: (duration: number) => void; setVideoAspectRatio: (aspectRatio: string) => void; setVideoResolution: (resolution: string) => void; setEnginesele: (enginesele: any) => void; setInputValue: (inputValue: string) => void; setCurrentMedia: (currentMedia: MediaReference[]) => void; resetGenerationConfig: () => void; } export const useAppStore = create((set, get) => ({ projects: [], records: emptyRecordsPage(), loading: false, // 生成配置状态初始值 mediaType: 'video', countType: '请选择', generationCount: 1, selectedRatio: '1:1', selectedResolution: '2K', width: 2048, height: 2048, videoDuration: 5, videoAspectRatio: '9:16', videoResolution: '720p', engineOptions: { ratios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'], resolutions: ['480p', '720p', '1080p'], durations: [5, 8, 10, 12, 15], }, enginesele: [], inputValue: '', currentMedia: [], fetchProjects: async () => { set({ loading: true }); try { const projects = await api.getProjects(); set({ projects, loading: false }); } catch { set({ loading: false }); } }, createProject: async (name, industry) => { const project = await api.createProject(name, industry); set({ projects: [project, ...get().projects] }); return project; }, deleteProject: async (id) => { await api.deleteProject(id); set({ projects: get().projects.filter((p) => p.id !== id) }); }, fetchRecords: async (params = {}) => { set({ loading: true }); try { const records = await api.getRecordsPage(params); set({ records, loading: false }); } catch { set({ loading: false }); } }, optimizePrompt: async (projectId, params) => { const result = await api.optimizePrompt(projectId, params); try { await useAuthStore.getState().checkAuth(); } catch { /* */ } const currentRecords = get().records; const existingIndex = currentRecords.items.findIndex((item) => item.id === result.record.id); const nextItems = existingIndex >= 0 ? currentRecords.items.map((item) => item.id === result.record.id ? result.record : item) : [result.record, ...currentRecords.items]; set({ records: { ...currentRecords, total: existingIndex >= 0 ? currentRecords.total : currentRecords.total + 1, items: nextItems, }, }); return result; }, generateVideo: async (recordId) => { const record = await api.generateVideo(recordId); try { await useAuthStore.getState().checkAuth(); } catch { /* */ } const currentRecords = get().records; set({ records: { ...currentRecords, items: currentRecords.items.map((r) => (r.id === recordId ? record : r)), }, }); return record; }, retryGeneration: async (recordId) => { const record = await api.retryGeneration(recordId); try { await useAuthStore.getState().checkAuth(); } catch { /* */ } const currentRecords = get().records; set({ records: { ...currentRecords, items: currentRecords.items.map((r) => (r.id === recordId ? record : r)), }, }); return record; }, updateRecordReferences: (recordId, references) => { const currentRecords = get().records; set({ records: { ...currentRecords, items: currentRecords.items.map((r) => (r.id === recordId ? { ...r, references } : r)), }, }); }, // 生成配置状态更新方法 setMediaType: (mediaType) => set({ mediaType }), setCountType: (countType) => set({ countType }), setGenerationCount: (generationCount) => set({ generationCount }), setImageSettings: (ratio, resolution, width, height) => set({ selectedRatio: ratio, selectedResolution: resolution, width, height }), setVideoSettings: (duration, aspectRatio, resolution) => set({ videoDuration: duration, videoAspectRatio: aspectRatio, videoResolution: resolution }), setEngineOptions: (options) => set({ engineOptions: options }), // 单独的 setter 方法 setSelectedRatio: (ratio) => set({ selectedRatio: ratio }), setSelectedResolution: (resolution) => set({ selectedResolution: resolution }), setWidth: (width) => set({ width }), setHeight: (height) => set({ height }), setVideoDuration: (duration) => set({ videoDuration: duration }), setVideoAspectRatio: (aspectRatio) => set({ videoAspectRatio: aspectRatio }), setVideoResolution: (resolution) => set({ videoResolution: resolution }), setEnginesele: (enginesele) => set({ enginesele }), setInputValue: (inputValue) => set({ inputValue }), setCurrentMedia: (currentMedia) => set({ currentMedia }), resetGenerationConfig: () => set({ mediaType: 'image', countType: '请选择', generationCount: 1, selectedRatio: '1:1', selectedResolution: '2K', width: 2048, height: 2048, videoDuration: 5, videoAspectRatio: '9:16', videoResolution: '720p', engineOptions: { ratios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'], resolutions: ['480p', '720p', '1080p'], durations: [5, 8, 10, 12, 15], }, enginesele: [], inputValue: '', currentMedia: [], }), }));