package com.ewaytek.deepseek.controller; import cn.hutool.http.ContentType; import com.alibaba.fastjson2.JSON; import com.ewaytek.deepseek.common.bean.base.ApiResponse; import com.ewaytek.deepseek.config.DifyConfig; import com.ewaytek.deepseek.doadmin.dto.dify.DIfyImportVerifyDTO; import com.ewaytek.deepseek.doadmin.dto.dify.demo.DIfyWorkflowsResultDTO; import com.ewaytek.deepseek.doadmin.dto.dify.demo.DifyWorkflowsDTO; import com.ewaytek.deepseek.task.DifyThread; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import org.apache.commons.collections4.CollectionUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author yangtq * @date 2025/3/6 */ @RequiredArgsConstructor @RestController @Slf4j @RequestMapping("/dify/demo") public class DifyDemoController { @Resource private OkHttpClient httpClient; @PostMapping(value = "/stream") @org.springframework.web.bind.annotation.ResponseBody public ApiResponse> demo(@org.springframework.web.bind.annotation.RequestBody DIfyImportVerifyDTO dto) throws ExecutionException, InterruptedException, JsonProcessingException { DifyConfig difyConfig = new DifyConfig(); difyConfig.setApiHost("http://192.168.103.69:9002/v1/"); difyConfig.setApiKey("app-9D2IddTOvZDeBGLm1iNtQ0EF"); // 创建 CompletableFuture 来接收结果 CompletableFuture future = new CompletableFuture<>(); // 创建 DifyThread 实例,并传入回调接口 DifyThread task = new DifyThread(dto, difyConfig, httpClient, future::complete); // 启动线程 Thread thread = new Thread(task); thread.start(); // 等待线程完成并获取结果 DIfyImportVerifyDTO result = future.get(); String answer =cleanContent(result.getAnswer()) ; return ApiResponse.success(DifyWorkflows(answer, difyConfig)); } @PostMapping(value = "/workflows") @org.springframework.web.bind.annotation.ResponseBody public ApiResponse> demo2(@org.springframework.web.bind.annotation.RequestBody DIfyImportVerifyDTO dto) throws ExecutionException, InterruptedException, JsonProcessingException { DifyConfig difyConfig = new DifyConfig(); difyConfig.setApiHost("http://192.168.103.69:9002/v1/"); difyConfig.setApiKey("app-9D2IddTOvZDeBGLm1iNtQ0EF"); return ApiResponse.success(DifyWorkflows(dto.getQuestion(), difyConfig)); } public List DifyWorkflows(String answer, DifyConfig difyConfig) throws JsonProcessingException { DifyWorkflowsDTO difyWorkflowsDTO = new DifyWorkflowsDTO(); difyWorkflowsDTO.setUser("abc-123"); difyWorkflowsDTO.setResponseMode("streaming"); Map inputs = new HashMap<>(); inputs.put("question", answer); difyWorkflowsDTO.setInputs(inputs); ObjectMapper mapper = new ObjectMapper(); String requestBody = mapper.writeValueAsString(difyWorkflowsDTO); Headers headers = new Headers.Builder().add("Authorization", "Bearer " + "app-9RuAoErdMXkG4jVN0YNjXekp").add("Content-Type", "application/json").build(); Request request = new Request.Builder().url(difyConfig.getApiHost() + "workflows/run").post(okhttp3.RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody)) .headers(headers).build(); List retrieverResourcesList = new ArrayList<>(); try (Response response = httpClient.newCall(request).execute()) { if (!response.isSuccessful()) { return retrieverResourcesList; } // 处理流式响应 ResponseBody responseBody = response.body(); if (responseBody != null) { while (!responseBody.source().exhausted()) { String line = responseBody.source().readUtf8Line(); if (line != null && !line.isEmpty()) { if (line.startsWith("data:")) { // 处理 SSE 格式 log.info("DifyWorkflows##"+line); String eventData = line.substring(5).trim(); // 去掉 "data:" 前缀 DIfyWorkflowsResultDTO blockingVO = JSON.parseObject(eventData, DIfyWorkflowsResultDTO.class); if(!"workflow_finished".equals(blockingVO.getEvent())){ continue; } DIfyWorkflowsResultDTO.Outputs metadataVO = blockingVO.getData().getOutputs(); if (metadataVO != null) { if (!CollectionUtils.isEmpty(metadataVO.getResult())) { for (DIfyWorkflowsResultDTO.ResultItem resultItem : metadataVO.getResult()) { retrieverResourcesList.add(resultItem.getContent()); } } } } } } } } catch (IOException e) { log.error(e.getMessage()); } return retrieverResourcesList; } public static String cleanContent(String content) { // 移除
标签及其内容 Pattern detailsPattern = Pattern.compile("", Pattern.DOTALL); Matcher detailsMatcher = detailsPattern.matcher(content); content = detailsMatcher.replaceAll("").trim(); // 移除尾部的 null Pattern nullPattern = Pattern.compile("null$", Pattern.DOTALL); Matcher nullMatcher = nullPattern.matcher(content); content = nullMatcher.replaceAll("").trim(); // 移除多余的换行符和空格 Pattern whitespacePattern = Pattern.compile("\\s+\\n", Pattern.DOTALL); Matcher whitespaceMatcher = whitespacePattern.matcher(content); content = whitespaceMatcher.replaceAll("\n").trim(); return content; } }