# ZCLAW 自动化系统重设计方案 > **状态**: 待审核 > **作者**: Claude > **日期**: 2026-03-18 > **版本**: 1.0 --- ## 一、背景与目标 ### 1.1 当前问题 | 问题 | 影响 | 严重程度 | |------|------|---------| | HandsPanel 使用 gatewayStore 而非 handStore | 状态管理混乱,新 store 未被使用 | 高 | | HandParamsForm 参数未传递给 triggerHand | 用户填写的参数被丢弃 | 致命 | | 缺少 WebSocket 实时状态更新 | 无法看到执行进度 | 高 | | 无执行结果展示 | 用户不知道 Hand 执行结果 | 高 | | 无执行历史查看 | 无法追溯过去的执行 | 中 | | Hands 与 Workflows 分离 | 用户体验割裂 | 中 | ### 1.2 设计目标 基于用户需求确认: 1. **专业版功能** - 完整重构 + 工作流集成 + 批量操作 + 调度管理 2. **可视化调度器** - 图形化界面选择时间/频率,无需了解 cron 语法 3. **结果流展示** - Hand 输出作为对话消息显示在聊天区域 4. **批量操作** - 支持批量触发、批量审批、批量配置 5. **统一视图** - Hands 和 Workflows 合并到一个"自动化"视图,按任务类型分类 --- ## 二、架构设计 ### 2.1 整体架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ UI Layer │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │AutomationPanel│ │ScheduleEditor│ │ExecutionResultStream│ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ State Management │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ automationStore.ts │ │ │ │ - hands: Hand[] │ │ │ │ - workflows: Workflow[] │ │ │ │ - runs: Run[] │ │ │ │ - schedules: Schedule[] │ │ │ │ - approvals: Approval[] │ │ │ │ - selectedIds: Set │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Data Layer │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ gateway-client.ts │ │ │ │ - listHands() / listWorkflows() │ │ │ │ - triggerHand() / executeWorkflow() │ │ │ │ - createSchedule() / updateSchedule() │ │ │ │ - WebSocket 事件监听 │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### 2.2 数据流 ``` 用户操作 → AutomationPanel → automationStore → gateway-client → OpenFang API │ ├── 更新 UI 状态 ├── WebSocket 事件 → 更新执行状态 └── 执行完成 → 注入结果到 chatStore ``` ### 2.3 文件结构 ``` desktop/src/ ├── components/ │ ├── Automation/ # 新建目录 │ │ ├── AutomationPanel.tsx # 统一入口(组合层) │ │ ├── AutomationCard.tsx # Hand/Workflow 卡片 │ │ ├── AutomationFilters.tsx # 分类筛选 │ │ ├── ScheduleEditor.tsx # 可视化调度器 │ │ ├── ExecutionResult.tsx # 结果展示组件 │ │ ├── BatchActionBar.tsx # 批量操作栏 │ │ └── ApprovalQueue.tsx # 审批队列 │ └── HandsPanel.tsx # 重构为 AutomationPanel 入口 ├── store/ │ ├── handStore.ts # 扩展:添加批量操作方法 │ ├── workflowStore.ts # 保留:工作流状态 │ └── automationCoordinator.ts # 新建:跨 store 协调层 ├── types/ │ ├── hands.ts # 扩展:添加 CategoryType │ └── automation.ts # 新建:类型适配器 └── hooks/ └── useAutomationEvents.ts # 新建:WebSocket 事件 Hook ``` > **设计决策**: 不创建新的 `automationStore.ts`,而是扩展现有的 `handStore.ts` 和 `workflowStore.ts`, > 通过轻量级的 `automationCoordinator.ts` 进行跨 store 协调。这遵循了现有代码库的模式。 --- ## 三、核心组件设计 ### 3.1 AutomationPanel(统一入口) ```typescript interface AutomationPanelProps { initialCategory?: CategoryType; onSelect?: (item: AutomationItem) => void; } interface AutomationPanelState { items: AutomationItem[]; // Hands + Workflows 合并 categories: CategoryStats; // 各分类统计 filters: FilterState; // 当前筛选条件 selectedIds: string[]; // 批量选择 viewMode: 'grid' | 'list'; // 视图模式 } type CategoryType = 'all' | 'research' | 'data' | 'automation' | 'communication'; ``` **UI 布局**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 自动化 [新建] [调度] │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 全部 │ │ 研究 │ │ 数据 │ │ 自动化 │ ... │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ [AutomationCard] [AutomationCard] [AutomationCard] │ │ [AutomationCard] [AutomationCard] [AutomationCard] │ └─────────────────────────────────────────────────────────────┘ ``` ### 3.2 AutomationCard(统一卡片) ```typescript interface AutomationCardProps { item: AutomationItem; status: ExecutionStatus; result?: ExecutionResult; onSelect: (selected: boolean) => void; onExecute: (params?: Record) => void; onSchedule: () => void; } interface AutomationItem { id: string; name: string; description: string; type: 'hand' | 'workflow'; category: CategoryType; status: ItemStatus; parameters: Parameter[]; lastRun?: RunInfo; schedule?: ScheduleInfo; requiresApproval: boolean; } ``` ### 3.3 ScheduleEditor(可视化调度器) ```typescript interface ScheduleEditorProps { schedule?: ScheduleInfo; onSave: (schedule: ScheduleInfo) => void; onCancel: () => void; } interface ScheduleInfo { enabled: boolean; frequency: 'once' | 'daily' | 'weekly' | 'monthly' | 'custom'; time: { hour: number; minute: number }; daysOfWeek?: number[]; // 0-6 for weekly dayOfMonth?: number; // 1-31 for monthly customCron?: string; // 高级模式可选 timezone: string; endDate?: Date; } ``` **UI 设计**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 调度设置 [保存] │ ├─────────────────────────────────────────────────────────────┤ │ 频率: ○ 一次 ● 每天 ○ 每周 ○ 每月 ○ 自定义 │ │ 时间: [09] : [00] 时区: [Asia/Shanghai ▼] │ │ ┌─ 每周重复 (选中"每周"时显示) ───────────────────────┐ │ │ │ [一] [二] [三] [四] [五] [六] [日] │ │ │ └───────────────────────────────────────────────────────┘ │ │ 结束日期: [无结束日期 ▼] 或 选择日期: [____-__-__] │ │ 预览: "每天 09:00 (Asia/Shanghai),无结束日期" │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 四、结果流设计 ### 4.1 消息类型扩展 ```typescript interface ChatMessage { id: string; role: 'user' | 'assistant' | 'system' | 'hand' | 'workflow'; // 新增 content: string; timestamp: number; executionInfo?: { type: 'hand' | 'workflow'; name: string; runId: string; status: 'running' | 'completed' | 'failed' | 'needs_approval'; duration?: number; output?: unknown; error?: string; }; } ``` ### 4.2 结果消息渲染 ``` ┌─────────────────────────────────────────────────────────────┐ │ 🔍 Researcher │ │ ─────────────────────────────────────────────────────── │ │ 状态: ✅ 完成 耗时: 2m 34s │ │ │ │ ## 研究结果摘要 │ │ ... │ │ │ │ [查看完整报告] [下载 PDF] [重新执行] │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 五、批量操作设计 ### 5.1 批量操作接口 ```typescript interface BatchOperations { selectedIds: Set; executeSelected: (params?: Record) => Promise; approveSelected: () => Promise; rejectSelected: (reason: string) => Promise; updateConfigSelected: (config: Partial) => Promise; scheduleSelected: (schedule: ScheduleInfo) => Promise; } ``` ### 5.2 批量操作栏 UI ``` ┌─────────────────────────────────────────────────────────────┐ │ 已选择 3 项 [取消选择] │ ├─────────────────────────────────────────────────────────────┤ │ [▶ 执行选中] [✓ 批量审批] [✗ 批量拒绝] [⏰ 批量调度] │ └─────────────────────────────────────────────────────────────┘ ``` ### 5.3 批量审批队列 ``` ┌─────────────────────────────────────────────────────────────┐ │ 审批队列 (5 待处理) [全部批准] [全部拒绝] │ ├─────────────────────────────────────────────────────────────┤ │ ☐ Browser - 访问 github.com/search │ │ 请求者: Agent-1 | 请求时间: 2分钟前 │ │ ☐ Lead - 搜索 LinkedIn 销售线索 │ │ 请求者: Agent-2 | 请求时间: 5分钟前 │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 六、实时状态与错误处理 ### 6.1 状态流转 ``` ┌─────────┐ trigger ┌─────────┐ execute ┌───────────┐ │ idle │ ──────────► │ pending │ ──────────► │ running │ └─────────┘ └─────────┘ └───────────┘ ▲ │ │ ┌──────────────┐ │ └──────────────│ completed │◄───────────────────┘ └──────────────┘ │ ┌──────────────┐ │ failed │ └──────────────┘ │ ┌──────────────┐ │needs_approval│ ──approve──► running └──────────────┘ ``` ### 6.2 WebSocket 事件处理 ```typescript interface AutomationWebSocketHandlers { onHandStatus: (data: { name: string; status: string; runId?: string }) => void; onHandResult: (data: { name: string; runId: string; result: unknown }) => void; onWorkflowStep: (data: { id: string; step: number; status: string }) => void; onWorkflowComplete: (data: { id: string; result: unknown }) => void; onApprovalRequest: (data: ApprovalRequest) => void; onApprovalResolved: (data: { id: string; approved: boolean }) => void; } ``` ### 6.3 错误处理 ```typescript type ErrorCode = | 'CONNECTION_LOST' | 'HAND_UNAVAILABLE' | 'PARAM_INVALID' | 'PERMISSION_DENIED' | 'RATE_LIMITED' | 'TIMEOUT' | 'APPROVAL_REQUIRED' | 'APPROVAL_REJECTED' | 'EXECUTION_FAILED'; interface AutomationError { code: ErrorCode; message: string; recoverable: boolean; suggestedAction?: string; } ``` ### 6.4 离线队列 ```typescript interface ConnectionState { status: 'connected' | 'disconnected' | 'reconnecting'; pendingActions: PendingAction[]; } // 离线时缓存操作,重连后批量执行 ``` --- ## 七、实现计划 ### 7.1 分阶段实施 | 阶段 | 任务 | 交付物 | 预计时间 | |------|------|--------|---------| | **Phase 1** | 基础修复 | 可用的 Hands 系统 | 1-2 天 | | **Phase 2** | UI 重构 | 统一自动化面板 | 2-3 天 | | **Phase 3** | 高级功能 | 调度与批量操作 | 2-3 天 | | **Phase 4** | 工作流集成 | 完整自动化系统 | 2-3 天 | ### 7.2 文件变更清单 **新建文件**: - `desktop/src/components/Automation/` 目录(7 个组件) - `desktop/src/store/automationStore.ts` - `desktop/src/types/automation.ts` - `desktop/src/hooks/useAutomationEvents.ts` - `tests/desktop/automation/` 测试目录 **修改文件**: - `desktop/src/components/HandsPanel.tsx` - 重构为入口 - `desktop/src/store/handStore.ts` - 合并到 automationStore - `desktop/src/lib/gateway-client.ts` - 增强 WebSocket 事件 - `desktop/src/store/chatStore.ts` - 支持 hand/workflow 消息类型 - `desktop/src/components/ChatArea.tsx` - 渲染结果流消息 - `desktop/src/components/Sidebar.tsx` - 导航更新 --- ## 八、测试策略 ### 8.1 测试覆盖 | 测试类型 | 覆盖范围 | 工具 | |---------|---------|------| | 单元测试 | Store 逻辑、工具函数、组件 | Vitest | | 集成测试 | API 调用、WebSocket 事件 | Vitest + MSW | | E2E 测试 | 完整用户流程 | Playwright | ### 8.2 关键测试用例 1. 参数从表单正确传递到 API 2. WebSocket 事件正确更新 UI 状态 3. 批量选择和操作功能 4. 调度器生成正确的 cron 表达式 5. 结果流消息正确注入聊天 6. 离线队列在重连后执行 7. 错误状态正确显示和恢复 --- ## 九、验收标准 | 功能 | 验收标准 | |------|---------| | Hand 执行 | 填写参数 → 执行 → 看到实时进度 → 结果显示在聊天流 | | 批量操作 | 选择 3 个 Hand → 批量执行 → 全部成功 | | 调度 | 设置"每天 9:00" → 保存 → 在调度列表看到正确预览 | | 审批 | Hand 需要审批 → 弹出审批请求 → 批准 → 继续执行 | | 离线 | 断网 → 触发 Hand → 重连 → 自动执行 | --- ## 十、风险评估 | 风险 | 可能性 | 影响 | 缓解措施 | |------|--------|------|---------| | 后端 API 不完整 | 中 | 高 | 使用 fallback 数据,明确标注未实现 | | WebSocket 不稳定 | 低 | 高 | 心跳机制 + 自动重连 + 离线队列 | | 迁移影响现有功能 | 中 | 中 | 分阶段迁移,保留旧组件作为 fallback | | 调度器复杂度 | 低 | 中 | 先实现基础频率,高级功能后续迭代 | --- ## 附录 A:API 端点参考 | 端点 | 方法 | 用途 | |------|------|------| | `/api/hands` | GET | 列出所有 Hands | | `/api/hands/{name}` | GET | 获取 Hand 详情 | | `/api/hands/{name}/activate` | POST | 触发 Hand 执行 | | `/api/hands/{name}/runs/{runId}` | GET | 获取执行状态 | | `/api/hands/{name}/runs/{runId}/approve` | POST | 批准执行 | | `/api/hands/{name}/runs/{runId}/cancel` | POST | 取消执行 | | `/api/hands/{name}/runs` | GET | 列出执行历史 | | `/api/workflows` | GET/POST | 工作流管理 | | `/api/triggers` | GET/POST/PUT/DELETE | 触发器管理 | --- ## 附录 B:WebSocket 事件参考 | 事件类型 | 字段 | 说明 | |---------|------|------| | `hand` | hand_name, hand_status, hand_result | Hand 状态变更 | | `workflow` | workflow_id, step, status | Workflow 步骤变更 | | `approval` | approval_id, type, status | 审批请求/响应 |