import { reactive, computed } from 'vue' import { invoke } from '@tauri-apps/api/core' import { projectApi, taskApi, ideaApi, workflowApi } from '../api' import type { ProjectRecord, TaskRecord, IdeaRecord, WorkflowRecord, WorkflowEventPayload } from '../api/types' // ── 全局响应式状态(单例) ── const state = reactive({ projects: [] as ProjectRecord[], tasks: [] as TaskRecord[], ideas: [] as IdeaRecord[], workflowExecutions: [] as WorkflowRecord[], liveEvents: [] as WorkflowEventPayload[], pendingApproval: null as { execution_id: string node_id: string title: string description: string options: string[] } | null, loading: false, error: null as string | null, }) let _eventUnlisten: (() => void) | null = null export function useProjectStore() { // ── 项目 CRUD ── async function loadProjects() { state.loading = true state.error = null try { state.projects = await projectApi.list() } catch (e: any) { state.error = e?.toString() ?? '加载项目失败' } finally { state.loading = false } } async function createProject(name: string, description = '', ideaId?: string) { const record = await projectApi.create({ name, description, idea_id: ideaId }) state.projects.push(record) return record } async function updateProject(id: string, field: string, value: string) { await projectApi.update(id, field, value) const idx = state.projects.findIndex(p => p.id === id) if (idx >= 0) { (state.projects[idx] as any)[field] = value } } async function deleteProject(id: string) { await projectApi.delete(id) state.projects = state.projects.filter(p => p.id !== id) } // ── 任务 CRUD ── async function loadTasks(projectId?: string) { try { state.tasks = await taskApi.list(projectId) } catch (e: any) { state.error = e?.toString() ?? '加载任务失败' } } async function createTask(input: { project_id: string; title: string; description?: string; priority?: number; branch_name?: string; assignee?: string }) { const record = await taskApi.create(input) state.tasks.push(record) return record } async function updateTask(id: string, field: string, value: string) { await taskApi.update(id, field, value) const idx = state.tasks.findIndex(t => t.id === id) if (idx >= 0) { (state.tasks[idx] as any)[field] = value } } async function deleteTask(id: string) { await taskApi.delete(id) state.tasks = state.tasks.filter(t => t.id !== id) } // ── 想法 CRUD ── async function loadIdeas() { try { state.ideas = await ideaApi.list() } catch (e: any) { state.error = e?.toString() ?? '加载想法失败' } } async function createIdea(input: { title: string; description?: string; priority?: number; tags?: string; source?: string }) { const record = await ideaApi.create(input) state.ideas.push(record) return record } async function updateIdea(id: string, field: string, value: string) { await ideaApi.update(id, field, value) const idx = state.ideas.findIndex(i => i.id === id) if (idx >= 0) { (state.ideas[idx] as any)[field] = value } } async function deleteIdea(id: string) { await ideaApi.delete(id) state.ideas = state.ideas.filter(i => i.id !== id) } // ── 工作流 ── async function runWorkflow(name: string, dag: unknown, config?: Record) { return await workflowApi.run(name, dag, config) } async function loadWorkflowExecutions() { try { state.workflowExecutions = await workflowApi.listExecutions() } catch (e: any) { state.error = e?.toString() ?? '加载工作流记录失败' } } async function startEventListener() { if (_eventUnlisten) return _eventUnlisten _eventUnlisten = await workflowApi.onEvent((payload) => { state.liveEvents.push(payload) // 处理人工审批请求 if (payload.event.type === 'HumanApprovalRequest') { state.pendingApproval = payload.event.data as typeof state.pendingApproval } }) return _eventUnlisten } function clearLiveEvents() { state.liveEvents = [] } async function approveHumanApproval(decision: string, comment?: string) { if (!state.pendingApproval) return try { // 调用 IPC 命令发送审批响应 await invoke('approve_human_approval', { execution_id: state.pendingApproval.execution_id, node_id: state.pendingApproval.node_id, decision, comment }) // 清除待审批状态 state.pendingApproval = null } catch (error) { console.error('审批失败:', error) } } function stopEventListener() { if (_eventUnlisten) { try { _eventUnlisten() } catch (e) { console.error('停止事件监听失败:', e) } _eventUnlisten = null } } // ── 统计 ── const stats = computed(() => ({ ideas: state.ideas.length, projects: state.projects.length, activeTasks: state.tasks.filter(t => t.status === 'in_progress').length, drafts: state.ideas.filter(i => i.status === 'draft').length, })) return reactive({ // reactive state — 直接引用 state 属性,已经是响应式的 projects: state.projects, tasks: state.tasks, ideas: state.ideas, workflowExecutions: state.workflowExecutions, liveEvents: state.liveEvents, loading: state.loading, error: state.error, // project actions loadProjects, createProject, updateProject, deleteProject, // task actions loadTasks, createTask, updateTask, deleteTask, // idea actions loadIdeas, createIdea, updateIdea, deleteIdea, // workflow actions runWorkflow, loadWorkflowExecutions, startEventListener, stopEventListener, clearLiveEvents, approveHumanApproval, pendingApproval: computed(() => state.pendingApproval), // computed stats, }) }