356 lines
13 KiB
Markdown
356 lines
13 KiB
Markdown
# ClawX 定时任务(Cron)功能实现分析参考
|
||
|
||
## 1. 功能概述
|
||
|
||
ClawX的定时任务(Cron)功能允许用户创建、管理、调度和自动化AI工作流。主要功能包括:
|
||
|
||
- **任务管理**:创建、编辑、删除、启用/禁用定时任务
|
||
- **调度配置**:支持预设调度(每分钟、每5分钟、每小时、每天9点等)和自定义Cron表达式
|
||
- **交付模式**:
|
||
- **仅应用内**:任务结果保留在应用内部
|
||
- **外部频道推送**:将任务结果通过已配置的频道(如飞书、Telegram、QQ机器人、企业微信、微信等)推送到指定目标
|
||
- **频道集成**:选择已配置的频道账户,并选择目标(用户、群组、频道)
|
||
- **任务执行**:立即触发任务执行,查看最近运行记录和状态
|
||
- **统计概览**:显示任务总数、活跃、暂停、失败的任务数量
|
||
- **依赖Gateway**:需要Gateway服务运行才能管理任务
|
||
|
||
## 2. 技术架构分析
|
||
|
||
### 2.1 前端架构(ClawX - React)
|
||
|
||
- **框架**:React 18 + TypeScript
|
||
- **状态管理**:Zustand(轻量级状态管理)
|
||
- **UI组件库**:shadcn/ui + Tailwind CSS
|
||
- **HTTP客户端**:自定义`hostApiFetch`封装IPC请求
|
||
- **国际化**:react-i18next
|
||
- **路由**:基于文件系统的路由(未显示但推测使用React Router)
|
||
|
||
### 2.2 后端架构(ClawX - Electron)
|
||
|
||
- **API路由**:`electron/api/routes/cron.ts`处理所有定时任务相关请求
|
||
- **数据存储**:Gateway管理的Cron作业配置,本地JSON文件(`cron.json`和`runs/*.jsonl`日志)
|
||
- **Gateway集成**:通过Gateway Manager RPC调用与OpenClaw交互
|
||
- **错误处理**:优雅降级,当Gateway不可用时回退到直接读取本地文件
|
||
- **数据转换**:在Gateway数据格式和UI数据格式之间进行转换
|
||
|
||
### 2.3 数据流
|
||
|
||
```
|
||
UI组件 (React) → Zustand Store → hostApiFetch → Electron IPC → API路由 (cron.ts)
|
||
↓ ↓
|
||
状态更新 Gateway Manager RPC
|
||
↓ ↓
|
||
重新渲染 OpenClaw Cron引擎
|
||
```
|
||
|
||
## 3. 关键组件分析
|
||
|
||
### 3.1 主页面组件 (`Cron/index.tsx`)
|
||
|
||
- **功能**:展示任务列表、统计卡片、创建/编辑对话框、任务卡片
|
||
- **子组件**:
|
||
- `TaskDialog`:创建/编辑任务的模态对话框
|
||
- `CronJobCard`:单个任务卡片,显示任务详情和操作按钮
|
||
- **状态管理**:使用`useCronStore`获取任务列表和操作函数
|
||
- **依赖检查**:检查Gateway状态,显示警告信息
|
||
|
||
### 3.2 任务对话框组件 (`TaskDialog`)
|
||
|
||
- **表单字段**:
|
||
- 任务名称、消息/提示词
|
||
- 调度选择(预设或自定义Cron表达式)
|
||
- 交付模式选择(仅应用内/外部频道)
|
||
- 频道选择、账户选择、目标选择
|
||
- 立即启用开关
|
||
- **动态加载**:根据选择的频道动态加载可用的账户和目标
|
||
- **验证**:前端表单验证,显示错误提示
|
||
- **调度预览**:显示下一次运行时间的预估
|
||
|
||
### 3.3 任务卡片组件 (`CronJobCard`)
|
||
|
||
- **信息展示**:任务名称、调度描述、消息预览、交付频道、最后运行状态、下次运行时间
|
||
- **操作按钮**:运行现在、编辑、删除、启用/禁用切换
|
||
- **状态指示器**:通过颜色圆点表示启用/禁用状态
|
||
- **错误显示**:最后运行失败时显示错误信息
|
||
|
||
### 3.4 Store模块 (`stores/cron.ts`)
|
||
|
||
- **状态**:`jobs`(任务列表)、`loading`(加载状态)、`error`(错误信息)
|
||
- **操作**:
|
||
- `fetchJobs`:获取任务列表
|
||
- `createJob`:创建新任务
|
||
- `updateJob`:更新任务
|
||
- `deleteJob`:删除任务
|
||
- `toggleJob`:启用/禁用任务
|
||
- `triggerJob`:立即触发任务
|
||
- **优化**:当已有数据时使用陈旧-重新验证模式,避免不必要的加载状态
|
||
|
||
## 4. API接口分析
|
||
|
||
### 4.1 接口端点
|
||
|
||
| 端点 | 方法 | 描述 |
|
||
|------|------|------|
|
||
| `/api/cron/jobs` | GET | 获取所有定时任务列表 |
|
||
| `/api/cron/jobs` | POST | 创建新的定时任务 |
|
||
| `/api/cron/jobs/{id}` | PUT | 更新指定定时任务 |
|
||
| `/api/cron/jobs/{id}` | DELETE | 删除指定定时任务 |
|
||
| `/api/cron/toggle` | POST | 启用/禁用定时任务 |
|
||
| `/api/cron/trigger` | POST | 立即触发定时任务 |
|
||
| `/api/cron/session-history` | GET | 获取任务运行历史记录(用于聊天会话) |
|
||
|
||
### 4.2 数据格式
|
||
|
||
#### 任务对象 (`CronJob`)
|
||
```typescript
|
||
interface CronJob {
|
||
id: string;
|
||
name: string;
|
||
message: string;
|
||
schedule: string | CronSchedule; // Cron表达式或Gateway调度对象
|
||
delivery?: CronJobDelivery; // 交付配置
|
||
target?: CronJobTarget; // 目标信息(UI展示用)
|
||
enabled: boolean;
|
||
createdAt: string;
|
||
updatedAt: string;
|
||
lastRun?: CronJobLastRun; // 最后运行信息
|
||
nextRun?: string; // 下次运行时间
|
||
}
|
||
```
|
||
|
||
#### 创建任务输入 (`CronJobCreateInput`)
|
||
```typescript
|
||
interface CronJobCreateInput {
|
||
name: string;
|
||
message: string;
|
||
schedule: string; // Cron表达式字符串
|
||
delivery?: CronJobDelivery;
|
||
enabled?: boolean;
|
||
}
|
||
```
|
||
|
||
#### 交付配置 (`CronJobDelivery`)
|
||
```typescript
|
||
interface CronJobDelivery {
|
||
mode: 'none' | 'announce';
|
||
channel?: string; // 频道类型
|
||
to?: string; // 目标ID
|
||
accountId?: string; // 账户ID
|
||
}
|
||
```
|
||
|
||
### 4.3 Gateway数据转换
|
||
|
||
API路由负责在Gateway数据格式和UI数据格式之间转换:
|
||
|
||
- **Gateway格式**:包含`createdAtMs`、`updatedAtMs`等毫秒时间戳
|
||
- **UI格式**:使用ISO字符串时间格式
|
||
- **调度对象**:Gateway使用`{kind: 'cron', expr: '...'}`格式,UI支持字符串和对象两种格式
|
||
|
||
## 5. 数据类型定义
|
||
|
||
### 5.1 核心类型 (`types/cron.ts`)
|
||
|
||
- `CronJobDeliveryMode`: `'none' | 'announce'`
|
||
- `CronJobDelivery`: 交付配置接口
|
||
- `CronJobTarget`: 目标信息接口(频道类型、频道ID、频道名称、接收者)
|
||
- `CronJobLastRun`: 最后运行信息接口
|
||
- `CronSchedule`: Gateway调度对象(`at`、`every`、`cron`三种类型)
|
||
- `CronJob`: 完整的任务对象
|
||
- `CronJobCreateInput`: 创建任务输入
|
||
- `CronJobUpdateInput`: 更新任务输入
|
||
- `ScheduleType`: 调度类型(`daily`、`weekly`、`monthly`、`interval`、`custom`)
|
||
|
||
### 5.2 辅助类型
|
||
|
||
- `DeliveryChannelAccount`: 交付频道账户
|
||
- `DeliveryChannelGroup`: 交付频道分组
|
||
- `ChannelTargetOption`: 频道目标选项
|
||
|
||
## 6. 错误处理机制
|
||
|
||
### 6.1 前端错误处理
|
||
|
||
- **加载错误**:显示错误提示但保留现有数据
|
||
- **表单验证**:实时验证并显示用户友好的错误消息
|
||
- **操作反馈**:使用toast通知显示操作结果(成功/失败)
|
||
- **降级策略**:当Gateway不可用时显示警告,但仍允许查看任务(如果存在本地缓存)
|
||
|
||
### 6.2 后端错误处理
|
||
|
||
- **Gateway超时**:8秒超时,超时后回退到读取本地文件
|
||
- **数据修复**:检测并自动修复孤立代理任务中的交付配置问题
|
||
- **输入验证**:验证交付频道支持性,返回适当的错误消息
|
||
- **日志记录**:记录错误但不暴露敏感信息给客户端
|
||
|
||
## 7. 国际化支持
|
||
|
||
### 7.1 多语言文件结构
|
||
|
||
- 支持英语、中文、日语、俄语
|
||
- 独立`cron.json`文件,包含所有定时任务相关文本
|
||
- 嵌套结构组织:`stats`、`empty`、`card`、`dialog`、`presets`、`toast`、`schedule`
|
||
|
||
### 7.2 关键翻译键
|
||
|
||
- `title`: "Scheduled Tasks"
|
||
- `subtitle`: "Automate AI workflows with scheduled tasks"
|
||
- `stats.total`: "Total Tasks"
|
||
- `dialog.createTitle`: "Create Task"
|
||
- `presets.every5Min`: "Every 5 minutes"
|
||
- `toast.created`: "Task created"
|
||
|
||
## 8. UI/UX设计分析
|
||
|
||
### 8.1 设计风格
|
||
|
||
- **卡片设计**:圆角大卡片,悬停效果,透明边框
|
||
- **色彩方案**:中性背景,主色用于操作按钮,状态色(绿/黄/红)用于指示器
|
||
- **排版**:大标题字体,清晰的层次结构
|
||
- **交互反馈**:平滑过渡,加载状态,即时验证
|
||
|
||
### 8.2 用户体验特性
|
||
|
||
- **调度预览**:实时显示下一次运行时间
|
||
- **智能默认值**:基于选择自动填充相关字段
|
||
- **渐进式披露**:高级选项(如自定义Cron)默认隐藏
|
||
- **批量操作**:支持多任务启用/禁用
|
||
- **状态可视化**:通过颜色和图标清晰表示任务状态
|
||
|
||
## 9. 与zn-ai项目的技术栈映射
|
||
|
||
### 9.1 技术栈对比
|
||
|
||
| 领域 | ClawX (React) | zn-ai (Vue) | 迁移策略 |
|
||
|------|---------------|-------------|----------|
|
||
| 框架 | React 18 | Vue 3 + Composition API | 组件重写 |
|
||
| 状态管理 | Zustand | Pinia | Store转换 |
|
||
| UI组件库 | shadcn/ui + Tailwind | Element Plus + Tailwind | 组件替换 |
|
||
| 国际化 | react-i18next | Vue I18n | 翻译文件转换 |
|
||
| HTTP客户端 | 自定义hostApiFetch | 相同hostApiFetch | 复用 |
|
||
| 类型系统 | TypeScript | TypeScript | 类型定义复用 |
|
||
|
||
### 9.2 组件映射建议
|
||
|
||
| ClawX组件 | Vue等价实现 | 说明 |
|
||
|-----------|-------------|------|
|
||
| `TaskDialog` | `CronTaskDialog.vue` | 使用Element Plus的Dialog、Form、Select等组件 |
|
||
| `CronJobCard` | `CronJobCard.vue` | 自定义卡片组件,使用Tailwind样式 |
|
||
| 统计卡片 | 使用Element Plus Card组件 | 可复用现有统计组件模式 |
|
||
| 确认对话框 | Element Plus MessageBox | 替换ConfirmDialog |
|
||
| 开关组件 | Element Plus Switch | 替换shadcn/ui Switch |
|
||
| 选择器 | Element Plus Select | 替换自定义SelectField |
|
||
|
||
### 9.3 Store迁移策略
|
||
|
||
- **保持相同状态结构**:`jobs`、`loading`、`error`
|
||
- **保持相同操作**:`fetchJobs`、`createJob`等
|
||
- **Pinia语法适配**:将Zustand的`create`转换为Pinia的`defineStore`
|
||
- **组合式函数**:可将部分逻辑提取到组合式函数中
|
||
|
||
## 10. 实现优先级建议
|
||
|
||
### 10.1 阶段一:基础架构与类型定义
|
||
1. 创建类型定义文件 (`src/lib/cron-types.ts`)
|
||
2. 创建Pinia store (`src/store/cron.ts`)
|
||
3. 创建API接口层(扩展host-api或创建专用服务)
|
||
4. 创建国际化文件 (`src/i18n/locales/*/cron.json`)
|
||
|
||
### 10.2 阶段二:核心UI组件开发
|
||
1. 主页面组件 (`src/pages/cron/index.vue`)
|
||
2. 任务卡片组件 (`src/pages/cron/components/CronJobCard.vue`)
|
||
3. 任务对话框组件 (`src/pages/cron/components/CronTaskDialog.vue`)
|
||
4. 统计卡片组件(可复用现有模式)
|
||
|
||
### 10.3 阶段三:功能集成与数据绑定
|
||
1. 集成store到组件
|
||
2. 实现表单验证和提交逻辑
|
||
3. 添加交付频道集成(依赖现有频道系统)
|
||
4. 实现调度预览功能
|
||
|
||
### 10.4 阶段四:测试、优化与完善
|
||
1. 添加加载状态和错误处理
|
||
2. 实现Gateway状态检查
|
||
3. 添加键盘快捷键和可访问性支持
|
||
4. 性能优化和代码清理
|
||
|
||
## 11. 风险评估与缓解措施
|
||
|
||
### 11.1 技术风险
|
||
- **Gateway依赖**:zn-ai可能没有相同的Gateway架构
|
||
- *缓解*:评估现有任务调度能力,或实现简化版本
|
||
- **频道集成复杂性**:交付功能依赖现有的频道配置系统
|
||
- *缓解*:先实现"仅应用内"模式,交付功能作为后续增强
|
||
- **Cron表达式解析**:需要可靠的Cron解析和预览
|
||
- *缓解*:使用成熟的Cron解析库(如`cron-parser`)
|
||
|
||
### 11.2 兼容性风险
|
||
- **数据格式差异**:与现有任务/调度系统的数据模型可能不兼容
|
||
- *缓解*:设计适配器层,确保向后兼容
|
||
- **UI一致性**:与zn-ai现有设计风格保持一致
|
||
- *缓解*:复用现有UI模式和组件库
|
||
|
||
### 11.3 开发资源风险
|
||
- **功能范围**:完整功能可能较复杂
|
||
- *缓解*:采用分阶段实施,优先核心功能
|
||
|
||
## 12. 依赖项分析
|
||
|
||
### 12.1 前端依赖
|
||
- **必需**:Vue 3, Pinia, Element Plus, Vue I18n, Tailwind CSS
|
||
- **可选**:Cron解析库(用于高级调度功能)
|
||
|
||
### 12.2 后端依赖
|
||
- **必需**:任务调度引擎(现有或需要实现)
|
||
- **必需**:频道账户管理系统(用于交付功能)
|
||
- **必需**:数据持久化(JSON文件或数据库)
|
||
|
||
### 12.3 外部服务依赖
|
||
- **可选**:外部频道服务(飞书、Telegram等API)
|
||
|
||
## 13. 测试策略
|
||
|
||
### 13.1 单元测试
|
||
- Store逻辑测试
|
||
- 工具函数测试(Cron解析、时间格式化等)
|
||
- 组件逻辑测试(使用Vue Test Utils)
|
||
|
||
### 13.2 集成测试
|
||
- API端点测试
|
||
- 组件集成测试
|
||
- 跨页面交互测试
|
||
|
||
### 13.3 端到端测试
|
||
- 完整用户流程测试(创建、编辑、删除任务)
|
||
- 调度执行测试
|
||
- 交付功能测试(如果实现)
|
||
|
||
## 14. 部署与维护
|
||
|
||
### 14.1 配置管理
|
||
- 调度配置持久化策略
|
||
- 日志文件管理和轮转
|
||
- 错误报告和监控
|
||
|
||
### 14.2 性能考虑
|
||
- 任务列表虚拟化(如果任务数量大)
|
||
- 调度检查优化(避免频繁轮询)
|
||
- 内存使用优化(大型历史记录处理)
|
||
|
||
### 14.3 可扩展性
|
||
- 插件架构支持(自定义调度类型)
|
||
- Webhook集成支持
|
||
- 多租户支持(如果未来需要)
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
ClawX的定时任务功能是一个完整、用户友好的调度系统,具有清晰的架构和良好的代码组织。迁移到zn-ai项目需要:
|
||
|
||
1. **技术栈转换**:从React/Zustand到Vue/Pinia的转换
|
||
2. **组件重写**:使用Element Plus替代shadcn/ui组件
|
||
3. **架构适配**:根据zn-ai现有架构调整后端集成
|
||
4. **分阶段实施**:优先核心功能,逐步增强
|
||
|
||
建议从基础的任务管理开始,先实现"仅应用内"模式,再逐步添加频道交付等高级功能。这样可以快速验证核心流程,降低初始风险。 |