|
|
@@ -0,0 +1,174 @@
|
|
|
+package edu.nju.software.aipaasagent.mcp.tool.examples;
|
|
|
+
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
+import cn.hutool.core.util.URLUtil;
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.ai.tool.annotation.Tool;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Hutool资源下载工具
|
|
|
+ * 使用 Hutool 进行文件下载和资源操作
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class ResourceDownloadTool {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 下载网络文件
|
|
|
+ *
|
|
|
+ * @param url 文件URL
|
|
|
+ * @param savePath 保存路径(可选)
|
|
|
+ * @return 下载结果
|
|
|
+ */
|
|
|
+ @Tool(name = "downloadFile", description = "下载网络文件到本地。参数url: 文件URL,参数savePath: 保存路径(可选)")
|
|
|
+ public String downloadFile(String url, String savePath) {
|
|
|
+ log.info("下载文件: {}, 保存到: {}", url, savePath);
|
|
|
+
|
|
|
+ try {
|
|
|
+ String destPath;
|
|
|
+ if (savePath == null || savePath.isEmpty()) {
|
|
|
+ String fileName = URLUtil.getPath(url);
|
|
|
+ if (fileName != null) {
|
|
|
+ fileName = new File(fileName).getName();
|
|
|
+ }
|
|
|
+ if (fileName == null || fileName.isEmpty()) {
|
|
|
+ fileName = "download_" + System.currentTimeMillis();
|
|
|
+ }
|
|
|
+ destPath = System.getProperty("user.dir") + File.separator + fileName;
|
|
|
+ } else {
|
|
|
+ destPath = savePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ long file = HttpUtil.downloadFile(url, destPath);
|
|
|
+
|
|
|
+ String result = String.format(
|
|
|
+ "文件下载成功\n保存路径: %s\n文件大小: %s",
|
|
|
+ file,
|
|
|
+ FileUtil.readableFileSize(file)
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info(result);
|
|
|
+ return result;
|
|
|
+ } catch (Exception e) {
|
|
|
+ String error = "文件下载失败: " + e.getMessage();
|
|
|
+ log.error(error, e);
|
|
|
+ return error;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取文件大小
|
|
|
+ *
|
|
|
+ * @param filePath 文件路径
|
|
|
+ * @return 文件大小信息
|
|
|
+ */
|
|
|
+ @Tool(name = "getFileSize", description = "获取文件大小。参数filePath: 文件路径")
|
|
|
+ public String getFileSize(String filePath) {
|
|
|
+ log.info("获取文件大小: {}", filePath);
|
|
|
+
|
|
|
+ try {
|
|
|
+ File file = new File(filePath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ return "文件不存在: " + filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ String result = String.format(
|
|
|
+ "文件路径: %s\n文件大小: %s (%,d 字节)",
|
|
|
+ file.getAbsolutePath(),
|
|
|
+ FileUtil.readableFileSize(file.length()),
|
|
|
+ file.length()
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info(result);
|
|
|
+ return result;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "获取文件大小失败: " + e.getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取文本文件内容
|
|
|
+ *
|
|
|
+ * @param filePath 文件路径
|
|
|
+ * @return 文件内容
|
|
|
+ */
|
|
|
+ @Tool(name = "readTextFile", description = "读取文本文件内容。参数filePath: 文件路径")
|
|
|
+ public String readTextFile(String filePath) {
|
|
|
+ log.info("读取文本文件: {}", filePath);
|
|
|
+
|
|
|
+ try {
|
|
|
+ File file = new File(filePath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ return "文件不存在: " + filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ String content = FileUtil.readUtf8String(file);
|
|
|
+ log.info("文件读取成功,内容长度: {} 字符", content.length());
|
|
|
+
|
|
|
+ return content.length() > 10000 ?
|
|
|
+ content.substring(0, 10000) + "\n\n[内容已截断,完整内容过长]" :
|
|
|
+ content;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "读取文件失败: " + e.getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 写入文本文件
|
|
|
+ *
|
|
|
+ * @param filePath 文件路径
|
|
|
+ * @param content 要写入的内容
|
|
|
+ * @return 写入结果
|
|
|
+ */
|
|
|
+ @Tool(name = "writeTextFile", description = "写入文本文件。参数filePath: 文件路径,参数content: 要写入的内容")
|
|
|
+ public String writeTextFile(String filePath, String content) {
|
|
|
+ log.info("写入文本文件: {}", filePath);
|
|
|
+
|
|
|
+ try {
|
|
|
+ FileUtil.writeUtf8String(content, filePath);
|
|
|
+
|
|
|
+ String result = String.format(
|
|
|
+ "文件写入成功\n文件路径: %s\n内容长度: %d 字符",
|
|
|
+ filePath,
|
|
|
+ content.length()
|
|
|
+ );
|
|
|
+
|
|
|
+ log.info(result);
|
|
|
+ return result;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "写入文件失败: " + e.getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除文件
|
|
|
+ *
|
|
|
+ * @param filePath 文件路径
|
|
|
+ * @return 删除结果
|
|
|
+ */
|
|
|
+ @Tool(name = "deleteFile", description = "删除文件。参数filePath: 文件路径")
|
|
|
+ public String deleteFile(String filePath) {
|
|
|
+ log.info("删除文件: {}", filePath);
|
|
|
+
|
|
|
+ try {
|
|
|
+ File file = new File(filePath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ return "文件不存在: " + filePath;
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean deleted = FileUtil.del(file);
|
|
|
+ String result = deleted ?
|
|
|
+ "文件删除成功: " + filePath :
|
|
|
+ "文件删除失败: " + filePath;
|
|
|
+
|
|
|
+ log.info(result);
|
|
|
+ return result;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "删除文件失败: " + e.getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|