家居大模型联调,分析sop执行情况

This commit is contained in:
ZLI263
2025-11-23 10:58:19 +08:00
parent 23fe2e70b1
commit 64fb90c381
9 changed files with 313 additions and 10 deletions

View File

@@ -14,9 +14,11 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rj.entity.AudioManagement;
import com.rj.entity.AudioTextAnalysisFurniture;
import com.rj.entity.AudioTextAnalysisSop;
import com.rj.entity.TodoItem;
import com.rj.service.IAudioManagementService;
import com.rj.service.IAudioTextAnalysisFurnitureService;
import com.rj.service.IAudioTextAnalysisSopService;
import com.rj.service.ITodoItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -55,6 +57,9 @@ public class AudioTextAnalysisFurnitureController {
@Autowired
private ITodoItemService todoItemService;
@Autowired
private IAudioTextAnalysisSopService sopService;
@Autowired
private ObjectMapper objectMapper;
@@ -238,8 +243,9 @@ public class AudioTextAnalysisFurnitureController {
}
AudioTextAnalysisFurniture furniture = new AudioTextAnalysisFurniture();
furniture.setRecordingText(recordingText);
// 4. 调用大模型生成总结,传递待办事项所需的关联信息
generateSummaryByLLM(furniture, id, audioManagement.getSalesName(), audioManagement.getSalesPhone());
// 4. 调用大模型生成总结,传递待办事项和SOP所需的关联信息
generateSummaryByLLM(furniture, id, audioManagement.getSalesName(), audioManagement.getSalesPhone(),
audioManagement.getCustomerName(), audioManagement.getCustomerPhone());
audioManagement = new AudioManagement();
@@ -287,8 +293,11 @@ public class AudioTextAnalysisFurnitureController {
* @param parentId 父IDAudioManagement的ID
* @param ownerName 所属人姓名
* @param ownerPhone 所属人电话
* @param customerName 客户姓名
* @param customerPhone 客户电话
*/
private void generateSummaryByLLM(AudioTextAnalysisFurniture furniture, String parentId, String ownerName, String ownerPhone) {
private void generateSummaryByLLM(AudioTextAnalysisFurniture furniture, String parentId, String ownerName, String ownerPhone,
String customerName, String customerPhone) {
// 记录开始时间
long startTime = System.currentTimeMillis();
log.info("开始调用大模型生成总结");
@@ -314,7 +323,7 @@ public class AudioTextAnalysisFurnitureController {
GenerationResult call = gen.call(param);
String rawContent = call.getOutput().getChoices().get(0).getMessage().getContent();
log.info("大模型生成总结完成,结果长度: {},内容是:{}", rawContent.length(), rawContent);
applyStructuredResult(furniture, rawContent, parentId, ownerName, ownerPhone);
applyStructuredResult(furniture, rawContent, parentId, ownerName, ownerPhone, customerName, customerPhone);
} catch (NoApiKeyException e) {
log.error("API密钥未配置", e);
throw new RuntimeException("API密钥未配置: " + e.getMessage(), e);
@@ -583,7 +592,8 @@ public class AudioTextAnalysisFurnitureController {
return prompt.toString();
}
private void applyStructuredResult(AudioTextAnalysisFurniture furniture, String rawContent, String parentId, String ownerName, String ownerPhone) {
private void applyStructuredResult(AudioTextAnalysisFurniture furniture, String rawContent, String parentId, String ownerName, String ownerPhone,
String customerName, String customerPhone) {
String normalized = normalizeJson(rawContent);
try {
JsonNode root = objectMapper.readTree(normalized);
@@ -606,9 +616,13 @@ public class AudioTextAnalysisFurnitureController {
furniture.setSecondaryBedroomCabinet(jsonObjectToString(root, "secondary_bedroom_cabinet"));
furniture.setShoeCabinet(jsonObjectToString(root, "shoe_cabinet"));
furniture.setBedAndMattress(jsonObjectToString(root, "bed_and_mattress"));
furniture.setSummary1(jsonObjectToString(root, "summary1"));
furniture.setSummary2(jsonObjectToString(root, "summary2"));
furniture.setSummary3(jsonObjectToString(root, "summary3"));
// 解析并保存待办事项
saveTodoItems(root, parentId, ownerName, ownerPhone);
// 解析并保存SOP评分信息
saveSopInfo(root, parentId, ownerName, ownerPhone, customerName, customerPhone);
} catch (JsonProcessingException e) {
log.warn("解析大模型返回JSON失败使用原始内容作为总结: {}", e.getMessage());
furniture.setSummarySentence(rawContent);
@@ -660,7 +674,7 @@ public class AudioTextAnalysisFurnitureController {
todoItem.setStatus("待处理"); // 默认状态
todoItem.setCreateTime(now);
todoItem.setUpdateTime(now);
todoItem.setPendingDate(now.plusDays(3)); // 延期处理时间为当前时间加三天
boolean success = todoItemService.save(todoItem);
if (success) {
savedCount++;
@@ -719,5 +733,110 @@ public class AudioTextAnalysisFurnitureController {
return node.isTextual() ? node.asText() : node.toString();
}
}
/**
* 解析并保存SOP评分信息
*
* @param root JSON根节点
* @param parentId 父IDAudioManagement的ID
* @param ownerName 所属人姓名
* @param ownerPhone 所属人电话
* @param customerName 客户姓名
* @param customerPhone 客户电话
*/
private void saveSopInfo(JsonNode root, String parentId, String ownerName, String ownerPhone,
String customerName, String customerPhone) {
try {
// 检查是否存在SOP相关字段
JsonNode comprehensiveScoreNode = root.get("comprehensive_score");
if (comprehensiveScoreNode == null) {
log.info("未找到SOP评分信息跳过保存");
return;
}
AudioTextAnalysisSop sop = new AudioTextAnalysisSop();
sop.setId(UUID.randomUUID().toString());
sop.setParentId(parentId);
sop.setOwnerName(ownerName);
sop.setOwnerPhone(ownerPhone);
sop.setCustomerName(customerName);
sop.setCustomerPhone(customerPhone);
sop.setIndustryType("furniture");
// 解析SOP评分字段
sop.setComprehensiveScore(intValue(root, "comprehensive_score"));
sop.setScoreSummaryReason(textValue(root, "score_summary_reason"));
sop.setGreetingIceBreaking(intValue(root, "greeting_ice_breaking"));
sop.setBrandIntroduction(intValue(root, "brand_introduction"));
sop.setGoldenThreeQuestions(intValue(root, "golden_three_questions"));
sop.setNeedsGuidance(intValue(root, "needs_guidance"));
sop.setServiceProgression(intValue(root, "service_progression"));
sop.setReassuranceHandbook(intValue(root, "reassurance_handbook"));
sop.setThreeLevelPricing(intValue(root, "three_level_pricing"));
sop.setObjectionHandling(intValue(root, "objection_handling"));
sop.setActivityImplantation(intValue(root, "activity_implantation"));
sop.setClosingCooperation(intValue(root, "closing_cooperation"));
sop.setProactiveWechatAdd(intValue(root, "proactive_wechat_add"));
sop.setPoliteFarewell(intValue(root, "polite_farewell"));
// 设置时间
LocalDateTime now = LocalDateTime.now();
sop.setCreatedAt(now);
sop.setUpdatedAt(now);
// 检查是否已存在相同parentId的记录如果存在则更新否则新增
LambdaQueryWrapper<AudioTextAnalysisSop> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AudioTextAnalysisSop::getParentId, parentId);
AudioTextAnalysisSop existingSop = sopService.getOne(wrapper);
if (existingSop != null) {
sop.setId(existingSop.getId());
boolean success = sopService.updateById(sop);
if (success) {
log.info("更新SOP评分信息成功ID: {}, parentId: {}", sop.getId(), parentId);
} else {
log.warn("更新SOP评分信息失败parentId: {}", parentId);
}
} else {
boolean success = sopService.save(sop);
if (success) {
log.info("保存SOP评分信息成功ID: {}, parentId: {}", sop.getId(), parentId);
} else {
log.warn("保存SOP评分信息失败parentId: {}", parentId);
}
}
} catch (Exception e) {
log.error("保存SOP评分信息时发生异常", e);
// 不抛出异常,避免影响主流程
}
}
/**
* 从JSON节点中获取整数值
*
* @param root JSON根节点
* @param field 字段名
* @return 整数值如果不存在或为null则返回null
*/
private Integer intValue(JsonNode root, String field) {
JsonNode node = root.get(field);
if (node == null || node.isNull()) {
return null;
}
if (node.isInt()) {
return node.asInt();
} else if (node.isTextual()) {
try {
String text = node.asText();
if (text == null || text.trim().isEmpty()) {
return null;
}
return Integer.parseInt(text.trim());
} catch (NumberFormatException e) {
log.warn("无法将字段 {} 的值 {} 转换为整数", field, node.asText());
return null;
}
}
return null;
}
}

View File

@@ -47,6 +47,10 @@ public class TodoItemController {
if (todoItem.getId() == null || todoItem.getId().trim().isEmpty()) {
todoItem.setId(UUID.randomUUID().toString());
}
// 如果待处理日期为空则设置为当前时间加3天
if (todoItem.getPendingDate() == null) {
todoItem.setPendingDate(LocalDateTime.now().plusDays(3));
}
todoItem.setCreateTime(LocalDateTime.now());
todoItem.setUpdateTime(LocalDateTime.now());
boolean success = todoItemService.save(todoItem);
@@ -331,6 +335,104 @@ public class TodoItemController {
}
}
/**
* 更新待办事项状态为已完成
*/
@PostMapping("/updateTodoStatus")
@Operation(summary = "更新待办事项状态为已完成", description = "根据ID将待办事项状态修改为已完成")
public ResponseEntity<Map<String, Object>> updateTodoStatus(
@Parameter(description = "包含id的请求体格式{\"id\": \"待办事项ID\"}", required = true)
@RequestBody Map<String, String> request) {
Map<String, Object> result = new HashMap<>();
try {
String id = request.get("id");
if (id == null || id.trim().isEmpty()) {
result.put("success", false);
result.put("message", "待办事项ID不能为空");
return ResponseEntity.badRequest().body(result);
}
TodoItem todoItem = todoItemService.getById(id);
if (todoItem == null) {
result.put("success", false);
result.put("message", "待办事项不存在");
return ResponseEntity.badRequest().body(result);
}
todoItem.setStatus("已完成");
todoItem.setUpdateTime(LocalDateTime.now());
boolean success = todoItemService.updateById(todoItem);
if (success) {
result.put("success", true);
result.put("message", "状态更新成功");
return ResponseEntity.ok(result);
} else {
result.put("success", false);
result.put("message", "状态更新失败");
return ResponseEntity.badRequest().body(result);
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "状态更新异常:" + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 延期处理待办事项
*/
@PostMapping("/delayProcessTodo")
@Operation(summary = "延期处理待办事项", description = "根据ID将待办事项的待处理日期延期3天")
public ResponseEntity<Map<String, Object>> delayProcessTodo(
@Parameter(description = "包含id的请求体格式{\"id\": \"待办事项ID\"}", required = true)
@RequestBody Map<String, String> request) {
Map<String, Object> result = new HashMap<>();
try {
String id = request.get("id");
if (id == null || id.trim().isEmpty()) {
result.put("success", false);
result.put("message", "待办事项ID不能为空");
return ResponseEntity.badRequest().body(result);
}
TodoItem todoItem = todoItemService.getById(id);
if (todoItem == null) {
result.put("success", false);
result.put("message", "待办事项不存在");
return ResponseEntity.badRequest().body(result);
}
// 计算延期3天后的日期
LocalDateTime newPendingDate;
if (todoItem.getPendingDate() != null) {
// 如果已有待处理日期则在原日期基础上延期3天
newPendingDate = todoItem.getPendingDate().plusDays(3);
} else {
// 如果没有待处理日期,则设置为当前日期+3天
newPendingDate = LocalDateTime.now().plusDays(3);
}
todoItem.setPendingDate(newPendingDate);
todoItem.setUpdateTime(LocalDateTime.now());
boolean success = todoItemService.updateById(todoItem);
if (success) {
result.put("success", true);
result.put("message", "延期处理成功,待处理日期已更新为:" + newPendingDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return ResponseEntity.ok(result);
} else {
result.put("success", false);
result.put("message", "延期处理失败");
return ResponseEntity.badRequest().body(result);
}
} catch (Exception e) {
result.put("success", false);
result.put("message", "延期处理异常:" + e.getMessage());
return ResponseEntity.internalServerError().body(result);
}
}
/**
* 获取待办事项统计信息
*/