From 51694876c0e31062ff1a33d5d5afd50e647dad2b Mon Sep 17 00:00:00 2001 From: qianbao Date: Sun, 1 Mar 2026 12:18:52 +0800 Subject: [PATCH] 1111 --- logPath_IS_UNDEFINED/2026-02-09/2026-02-09.debug-0.log | 0 logPath_IS_UNDEFINED/2026-02-09/2026-02-09.error-0.log | 0 logPath_IS_UNDEFINED/2026-02-09/2026-02-09.info-0.log | 0 src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java | 7 +++++-- src/main/java/com/xly/agent/ErpAiAgent.java | 4 +++- src/main/java/com/xly/mapper/AiToolDetailParamsMapper.java | 2 +- src/main/java/com/xly/service/UserSceneSessionService.java | 15 +++++++++++++++ src/main/java/com/xly/service/XlyErpService.java | 6 ++++-- src/main/java/com/xly/tool/DynamicToolProvider.java | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------ src/main/java/com/xly/tts/service/PythonTtsProxyService.java | 5 +++++ src/main/resources/templates/chat.html | 12 ++++++------ 11 files changed, 142 insertions(+), 96 deletions(-) delete mode 100644 logPath_IS_UNDEFINED/2026-02-09/2026-02-09.debug-0.log delete mode 100644 logPath_IS_UNDEFINED/2026-02-09/2026-02-09.error-0.log delete mode 100644 logPath_IS_UNDEFINED/2026-02-09/2026-02-09.info-0.log diff --git a/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.debug-0.log b/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.debug-0.log deleted file mode 100644 index e69de29..0000000 --- a/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.debug-0.log +++ /dev/null diff --git a/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.error-0.log b/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.error-0.log deleted file mode 100644 index e69de29..0000000 --- a/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.error-0.log +++ /dev/null diff --git a/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.info-0.log b/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.info-0.log deleted file mode 100644 index e69de29..0000000 --- a/logPath_IS_UNDEFINED/2026-02-09/2026-02-09.info-0.log +++ /dev/null diff --git a/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java b/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java index da99c80..da4a81c 100644 --- a/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java +++ b/src/main/java/com/xly/agent/DynamicTableNl2SqlAiAgent.java @@ -25,9 +25,12 @@ public interface DynamicTableNl2SqlAiAgent { 3.1 多表关联必须使用 表名+字段名(如表名.字段名),严格按下面[涉及表名]中的表次序关联,聚合函数(SUM/COUNT/AVG/MIN/MAX)必须加业务化别名,日期过滤使用标准DATE格式(yyyy-MM-dd); 3.2 SQL所有字段均采用 表名.字段名 方式生成,务必确保 字段名 在相应的 表名 描述的字段中存在,如果不存在重试其它方式,直到满足条件 3.3 SQL所有字段涉及的所有表名,都要**严格**按下面[涉及表名]中的表次序关联,没有关联不允许使用 - 3.4 SQL所有的查询条件,如果是字符类型的字段,均需要加不为空判断(如ifnull(customername,'')<>'') + 3.4 SQL所有的查询条件,如果是字符类型的字段,均需要加不为空判断,用示例格式判断,示例:ifnull(customername,'')<>'' + 3.5 SQL所有的显示字段的别名中,不能出现空格,如: tCreateDate as earliest 订单日期,正确的应是 tCreateDate as earliest订单日期 4. 安全约束:禁止生成任何DDL/DML语句(DROP/ALTER/INSERT/UPDATE/DELETE等),禁止使用子查询、存储过程、自定义函数、临时表; - 5. 精准性:严格按用户需求+传入的表结构生成,仅使用指定字段/表,无多余字段、无无效表关联、无冗余过滤条件; + 5. 精准性: + 5.1 严格按用户需求+传入的表结构生成,仅使用指定字段/表,无多余字段、无无效表关联、无冗余过滤条件; + 5.2 用户需求中没有明确的日期条件,默认为全部数据,禁止增加任何日期过滤条件 6. 关联规则:多表关联时,必须使用外键/业务唯一键关联,禁止无意义关联。 """) @UserMessage(""" diff --git a/src/main/java/com/xly/agent/ErpAiAgent.java b/src/main/java/com/xly/agent/ErpAiAgent.java index 2ba1c0b..0aebb13 100644 --- a/src/main/java/com/xly/agent/ErpAiAgent.java +++ b/src/main/java/com/xly/agent/ErpAiAgent.java @@ -14,7 +14,9 @@ public interface ErpAiAgent { 你是一个专业的 工具方法匹配与参数提取 助手,核心职责是根据用户输入(含历史对话)精准匹配工具方法、提取参数、判断缺失并生成交互式补全提示; 按严格按以下步骤处理,无任何额外输出!规则如下: 1. 方法匹配:先精准拆解用户查询的核心业务意图,再自动匹配唯一符合用户问题的工具方法(MethodNo),禁止自创; - 2. 参数提取:提取该工具的全部参数,与描述完全一致,严格按标注类型赋值,数字无引号,为空时禁止赋值0; + 2. 参数提取:提取该工具的全部参数,与描述完全一致,严格按标注类型赋值,规则如下: + 2.1 数字无引号,为空时禁止赋值0; + 2.2 如果有空格需要去掉空格后再提取。 """) @UserMessage("用户输入:{{userInput}}") String chat(@MemoryId String userId, @V("userInput") String userInput); diff --git a/src/main/java/com/xly/mapper/AiToolDetailParamsMapper.java b/src/main/java/com/xly/mapper/AiToolDetailParamsMapper.java index 3ce6c1f..1f0d2f0 100644 --- a/src/main/java/com/xly/mapper/AiToolDetailParamsMapper.java +++ b/src/main/java/com/xly/mapper/AiToolDetailParamsMapper.java @@ -12,6 +12,6 @@ import java.util.List; public interface AiToolDetailParamsMapper { // XML配置方式 - @Select("SELECT * FROM ai_tool_detail_params") + @Select("SELECT * FROM ai_tool_detail_params ORDER BY iOrder,iIncrement ") List findAll(); } \ No newline at end of file diff --git a/src/main/java/com/xly/service/UserSceneSessionService.java b/src/main/java/com/xly/service/UserSceneSessionService.java index 6739606..8577db9 100644 --- a/src/main/java/com/xly/service/UserSceneSessionService.java +++ b/src/main/java/com/xly/service/UserSceneSessionService.java @@ -75,6 +75,21 @@ public class UserSceneSessionService { CHAT_AGENT_CACHE.clear(); ERP_DynamicTableNl2SqlAiAgent_CACHE.clear(); } + + /*** + * @Author 钱豹 + * @Date 14:03 2026/2/10 + * @Param [] + * @return void + * @Description 清除用户记忆 + **/ + public void cleanUserSession(String sUserId){ + USER_SCENE_SESSION_CACHE.remove(sUserId); + ERP_AGENT_CACHE.remove(sUserId); + CHAT_AGENT_CACHE.remove(sUserId); + ERP_DynamicTableNl2SqlAiAgent_CACHE.remove(sUserId); + } + public UserSceneSession getUserSceneSession(String sUserId, String sUserType,String authorization){ if (USER_SCENE_SESSION_CACHE.containsKey(sUserId)) { return USER_SCENE_SESSION_CACHE.get(sUserId); diff --git a/src/main/java/com/xly/service/XlyErpService.java b/src/main/java/com/xly/service/XlyErpService.java index 8a34899..94ea7c0 100644 --- a/src/main/java/com/xly/service/XlyErpService.java +++ b/src/main/java/com/xly/service/XlyErpService.java @@ -111,6 +111,7 @@ public class XlyErpService { ){ sResponMessage = getDynamicTableSql(session, input, userId, userInput); } + //如果返回空的进入闲聊模式 if (ObjectUtil.isEmpty(sResponMessage)){ return getChatiAgent (input, session); @@ -259,6 +260,8 @@ public class XlyErpService { .toolProvider(dynamicToolProvider) .build(); UserSceneSessionService.ERP_AGENT_CACHE.put(userId, aiAgent); +// 初始化AiService 以防止热加载太慢 找不到相应的方法 + aiAgent.chat(userId, "initAiService"); log.info("用户{}Agent构建完成,已选场景:{},场景ID{}", userId, session.isSceneSelected() ? session.getCurrentScene().getSSceneName() : "未选(全场景匹配)", dynamicToolProvider.sSceneIdMap.get(userId)); } @@ -353,8 +356,7 @@ public class XlyErpService { .build(); UserSceneSessionService.CHAT_AGENT_CACHE.put(session.getUserId(), chatiAgent); } String sChatMessage = chatiAgent.chat(session.getUserId(), input); - String systemText = " 你已进入「随便聊聊」专栏, 可"+CommonConstant.RESET; - return AiResponseDTO.builder().aiText(sChatMessage).sSceneName("随便聊聊").systemText(systemText).sReturnType(ReturnTypeCode.HTML.getCode()).build(); + return AiResponseDTO.builder().aiText(sChatMessage).sSceneName("随便聊聊").systemText(StrUtil.EMPTY).sReturnType(ReturnTypeCode.HTML.getCode()).build(); } } \ No newline at end of file diff --git a/src/main/java/com/xly/tool/DynamicToolProvider.java b/src/main/java/com/xly/tool/DynamicToolProvider.java index 26dba5e..faf0a24 100644 --- a/src/main/java/com/xly/tool/DynamicToolProvider.java +++ b/src/main/java/com/xly/tool/DynamicToolProvider.java @@ -62,7 +62,7 @@ import java.util.stream.IntStream; @RequiredArgsConstructor public class DynamicToolProvider implements ToolProvider { -// private final ToolMetaMapper toolMetaMapper; + // private final ToolMetaMapper toolMetaMapper; private final ObjectMapper objectMapper; private final ToolMetaMapper toolMetaMapper; private final ParamRuleMapper paramRuleMapper; @@ -111,7 +111,7 @@ public class DynamicToolProvider implements ToolProvider { String sceneId = meta.getSSceneId(); List dataList = new ArrayList<>(); if(ObjectUtil.isNotEmpty(sceneToolCacheMap.get(sceneId))) { - dataList = sceneToolCacheMap.get(sceneId); + dataList = sceneToolCacheMap.get(sceneId); } dataList.add(new ToolSpecificationHolder(spec, executor)); sceneToolCacheMap.put(sceneId, dataList); @@ -141,7 +141,7 @@ public class DynamicToolProvider implements ToolProvider { sAIshowfieldArry.add("sSlaveId"); String sSrcFormId = meta.getSSrcFormId(); //获取对应的窗体配置 - StringBuffer sSql =new StringBuffer().append("SELECT A.sChinese AS label,A.sName,A.sControlName,B.sId AS sFormcustomId,A.sName AS sId FROM gdsconfigformslave AS A ") + StringBuffer sSql =new StringBuffer().append("SELECT 10000 AS iOrderShow,A.sChinese AS label,A.sName,A.sControlName,B.sId AS sFormcustomId,A.sName AS sId FROM gdsconfigformslave AS A ") .append("JOIN gdsconfigformmaster AS B ON A.sParentId = B.sId ") .append("WHERE B.sParentId = #{sSrcFormId} AND A.sName <> '' AND INSTR(A.sControlName,'Btn')=0 AND (A.bVisible = 1 OR A.sName =#{sName}) "); Map searMap = new HashMap<>(); @@ -150,11 +150,17 @@ public class DynamicToolProvider implements ToolProvider { List> sAIshowfieldShowAll = dynamicExeDbService.findSql(searMap,sSql.toString()); if(ObjectUtil.isNotEmpty(sAIshowfieldShowAll)){ sAIshowfieldShowAll = sAIshowfieldShowAll.stream().filter(m-> sAIshowfieldArry.contains(m.get("sName").toString())).collect(Collectors.toUnmodifiableList()); - meta.setSAIshowfieldShow(sAIshowfieldShowAll); + sAIshowfieldShowAll.forEach(one->{ + one.put("iOrderShow",sAIshowfieldArry.indexOf(one.get("sName").toString())+1); + }); + List> sAIshowfieldShowData = new ArrayList<>(); + sAIshowfieldShowData.addAll(sAIshowfieldShowAll); + sAIshowfieldShowData.sort(Comparator.comparing(h -> Integer.valueOf(h.get("iOrderShow").toString()))); + meta.setSAIshowfieldShow(sAIshowfieldShowData); } List paramRuleListNew = new ArrayList<>(paramRuleList); for(int i=0;i sAIshowfieldShow = sAIshowfieldShowAll.get(i); + Map sAIshowfieldShow = sAIshowfieldShowAll.get(i); List one = paramRuleList.stream().filter(m->m.getSParamValue().equals(sAIshowfieldShow.get("sName"))).collect(Collectors.toUnmodifiableList()); if(ObjectUtil.isEmpty(one)){ ParamRule pr = new ParamRule(); @@ -188,7 +194,7 @@ public class DynamicToolProvider implements ToolProvider { // List specs = new ArrayList<>(); String sUserId = request.chatMemoryId().toString(); Map executors = new HashMap<>(); - // sceneToolCacheMap.get(sSceneIdMap.get(sUserId)); + // sceneToolCacheMap.get(sSceneIdMap.get(sUserId)); //获取Session UserSceneSession session = UserSceneSessionService.USER_SCENE_SESSION_CACHE.get(sUserId); //过滤对应的权限方法 @@ -240,7 +246,7 @@ public class DynamicToolProvider implements ToolProvider { // 示例:{\"客户名称\":\"小羚羊软件开发有限公司\",\"产品名称\":\"企业宣传册\",\"数量\":1000,\"产品描述\":\"黑色注意色差\",\"生产要求\":\"上光,覆膜\"} Map slMap = new HashMap<>(); for (ParamRule paramRule : paramRuleData) { - String paramName = ObjectUtil.isEmpty(paramRule.getSParamValue())?null:paramRule.getSParamValue(); +// String paramName = ObjectUtil.isEmpty(paramRule.getSParamValue())?null:paramRule.getSParamValue(); String paramDesc = ObjectUtil.isEmpty(paramRule.getSParam())?null:paramRule.getSParam(); String paramType = paramRule.getSType(); Boolean bEmpty = paramRule.getBEmpty(); @@ -251,7 +257,7 @@ public class DynamicToolProvider implements ToolProvider { //中文 slMap.put(paramDesc,sExampleValue); } - if (paramName == null || paramName.trim().isEmpty()) { + if (paramDesc == null || paramDesc.trim().isEmpty()) { continue; } // 构建参数属性 @@ -335,7 +341,7 @@ public class DynamicToolProvider implements ToolProvider { }else{ sRuleCost = getArrrayBySql(paramRule); } - // eg: 付款方式(字符串,互斥枚举值[90天、60天、现结],默认值[现结]) + // eg: 付款方式(字符串,互斥枚举值[90天、60天、现结],默认值[现结]) if(bEmpty){ sbt.append(paramDesc).append("(").append("字符串") .append(",互斥枚举值 [").append(sRuleCost).append("]"); if(ObjectUtil.isNotEmpty(paramRule.getSDefaultValue())){ @@ -369,9 +375,9 @@ public class DynamicToolProvider implements ToolProvider { boolean required = bEmpty; // 添加参数 if (required) { - builder.addParameter(paramName, properties); + builder.addParameter(paramDesc, properties); } else { - builder.addOptionalParameter(paramName, properties); + builder.addOptionalParameter(paramDesc, properties); } } @@ -500,15 +506,14 @@ public class DynamicToolProvider implements ToolProvider { log.warn("参数解析失败,tool={}, args={}", meta.getSMethodNo(), toolExecutionRequest.arguments(), e); return String.valueOf(errorResult(toolExecutionRequest, errorMsg)); } - Map argsOld = DeepCopyUtils.deepCopy(args); - +// Map argsOld = DeepCopyUtils.deepCopy(args); List paramRuleData = meta.getParamRuleListAll(); // 2. 【自动补全】应用参数的默认值 args = applyDefaultValues(args, paramRuleData); // 2.1 【补全动态参数】动态参数补全 try{ - args = applyValues(args, meta.getParamRuleListCheck()); + args = applyValues(args, meta.getParamRuleListCheck()); }catch (Exception e){ log.error("返回信息",e); String sTsMsg = e.getMessage(); @@ -554,7 +559,7 @@ public class DynamicToolProvider implements ToolProvider { operableChatMemoryProvider.get(memoryId).add(UserMessage.from("SYSTEM: 等待用户确认或选择部分数据操作")); return String.valueOf(successResult(toolExecutionRequest,askconfirmMsg)); }else{ - askconfirmMsg =getDefMessage(argsOld,meta.getSControlName()); + askconfirmMsg =getDefMessage(args,meta.getSControlName(),meta); } // 返回需要确认的结果 return executeWithConfirmation(toolExecutionRequest,askconfirmMsg,operableChatMemoryProvider.get(memoryId), session, meta).text(); @@ -567,17 +572,23 @@ public class DynamicToolProvider implements ToolProvider { * @return java.lang.String * @Description MAP转提示 **/ - private String getDefMessage(Map argMap,String sName){ + private String getDefMessage(Map argMap,String sName,ToolMeta meta){ + List showList = meta.getParamRuleListAll(); + List showListData = new ArrayList<>(); + showList = showList.stream().filter(one->one.getBTipModel()).collect(Collectors.toUnmodifiableList()); + showListData.addAll(showList); + showListData.sort(Comparator.comparing(h -> h.getIOrder())); StringBuilder markdown = new StringBuilder().append("\n"); markdown.append("\n---\n"); - // 遍历 Map 生成表格行 - argMap.forEach((key, value) -> { - String valueStr = value != null ? value.toString() : ""; - markdown.append("- ") - .append(key) - .append(": `") - .append(valueStr) - .append("`\n"); + showListData.forEach(one->{ + if(argMap.containsKey(one.getSParam())){ + String valueStr = argMap.get(one.getSParam()) != null ? argMap.get(one.getSParam()).toString() : ""; + markdown.append("- ") + .append(one.getSParam()) + .append(": `") + .append(valueStr) + .append("`\n"); + } }); markdown.append("\n---\n"); appendConfirm(markdown,sName); @@ -595,8 +606,8 @@ public class DynamicToolProvider implements ToolProvider { markdown.append("请确认是否执行").append(sName).append("操作?如果全部,直接回复"全部确认",如果部分,选择后回复"部分确认"\n"); //全部确认 ,部分确认,取消 markdown.append("回复:  ").append("**全部确认**").append(" ") - .append("**部分确认**").append(" ") - .append("**取消**"); + .append("**部分确认**").append(" ") + .append("**取消**"); } /*** @@ -656,7 +667,7 @@ public class DynamicToolProvider implements ToolProvider { } }); } - }); + }); return result; } @@ -711,6 +722,12 @@ public class DynamicToolProvider implements ToolProvider { } } List> dataListNew = dataList.stream().filter(one-> one.get(sValue).equals(args.get(name)) || one.get(sValue).equals(args.get(sValue))).collect(Collectors.toUnmodifiableList()); + //如果枚举类型枚举值中又不存在AI 返回的数据 + if("enum".equals(sType) && ObjectUtil.isEmpty(dataListNew)){ + args.remove(name); + args.remove(sValue); + continue; + } if(ObjectUtil.isNotEmpty(dataListNew)){ dataList = new ArrayList<>(); dataList.add(dataListNew.get(0)); @@ -735,14 +752,14 @@ public class DynamicToolProvider implements ToolProvider { if(dataList.size()>1){ List> finalDataList = dataList; IntStream.range(0, dataList.size()) - .forEach(iRowNum ->{ - sData.append((iRowNum + 1)).append(".").append(finalDataList.get(iRowNum).get(pd.getSParamValue())) - .append("\n"); + .forEach(iRowNum ->{ + sData.append((iRowNum + 1)).append(".").append(finalDataList.get(iRowNum).get(pd.getSParamValue())) + .append("\n\n"); - }); + }); String sParamMissMemo = StrUtil.EMPTY; if(ObjectUtil.isEmpty(pd.getSParamMissMemo())){ - sParamMissMemo = pd.getSParam()+"存在多个,请选择:"+sData; + sParamMissMemo = pd.getSParam()+"存在多个,请选择:
"+sData; }else{ sParamMissMemo = StrUtil.format(pd.getSParamMissMemo(),sData.toString()); } @@ -779,7 +796,7 @@ public class DynamicToolProvider implements ToolProvider { .filter(pd -> Boolean.TRUE.equals(pd.getBEmpty()) && pd.getBTipModel()) .filter(pd -> (!returnMap.containsKey(pd.getSParam()) || (ObjectUtil.isEmpty(returnMap.get(pd.getSParam())))) - && (!returnMap.containsKey(pd.getSParamValue()) || (ObjectUtil.isEmpty(returnMap.get(pd.getSParamValue())))) + && (!returnMap.containsKey(pd.getSParamValue()) || (ObjectUtil.isEmpty(returnMap.get(pd.getSParamValue())))) ) .map(ParamRule::getSParam) .toList(); @@ -807,7 +824,7 @@ public class DynamicToolProvider implements ToolProvider { log.info("执行工具:{},参数:{}", meta.getSMethodNo(), args); // 2.2 将中文key转换成英文key args = transformationArgs( args, paramRuleData); - String sReturn ="成功"; + String sReturn ="执行成功"; try{ sReturn = executeToolAfter(meta, args,toolExecutionRequest,paramRuleData,session); }catch (Exception e) { @@ -827,55 +844,57 @@ public class DynamicToolProvider implements ToolProvider { **/ private String executeToolAfter(ToolMeta meta, Map args,ToolExecutionRequest toolExecutionRequest,List paramDefs,UserSceneSession session) { // {"1":"存储过程","2":"SQL查询","3":"第三方API","4":"窗体查询","5":"按钮执行","6":"其它"} - String sBizContent = meta.getSBizContent(); - Integer iBizType = meta.getIBizType(); - args.put("sUserId",session.getUserId()); - if(iBizType==1 || iBizType==4){ - Map data = new HashMap<>(args); - data.put("sData", JSONObject.toJSONString(data)); - Map searMap = this.dynamicExeDbService.getDoProMap(sBizContent, data); - Map sReturn = this.dynamicExeDbService.getCallPro(searMap,sBizContent); - Integer sCode = ObjectUtil.isNotEmpty(sReturn.get(ProcedureConstant.SCODE))? Integer.valueOf(sReturn.get(ProcedureConstant.SCODE).toString()):0; - String sMsgText = ObjectUtil.isNotEmpty(sReturn.get(ProcedureConstant.SRETURN))? sReturn.get(ProcedureConstant.SRETURN).toString():"操作成功"; - if(sCode< 0){ - String msg = ObjectUtil.isEmpty(sMsgText) ?"调用过程sCode:"+Integer.valueOf(searMap.get(ProcedureConstant.SCODE).toString()):sMsgText; - return String.valueOf(askUserResult(toolExecutionRequest, msg)); - } - return String.valueOf(successResult(toolExecutionRequest, sMsgText)); - }else if(iBizType==2 && ObjectUtil.isNotEmpty(sBizContent)){ - //SQL查询 - if(sBizContent.toLowerCase().startsWith("update")){ - this.dynamicExeDbService.updateSql(args,sBizContent); - }else if(sBizContent.toLowerCase().startsWith("delete")){ - this.dynamicExeDbService.delSql(args,sBizContent); - }else if(sBizContent.toLowerCase().startsWith("insert")){ - this.dynamicExeDbService.addSql(args,sBizContent); - }else{ - List> retData = this.dynamicExeDbService.findSql(args,sBizContent); - if(ObjectUtil.isNotEmpty(retData)){ - StringBuffer sb = new StringBuffer(); - retData.forEach(one->{ - one.forEach((k,v)->{ - sb.append(v).append(" "); - }); - sb.append("
"); - }); - if(ObjectUtil.isNotEmpty(retData)){ - sb.append("请根据这些信息安排今天的工作吧!如果有具体任务需要进一步处理,请告诉我"); - } - session.setSFunPrompts(sb.toString()); - if("queryTodayTask".equals(meta.getSMethodNo())){ - session.setBCleanMemory(true); - } - return String.valueOf(successResult(toolExecutionRequest, sb.toString())); - }else{ - return String.valueOf(askUserResult(toolExecutionRequest, "未找到对应的数据")); - } - } - }else if(iBizType==3){ - return HttpsRequestUtil.me().doRequestHttp(sBizContent,JSONUtil.toJsonStr(args), - new HashMap<>(),"POST","JSON"); - } + String sBizContent = meta.getSBizContent(); + Integer iBizType = meta.getIBizType(); + args.put("sUserId",session.getUserId()); + if(iBizType==1 || iBizType==4){ + Map data = new HashMap<>(args); + data.put("sData", JSONObject.toJSONString(data)); + Map searMap = this.dynamicExeDbService.getDoProMap(sBizContent, data); + Map sReturn = this.dynamicExeDbService.getCallPro(searMap,sBizContent); + Integer sCode = ObjectUtil.isNotEmpty(sReturn.get(ProcedureConstant.SCODE))? Integer.valueOf(sReturn.get(ProcedureConstant.SCODE).toString()):0; + String sMsgText = ObjectUtil.isNotEmpty(sReturn.get(ProcedureConstant.SRETURN))? sReturn.get(ProcedureConstant.SRETURN).toString():"操作成功"; + if(sCode< 0){ + String msg = ObjectUtil.isEmpty(sMsgText) ?"调用过程sCode:"+Integer.valueOf(searMap.get(ProcedureConstant.SCODE).toString()):sMsgText; + return String.valueOf(askUserResult(toolExecutionRequest, msg)); + } + session.setSFunPrompts(sMsgText); + return sMsgText; + }else if(iBizType==2 && ObjectUtil.isNotEmpty(sBizContent)){ + //SQL查询 + if(sBizContent.toLowerCase().startsWith("update")){ + this.dynamicExeDbService.updateSql(args,sBizContent); + }else if(sBizContent.toLowerCase().startsWith("delete")){ + this.dynamicExeDbService.delSql(args,sBizContent); + }else if(sBizContent.toLowerCase().startsWith("insert")){ + this.dynamicExeDbService.addSql(args,sBizContent); + }else{ + List> retData = this.dynamicExeDbService.findSql(args,sBizContent); + if(ObjectUtil.isNotEmpty(retData)){ + StringBuffer sb = new StringBuffer(); + retData.forEach(one->{ + one.forEach((k,v)->{ + sb.append(v).append(" "); + }); + sb.append("
"); + }); + if(ObjectUtil.isNotEmpty(retData)){ + sb.append("请根据这些信息安排今天的工作吧!如果有具体任务需要进一步处理,请告诉我"); + } + session.setSFunPrompts(sb.toString()); + if("queryTodayTask".equals(meta.getSMethodNo())){ + session.setBCleanMemory(true); + } + return String.valueOf(successResult(toolExecutionRequest, sb.toString())); + }else{ + session.setSFunPrompts("未找到对应的数据"); + return "未找到对应的数据"; + } + } + }else if(iBizType==3){ + return HttpsRequestUtil.me().doRequestHttp(sBizContent,JSONUtil.toJsonStr(args), + new HashMap<>(),"POST","JSON"); + } return String.valueOf(successResult(toolExecutionRequest, "操作成功")); } @@ -1056,7 +1075,7 @@ public class DynamicToolProvider implements ToolProvider { .filter(Objects::nonNull) .collect(Collectors.toList()); } - + /** * 构建确认操作消息 */ diff --git a/src/main/java/com/xly/tts/service/PythonTtsProxyService.java b/src/main/java/com/xly/tts/service/PythonTtsProxyService.java index 4d5f0eb..2b1ea81 100644 --- a/src/main/java/com/xly/tts/service/PythonTtsProxyService.java +++ b/src/main/java/com/xly/tts/service/PythonTtsProxyService.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.xly.constant.ReturnTypeCode; import com.xly.entity.AiResponseDTO; +import com.xly.service.UserSceneSessionService; import com.xly.service.XlyErpService; import com.xly.tts.bean.*; import com.xly.util.AdvancedSymbolRemover; @@ -40,6 +41,8 @@ public class PythonTtsProxyService { private final XlyErpService xlyErpService; + private final UserSceneSessionService userSceneSessionService; + @PostConstruct public void init() { executorService = Executors.newFixedThreadPool(5); @@ -86,6 +89,8 @@ public class PythonTtsProxyService { String sUserId = request.getUserid(); String sUserType = request.getUsertype(); String authorization = request.getAuthorization(); + //清空记忆 + userSceneSessionService.cleanUserSession(sUserId); // xlyErpService.initSceneGuide(sUserId,sUserType,StrUtil.EMPTY) AiResponseDTO voiceText = xlyErpService.initSceneGuide(StrUtil.EMPTY,sUserId,sUserType, authorization); voiceText.setSReturnType(ReturnTypeCode.HTML.getCode()); diff --git a/src/main/resources/templates/chat.html b/src/main/resources/templates/chat.html index 332c5e0..f2af5cd 100644 --- a/src/main/resources/templates/chat.html +++ b/src/main/resources/templates/chat.html @@ -461,12 +461,12 @@