From 3ba4dd16713378014482af5311db50e2f21bbb8e Mon Sep 17 00:00:00 2001 From: qianbao Date: Tue, 7 Apr 2026 10:19:23 +0800 Subject: [PATCH] 添加向量库 --- src/main/java/com/xly/service/XlyErpService.java | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------- src/main/java/com/xly/tts/service/PythonTtsProxyService.java | 20 ++++++++++++++++++++ src/main/java/com/xly/web/TTSStreamController.java | 13 +++++++++++++ 3 files changed, 136 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/xly/service/XlyErpService.java b/src/main/java/com/xly/service/XlyErpService.java index 2c84bcb..05e9f18 100644 --- a/src/main/java/com/xly/service/XlyErpService.java +++ b/src/main/java/com/xly/service/XlyErpService.java @@ -37,6 +37,7 @@ import dev.langchain4j.service.MemoryId; import dev.langchain4j.service.V; import io.milvus.v2.common.DataType; import io.milvus.v2.service.collection.request.CreateCollectionReq; +import jnr.ffi.annotations.In; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.time.DateFormatUtils; @@ -227,6 +228,25 @@ public class XlyErpService { } } + /**** + * @Author 钱豹 + * @Date 8:54 2026/4/7 + * @Param [userInput, userId, sUserName, sBrandsId, sSubsidiaryId, sUserType, authorization] + * @return com.xly.entity.AiResponseDTO + * @Description 换一换 + **/ + public AiResponseDTO change(String userId , + String sUserName , + String sBrandsId , + String sSubsidiaryId, + String sUserType, + String authorization, + Integer iPage) { + // 1. 初始化用户场景会话(权限内场景) + UserSceneSession session = userSceneSessionService.getUserSceneSession(userId,sUserName,sBrandsId,sSubsidiaryId,sUserType,authorization); + return getChange(session, iPage); + } + /*** * @Author 钱豹 * @Date 19:18 2026/1/27 @@ -270,7 +290,7 @@ public class XlyErpService { // 3. 未选场景:先展示场景选择界面,处理用户序号选择 if (!session.isSceneSelected() && ValiDataUtil.me().isPureNumber(input)){ // 3.1 尝试处理场景选择(输入序号则匹配,否则展示选择提示) - return handleSceneSelect(userId, input, session); + return handleSceneSelect(userId, input, session,1); } // 4. 构建Agent,执行业务交互,如果返回为null,说明大模型没有判段出场景,必判断出后才能继续 ErpAiAgent aiAgent = createErpAiAgent(userId, input, session); @@ -942,7 +962,7 @@ public class XlyErpService { /** * 处理用户场景选择:输入序号→匹配场景→更新会话状态 */ - private AiResponseDTO handleSceneSelect(String userId, String userInput, UserSceneSession session) { + private AiResponseDTO handleSceneSelect(String userId, String userInput, UserSceneSession session,Integer page) { // 1. 尝试根据序号匹配场景 boolean selectSuccess = session.selectSceneByInput(userInput); String sceneName = StrUtil.EMPTY; @@ -954,20 +974,34 @@ public class XlyErpService { UserSceneSessionService.ERP_AGENT_CACHE.remove(userId); //清除记忆缓存 operableChatMemoryProvider.clearSpecifiedMemory(userId); - StringBuffer aiText = new StringBuffer().append("
") - .append("
") - .append("智能体选择成功! 现在可以问她相关问题(如" + String.join("、", session.getCurrentScene().getSSceneContext()) + ")") - .append("
"); - //插入用户常用问题 - aiText.append(getSelectAgent(session,1)); - sceneName = ObjectUtil.isNotEmpty(session.getCurrentScene())?session.getCurrentScene().getSSceneName():StrUtil.EMPTY; - methodName = ObjectUtil.isNotEmpty(session.getCurrentTool())?session.getCurrentTool().getSControlName():StrUtil.EMPTY; - return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(aiText.toString()).sSceneName(session.getCurrentScene().getSSceneName()).build(); + return getChange( session, page); } else { // 3. 选择失败:重新展示场景选择提示 return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(session.buildSceneSelectHint()).build(); } } + + /*** + * @Author 钱豹 + * @Date 9:00 2026/4/7 + * @Param [session, page] + * @return com.xly.entity.AiResponseDTO + * @Description 用户输入数字换一换 + **/ + private AiResponseDTO getChange(UserSceneSession session,Integer page){ + StringBuffer aiText = new StringBuffer().append("
") + .append("
") + .append("智能体选择成功! 现在可以问她相关问题(如" + String.join("、", session.getCurrentScene().getSSceneContext()) + ")") + .append("
"); + //插入用户常用问题 + aiText.append(getSelectAgent(session,page)); + String sceneName = ObjectUtil.isNotEmpty(session.getCurrentScene())?session.getCurrentScene().getSSceneName():StrUtil.EMPTY; + String methodName = ObjectUtil.isNotEmpty(session.getCurrentTool())?session.getCurrentTool().getSControlName():StrUtil.EMPTY; + return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(aiText.toString()).sSceneName(session.getCurrentScene().getSSceneName()).build(); + } + + + /*** * @Author 钱豹 * @Date 11:45 2026/3/13 @@ -978,18 +1012,24 @@ public class XlyErpService { private String getSelectAgent(UserSceneSession session,Integer page){ List toolMetaAll = session.getAuthTool(); String sSceneId = session.getCurrentScene().getSId(); + String sToolId = session.getCurrentTool().getSId(); toolMetaAll = toolMetaAll.stream().filter(to-> to.getSSceneId().equals(session.getCurrentScene().getSId())).collect(Collectors.toUnmodifiableList()); StringBuffer sb = new StringBuffer(); - List> firstFive = ListUtil.split(toolMetaAll,5); - List showList; - if(ObjectUtil.isNotEmpty(firstFive.get(page-1))){ - showList = firstFive.get(page-1); - page = page + 1; - }else{ - showList = firstFive.get(0); - page = 1; + //获取用户最近五次问题 + List> data = getAiUserAgentQuestion(session.getUserId(),sSceneId, sToolId, page,3); + Integer iPageCount = 0; + if(page==1){ + iPageCount =getAiUserAgentQuestionCount(session.getUserId(), sSceneId, sToolId); + } + List showListAll = new ArrayList<>(); + if(ObjectUtil.isNotEmpty(data)){ + data.forEach(one->{ + ToolMeta tm = new ToolMeta(); + tm.setSMethodName(one.get("sUserInput").toString()); + }); } - showList.forEach(one->{ + showListAll.addAll(toolMetaAll); + showListAll.forEach(one->{ sb.append("
") .append("") @@ -997,11 +1037,53 @@ public class XlyErpService { .append("
"); }); sb.append("
"); - sb.append("
"); + sb.append("
"); sb.append(" 换一换").append("
"); return sb.toString(); } + /*** + * @Author 钱豹 + * @Date 10:02 2026/4/7 + * @Param [sLoginId, sSceneId, sMethodId, iPageNum, iPageSize] + * @return java.util.List> + * @Description 换一换获取最近数据 + **/ + private List> getAiUserAgentQuestion(String sLoginId, String sSceneId, String sMethodId, Integer iPageNum,Integer iPageSize){ + StringBuffer sb = new StringBuffer().append("SELECT sId,iUpdate,sUserInput FROM ai_user_agent_question ") + .append("WHERE sLoginId = #{sLoginId} ") + .append("AND sSceneId = #{sSceneId} ") + .append("AND sMethodId = #{sMethodId} ") + .append("AND IFNULL(sUserInput,'') <> '' ") + .append("ORDER BY iUpdate DESC,tUpdateDate DESC ") + .append("LIMIT #{iPageNum},#{iPageSize} "); + Map serMap = new HashMap<>(); + serMap.put("sLoginId",sLoginId); + serMap.put("sSceneId",sSceneId); + serMap.put("sMethodId",sMethodId); + serMap.put("iPageNum",iPageNum); + serMap.put("iPageSize",iPageSize); + return dynamicExeDbService.findSql(serMap,sb.toString()); + } + + private Integer getAiUserAgentQuestionCount(String sLoginId, String sSceneId, String sMethodId){ + StringBuffer sb = new StringBuffer().append("SELECT COUNT(1) AS iCount FROM ai_user_agent_question ") + .append("WHERE sLoginId = #{sLoginId} ") + .append("AND sSceneId = #{sSceneId} ") + .append("AND sMethodId = #{sMethodId} ") + .append("AND IFNULL(sUserInput,'') <> '' "); + Map serMap = new HashMap<>(); + serMap.put("sLoginId",sLoginId); + serMap.put("sSceneId",sSceneId); + serMap.put("sMethodId",sMethodId); + List> data = dynamicExeDbService.findSql(serMap,sb.toString()); + if(ObjectUtil.isNotEmpty(data)){ + return (Integer) data.get(0).get("iCount"); + } + return 0; + } + + /** * @Author 钱豹 * @Date 13:32 2026/2/6 @@ -1056,25 +1138,5 @@ public class XlyErpService { String sChatMessage = chatiAgent.chat(session.getUserId(), input); return AiResponseDTO.builder().sSceneName(sceneName).sMethodName(methodName).aiText(sChatMessage).systemText(StrUtil.EMPTY).sReturnType(ReturnTypeCode.HTML.getCode()).build(); } - /*** - * @Author 钱豹 - * @Date 12:14 2026/3/8 - * @Param [chatMessage, memoryId] - * @return void - * @Description 随便聊聊移除最后一个AI 返回信息 跟系统询问的随便聊聊 - **/ - private void removeMssageSbll(List chatMessage,String memoryId){ - if(chatMessage!=null){ -// operableChatMemoryProvider.deleteSingleMessage(memoryId,chatMessage.get(chatMessage.size()-1)); - for(int i=chatMessage.size()-1;i>0;i--){ - ChatMessage data = chatMessage.get(i); - ChatMessageType sType = data.type(); - if(ChatMessageType.SYSTEM.equals(sType)){ - operableChatMemoryProvider.deleteSingleMessage(memoryId,data); - return; - } - } - } - } } \ No newline at end of file diff --git a/src/main/java/com/xly/tts/service/PythonTtsProxyService.java b/src/main/java/com/xly/tts/service/PythonTtsProxyService.java index 4659254..56f8b0e 100644 --- a/src/main/java/com/xly/tts/service/PythonTtsProxyService.java +++ b/src/main/java/com/xly/tts/service/PythonTtsProxyService.java @@ -68,6 +68,26 @@ public class PythonTtsProxyService { } /** + * @Author 钱豹 + * @Date 8:54 2026/4/7 + * @Param [request] + * @return org.springframework.http.ResponseEntity + * @Description 换一换 + **/ + public ResponseEntity change(TTSRequestDTO request) { + String userInput = request.getText(); + String sUserId = request.getUserid(); + String sUserName = request.getUsername(); + String sBrandsId = request.getBrandsid(); + String sSubsidiaryId = request.getSubsidiaryid(); + String sUserType = request.getUsertype(); + String authorization = request.getAuthorization(); + Integer iPage = Integer.valueOf(userInput); + AiResponseDTO voiceText = xlyErpService.change(sUserId, sUserName , sBrandsId , sSubsidiaryId, sUserType, authorization,iPage); + return synthesizeStreamAi(request, voiceText); + } + + /** * 【保持原有返回类型】AI对话 + 流式TTS */ public ResponseEntity synthesizeStreamAi(TTSRequestDTO request) { diff --git a/src/main/java/com/xly/web/TTSStreamController.java b/src/main/java/com/xly/web/TTSStreamController.java index 58b3372..6a59eef 100644 --- a/src/main/java/com/xly/web/TTSStreamController.java +++ b/src/main/java/com/xly/web/TTSStreamController.java @@ -77,6 +77,19 @@ public class TTSStreamController { pythonTtsProxyService.shutdown(); } + /*** + * @Author 钱豹 + * @Date 8:53 2026/4/7 + * @Param [request] + * @return org.springframework.http.ResponseEntity + * @Description 换一换 + **/ + @PostMapping(value = "/stream/change", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE}) + public ResponseEntity change(@RequestBody TTSRequestDTO request) { + return pythonTtsProxyService.change(request); + } + + /** * 流式合成语音(代理到Python服务) */ -- libgit2 0.22.2