调用dify

This commit is contained in:
spllzh
2025-09-07 23:02:25 +08:00
parent 84ff3b3a4e
commit b475a864c6
45 changed files with 2158 additions and 44 deletions

View File

@@ -0,0 +1,189 @@
package com.rj.service.biz;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rj.controller.biz.dto.ConsultingScenarioRequest;
import com.rj.entity.bz.ConsultingScenario;
import com.rj.mapper.biz.ConsultingScenarioMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.time.LocalDateTime;
/**
* Author: 李中华 wx: spllzh email(qq): 28668817@qq.com
* Date: 2025/9/2 19:56
**/
@Service
@Slf4j
public class ConsultingScenarioServiceImpl
extends ServiceImpl<ConsultingScenarioMapper, ConsultingScenario> implements IConsultingScenarioService {
// Dify API 配置
@Value("${dify.api.base-url}")
private String difyApiUrlBase;
@Value("${dify.api.workflow-endpoint-consultingScenar}")
private String difyApiUrlEndPoint;
@Value("${dify.api.apikey-consultingScenar}")
private String difyApiKey;
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public Object processConsultingScenario(ConsultingScenarioRequest request) {
log.info("开始处理咨询场景请求: chat={}, businessType={}, sourceCorpusId={}, sourceCorpusTime={}",
request.getChat(), request.getBusinessType(), request.getSourceCorpusId(), request.getSourceCorpusTime());
try {
// 构造调用Dify工作流的请求
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("inputs", Map.of(
"chat", request.getChat(),
// Dify 要求在 inputs 中提供 businessType
"businessType", request.getBusinessType(),
"sourceCorpusId", request.getSourceCorpusId(),
"sourceCorpusTime", request.getSourceCorpusTime()
));
requestBody.put("response_mode", "blocking");
requestBody.put("user", "api_user");
// 发起HTTP请求调用Dify工作流
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + difyApiKey);
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
String difyApiUrl = difyApiUrlBase + difyApiUrlEndPoint;
log.info("调用Dify工作流: url={}, requestBody={}", difyApiUrl, requestBody);
ResponseEntity<String> response = restTemplate.postForEntity(difyApiUrl, entity, String.class);
// 解析响应并打印到控制台
JsonNode jsonResponse = objectMapper.readTree(response.getBody());
log.info("Dify工作流响应结果: {}", jsonResponse.toPrettyString());
// 从响应中提取 outputs.text
JsonNode outputsNode = jsonResponse.path("data").path("outputs");
String textBlock = outputsNode.path("text").asText(null);
if (textBlock == null || textBlock.isEmpty()) {
log.warn("未在响应中找到 outputs.text返回原始响应");
return jsonResponse;
}
// 提取代码块中的 JSON优先 ```json ... ```,否则回退到最外层花括号)
String extractedJson = extractJsonString(textBlock);
if (extractedJson == null) {
log.warn("未能从文本中提取 JSON返回原始响应");
return jsonResponse;
}
JsonNode parsedNode = objectMapper.readTree(extractedJson);
// 映射到实体并保存
com.rj.entity.bz.ConsultingScenario entityToSave = mapToEntity(parsedNode);
// 主键与时间戳
if (entityToSave.getId() == null || entityToSave.getId().isEmpty()) {
entityToSave.setId(UUID.randomUUID().toString());
}
entityToSave.setCreatedAt(LocalDateTime.now());
entityToSave.setUpdatedAt(LocalDateTime.now());
boolean saved = this.save(entityToSave);
log.info("ConsultingScenario 保存结果: {}", saved);
Map<String, Object> result = new HashMap<>();
result.put("saved", saved);
result.put("entity", entityToSave);
result.put("difyResponse", jsonResponse);
return result;
} catch (Exception e) {
log.error("调用Dify工作流时发生错误", e);
throw new RuntimeException("调用Dify工作流失败: " + e.getMessage(), e);
}
}
/**
* 从包含思考与代码块的文本中提取 JSON 字符串
*/
private String extractJsonString(String text) {
try {
String startFlag = "```json";
String fence = "```";
int start = text.indexOf(startFlag);
if (start >= 0) {
int jsonStart = start + startFlag.length();
int end = text.indexOf(fence, jsonStart);
if (end > jsonStart) {
return text.substring(jsonStart, end).trim();
}
}
// 回退方案:提取第一个 '{' 到最后一个 '}'
int firstBrace = text.indexOf('{');
int lastBrace = text.lastIndexOf('}');
if (firstBrace >= 0 && lastBrace > firstBrace) {
return text.substring(firstBrace, lastBrace + 1);
}
return null;
} catch (Exception e) {
log.warn("提取 JSON 文本失败", e);
return null;
}
}
/**
* 将解析后的 JSON 映射为 ConsultingScenario 实体
*/
private com.rj.entity.bz.ConsultingScenario mapToEntity(JsonNode root) {
com.rj.entity.bz.ConsultingScenario entity = new com.rj.entity.bz.ConsultingScenario();
// consultingScenario 主体
JsonNode cs = root.path("consultingScenario");
if (cs.isObject()) {
entity.setMainCategory(cs.path("mainCategory").asText(null));
entity.setSubCategory(cs.path("subCategory").asText(null));
entity.setConfidence(cs.path("confidence").asText(null));
}
entity.setUserDemand(root.path("userDemand").asText(null));
entity.setConsultingContent(joinArray(root.path("consultingContent")));
entity.setInvolvedVehicleModels(joinArray(root.path("involvedVehicleModels")));
entity.setKnowledgeGap(joinArray(root.path("knowledgeGap")));
entity.setPriority(root.path("priority").asText(null));
entity.setRemarks(root.path("remarks").asText(null));
return entity;
}
private String joinArray(JsonNode node) {
if (node == null || !node.isArray()) {
return null;
}
List<String> list = new ArrayList<>();
Iterator<JsonNode> it = node.elements();
while (it.hasNext()) {
JsonNode n = it.next();
if (n.isTextual()) {
list.add(n.asText());
} else {
list.add(n.toString());
}
}
return String.join("\n", list);
}
}

View File

@@ -0,0 +1,15 @@
package com.rj.service.biz;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.entity.bz.DifyWorkflowAnalysis;
import com.rj.mapper.biz.DifyWorkflowAnalysisMapper;
import org.springframework.stereotype.Service;
/**
* Dify工作流分析结果服务实现类
*/
@Service
public class DifyWorkflowAnalysisServiceImpl extends ServiceImpl<DifyWorkflowAnalysisMapper, DifyWorkflowAnalysis>
implements IDifyWorkflowAnalysisService {
}

View File

@@ -0,0 +1,26 @@
package com.rj.service.biz;
import com.rj.controller.biz.dto.ConsultingScenarioRequest;
import com.rj.entity.bz.ConsultingScenario;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 咨询场景表 服务类
* </p>
*
* @author lingma
* @since 2025-09-02
*/
public interface IConsultingScenarioService extends IService<ConsultingScenario> {
/**
* 处理咨询场景请求
* @param request 咨询场景请求参数
* @return 处理结果
*/
Object processConsultingScenario(ConsultingScenarioRequest request);
}

View File

@@ -0,0 +1,10 @@
package com.rj.service.biz;
import com.baomidou.mybatisplus.extension.service.IService;
import com.rj.entity.bz.DifyWorkflowAnalysis;
/**
* Dify工作流分析结果服务接口
*/
public interface IDifyWorkflowAnalysisService extends IService<DifyWorkflowAnalysis> {
}