2 Achegas cc6c1f2f31 ... 7f53864816

Autor SHA1 Mensaxe Data
  183207892172 7f53864816 Merge remote-tracking branch 'origin/master' hai 4 días
  183207892172 93707fd7ec 流程及对话 hai 4 días

+ 74 - 0
java/storlead-knowledge/storlead-knowledge-api/src/main/java/com/storlead/knowledge/api/ChatController.java

@@ -0,0 +1,74 @@
+package com.storlead.knowledge.api;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.storlead.framework.common.result.Result;
+import com.storlead.knowledge.config.DifyProperties;
+import com.storlead.knowledge.pojo.dto.ChatDTO;
+import com.storlead.knowledge.pojo.dto.TagDTO;
+import com.storlead.knowledge.utils.HttpService;
+import com.storlead.knowledge.utils.JacksonHolder;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+
+
+@RestController
+@RequestMapping("/chat/")
+@Api(tags = "对话及流程")
+public class ChatController {
+    @Resource
+    private HttpService httpService;
+
+    @Resource
+    private DifyProperties difyProperties;
+
+    /**
+     * 创建聊天 blocking模式
+     * @param chatDTO
+     * @return
+     * @throws JsonProcessingException
+     */
+    @PostMapping("chat")
+    @ApiOperation("创建聊天")
+    public Result<Object> chat(@RequestBody ChatDTO chatDTO) throws JsonProcessingException {
+        String url = difyProperties.getBaseUrl() + "chat-messages";
+        String body = JacksonHolder.OBJECT_MAPPER.writeValueAsString(chatDTO);
+        return httpService.post(url, null, "Bearer "+difyProperties.getAppKeys().get(chatDTO.getAppId()), body, new TypeReference<>() {});
+    }
+
+
+    /**
+     * 创建聊天 流式模式
+     * @param chatDTO
+     * @return
+     * @throws IOException
+     */
+    @PostMapping(value = "/chatStreaming", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+    public SseEmitter chatStreaming(@RequestBody ChatDTO chatDTO) throws IOException {
+
+        SseEmitter emitter = new SseEmitter(0L); // 0 = 不超时
+
+        String url = difyProperties.getBaseUrl() + "chat-messages";
+
+        // 强制开启流式
+        //chatDTO.setStream(true);
+
+        String body = JacksonHolder.OBJECT_MAPPER.writeValueAsString(chatDTO);
+
+        httpService.postStream(
+                url,
+                "Bearer " + difyProperties.getAppKeys().get(chatDTO.getAppId()),
+                body,
+                emitter
+        );
+
+        return emitter;
+    }
+
+}

+ 4 - 2
java/storlead-knowledge/storlead-knowledge-api/src/main/java/com/storlead/knowledge/api/DocumentController.java

@@ -100,11 +100,13 @@ public class DocumentController {
         return httpService.patch(url, null, "Bearer "+difyProperties.getDatasetApiKey(), body, new TypeReference<>() {});
         return httpService.patch(url, null, "Bearer "+difyProperties.getDatasetApiKey(), body, new TypeReference<>() {});
     }
     }
 
 
