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 7756c39ec27c2133c04c81b6bb4f12aed119a8ce..6bc0fa9aec4ef3104fa99ad60fa97789267832b1 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();
+// });
+// });
+// }
}