客户画像代码开发
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
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}")
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user