| ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| smartor/src/main/java/com/smartor/common/QwenLLMUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskController.java
@@ -883,6 +883,16 @@ ryTask.dealOutHospInfo(); } @PostMapping("/compensateTasktest") public void compensateTasktest(@RequestParam("subId")Long subId) { ryTask.compensateTaskTest(subId); } @PostMapping("/longTaskSendtest") public void longTaskSendtest(@RequestParam("subId")Long subId) { ryTask.longTaskSendTest(subId); } @PostMapping("/syncMedInhospForShiyi") public void syncMedInhospForShiyi(@RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) { collectHISService.syncMedInhosp(startTime, endTime); ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -685,6 +685,86 @@ } /** * é¿æä»»å¡åé */ public void longTaskSendTest(Long subId) { //è·åä»»å¡ä¿¡æ¯ ServiceTask st = new ServiceTask(); st.setDelFlag("0"); st.setLongTask(1); List<ServiceTask> serviceTasks = serviceTaskMapper.selectServiceTaskList(st); log.info("ãlongTaskSendãè·åå°{}ä¸ªé¿æä»»å¡", serviceTasks.size()); for (ServiceTask serviceTask : serviceTasks) { CommonTaskcallMQ commonTaskcallMQ = new CommonTaskcallMQ(); commonTaskcallMQ.setTaskid(serviceTask.getTaskid()); commonTaskcallMQ.setPreachform(serviceTask.getPreachform()); commonTaskcallMQ.setSendType("2"); //éè¿ä»»å¡IDæ¿å°æ£è ä¿¡æ¯,å¹¶ä¸é访æ¶é´å¾æ¯ä»å¤©ä¹åç ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity(); serviceSubtaskVO.setTaskid(commonTaskcallMQ.getTaskid()); serviceSubtaskVO.setSendstate(2L); serviceSubtaskVO.setIsVisitAgain(1); serviceSubtaskVO.setSubId(subId); serviceSubtaskVO.setVisitTime(new Date()); List<ServiceSubtask> selectServiceSubtaskList = serviceSubtaskMapper.queryServiceSubtaskList(serviceSubtaskVO); for (ServiceSubtask serviceSubtask : selectServiceSubtaskList) { sfHandlle(serviceSubtask); } } } /** * å¤çè¡¥å¿ä»»å¡ */ public void compensateTaskTest(Long subId) { //è·åå°sendstate=3 å¹¶ä¸ visit_time为å°äºçäºä»å¤©çsubtask ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity(); serviceSubtaskVO.setSendstate(3L); serviceSubtaskVO.setSubId(subId); serviceSubtaskVO.setVisitTime(new Date()); List<ServiceSubtask> serviceSubtaskList = serviceSubtaskMapper.getCompensateServiceSubtaskList(serviceSubtaskVO); for (ServiceSubtask serviceSubtask : serviceSubtaskList) { //æ ¹æ®å½åçæ§è¡æ¹å¼ï¼è·åä¸ä¸ç§æ§è¡æ¹å¼ ServiceSubtaskPreachform serviceSubtaskPreachform = new ServiceSubtaskPreachform(); serviceSubtaskPreachform.setTaskid(serviceSubtask.getTaskid()); serviceSubtaskPreachform.setSubid(serviceSubtask.getId()); serviceSubtaskPreachform.setOrgid(serviceSubtask.getOrgid()); List<ServiceSubtaskPreachform> serviceSubtaskPreachforms = serviceSubtaskPreachformMapper.selectServiceSubtaskPreachformList(serviceSubtaskPreachform); //è·åå½åæ§è¡æ¹å¼çåºå· Optional<Long> currentSort = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getSort).findFirst(); Optional<Long> id = serviceSubtaskPreachforms.stream().filter(item -> serviceSubtask.getCurrentPreachform().equals(item.getPreachform())).map(ServiceSubtaskPreachform::getId).findFirst(); if (currentSort.isPresent()) { //1å æ£æ¥ä¸ä¸ï¼æ¯ä¸æ¯ææ§è¡ç¶ææ¯å®æçï¼æä¹åå·²ç»æå®çäºï¼æ²¡æå°servuce_subtaskçç¶ææ¹æåï¼è¿é忣æ¥ä¸ä¸ï¼ boolean finishState = serviceSubtaskPreachforms.stream().allMatch(item -> item.getSendstate().equals("9")); if (finishState) { serviceSubtask.setSendstate(6L); serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); continue; } //2夿ä¸ä¸ï¼å½åçsortæ¯ä¸æ¯çäºéè¦æ§è¡çæ»ä¸ªæ°ï¼å¦æçäºçè¯ï¼è¯´ææ¯æåä¸ä¸ªï¼ç´æ¥å°servuce_subtaskçç¶ææ¹æ5ï¼æ§è¡å¤±è´¥å°±è¡äº Long cs = currentSort.get(); if (cs.equals(serviceSubtaskPreachforms.size())) { serviceSubtask.setSendstate(7L); serviceSubtask.setRemark("å¤çè¡¥å¿ä»»å¡,å½åå¤çæåè¡¥å¿ï¼å ¨é¨æ§è¡å¤±è´¥ï¼è¶ æ¶ï¼"); serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); //ä¿®æ¹åéæ¹å¼çç¶æä¸ºå¤±è´¥ serviceSubtaskPreachform.setSendstate("5"); serviceSubtaskPreachform.setId(id.get()); serviceSubtaskPreachformMapper.updateServiceSubtaskPreachform(serviceSubtaskPreachform); continue; } //3.䏿¯æåä¸ä¸ªï¼è·åå°ä¸ä¸ä¸ªæ§è¡æ¹å¼(å ä¸ºé½æ¯å¨ä»å¤©æ§è¡ï¼é£å°±ç´æ¥ååºå»å°±å®äº) sfHandlle(serviceSubtask); } } } /** * 设置失败任å¡é»è®¤å¼,å¹¶å°å¤±è´¥ä»»å¡éæ°ç½®ä¸ºæå * <p> * *@param failDay (失败天æ°ï¼è·ç¦»å½åæ¥æå¤±è´¥å¤©æ°) @@ -971,6 +1051,7 @@ //ä»»å¡åéè®°å½ ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord(); serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString()); serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId()); serviceSubtaskRecord.setUuid(UUID.randomUUID().toString()); serviceSubtaskRecord.setTasktype(serviceSubtask.getType()); serviceSubtaskRecord.setPreachform("4"); @@ -1028,8 +1109,6 @@ if (active.equals("hzszlyy")) { //å¤ç䏿乱ç é®é¢ wxCode = smsUtils.sendChat(url, patArchive.getTelcode(), serviceSubtask.getSfzh()); log.info(wxCode); } else { wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskDesc(), patArchive.getTelcode(), serviceSubtask.getSendname(), patArchive.getPatidHis(), wxqqxx); } @@ -1346,9 +1425,7 @@ //serviceSubtask.setRemark("setSuccessPreachFormæ¹æ³ï¼å½åçpreachformå·²ç»æ¯æåä¸ä¸ªäºï¼å ¨é¨æ§è¡å¤±è´¥"); serviceSubtaskMapper.updateServiceSubtask(serviceSubtask); return true; } } } else { log.error("ã宿¶ä»»å¡ä¸è¯¥æ£è æ²¡ææ¥è¯¢å°å±äºä»çåéæ¹å¼ï¼subidï¼{},prechform:{},orgid:{}ã", serviceSubtask.getId(), preachform, serviceSubtask.getOrgid()); smartor/src/main/java/com/smartor/common/QwenLLMUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,214 @@ package com.smartor.common; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.http.HttpUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * éä¹åé®ï¼Qwenï¼å¤§æ¨¡åå·¥å ·ç±»ã * <p> * åºäºé¿éäºç¾ç¼ DashScope ç OpenAI å ¼å®¹æ¥å£ï¼{@code /compatible-mode/v1/chat/completions}ï¼ï¼ * 主è¦ç¨äºè¯ä¹å¹é ï¼æè¯é³è¯å«å¾å°çèªç±ææ¬ï¼å½ä¸åå°ä¸ç»é¢è®¾é项䏿æ¥è¿çä¸ä¸ªã * <p> * é 置项ï¼application.ymlï¼ï¼ * <pre> * qwen: * api-key: sk-xxxxxxxx # ç¾ç¼ API Keyï¼å¿ å¡« * model: qwen-plus # 模ååç§°ï¼é»è®¤ qwen-plus * url: https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions * </pre> */ @Slf4j @Component public class QwenLLMUtil { /** ç¾ç¼ API Key */ @Value("${qwen.api-key:}") private String apiKey; /** 模ååç§° */ @Value("${qwen.model:qwen-plus}") private String model; /** æ¥å£å°åï¼OpenAI å ¼å®¹æ¨¡å¼ï¼ */ @Value("${qwen.url:https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions}") private String url; /** * 夿è¯é³ææ¬ææ¥è¿åªä¸ªé项ã * * @param voiceText è¯é³è¯å«å¾å°çææ¬ * @param options åéé项å表 * @return å½ä¸çé项åæï¼æ æ³å¹é ä»»ä¸é项æ¶è¿å {@code null} */ public String matchOption(String voiceText, List<String> options) { int index = matchOptionIndex(voiceText, options); return index < 0 ? null : options.get(index); } /** * 夿è¯é³ææ¬ææ¥è¿åªä¸ªé项ï¼è¿åé项å¨å表ä¸ç䏿 ã * * @param voiceText è¯é³è¯å«å¾å°çææ¬ * @param options åéé项å表 * @return å½ä¸é项ç䏿 ï¼ä» 0 å¼å§ï¼ï¼æ æ³å¹é ä»»ä¸é项æ¶è¿å {@code -1} */ public int matchOptionIndex(String voiceText, List<String> options) { if (StringUtils.isBlank(voiceText) || options == null || options.isEmpty()) { return -1; } // åªæä¸ä¸ªéé¡¹æ¶æ éè°ç¨æ¨¡å if (options.size() == 1) { return 0; } StringBuilder optionText = new StringBuilder(); for (int i = 0; i < options.size(); i++) { optionText.append(i + 1).append(". ").append(options.get(i)).append('\n'); } String systemPrompt = "ä½ æ¯ä¸ä¸ªè¯ä¹å¹é 婿ãç¨æ·ä¼ç»åºä¸æ®µè¯é³è¯å«ææ¬åè¥å¹²ä¸ªå¸¦ç¼å·çé项ï¼" + "è¯·å¤æè¿æ®µææ¬å¨è¯ä¹ä¸ææ¥è¿åªä¸ä¸ªé项ãåªå 许ä»ç»å®é项ä¸éæ©ï¼" + "ä¸è¦åä»»ä½è§£éãç´æ¥è¾åºæå¹é é项çç¼å·æ°åï¼è¥æ²¡æä»»ä½é项䏿æ¬ç¸å ³ï¼åè¾åº 0ã"; String userPrompt = "è¯é³ææ¬ï¼" + voiceText + "\n\né项ï¼\n" + optionText + "\n请åªè¾åºä¸ä¸ªæ°åï¼æå¹é é项çç¼å·ï¼æ²¡æå¹é åè¾åº 0ï¼ã"; String content = chat(systemPrompt, userPrompt); if (StringUtils.isBlank(content)) { return -1; } Integer number = extractFirstNumber(content); if (number == null || number <= 0 || number > options.size()) { log.warn("Qwen é项å¹é æªå½ä¸ï¼voiceText={}, options={}, modelReturn={}", voiceText, options, content); return -1; } return number - 1; } /** * 夿è¯é³ææ¬æ¯å¦ç¬¦åè¿ä¸ªææ * * @param voiceText è¯é³è¯å«å¾å°çææ¬ * @return å½ä¸çé项åæï¼æ æ³å¹é ä»»ä¸é项æ¶è¿å {@code null} */ public int matchRegex(String voiceText, String value, String regexText) { if (StringUtils.isBlank(voiceText) || regexText == null || regexText.isEmpty()) { return -1; } String systemPrompt = "ä½ æ¯ä¸ä¸ªè¯ä¹å¹é 婿ãç¨æ·ä¼ç»åºä¸æ®µè¯é³è¯å«ææ¬ãæ£åå¹é ææ¬ãå¯¹åºææ å¼" + "è¯·å¤æè¿æ®µææ¬æ¯å¦æ¥è¿æ£åå¹é è§åæè å¯¹åºææ å¼çææ" + "ä¸è¦åä»»ä½è§£éãè¥æç¸å ³ææï¼è½å¹é çä¸ï¼ç´æ¥è¾åº 1ï¼è¥ä¸ææ¬ææå®å ¨ä¸ç¸å ³ï¼åè¾åº 0ã"; String userPrompt = "è¯é³ææ¬ï¼" + voiceText + "\n\næ£åå¹é ææ¬ï¼\n" + regexText + "\n\nå¯¹åºææ å¼ï¼\n" + value + "\n请åªè¾åºä¸ä¸ªæ°åï¼å¹é è¾åº 1ï¼æ²¡æå¹é åè¾åº 0ï¼ã"; String content = chat(systemPrompt, userPrompt); if (StringUtils.isBlank(content)) { return -1; } Integer number = extractFirstNumber(content); if (number == null || number <= 0) { log.warn("Qwen é项å¹é æªå½ä¸ï¼voiceText={}, regexText={}, modelReturn={}", voiceText, regexText, content); return -1; } return number - 1; } /** * éç¨å¯¹è¯è°ç¨ï¼è¿å模ååå¤çææ¬å 容ã * * @param systemPrompt ç³»ç»æç¤ºè¯ï¼å¯ä¸ºç©º * @param userPrompt ç¨æ·æç¤ºè¯ * @return 模åå夿£æï¼è°ç¨å¤±è´¥è¿å {@code null} */ public String chat(String systemPrompt, String userPrompt) { if (StringUtils.isBlank(apiKey)) { throw new IllegalStateException("éä¹åé® API Key æªé ç½®ï¼qwen.api-keyï¼"); } if (StringUtils.isBlank(userPrompt)) { throw new IllegalArgumentException("userPrompt ä¸è½ä¸ºç©º"); } JSONArray messages = new JSONArray(); if (StringUtils.isNotBlank(systemPrompt)) { messages.add(message("system", systemPrompt)); } messages.add(message("user", userPrompt)); JSONObject body = new JSONObject(); body.put("model", model); body.put("messages", messages); // å¹é åºæ¯éè¦ç¨³å®ç»æï¼æ¸©åº¦è°ä½ body.put("temperature", 0.01); Map<String, String> headers = new HashMap<>(); headers.put("Authorization", "Bearer " + apiKey); headers.put("Content-Type", "application/json"); String response = HttpUtils.sendPostByHeader(url, body.toJSONString(), headers); if (StringUtils.isBlank(response)) { log.error("éä¹åé®è¿å为空ï¼url={}, body={}", url, body.toJSONString()); return null; } try { JSONObject json = JSONObject.parseObject(response); JSONArray choices = json.getJSONArray("choices"); if (choices == null || choices.isEmpty()) { log.error("éä¹åé®ååºæ choicesï¼response={}", response); return null; } JSONObject msg = choices.getJSONObject(0).getJSONObject("message"); return msg == null ? null : StringUtils.trim(msg.getString("content")); } catch (Exception e) { log.error("è§£æéä¹åé®ååºå¤±è´¥ï¼response={}", response, e); return null; } } private JSONObject message(String role, String content) { JSONObject msg = new JSONObject(); msg.put("role", role); msg.put("content", content); return msg; } /** * 仿¨¡ååå¤ä¸æå第ä¸ä¸ªæ´æ°ã模åå¶å°ä¼åå¤ âé项2â â2ãâ ä¹ç±»ï¼å䏿¬¡å åºè§£æã */ private Integer extractFirstNumber(String text) { List<Character> digits = new ArrayList<>(); for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (c >= '0' && c <= '9') { digits.add(c); } else if (!digits.isEmpty()) { break; } } if (digits.isEmpty()) { return null; } StringBuilder sb = new StringBuilder(); for (char c : digits) { sb.append(c); } try { return Integer.parseInt(sb.toString()); } catch (NumberFormatException e) { return null; } } } smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -275,6 +275,9 @@ <if test="orgid != null and orgid != ''"> and orgid = #{orgid} </if> <if test="subId != null"> AND id = #{subId} </if> <if test="taskid != null ">and taskid = #{taskid}</if> <if test="visitTime != null"> AND date_format(visit_time,'%y%m%d') <= date_format(#{visitTime},'%y%m%d') @@ -291,6 +294,9 @@ and sendstate = 5 <if test="orgid != null and orgid != ''"> and orgid = #{orgid} </if> <if test="subId != null"> AND id = #{subId} </if> <if test="taskid != null ">and taskid = #{taskid}</if> <if test="visitTime != null"> @@ -570,6 +576,9 @@ <if test="visitTime != null"> AND date_format(visit_time,'%y%m%d') <= date_format(#{visitTime},'%y%m%d') </if> <if test="subId != null"> AND id = #{subId} </if> <if test="sendstate != null ">and sendstate = #{sendstate}</if> <if test="continueFlag != null ">and continue_flag = #{continueFlag}</if> <if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if> @@ -585,6 +594,9 @@ <if test="visitTime != null"> AND date_format(visit_time,'%y%m%d') <= date_format(DATE_ADD(#{visitTime}, INTERVAL 1 DAY),'%y%m%d') </if> <if test="subId != null"> AND id = #{subId} </if> <if test="sendstate != null ">and sendstate = #{sendstate}</if> <if test="continueFlag != null ">and continue_flag = #{continueFlag}</if> <if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>