优化dify返回内容解析
This commit is contained in:
@@ -35,6 +35,11 @@ public class AuditContentRequest {
|
|||||||
*/
|
*/
|
||||||
private String history;
|
private String history;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 知识库关键词
|
||||||
|
*/
|
||||||
|
private String keywords;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优化建议
|
* 优化建议
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -70,12 +72,24 @@ public abstract class AbstractAuditContentService {
|
|||||||
.asText();
|
.asText();
|
||||||
|
|
||||||
if (StrUtil.isBlank(outputText)) {
|
if (StrUtil.isBlank(outputText)) {
|
||||||
log.warn("{}工作流返回结果为空", workflowName);
|
log.warn("{}工作流返回 result 为空", workflowName);
|
||||||
return new JSONArray();
|
return new JSONArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode arrayNode = objectMapper.readTree(outputText);
|
// ★ NEW:先从 ```json``` 中提取
|
||||||
JSONArray jsonArray = JSONArray.parseArray(arrayNode.toString());
|
String jsonText = extractJsonFromMarkdown(outputText);
|
||||||
|
|
||||||
|
// ★ NEW:兜底提取
|
||||||
|
if (StrUtil.isBlank(jsonText)) {
|
||||||
|
jsonText = extractFirstJson(outputText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(jsonText)) {
|
||||||
|
log.error("{} 工作流返回内容无法解析为 JSON,原始内容:{}", workflowName, outputText);
|
||||||
|
throw new RuntimeException("Dify 返回内容中未找到有效 JSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray jsonArray = JSONArray.parseArray(jsonText);
|
||||||
|
|
||||||
log.info("成功解析{}工作流返回数据,记录数: {}", workflowName, jsonArray.size());
|
log.info("成功解析{}工作流返回数据,记录数: {}", workflowName, jsonArray.size());
|
||||||
return jsonArray;
|
return jsonArray;
|
||||||
@@ -86,6 +100,55 @@ public abstract class AbstractAuditContentService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 ```json 代码块中提取 JSON
|
||||||
|
*/
|
||||||
|
private static String extractJsonFromMarkdown(String text) {
|
||||||
|
if (StrUtil.isBlank(text)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Pattern pattern = Pattern.compile("```json\\s*(.*?)\\s*```", Pattern.DOTALL);
|
||||||
|
Matcher matcher = pattern.matcher(text);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).trim();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兜底:从混合文本中提取第一个完整 JSON({} 或 [])
|
||||||
|
*/
|
||||||
|
private static String extractFirstJson(String text) {
|
||||||
|
if (StrUtil.isBlank(text)) return null;
|
||||||
|
|
||||||
|
int start = -1;
|
||||||
|
char open = 0, close = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < text.length(); i++) {
|
||||||
|
char c = text.charAt(i);
|
||||||
|
if (c == '{' || c == '[') {
|
||||||
|
start = i;
|
||||||
|
open = c;
|
||||||
|
close = (c == '{') ? '}' : ']';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start == -1) return null;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (int i = start; i < text.length(); i++) {
|
||||||
|
char c = text.charAt(i);
|
||||||
|
if (c == open) count++;
|
||||||
|
if (c == close) count--;
|
||||||
|
if (count == 0) {
|
||||||
|
return text.substring(start, i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建工作流请求通用方法
|
* 构建工作流请求通用方法
|
||||||
*/
|
*/
|
||||||
@@ -208,11 +271,22 @@ public abstract class AbstractAuditContentService {
|
|||||||
String docName = extractDocumentName(node);
|
String docName = extractDocumentName(node);
|
||||||
String docId = extractDocumentId(node);
|
String docId = extractDocumentId(node);
|
||||||
String fileUrl = fileUrlMap.get(docId);
|
String fileUrl = fileUrlMap.get(docId);
|
||||||
|
if(StrUtil.isBlank(fileUrl)) {
|
||||||
|
fileUrl = extractDocumentUrl(node);
|
||||||
|
}
|
||||||
|
if(StrUtil.isBlank(fileUrl)) {
|
||||||
|
fileUrl = "无链接";
|
||||||
|
}
|
||||||
|
|
||||||
// 处理文件URL为空的情况
|
// 处理文件URL为空的情况
|
||||||
String url = StrUtil.isNotBlank(fileUrl) ? fileUrl : "无";
|
// String url = StrUtil.isNotBlank(fileUrl) ? fileUrl : "无";
|
||||||
// 格式化结果
|
// 格式化结果
|
||||||
String formattedText = String.format("《%s》【FileUrl:%s】%s", docName, url, text);
|
// String formattedText = String.format("《%s》【FileUrl:%s】%s", docName, url, text);
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("document_name", docName);
|
||||||
|
json.put("file_url", fileUrl);
|
||||||
|
json.put("content", text);
|
||||||
|
String formattedText = json.toJSONString();
|
||||||
results.add(formattedText);
|
results.add(formattedText);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("处理知识库节点失败", e);
|
log.warn("处理知识库节点失败", e);
|
||||||
@@ -259,6 +333,25 @@ public abstract class AbstractAuditContentService {
|
|||||||
return "相关文档";
|
return "相关文档";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取文档url通用方法
|
||||||
|
*/
|
||||||
|
protected String extractDocumentUrl(RetrieveResponseBodyDataNodes node) {
|
||||||
|
try {
|
||||||
|
Object metadataObj = node.getMetadata();
|
||||||
|
if (metadataObj instanceof Map) {
|
||||||
|
Map<?, ?> metadata = (Map<?, ?>) metadataObj;
|
||||||
|
Object docIdObj = metadata.get("doc_url");
|
||||||
|
if (docIdObj != null) {
|
||||||
|
return docIdObj.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("提取文档名称失败", e);
|
||||||
|
}
|
||||||
|
return "相关文档";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建成功响应通用方法
|
* 构建成功响应通用方法
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user