Commit 998f1d1d authored by ligaowei's avatar ligaowei

Merge remote changes

parents 8b605b53 23ae72a7
# HiAgent定时器模块代码优化计划
## 1. 组件结构设计不一致问题
### 1.1 后端重构计划
- **创建TimerHistoryController**:负责处理执行历史API端点
- **实现HistoryService**:管理执行历史相关的业务逻辑
- **移除TimerController中的执行历史代码**:将执行历史功能分离
- **完善查询功能**:完成所有标记为TODO的查询功能
### 1.2 具体实现步骤
1. 创建`TimerHistoryController.java`,包含以下API端点:
- GET /api/v1/timer-history - 获取执行历史列表
- GET /api/v1/timer-history/{timerId} - 获取指定定时器的执行历史
- GET /api/v1/timer-history/{id}/detail - 获取执行历史详情
2. 创建`HistoryService.java`,实现以下功能:
- 执行历史的查询、统计和管理
- 支持多条件筛选和分页查询
- 执行历史的详情查询
3.`TimerController.java`中移除执行历史相关的代码
4. 完善数据库查询功能,确保所有执行历史查询都能正常工作
## 2. 前端组件实现缺失问题
### 2.1 实现CronEditor.vue组件
- **功能**:提供可视化的Cron表达式编辑界面
- **设计**:支持秒级、分钟级、小时级、每日、每周、每月等多种配置方式
- **交互**:实时生成和验证Cron表达式,支持可视化展示
### 2.2 实现TimerHistory.vue页面
- **功能**:显示定时器执行历史
- **设计**:包含筛选条件、执行历史表格、详情对话框
- **交互**:支持多条件筛选、排序、查看执行详情
### 2.3 具体实现步骤
1. 创建`CronEditor.vue`组件,包含:
- 可视化配置界面
- Cron表达式生成和验证逻辑
- 与现有表单的集成
2. 创建`TimerHistory.vue`页面,包含:
- 筛选条件区域(定时器ID、时间范围、执行结果)
- 执行历史表格(支持排序和分页)
- 执行详情对话框
3. 更新`TimerManagement.vue`,集成CronEditor组件
## 3. 定时任务执行逻辑不完整问题
### 3.1 增强TimerJob执行流程
- **确保完整执行流程**:配置检索 → 模板解析 → Agent调用 → 历史记录 → 结果处理
- **完善错误处理**:在每个执行阶段添加适当的错误处理
- **增强执行历史记录**:记录更详细的执行信息
### 3.2 具体实现步骤
1. 增强`TimerJob.executeInternal()`方法,确保完整的执行流程
2. 完善`TimerService.executeTimerTask()`方法,添加更详细的执行历史记录
3. 在每个执行阶段添加try-catch块,确保错误能够被正确捕获和记录
4. 实现执行结果的完整处理和记录
## 4. 性能优化措施未实现问题
### 4.1 实现缓存机制
- **缓存Agent列表**:减少频繁查询数据库
- **缓存提示词模板**:提高模板渲染效率
### 4.2 实现定期清理任务
- **创建定时清理任务**:定期清理过期的执行历史记录
### 4.3 数据库优化
- **添加索引**:为执行历史表添加适当的索引
- **优化查询语句**:确保查询效率
### 4.4 任务调度优化
- **优化Quartz配置**:调整线程池大小和任务执行策略
### 4.5 具体实现步骤
1. 添加缓存配置,使用Spring Cache实现Agent列表和提示词模板的缓存
2. 创建定时清理任务,使用Spring Scheduler定期清理过期的执行历史
3.`hiagent_timer_execution_history`表添加索引
4. 优化Quartz配置,调整线程池大小和任务执行策略
## 5. 测试计划
### 5.1 单元测试
- 为新创建的Controller和Service添加单元测试
- 测试执行历史查询功能
- 测试Cron表达式生成和验证
### 5.2 集成测试
- 测试定时器执行的完整流程
- 测试缓存机制的有效性
- 测试定期清理任务的执行
### 5.3 性能测试
- 测试大量定时器同时执行的性能
- 测试执行历史查询的性能
- 测试缓存机制对系统性能的提升
## 6. 代码质量保证
- 遵循项目的编码规范
- 确保代码的可读性和可维护性
- 添加适当的注释
- 确保向后兼容
## 7. 部署计划
- 更新API文档
- 提供前端组件的使用说明
- 确保所有优化措施都能正常工作
## 8. 预期效果
- 组件结构符合设计文档要求
- 前端功能完整,用户体验提升
- 定时任务执行逻辑完整,错误处理完善
- 系统性能显著提升
- 代码质量和可维护性提高
\ No newline at end of file
This diff is collapsed.
# 实现POP3邮件工具类
## 1. 添加依赖
在pom.xml中添加JavaMail API依赖,用于实现POP3邮件访问功能。
## 2. 创建邮件工具类
创建`EmailTools.java`文件,包含以下功能:
### 2.1 核心功能实现
- **获取今日所有邮件**:通过POP3协议连接邮箱,筛选今日收到的邮件,返回发件人和标题
- **获取所有未读邮件**:连接邮箱,筛选未读邮件,返回发件人和标题
- **获取指定邮件内容**:根据邮件ID获取邮件的详细内容
- **获取指定邮件附件**:根据邮件ID下载并保存附件
- **标记邮件为已读/未读**:修改邮件的阅读状态
- **删除指定邮件**:从邮箱中删除指定邮件
### 2.2 数据结构设计
- 定义请求参数类:包含邮箱服务器、端口、用户名、密码等必要信息
- 定义响应数据类:包含邮件ID、发件人、收件人、标题、日期、内容等信息
- 定义邮件附件数据类:包含附件名称、大小、内容类型等信息
### 2.3 工具方法
- 实现POP3连接管理(连接、断开连接)
- 实现邮件解析功能(解析邮件头、正文、附件)
- 实现日期筛选和格式转换
- 实现邮件状态管理
## 3. 代码实现要点
- 使用Spring的`@Component``@Tool`注解标记工具类和方法
- 使用Lombok的`@Slf4j`进行日志记录
- 处理异常情况,确保工具的健壮性
- 遵循现有工具类的代码风格和命名规范
- 提供清晰的工具描述和参数说明
## 4. 测试和验证
- 确保代码编译通过
- 验证各个方法的功能正确性
- 处理各种边界情况
通过以上步骤,实现一个功能完整、使用方便的POP3邮件工具类,满足用户的需求。
\ No newline at end of file
# 工具类参数配置机制实现方案
## 1. 设计目标
为项目中所有工具类实现参数配置功能,支持:
- 参数的UI动态配置展示
- 参数的数据库存储与读取
- 类似Spring Boot中@Value注解的机制实现参数管理
- 参数的默认值设置
- 数据库持久化存储与读取功能
## 2. 核心组件设计
### 2.1 自定义注解设计
创建`@ToolParam`注解,用于标记工具类中的配置参数:
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ToolParam {
String name() default "";
String description() default "";
String defaultValue() default "";
String type() default "string";
boolean required() default false;
String group() default "default";
}
```
### 2.2 数据库实体设计
创建`ToolConfig`实体类,用于存储工具参数配置:
```java
@Entity
@Table(name = "tool_configs")
public class ToolConfig {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
private String toolName;
private String paramName;
private String paramValue;
private String description;
private String defaultValue;
private String type;
private boolean required;
private String groupName;
// getter和setter方法
}
```
### 2.3 参数配置服务
创建`ToolConfigService`服务类,用于处理参数的读取和保存:
```java
public interface ToolConfigService {
Map<String, String> getToolParams(String toolName);
String getParamValue(String toolName, String paramName);
void saveParamValue(String toolName, String paramName, String paramValue);
List<ToolConfig> getAllToolConfigs();
ToolConfig getToolConfig(String toolName, String paramName);
void saveToolConfig(ToolConfig toolConfig);
void deleteToolConfig(String id);
}
```
### 2.4 参数配置处理器
创建`ToolParamProcessor`类,用于处理工具类中的`@ToolParam`注解:
```java
@Component
public class ToolParamProcessor {
private final ToolConfigService toolConfigService;
// 构造函数注入
@PostConstruct
public void processToolParams() {
// 扫描所有带有@Component注解的工具类
// 处理@ToolParam注解
// 从数据库读取参数值并注入到工具类字段
}
public void injectParams(Object toolInstance) {
// 为工具实例注入参数值
}
}
```
### 2.5 参数配置控制器
创建`ToolConfigController`类,用于提供参数配置的REST API:
```java
@RestController
@RequestMapping("/api/tool-configs")
public class ToolConfigController {
private final ToolConfigService toolConfigService;
// 构造函数注入
@GetMapping
public List<ToolConfig> getAllToolConfigs() {
// 返回所有工具配置
}
@GetMapping("/{toolName}")
public Map<String, String> getToolParams(@PathVariable String toolName) {
// 返回指定工具的配置参数
}
@PostMapping
public ToolConfig saveToolConfig(@RequestBody ToolConfig toolConfig) {
// 保存工具配置
}
@DeleteMapping("/{id}")
public void deleteToolConfig(@PathVariable String id) {
// 删除工具配置
}
}
```
## 3. 实现步骤
### 3.1 创建核心组件
1. 创建`@ToolParam`注解
2. 创建`ToolConfig`实体类
3. 创建`ToolConfigRepository`接口
4. 创建`ToolConfigService`接口及实现类
5. 创建`ToolParamProcessor`
6. 创建`ToolConfigController`
7. 创建数据库初始化脚本,添加`tool_configs`
### 3.2 修改工具类
`FileProcessingTools.java`为例,修改其参数定义:
```java
@Slf4j
@Component
public class FileProcessingTools {
// 支持的文本文件扩展名
private static final List<String> TEXT_FILE_EXTENSIONS = Arrays.asList(
".txt", ".md", ".java", ".html", ".htm", ".css", ".js", ".json",
".xml", ".yaml", ".yml", ".properties", ".sql", ".py", ".cpp",
".c", ".h", ".cs", ".php", ".rb", ".go", ".rs", ".swift", ".kt",
".scala", ".sh", ".bat", ".cmd", ".ps1", ".log", ".csv", ".ts",
".jsx", ".tsx", ".vue", ".scss", ".sass", ".less"
);
// 支持的图片文件扩展名
private static final List<String> IMAGE_FILE_EXTENSIONS = Arrays.asList(
".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp", ".ico"
);
// 默认文件存储目录
@ToolParam(
name = "defaultStorageDir",
description = "默认文件存储目录",
defaultValue = "storage",
type = "string",
required = true,
group = "file"
)
private String defaultStorageDir;
// getter和setter方法
// 其他方法保持不变
}
```
### 3.3 实现参数注入机制
`ToolParamProcessor`类中实现参数注入逻辑,使用Spring的`BeanPostProcessor`接口,在Bean初始化后注入参数值:
```java
@Component
public class ToolParamProcessor implements BeanPostProcessor {
private final ToolConfigService toolConfigService;
// 构造函数注入
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean.getClass().getPackage().getName().contains("pangea.hiagent.tools")) {
injectParams(bean);
}
return bean;
}
private void injectParams(Object bean) {
Class<?> clazz = bean.getClass();
String toolName = clazz.getSimpleName();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ToolParam.class)) {
ToolParam annotation = field.getAnnotation(ToolParam.class);
String paramName = annotation.name().isEmpty() ? field.getName() : annotation.name();
// 从数据库获取参数值,如果不存在则使用默认值
String paramValue = toolConfigService.getParamValue(toolName, paramName);
if (paramValue == null) {
paramValue = annotation.defaultValue();
}
// 设置字段值
field.setAccessible(true);
try {
// 根据字段类型转换参数值
if (field.getType() == String.class) {
field.set(bean, paramValue);
} else if (field.getType() == int.class || field.getType() == Integer.class) {
field.set(bean, Integer.parseInt(paramValue));
} else if (field.getType() == long.class || field.getType() == Long.class) {
field.set(bean, Long.parseLong(paramValue));
} else if (field.getType() == boolean.class || field.getType() == Boolean.class) {
field.set(bean, Boolean.parseBoolean(paramValue));
} else if (field.getType() == double.class || field.getType() == Double.class) {
field.set(bean, Double.parseDouble(paramValue));
}
// 可以扩展支持更多类型
} catch (Exception e) {
// 处理异常
}
}
}
}
}
```
### 3.4 实现数据库初始化
创建`schema.sql`文件,添加`tool_configs`表的创建语句:
```sql
CREATE TABLE IF NOT EXISTS tool_configs (
id VARCHAR(36) PRIMARY KEY,
tool_name VARCHAR(255) NOT NULL,
param_name VARCHAR(255) NOT NULL,
param_value TEXT,
description TEXT,
default_value TEXT,
type VARCHAR(50) NOT NULL,
required BOOLEAN NOT NULL DEFAULT FALSE,
group_name VARCHAR(100) NOT NULL DEFAULT 'default',
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_tool_param (tool_name, param_name)
);
```
## 4. 扩展支持
### 4.1 UI配置界面支持
前端可以通过调用`/api/tool-configs`接口获取所有工具的配置参数,然后动态生成配置界面。
### 4.2 支持更多参数类型
可以扩展`ToolParamProcessor`类,支持更多参数类型,如枚举、数组、列表等。
### 4.3 支持参数验证
可以在`@ToolParam`注解中添加验证规则,如正则表达式、最小值、最大值等,然后在参数注入时进行验证。
## 5. 测试计划
1. 测试`@ToolParam`注解的基本功能
2. 测试参数的数据库存储与读取
3. 测试参数的默认值设置
4. 测试参数的类型转换
5. 测试参数的UI动态配置展示
6. 测试多个工具类的参数配置
## 6. 实现顺序
1. 创建核心组件(注解、实体、服务等)
2. 实现数据库初始化脚本
3. 实现参数注入机制
4. 修改现有工具类,添加`@ToolParam`注解
5. 实现参数配置控制器
6. 测试功能
7. 优化和扩展功能
## 7. 预期效果
通过本方案的实现,项目中的所有工具类都将支持参数的动态配置,用户可以通过UI界面方便地配置和管理工具参数,参数配置将持久化到数据库中,并且支持类似Spring Boot中@Value注解的机制实现参数管理。
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment