Files
smartDriveEE/src/main/java/com/rj/service/biz/impl/ConsultingScenarioServiceImpl.java
2025-10-04 19:52:06 +08:00

190 lines
7.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.rj.service.biz.impl;
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 com.rj.service.biz.IConsultingScenarioService;
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}") //【AI】DCC用户问题分类提取
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);
}
}