多场景分析代码架构
This commit is contained in:
@@ -2,14 +2,12 @@ package com.rj.controller;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.rj.common.AudioAnalysisSceneType;
|
||||||
import com.rj.common.AudioManagementConstants;
|
import com.rj.common.AudioManagementConstants;
|
||||||
import com.rj.common.DataEnrichmentUtil;
|
import com.rj.common.DataEnrichmentUtil;
|
||||||
import com.rj.entity.AudioManagement;
|
import com.rj.entity.AudioManagement;
|
||||||
import com.rj.entity.AudioManagementSegments;
|
import com.rj.entity.AudioManagementSegments;
|
||||||
import com.rj.service.IAudioManagementService;
|
import com.rj.service.*;
|
||||||
import com.rj.service.IFileUploadService;
|
|
||||||
import com.rj.service.MinIOService;
|
|
||||||
import com.rj.service.ITtsRequestLogService;
|
|
||||||
import com.rj.dto.AsrRequest;
|
import com.rj.dto.AsrRequest;
|
||||||
import com.rj.dto.AsrResponse;
|
import com.rj.dto.AsrResponse;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -44,6 +42,11 @@ import java.util.UUID;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class AudioManagementController {
|
public class AudioManagementController {
|
||||||
|
|
||||||
|
// 场景常量,避免在解析逻辑中硬编码字符串
|
||||||
|
private static final String SCENARIO_FURNITURE_SALE = "FURNITURE_SALE";
|
||||||
|
private static final String SCENARIO_MEETING_SUMMARY = "MEETING_SUMMARY";
|
||||||
|
private static final String SCENARIO_CAR_SALE = "CAR_SALE";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IAudioManagementService audioManagementService;
|
private IAudioManagementService audioManagementService;
|
||||||
|
|
||||||
@@ -56,6 +59,9 @@ public class AudioManagementController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ITtsRequestLogService ttsRequestLogService;
|
private ITtsRequestLogService ttsRequestLogService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IAudioTextAnalysisLlmService audioTextAnalysisLlmService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增录音
|
* 新增录音
|
||||||
*/
|
*/
|
||||||
@@ -485,6 +491,110 @@ public class AudioManagementController {
|
|||||||
return ResponseEntity.internalServerError().body(result);
|
return ResponseEntity.internalServerError().body(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 更新录音信息
|
||||||
|
*/
|
||||||
|
@PostMapping("/AIAnlyzById")
|
||||||
|
@Operation(summary = "AI分析", description = "AI分析的总入口")
|
||||||
|
public ResponseEntity<Map<String, Object>> AIAnlyById(
|
||||||
|
@Parameter(description = "录音信息", required = true)
|
||||||
|
@RequestBody AudioManagement audioManagement) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
try {
|
||||||
|
if (audioManagement.getId() == null || audioManagement.getId().trim().isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "录音ID不能为空");
|
||||||
|
return ResponseEntity.badRequest().body(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 根据ID查询家具意向分析记录
|
||||||
|
AudioManagement audioManagementFromDB = audioManagementService.getById(audioManagement.getId());
|
||||||
|
if (audioManagementFromDB == null) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "记录不存在");
|
||||||
|
return ResponseEntity.badRequest().body(result);
|
||||||
|
}
|
||||||
|
// 3. 获取录音文本;如主表为空,则从分段表拼接
|
||||||
|
String recordingText = audioManagementFromDB.getRecordingText();
|
||||||
|
if (recordingText == null || recordingText.trim().isEmpty()) {
|
||||||
|
LambdaQueryWrapper<AudioManagementSegments> segQuery = new LambdaQueryWrapper<>();
|
||||||
|
segQuery.eq(AudioManagementSegments::getParentId, audioManagementFromDB.getId())
|
||||||
|
.orderByAsc(AudioManagementSegments::getChunkIndex);
|
||||||
|
List<AudioManagementSegments> segmentList = audioManagementSegmentsService.list(segQuery);
|
||||||
|
int emptyCount = 0 ;
|
||||||
|
StringBuilder mergedText = new StringBuilder();
|
||||||
|
if (segmentList != null && !segmentList.isEmpty()) {
|
||||||
|
for (AudioManagementSegments seg : segmentList) {
|
||||||
|
String segText = seg.getRecordingText();
|
||||||
|
if (segText != null && !segText.trim().isEmpty()) {
|
||||||
|
if (mergedText.length() > 0) {
|
||||||
|
mergedText.append("\n");
|
||||||
|
}
|
||||||
|
mergedText.append(segText.trim());
|
||||||
|
}else {
|
||||||
|
emptyCount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mergedText.length() > 0) {
|
||||||
|
recordingText = mergedText.toString();
|
||||||
|
audioManagementFromDB.setRecordingText(recordingText);
|
||||||
|
}
|
||||||
|
log.info(" AudioManagementSegments 总数是: {} ,未转文本记录条数是: {}",segmentList.size(), emptyCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recordingText == null || recordingText.trim().isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "录音文本为空");
|
||||||
|
return ResponseEntity.badRequest().body(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 根据场景动态选择业务场景类型,调用业务层通用服务生成总结
|
||||||
|
AudioAnalysisSceneType sceneType = resolveSceneType(audioManagementFromDB.getScenario());
|
||||||
|
String rawContent = audioTextAnalysisLlmService.generateSummaryByLLM(
|
||||||
|
sceneType,
|
||||||
|
recordingText
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
boolean success = true;
|
||||||
|
if (success) {
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("message", "录音finishServiceById更新成功");
|
||||||
|
result.put("data", audioManagement);
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
} else {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "录音finishServiceById更新失败");
|
||||||
|
return ResponseEntity.badRequest().body(result);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "更新异常:" + e.getMessage());
|
||||||
|
return ResponseEntity.internalServerError().body(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据录音场景字符串解析为大模型分析场景类型
|
||||||
|
*/
|
||||||
|
private AudioAnalysisSceneType resolveSceneType(String scenario) {
|
||||||
|
|
||||||
|
String s = scenario.trim().toUpperCase();
|
||||||
|
// 根据约定的大写场景值进行映射
|
||||||
|
if (SCENARIO_FURNITURE_SALE.equals(s)) {
|
||||||
|
return AudioAnalysisSceneType.SCENARIO_FURNITURE_SALE;
|
||||||
|
}
|
||||||
|
if (SCENARIO_CAR_SALE.equals(s)) {
|
||||||
|
return AudioAnalysisSceneType.SCENARIO_CAR_SALE;
|
||||||
|
}
|
||||||
|
if (SCENARIO_MEETING_SUMMARY.equals(s)) {
|
||||||
|
return AudioAnalysisSceneType.SCENARIO_MEETING_SUMMARY;
|
||||||
|
}
|
||||||
|
// 未识别场景时,默认按会议场景处理
|
||||||
|
return AudioAnalysisSceneType.SCENARIO_MEETING_SUMMARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据ID删除录音
|
* 根据ID删除录音
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.rj.common.AudioAnalysisSceneType;
|
||||||
import com.rj.entity.AudioManagement;
|
import com.rj.entity.AudioManagement;
|
||||||
import com.rj.entity.AudioTextAnalysisFurniture;
|
import com.rj.entity.AudioTextAnalysisFurniture;
|
||||||
import com.rj.entity.AudioTextAnalysisSop;
|
import com.rj.entity.AudioTextAnalysisSop;
|
||||||
@@ -19,6 +20,7 @@ import com.rj.entity.TodoItem;
|
|||||||
import com.rj.service.IAudioManagementService;
|
import com.rj.service.IAudioManagementService;
|
||||||
import com.rj.service.IAudioTextAnalysisFurnitureService;
|
import com.rj.service.IAudioTextAnalysisFurnitureService;
|
||||||
import com.rj.service.IAudioTextAnalysisSopService;
|
import com.rj.service.IAudioTextAnalysisSopService;
|
||||||
|
import com.rj.service.IAudioTextAnalysisLlmService;
|
||||||
import com.rj.service.ITodoItemService;
|
import com.rj.service.ITodoItemService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
@@ -63,11 +65,12 @@ public class AudioTextAnalysisFurnitureController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ObjectMapper objectMapper;
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
// 提示词文件路径
|
@Autowired
|
||||||
|
private IAudioTextAnalysisLlmService audioTextAnalysisLlmService;
|
||||||
|
|
||||||
|
// 兼容旧代码的字段声明(已不再在控制层使用,实际逻辑已迁移到业务层)
|
||||||
private static final String SYSTEM_PROMPT_PATH = "prompts/audio_text_analysis_furniture_system.txt";
|
private static final String SYSTEM_PROMPT_PATH = "prompts/audio_text_analysis_furniture_system.txt";
|
||||||
private static final String USER_PROMPT_PATH = "prompts/audio_text_analysis_furniture_user.txt";
|
private static final String USER_PROMPT_PATH = "prompts/audio_text_analysis_furniture_user.txt";
|
||||||
|
|
||||||
// 缓存提示词内容,避免重复读取文件
|
|
||||||
private static String cachedSystemPrompt;
|
private static String cachedSystemPrompt;
|
||||||
private static String cachedUserPromptTemplate;
|
private static String cachedUserPromptTemplate;
|
||||||
|
|
||||||
@@ -243,9 +246,20 @@ public class AudioTextAnalysisFurnitureController {
|
|||||||
}
|
}
|
||||||
AudioTextAnalysisFurniture furniture = new AudioTextAnalysisFurniture();
|
AudioTextAnalysisFurniture furniture = new AudioTextAnalysisFurniture();
|
||||||
furniture.setRecordingText(recordingText);
|
furniture.setRecordingText(recordingText);
|
||||||
// 4. 调用大模型生成总结,传递待办事项和SOP所需的关联信息
|
// 4. 通过业务层通用服务调用大模型生成总结,然后解析结构化结果
|
||||||
generateSummaryByLLM(furniture, id, audioManagement.getSalesName(), audioManagement.getSalesPhone(),
|
String rawContent = audioTextAnalysisLlmService.generateSummaryByLLM(
|
||||||
audioManagement.getCustomerName(), audioManagement.getCustomerPhone());
|
AudioAnalysisSceneType.SCENARIO_MEETING_SUMMARY,
|
||||||
|
furniture.getRecordingText()
|
||||||
|
);
|
||||||
|
applyStructuredResult(
|
||||||
|
furniture,
|
||||||
|
rawContent,
|
||||||
|
id,
|
||||||
|
audioManagement.getSalesName(),
|
||||||
|
audioManagement.getSalesPhone(),
|
||||||
|
audioManagement.getCustomerName(),
|
||||||
|
audioManagement.getCustomerPhone()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
audioManagement = new AudioManagement();
|
audioManagement = new AudioManagement();
|
||||||
|
|||||||
Reference in New Issue
Block a user