Ver Fonte

`添加ai`

wenhongquan há 3 meses atrás
pai
commit
1214624f5a

+ 3 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -44,6 +44,9 @@ logging:
 # 用户配置
 user:
   filepath: ${filepath:./ruoyi/file}
+  fileUrl: http://jtjai.xt.wenhq.top:8083/api/oss/local/upload/
+  difyUrl: http://192.168.39.17:9000/v1
+  difykey: app-UWNxgj5tXtHvUs3d1SVpuPpw
   password:
     # 密码最大错误次数
     maxRetryCount: 5

+ 1 - 1
ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java

@@ -669,7 +669,7 @@ public class OssClient {
      *
      * @param path 文件相对路径
      */
-    private File getLocalEnvFile(String path) {
+    public File getLocalEnvFile(String path) {
         return new File(FilenameUtils.normalize(getLocalEnvDir() + File.separator + path));
     }
 

+ 93 - 6
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/TblEventController.java

@@ -1,11 +1,25 @@
 package org.dromara.system.controller;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.oss.core.OssClient;
+import org.dromara.common.oss.factory.OssFactory;
+import org.dromara.system.utils.DifyUtil;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -36,10 +50,16 @@ public class TblEventController extends BaseController {
 
     private final ITblEventService tblEventService;
 
+    private final DifyUtil difyUtil;
+
+    @Value("${user.fileUrl}")
+    String FileBASE_URL = "http://192.168.39.17:9000/v1";
+
+
     /**
      * 查询事件列表
      */
-    @SaCheckPermission("system:event:list")
+//    @SaCheckPermission("system:event:list")
     @GetMapping("/list")
     public TableDataInfo<TblEventVo> list(TblEventBo bo, PageQuery pageQuery) {
         return tblEventService.queryPageList(bo, pageQuery);
@@ -48,7 +68,7 @@ public class TblEventController extends BaseController {
     /**
      * 导出事件列表
      */
-    @SaCheckPermission("system:event:export")
+//    @SaCheckPermission("system:event:export")
     @Log(title = "事件", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     public void export(TblEventBo bo, HttpServletResponse response) {
@@ -61,7 +81,7 @@ public class TblEventController extends BaseController {
      *
      * @param id 主键
      */
-    @SaCheckPermission("system:event:query")
+//    @SaCheckPermission("system:event:query")
     @GetMapping("/{id}")
     public R<TblEventVo> getInfo(@NotNull(message = "主键不能为空")
                                      @PathVariable Long id) {
@@ -71,7 +91,7 @@ public class TblEventController extends BaseController {
     /**
      * 新增事件
      */
-    @SaCheckPermission("system:event:add")
+//    @SaCheckPermission("system:event:add")
     @Log(title = "事件", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
@@ -82,7 +102,7 @@ public class TblEventController extends BaseController {
     /**
      * 修改事件
      */
-    @SaCheckPermission("system:event:edit")
+//    @SaCheckPermission("system:event:edit")
     @Log(title = "事件", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
@@ -95,11 +115,78 @@ public class TblEventController extends BaseController {
      *
      * @param ids 主键串
      */
-    @SaCheckPermission("system:event:remove")
+//    @SaCheckPermission("system:event:remove")
     @Log(title = "事件", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空")
                           @PathVariable Long[] ids) {
         return toAjax(tblEventService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+     * 生成事件详情
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("system:event:generate")
+    @Log(title = "事件", businessType = BusinessType.UPDATE)
+    @PostMapping("/generate/{id}")
+    public R<Void> generate(@NotNull(message = "主键不能为空") @PathVariable Long id){
+        TblEventVo tblEventVo = tblEventService.queryById(id);
+        if(tblEventVo== null){
+            return R.fail("事件不存在");
+        }
+        OssClient storage = OssFactory.instance();
+        Map<String, Object> data = new HashMap<>();
+        data.put("地点",tblEventVo.getAddr());
+        data.put("事故时间",tblEventVo.getCreateTime());
+        try{
+            data.put("事故类型", JSONUtil.parseObj(tblEventVo.getExt2()).getStr("lx"));
+        }catch (Exception e) {}
+        try{
+            data.put("事件来源", JSONUtil.parseObj(tblEventVo.getExt2()).getStr("from"));
+        }catch (Exception e) {}
+
+
+        //获取事件图片
+        List fileInput = new ArrayList();
+        try{
+            JSONArray images = JSONUtil.parseArray(tblEventVo.getExt1());
+            for(int i = 0; i < images.size(); i++){
+                String  image = images.get(i).toString();
+                if(image.toString().contains("mp4")) continue;
+                try {
+                    File file = storage.getLocalEnvFile(image);
+                    String imageUrl = difyUtil.uploadFile(file.getAbsolutePath());
+                    String imgid = JSONUtil.parseObj(imageUrl).getStr("id");
+                    Map<String, Object> fileItem = new HashMap<>();
+                    fileItem.put("transfer_method", "local_file");
+                    fileItem.put("upload_file_id", imgid);
+                    fileItem.put("type", image.toString().contains("mp4") ? "video" : "image");
+                    fileInput.add(fileItem);
+                }catch (Exception e){}
+            }
+
+
+        }catch(Exception e){}
+
+        String  eventString = JSONUtil.toJsonStr( data);
+        Map<String, Object> workflowInputs = new HashMap<>();
+
+        workflowInputs.put("files", fileInput);
+        workflowInputs.put("event",eventString);
+        try {
+            String workflowResult = difyUtil.runWorkflow(
+                null,
+                workflowInputs,
+                "blocking",
+                "user-12"
+            );
+            System.out.println("工作流结果: " + workflowResult);
+            return R.ok(workflowResult);
+
+        }catch (Exception e){}
+
+       return R.fail("生成事件详情失败");
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/TblEventVo.java

@@ -23,7 +23,7 @@ import java.util.Date;
 @Data
 @ExcelIgnoreUnannotated
 @AutoMapper(target = TblEvent.class)
-public class TblEventVo implements Serializable {
+public class TblEventVo extends TblEvent implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;

+ 239 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/utils/DifyUtil.java

@@ -0,0 +1,239 @@
+package org.dromara.system.utils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DifyUtil {
+    // API配置常量
+    @Value("${user.difyUrl}")
+    String API_BASE_URL = "http://192.168.39.17:9000/v1";
+//    private static final String API_KEY = System.getenv("Dify_KEY");
+    @Value("${user.difykey}")
+    String API_KEY = "app-UWNxgj5tXtHvUs3d1SVpuPpw";
+    private static final String BOUNDARY = "----WebKitFormBoundary" + UUID.randomUUID().toString().replace("-", "");
+
+    /**
+     * 文件上传接口
+     * @param filePath 本地文件路径
+     * @return API响应结果
+     * @throws IOException IO异常
+     */
+    public  String uploadFile(String filePath) throws IOException {
+        String endpoint = "/files/upload";
+        HttpURLConnection connection = null;
+        File file = new File(filePath);
+
+        try {
+            URL url = new URL(API_BASE_URL + endpoint);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Authorization", "Bearer " + API_KEY);
+            connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
+            connection.setDoOutput(true);
+
+            try (OutputStream output = connection.getOutputStream();
+                 PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8))) {
+
+                // 添加文件部分
+                writer.append("--").append(BOUNDARY).append("\r\n");
+                writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(file.getName()).append("\"\r\n");
+                writer.append("Content-Type: application/octet-stream\r\n\r\n");
+                writer.flush();
+                try (FileInputStream fileInputStream = new FileInputStream(file)) {
+                    byte[] buffer = new byte[4096];
+                    int bytesRead;
+                    while ((bytesRead = fileInputStream.read(buffer)) != -1) {
+                        output.write(buffer, 0, bytesRead);
+                    }
+                }
+                writer.append("\r\n");
+
+                // 完成边界
+                writer.append("--").append(BOUNDARY).append("--\r\n");
+            }
+
+            return getResponseString(connection);
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    /**
+     * Chat对话接口
+     * @param model 模型名称
+     * @param prompt 用户输入
+     * @param params 附加参数
+     * @return API响应结果
+     * @throws IOException IO异常
+     */
+    public  String chat(String model, String prompt, Map<String, Object> params) throws IOException {
+        String endpoint = "/chat/completions";
+        HttpURLConnection connection = null;
+
+        try {
+            URL url = new URL(API_BASE_URL + endpoint);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Authorization", "Bearer " + API_KEY);
+            connection.setRequestProperty("Content-Type", "application/json");
+            connection.setDoOutput(true);
+
+            // 构建请求体
+            StringBuilder jsonBody = new StringBuilder();
+            jsonBody.append("{");
+            jsonBody.append("\"model\": \"").append(model).append("\",");
+            jsonBody.append("\"prompt\": \"").append(prompt).append("\",");
+            jsonBody.append("\"temperature\": ").append(params.getOrDefault("temperature", 0.7)).append(",");
+            jsonBody.append("\"max_tokens\": ").append(params.getOrDefault("max_tokens", 2048));
+
+            if (params.containsKey("top_p")) {
+                jsonBody.append(",\"top_p\": ").append(params.get("top_p"));
+            }
+
+            jsonBody.append("}");
+
+            try (OutputStream os = connection.getOutputStream()) {
+                byte[] input = jsonBody.toString().getBytes(StandardCharsets.UTF_8);
+                os.write(input, 0, input.length);
+            }
+
+            return getResponseString(connection);
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+
+
+/**
+ * 工作流调用接口
+ * @param workflowId 工作流ID
+ * @param inputs 输入参数
+ * @param responseMode 返回响应模式
+ * @param user 用户标识
+ * @return API响应结果
+ * @throws IOException IO异常
+ */
+public  String runWorkflow(String workflowId, Map<String, Object> inputs, String responseMode, String user) throws IOException {
+    String endpoint = "/workflows/run";
+    if(workflowId==null){
+        endpoint = "/workflows/run" ;
+    }else{
+        endpoint = "/workflows/run/" + workflowId;
+    }
+    HttpURLConnection connection = null;
+
+    try {
+        URL url = new URL(API_BASE_URL + endpoint);
+        connection = (HttpURLConnection) url.openConnection();
+        connection.setRequestMethod("POST");
+        connection.setRequestProperty("Authorization", "Bearer " + API_KEY);
+        connection.setRequestProperty("Content-Type", "application/json");
+        connection.setDoOutput(true);
+
+        // 构建请求体
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("inputs", inputs);
+        if(responseMode!=null){
+            requestBody.put("response_mode", responseMode);
+        }
+        if(user!=null){
+            requestBody.put("user", user);
+        }
+
+
+        String jsonBody = JSONUtil.toJsonStr(requestBody);
+
+        try (OutputStream os = connection.getOutputStream()) {
+            byte[] input = jsonBody.getBytes(StandardCharsets.UTF_8);
+            os.write(input, 0, input.length);
+        }
+
+        return getResponseString(connection);
+    } finally {
+        if (connection != null) {
+            connection.disconnect();
+        }
+    }
+}
+
+
+    /**
+     * 获取响应内容
+     * @param connection HTTP连接
+     * @return 响应字符串
+     * @throws IOException IO异常
+     */
+    private static String getResponseString(HttpURLConnection connection) throws IOException {
+        StringBuilder response = new StringBuilder();
+        int responseCode = connection.getResponseCode();
+
+        try (BufferedReader reader = new BufferedReader(
+                new InputStreamReader(responseCode < 400 ? connection.getInputStream() : connection.getErrorStream(), StandardCharsets.UTF_8))) {
+
+            String line;
+            while ((line = reader.readLine()) != null) {
+                response.append(line.trim());
+            }
+        }
+
+        return response.toString();
+    }
+
+    // 示例调用方法
+//    public static void main(String[] args) {
+//        try {
+            // 示例文件上传
+//            String uploadResult = uploadFile("/Users/wenhongquan/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/wenhongquan_b92c/msg/file/2025-06/智能识别数据/未命名文件夹/1.jpg");
+//            System.out.println("文件上传结果: " + uploadResult);
+
+//            // 示例Chat调用
+//            Map<String, Object> chatParams = new HashMap<>();
+//            chatParams.put("temperature", 0.8);
+//            chatParams.put("max_tokens", 1024);
+//            String chatResult = chat("gpt-3.5-turbo", "你好,请介绍一下你自己", chatParams);
+//            System.out.println("Chat结果: " + chatResult);
+
+            // 示例工作流调用
+//            Map<String, Object> workflowInputs = new HashMap<>();
+//
+//            // 示例inputs结构
+//            List fileInput = new ArrayList();
+//            Map<String, Object> fileItem = new HashMap<>();
+//            fileItem.put("transfer_method", "local_file");
+//            fileItem.put("upload_file_id", "08836f9b-6bd1-4951-8fd4-344b123e7ac3");
+//            fileItem.put("type", "image");
+//
+//            fileInput.add(fileItem);
+//
+//
+//            workflowInputs.put("files", fileInput);
+//            workflowInputs.put("event","地点:G42绕城公路-路网监测-铁心桥立交-K302+000-1  事故类型:交通事故 事故时间: 2025-06-10 19:10:18  事件来源:国省干线" );
+//
+//            String workflowResult = runWorkflow(
+//                null,
+//                workflowInputs,
+//                "blocking",
+//                "user-12"
+//            );
+//            System.out.println("工作流结果: " + workflowResult);
+//
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+//    }
+}