+
+
     @PostMapping("{dataset_id}/documents/{document_id}/update-by-file")
     @PostMapping("{dataset_id}/documents/{document_id}/update-by-file")
     @ApiOperation("以文件创建文档")
     @ApiOperation("以文件创建文档")
     public Result<Object> updateDocumentByFile(
     public Result<Object> updateDocumentByFile(
             @RequestParam("file") MultipartFile file,
             @RequestParam("file") MultipartFile file,
-            @RequestParam("data") String data,
+            @RequestParam("data") String data,  //格式 {"indexing_technique":"high_quality","doc_form":"text_model","doc_language":"English","process_rule":{"mode":"automatic"}}
             @PathVariable String dataset_id,
             @PathVariable String dataset_id,
             @PathVariable String document_id
             @PathVariable String document_id
     ) {
     ) {
@@ -124,7 +126,7 @@ public class DocumentController {
             @RequestParam("file") MultipartFile file,
             @RequestParam("file") MultipartFile file,
             @RequestParam("data") String data,
             @RequestParam("data") String data,
             @PathVariable String dataset_id,
             @PathVariable String dataset_id,
-            @PathVariable String batch
+            @PathVariable String batch  //上传文件返回的batch
     ) {
     ) {
         String url = difyProperties.getBaseUrl() + "datasets/"+dataset_id + "/documents/"+ batch+"/indexing-status";
         String url = difyProperties.getBaseUrl() + "datasets/"+dataset_id + "/documents/"+ batch+"/indexing-status";
         return httpService.uploadWithJson(
         return httpService.uploadWithJson(

+ 7 - 15
java/storlead-knowledge/storlead-knowledge-core/src/main/java/com/storlead/knowledge/config/DifyProperties.java

@@ -1,28 +1,20 @@
 package com.storlead.knowledge.config;
 package com.storlead.knowledge.config;
 
 
+import lombok.Getter;
+import lombok.Setter;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
+import java.util.Map;
+
+@Setter
+@Getter
 @Component
 @Component
 @ConfigurationProperties(prefix = "dify")
 @ConfigurationProperties(prefix = "dify")
 public class DifyProperties {
 public class DifyProperties {
 
 
     private String baseUrl;
     private String baseUrl;
     private String datasetApiKey;
     private String datasetApiKey;
+    private Map<String, String> appKeys;
 
 
-    public String getBaseUrl() {
-        return baseUrl;
-    }
-
-    public void setBaseUrl(String baseUrl) {
-        this.baseUrl = baseUrl;
-    }
-
-    public String getDatasetApiKey() {
-        return datasetApiKey;
-    }
-
-    public void setDatasetApiKey(String apiKey) {
-        this.datasetApiKey = apiKey;
-    }
 }
 }

+ 23 - 0
java/storlead-knowledge/storlead-knowledge-core/src/main/java/com/storlead/knowledge/pojo/dto/ChatDTO.java

@@ -0,0 +1,23 @@
+package com.storlead.knowledge.pojo.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ChatDTO {
+    @ApiModelProperty(value = "默认输入")
+    private List<String> input;
+    @ApiModelProperty(value = "查询内容")
+    private String query;
+    @ApiModelProperty(value = "返回模式 blocking/streaming")
+    private String response_mode;
+    @ApiModelProperty(value = "会话id")
+    private String conversation_id;
+    @ApiModelProperty(value = "用户id")
+    private String user;
+    @ApiModelProperty(value = "应用id")
+    private String appId;
+
+}

+ 49 - 0
java/storlead-knowledge/storlead-knowledge-core/src/main/java/com/storlead/knowledge/utils/HttpService.java

@@ -5,8 +5,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.storlead.framework.common.result.Result;
 import com.storlead.framework.common.result.Result;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
 
+import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.URI;
 import java.net.URI;
 import java.net.http.*;
 import java.net.http.*;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.StandardCharsets;
@@ -23,6 +27,7 @@ public class HttpService {
     private final HttpClient httpClient;
     private final HttpClient httpClient;
     private final ObjectMapper objectMapper = JacksonHolder.OBJECT_MAPPER;
     private final ObjectMapper objectMapper = JacksonHolder.OBJECT_MAPPER;
 
 
+
     public HttpService() {
     public HttpService() {
         this.httpClient = HttpClient.newBuilder()
         this.httpClient = HttpClient.newBuilder()
                 .connectTimeout(Duration.ofSeconds(5))
                 .connectTimeout(Duration.ofSeconds(5))
@@ -124,6 +129,50 @@ public class HttpService {
         }
         }
     }
     }
 
 
+
+    public void postStream(
+            String url,
+            String authorization,
+            String body,
+            SseEmitter emitter
+    ) {
+        try {
+            HttpRequest request = HttpRequest.newBuilder()
+                    .uri(URI.create(url))
+                    .timeout(Duration.ofSeconds(60))
+                    .header("Authorization", authorization)
+                    .header("Accept", "text/event-stream")
+                    .header("Content-Type", "application/json")
+                    .POST(HttpRequest.BodyPublishers.ofString(body))
+                    .build();
+
+            HttpResponse<InputStream> response =
+                    httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
+
+            try (BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(response.body(), StandardCharsets.UTF_8))) {
+
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    if (line.startsWith("data:")) {
+                        String data = line.substring(5);
+
+                        if (data.contains("message_end")) {
+                            emitter.complete();
+                            return;
+                        }
+                        emitter.send(data);
+                    }
+                }
+            }
+
+            emitter.complete();
+
+        } catch (Exception e) {
+            emitter.completeWithError(e);
+        }
+    }
+
     /* ================= PUT ================= */
     /* ================= PUT ================= */
 
 
     public <T> Result<T> put(
     public <T> Result<T> put(