feat: 新增定时任务功能

This commit is contained in:
duanshuwen
2026-04-11 23:17:54 +08:00
parent 37ed157e4a
commit 67808a459e
25 changed files with 4149 additions and 22 deletions

View File

@@ -0,0 +1,356 @@
# 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. **分阶段实施**:优先核心功能,逐步增强
建议从基础的任务管理开始,先实现"仅应用内"模式,再逐步添加频道交付等高级功能。这样可以快速验证核心流程,降低初始风险。