From 0e7acb738d08d8c381c5f3a648bff8136ccc2bdd Mon Sep 17 00:00:00 2001 From: gaozhaochen Date: Wed, 9 Aug 2023 10:40:42 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E9=97=AE=E8=AF=8A=E6=9C=BA=E5=99=A8?= =?UTF-8?q?=E4=BA=BA=E5=AE=9A=E5=88=B6=E5=8C=96=E9=97=AE=E9=A2=98=E5=A4=84?= =?UTF-8?q?=E7=90=86=EF=BC=8C=E8=BF=94=E5=9B=9E=E7=BB=93=E6=9E=9C=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/HpGpIntelligentQAController.java | 113 +++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hpgp/controller/mobile/HpGpIntelligentQAController.java b/smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hpgp/controller/mobile/HpGpIntelligentQAController.java index 7756c39..6bc0fa9 100644 --- a/smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hpgp/controller/mobile/HpGpIntelligentQAController.java +++ b/smart-health-modules/theme-schema/src/main/java/cn/sh/stc/sict/theme/hpgp/controller/mobile/HpGpIntelligentQAController.java @@ -16,15 +16,20 @@ import com.google.api.client.util.Lists; import com.google.common.collect.Sets; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.reactive.function.client.WebClient; import java.util.ArrayList; import java.util.List; +import java.util.Random; import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; /** * @author F_xh @@ -33,6 +38,7 @@ import java.util.Set; @RestController @Api(tags = "[C]黄浦精准预约——智能问答") @RequestMapping("/hpgp/c/intelligent/qa") +@RequiredArgsConstructor public class HpGpIntelligentQAController { private final static String CONTENT = "Content"; @@ -41,8 +47,12 @@ public class HpGpIntelligentQAController { @Value("${hpgp-guide.qa-history-limit:3}") private Integer qaHistoryLimit; + private WebClient webClient; private final static String QA_RESULT_FLAG = "Helper: "; + private static final String ERROR_MSG = "使用的人太多啦!等下再用吧!"; + private static final Random RANDOM = new Random(); + private static final Executor EXECUTOR = Executors.newFixedThreadPool(10); /** * 打浦桥科室 @@ -108,6 +118,11 @@ public class HpGpIntelligentQAController { @ApiOperation("智能问答") @PostMapping public R qaV2(String question) { + if (StrUtil.isNotBlank(question) && question.contains("上周的血检报告出了")) { + IntelligentAnswerVO answerVO = new IntelligentAnswerVO(); + answerVO.setAnswer("https://ffyjs.hpwjsns.org.cn/huangpuH5/healthExam"); + return new R(answerVO); + } CurrentUser current = SecurityUtils.getCurrentUser(); List qaHistory = JSON.parseArray(current.getQaHistory(), String.class); String from = current.getId().toString(); @@ -149,14 +164,104 @@ public class HpGpIntelligentQAController { return new R(); } - body = body.replaceAll(QA_RESULT_FLAG, ""); - body = body.substring(1, body.lastIndexOf("\"")); - currentQa.set(1, body); + JSONObject bodyJson = JSON.parseObject(body); + String chat = bodyJson.getString("chat"); + JSONArray departmentArray = bodyJson.getJSONArray("Department"); + if (StrUtil.isBlank(chat)) { + return new R(); + } + + chat = chat.replaceAll(QA_RESULT_FLAG, ""); + if (chat.startsWith("\"") && chat.endsWith("\"")) { + chat = chat.substring(1, chat.length() - 1); + } + currentQa.set(1, chat); current.setQaHistory(JSON.toJSONString(qaHistory)); SecurityUtils.updateCurrent(current); IntelligentAnswerVO answerVO = new IntelligentAnswerVO(); - answerVO.setAnswer(body); + answerVO.setAnswer(chat); + if (CollUtil.isNotEmpty(departmentArray)) { + answerVO.setDeptName(departmentArray.getString(0)); + } return new R(answerVO); } + + /** + * post方式,可以解决特殊符号,过长的文本等问题 + * + * @return + */ +// @PostMapping(value = "/completions/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) +// public Flux streamCompletionsPost(@RequestBody Map param) { +// CurrentUser current = SecurityUtils.getCurrentUser(); +// String user = param.get("user"); +// String prompt = param.get("prompt"); +// +// Assert.hasLength(user, "user不能为空"); +// Assert.hasLength(prompt, "prompt不能为空"); +// try { +// return getChatResponse(param.get("question"), current); +// } catch (RuntimeException e) { +// log.warn("e:{}", e.getMessage()); +// return getErrorRes(e.getMessage()); +// } catch (Exception e) { +// log.error("e:{}", e.getMessage(), e); +// return getErrorRes(ERROR_MSG); +// } +// } +// +// public Flux getChatResponse(String question, CurrentUser current) { +// JSONObject params = new JSONObject(); +// +// params.put("username", current.getId()); +// List currentQuestionList = Lists.newArrayListWithCapacity(2); +// currentQuestionList.add(question); +// currentQuestionList.add(null); +// params.put("history", Collections.singletonList(currentQuestionList)); +// +// return webClient.post() +// .uri("http://localhost:12998/theme-schema/hpStatistics/hos-org-mg-status?endTime=2023-07-23&startTime=2023-07-17") +// //.header(HttpHeaders.AUTHORIZATION, "Bearer " + "") +// .syncBody(params.toJSONString()) +// .retrieve() +// .bodyToFlux(String.class) +// .onErrorResume(WebClientResponseException.class, ex -> { +// HttpStatus status = ex.getStatusCode(); +// String res = ex.getResponseBodyAsString(); +// log.error("小欣AI API error: {} {}", status, res); +// return Mono.error(new RuntimeException(res)); +// }); +// +// } +// +// /** +// * 对sse接口的异常处理 +// * 我这里的建议是不要直接抛出异常中断sse链接,因为这样前端无法获取错误信息,只能获取到链接断开了 +// * 所以建议正常返回数据,把返回的数据中的code设置为非0的值,前端根据code来判断是否是错误信息,参考 @see org.chatgptstream.openai.util.R +// * +// * @param msg +// * @return +// */ +// private Flux getErrorRes(String msg) { +// return Flux.create(emitter -> { +// emitter.next(" "); +// emitter.next(" "); +// EXECUTOR.execute(() -> { +// try { +// int time = RANDOM.nextInt(200); +// // 请注意!这里加线程池休眠是为了解决一个问题,如果你不需要则删除掉这里线程池就行 +// // 问题:假如系统使用了nginx负载均衡,然后后端这个接口遇到异常立即断开sse会导致nginx重连,进而重复请求后端 +// // 所以休眠一下再断开让nginx知道正常连接了,不要重连 +// +// //不延迟的话nginx会重连sse,导致nginx重复请求后端 +// Thread.sleep(Math.max(time, 100)); +// } catch (InterruptedException e) { +// log.info("e:", e); +// } +// emitter.next(JSON.toJSONString(new R<>().error(msg))); +// emitter.complete(); +// }); +// }); +// } } -- 2.22.0