diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 48a42ed559873f2da55974782ddd99e4919be9f4..e8b2270336b81320206159916801952bf7a5b41c 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -73,11 +73,12 @@
weixin-java-miniapp
-
+
+
com.squareup.okhttp3
okhttp
- 4.8.1
+ 4.12.0
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatController.java
index 044652c1f20a643ba3d7cf3ae96dfdcd34e2c8c3..3680554321c47bf7b426f9660546623db8aee021 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatController.java
@@ -1,600 +1,600 @@
-package com.ruoyi.web.controller.api;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import com.github.pagehelper.PageInfo;
-import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.mall.domain.Bo.SaveChatRequestMessage;
-import com.ruoyi.mall.domain.Bo.SaveMessage;
-import com.ruoyi.mall.domain.Chat.ChatRequestMessage;
-import com.ruoyi.mall.domain.Chat.ChatResponseMessage;
-import com.ruoyi.mall.domain.Chat.Message;
-import com.ruoyi.mall.domain.MallMemberUser;
-import com.ruoyi.mall.service.IMallMemberUserService;
-import okhttp3.*;
-import okhttp3.RequestBody;
-import org.apache.commons.lang3.ObjectUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-import javax.validation.constraints.NotNull;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * @ClassName 智能对话接口
- * @Description 智能对话接口
- * @Author LHY
- * @Date 2023/10/18
- * @Version 1.0
- **/
-@RestController
-@RequestMapping("/api/chat")
-public class ApiChatController {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- @Resource
- private RedisTemplate redisTemplate;
-
- @Resource
- private IMallMemberUserService mallMemberUserService;
- //读取超时为60s
- private static final long READ_TIMEOUT = 60000;
- //写入超时为60s
- private static final long WRITE_TIMEOUT = 60000;
- //连接超时为60s
- private static final long CONNECT_TIMEOUT = 60000;
-
- private OkHttpClient.Builder builder = new OkHttpClient.Builder()
- .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
- .writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
- .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS);
-
-
- private OkHttpClient client = builder.build();
- private final String ACCESS_TOKEN_URI = "https://aip.baidubce.com/oauth/2.0/token";
- // private final String CHAT_URI = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions";
- private final String CHAT_URI = "https://aip.baidubce.com/rpc/2.0/ai_custom/v2/wenxinworkshop/chat/completions";
-
- private String apiKey = "hco0U4TGdVpA73F5mGBZliai";
- private String secretKey = "kBwPxP7PxRy5fTtIalW81GN7A3LFBrEN";
-
-
- //响应超时时间
- private int responseTimeOut = 5000;
-
-
- /**
- * 删除旧token
- *
- * @return
- */
- @GetMapping("/delQFAccessToken")
- public AjaxResult delQFAccessToken(){
- try {
- // 删除原来的token
- redisTemplate.delete("qianFanAccessToken");
- return AjaxResult.success("删除token成功");
- }catch (Exception e){
- return AjaxResult.error("获取AccessToken异常!");
- }
- }
-
-
- /**
- * 获取千帆AccessToken
- *
- * @return
- */
- @GetMapping("/getQFAccessToken")
- public AjaxResult getAccessToken(){
- try {
- String token = getQianFanAccessToken();
- return AjaxResult.success(token);
- }catch (Exception e){
- return AjaxResult.error("获取AccessToken异常!");
- }
- }
-
-
-
- /**
- * 从缓存中拿到千帆AccessToken
- *
- * @return
- */
- private String getQianFanAccessToken() {
- String qianFanAccessToken = new String();
- if(null == redisTemplate.boundValueOps("qianFanAccessToken").get()){
- MediaType mediaType = MediaType.parse("application/json");
- // MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
- RequestBody body = RequestBody.create(mediaType, "");
- //创建一个请求
- Request request = new Request.Builder()
- .url(ACCESS_TOKEN_URI+"?client_id=" + apiKey + "&client_secret=" + secretKey + "&grant_type=client_credentials")
- .method("POST",body)
- .addHeader("Content-Type", "application/json")
- .addHeader("Accept", "application/json")
- // .addHeader("Content-Type", "application/x-www-form-urlencoded")
- .build();
- try {
- //使用浏览器对象发起请求
- Response response = client.newCall(request).execute();
- //只能执行一次response.body().string()。下次再执行会抛出流关闭异常,因此需要一个对象存储返回结果
- String responseMessage = response.body().string();
- logger.info("获取accessToken成功");
- JSONObject jsonObject = JSONUtil.parseObj(responseMessage);
- String accessToken = (String) jsonObject.get("access_token");
- redisTemplate.boundValueOps("qianFanAccessToken").set(accessToken, 30, TimeUnit.DAYS);
-
- qianFanAccessToken = (String) redisTemplate.boundValueOps("qianFanAccessToken").get();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }else{
- qianFanAccessToken = (String) redisTemplate.boundValueOps("qianFanAccessToken").get();
- }
- return qianFanAccessToken;
- }
-
- /**对话
- *
- * @param params
- * @return
- * @throws IOException
- */
- @PostMapping("/createPicture")
- @org.springframework.web.bind.annotation.ResponseBody
- public AjaxResult chat(@org.springframework.web.bind.annotation.RequestBody Map params) throws IOException {
- //对用户问题的判断
- if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
- return AjaxResult.error("缺少问题");
- }
- if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
- return AjaxResult.error("缺少用户id");
- }
- long userId = Long.parseLong(params.get("userId").toString());
-
- MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
- if (memberUser == null) {
- return AjaxResult.error("用户信息异常!!!");
- }
-
- String question = params.get("question").toString();
- //通过参数获取一个Message
- Message message = new Message("user",question);
- //请求参数
- ChatRequestMessage requestBody = new ChatRequestMessage();
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
- //System.out.println("json:"+json);
- requestBody = JSONUtil.toBean(json, ChatRequestMessage.class);
- }
- //将新的问题添加到消息上下文
- requestBody.addMessage(message);
- String jsonStr = JSONUtil.toJsonStr(requestBody);
- //System.out.println("jsonStr:"+jsonStr);
- MediaType mediaType = MediaType.parse("application/json");
- RequestBody body = RequestBody.create(mediaType, jsonStr);
- Request request = new Request.Builder()
- .url(CHAT_URI+"?access_token="+getQianFanAccessToken())
- .method("POST", body)
- .addHeader("Content-Type", "application/json")
- .build();
- try{
- //logger.info("千帆AccessToken:{}",getQianFanAccessToken());
- Response response = client.newCall(request).execute();
- String responseJsonStr = response.body().string();
- logger.info("发送一次请求,询问问题:{}",question);
- ChatResponseMessage responseMessage = JSONUtil.toBean(responseJsonStr, ChatResponseMessage.class);
- System.out.println("返回的响应结果为:"+responseJsonStr);
- String result = responseMessage.getResult();
- String answer = result.replaceAll("\n+", "\n");
- logger.info("{}",answer);
- Message assistant = new Message("assistant", answer);
- requestBody.addMessage(assistant);
- //redis 存储
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- Long expire = redisTemplate.getExpire("ChatWith" + memberUser.getId());
- redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(requestBody), 30, TimeUnit.DAYS);
- }else{
- redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(requestBody), 30, TimeUnit.DAYS);
- }
- logger.info("存入redis:" +redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
- return AjaxResult.success(requestBody);
- }catch (Exception e){
- e.printStackTrace();
- return AjaxResult.error("对话失败!");
- }
-
- }
-
- /**对话 只返回最新内容
- *
- * @param params
- * @return
- * @throws IOException
- */
- @PostMapping("/newChat")
- @org.springframework.web.bind.annotation.ResponseBody
- public AjaxResult chatNew(@org.springframework.web.bind.annotation.RequestBody Map params) throws IOException {
- //对用户问题的判断
- if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
- return AjaxResult.error("缺少问题");
- }
- if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
- return AjaxResult.error("缺少用户id");
- }
- if (!params.containsKey("hasVoice") || ObjectUtils.isEmpty(Integer.valueOf(params.get("hasVoice").toString()))){
- return AjaxResult.error("缺少语音状态");
- }
- long userId = Long.parseLong(params.get("userId").toString());
- // 是否有语音0-没有,1-有
- Integer hasVoice = Integer.valueOf(params.get("hasVoice").toString());
-
- MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
- if (memberUser == null) {
- return AjaxResult.error("用户信息异常!!!");
- }
-
- String question = params.get("question").toString();
- //通过参数获取一个Message
- Message message = new Message("user",question);
- // 创建存储用saveMessage
- SaveMessage saveMessage = new SaveMessage();
- saveMessage.setRole("user");
- saveMessage.setContent(question);
- saveMessage.setHasVoice(hasVoice);
- if (hasVoice == 1){
- saveMessage.setVoiceUrl(params.get("voiceUrl").toString());
- }
- //请求参数
- ChatRequestMessage requestBody = new ChatRequestMessage();
- // 创建存储类
- SaveChatRequestMessage saveChatRequestMessage = new SaveChatRequestMessage();
-
- // 查询是否有记录
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
- //System.out.println("json:"+json);
- //requestBody = JSONUtil.toBean(json, ChatRequestMessage.class);
- saveChatRequestMessage = JSONUtil.toBean(json, SaveChatRequestMessage.class);
- // 记录信息复制到请求参数中
- BeanUtil.copyProperties(saveChatRequestMessage, requestBody);
- List saveMessageList = saveChatRequestMessage.getSaveMessageList();
- ArrayList list = new ArrayList<>();
- if (!saveMessageList.isEmpty()){
- for (SaveMessage saveMessageHistory : saveMessageList) {
- Message m = BeanUtil.copyProperties(saveMessageHistory, Message.class);
- list.add(m);
- }
- requestBody.setMessages(list);
- }
- }
- //将新的问题添加到消息上下文
- requestBody.addMessage(message);
- // 新信息添加保存
- saveChatRequestMessage.addSaveMessage(saveMessage);
-
- String jsonStr = JSONUtil.toJsonStr(requestBody);
- //System.out.println("jsonStr:"+jsonStr);
- MediaType mediaType = MediaType.parse("application/json");
- RequestBody body = RequestBody.create(mediaType, jsonStr);
- Request request = new Request.Builder()
- .url(CHAT_URI+"?access_token="+getQianFanAccessToken())
- .method("POST", body)
- .addHeader("Content-Type", "application/json")
- .build();
- try{
- //logger.info("千帆AccessToken:{}",getQianFanAccessToken());
- Response response = client.newCall(request).execute();
- String responseJsonStr = response.body().string();
- logger.info("发送一次请求,询问问题:{}",question);
- ChatResponseMessage responseMessage = JSONUtil.toBean(responseJsonStr, ChatResponseMessage.class);
- System.out.println("返回的响应结果为:"+responseJsonStr);
- String result = responseMessage.getResult();
- String answer = result.replaceAll("\n+", "\n");
- logger.info("{}",answer);
- Message assistant = new Message("assistant", answer);
- requestBody.addMessage(assistant);
-
- // 存储信息
- SaveMessage saveAnswer = BeanUtil.copyProperties(assistant, SaveMessage.class);
- saveAnswer.setHasVoice(hasVoice);
- saveChatRequestMessage.addSaveMessage(saveAnswer);
-
- //redis 存储
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- Long expire = redisTemplate.getExpire("ChatWith" + memberUser.getId());
- redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
- }else{
- redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
- }
- logger.info("存入redis:" +redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
- List newChat = new ArrayList<>();
- newChat.add(saveMessage);
- newChat.add(saveAnswer);
- return AjaxResult.success(newChat);
- }catch (Exception e){
- e.printStackTrace();
- return AjaxResult.error("对话失败!");
- }
-
- }
-
- /**对话历史-近到远—分页
- *
- * @param userId 当前对话用户id
- * @return
- */
- @GetMapping("/getChatHistory")
- public AjaxResult getChatHistory(@RequestParam(defaultValue = "1") Integer pageNum,
- @RequestParam(defaultValue = "10") Integer pageSize,
- @NotNull(message = "Chat.getChatHistory.userId.isNull") Long userId){
- try {
- MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
- if (memberUser == null) {
- return AjaxResult.error("用户信息异常!!!");
- }
- SaveChatRequestMessage requestBody = new SaveChatRequestMessage();
- List history = new ArrayList<>();
- //有历史消息
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
- System.out.println("json:"+json);
- requestBody = JSONUtil.toBean(json, SaveChatRequestMessage.class);
- if(null != requestBody.getSaveMessageList() && requestBody.getSaveMessageList().size()>0){
- history = requestBody.getSaveMessageList();
- Collections.reverse(history);
- }
- }
-
- //Page page = new Page<>(pageNum,pageSize);
- ////为Page类中的total属性赋值
- //int total = history.size();
- //page.setTotal(total);
- ////计算当前需要显示的数据下标起始值
- //int startIndex = (pageNum - 1) * pageSize;
- //int endIndex = Math.min(startIndex + pageSize,total);
- ////从链表中截取需要显示的子链表,并加入到Page
- //page.addAll(history.subList(startIndex,endIndex));
- ////以Page创建PageInfo
- //PageInfo pageInfo = new PageInfo<>(page);
- //return AjaxResult.success().put("data",pageInfo);
-
- //java8 stream实现list分页
-
- List pageList = history.stream().sorted().skip((pageNum - 1) * pageSize)
- .limit(pageSize)
- .collect(Collectors.toList());
- PageInfo pageInfo = new PageInfo(pageList);
- //获取PageInfo其他参数
- pageInfo.setTotal(history.size());
-
- int endRow = pageInfo.getEndRow() == 0 ? 0 : (int)((pageNum - 1) * pageSize + pageInfo.getEndRow() + 1);
- pageInfo.setEndRow(endRow);
- boolean hasNextPage = history.size() <= pageSize * pageNum ? false : true;
- pageInfo.setHasNextPage(hasNextPage);
- boolean hasPreviousPage = pageNum == 1 ? false : true;
- pageInfo.setHasPreviousPage(hasPreviousPage);
- pageInfo.setIsFirstPage(!hasPreviousPage);
- boolean isLastPage = (history.size() > pageSize * (pageNum - 1) && history.size() <= pageSize * pageNum) ? true : false;
- pageInfo.setIsLastPage(isLastPage);
- int pages = history.size() % pageSize == 0 ? history.size() / pageSize : (history.size() / pageSize) + 1;
- pageInfo.setNavigateLastPage(pages);
- int[] navigatePageNums = new int[pages];
- for (int i = 1; i < pages; i++) {
- navigatePageNums[i - 1] = i;
- }
- pageInfo.setNavigatepageNums(navigatePageNums);
- int nextPage = pageNum < pages ? pageNum + 1 : 0;
- pageInfo.setNextPage(nextPage);
- pageInfo.setPageNum(pageNum);
- pageInfo.setPageSize(pageSize);
- pageInfo.setPages(pages);
- pageInfo.setPrePage(pageNum - 1);
- pageInfo.setSize(pageInfo.getList().size());
- int starRow = history.size() < pageSize * pageNum ? 1 + pageSize * (pageNum - 1) : 0;
- pageInfo.setStartRow(starRow);
- return AjaxResult.success().put("data", pageInfo);
-
- }catch (Exception e){
- return AjaxResult.error("获取对话历史异常!");
- }
- }
-
- /** 最后一页页数
- *
- * @param pageNum
- * @param pageSize
- * @param userId
- * @return
- */
- @GetMapping("/getLastNum")
- public AjaxResult getLastNum(@RequestParam(defaultValue = "1") Integer pageNum,
- @RequestParam(defaultValue = "10") Integer pageSize,
- @NotNull(message = "Chat.getChatHistory.userId.isNull") Long userId){
- try {
- MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
- if (memberUser == null) {
- return AjaxResult.error("用户信息异常!!!");
- }
- SaveChatRequestMessage requestBody = new SaveChatRequestMessage();
- List history = new ArrayList<>();
- //有历史消息
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
- System.out.println("json:"+json);
- requestBody = JSONUtil.toBean(json, SaveChatRequestMessage.class);
- if(null != requestBody.getSaveMessageList() && requestBody.getSaveMessageList().size()>0){
- history = requestBody.getSaveMessageList();
- }
- int total = history.size();
- int num = total/pageSize;
- int remain = total%pageSize;
- if(num == 0 && remain > 0){
- return AjaxResult.success().put("lastPage",1);
- } else if(num > 0 && remain > 0) {
- return AjaxResult.success().put("lastPage",num+1);
- }else if(num > 0 && remain == 0) {
- return AjaxResult.success().put("lastPage",num);
- }else{
- return AjaxResult.success().put("lastPage",0);
- }
- }else{
- return AjaxResult.success().put("lastPage",0);
- }
-
-
- }catch (Exception e){
- return AjaxResult.error("获取最后页数异常!");
- }
- }
-
-
- /**
- * 调用知识库
- */
- @PostMapping("/chatNew")
- @org.springframework.web.bind.annotation.ResponseBody
- public AjaxResult newChat(@org.springframework.web.bind.annotation.RequestBody Map params){
- //对用户问题的判断
- if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
- return AjaxResult.error("缺少问题");
- }
- if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
- return AjaxResult.error("缺少用户id");
- }
- if (!params.containsKey("hasVoice") || ObjectUtils.isEmpty(Integer.valueOf(params.get("hasVoice").toString()))){
- return AjaxResult.error("缺少语音状态");
- }
- long userId = Long.parseLong(params.get("userId").toString());
- // 是否有语音0-没有,1-有
- Integer hasVoice = Integer.valueOf(params.get("hasVoice").toString());
-
- MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
- if (memberUser == null) {
- return AjaxResult.error("用户信息异常!!!");
- }
-
- String question = params.get("question").toString();
- //通过参数获取一个Message
- Message message = new Message("user",question);
- // 创建存储用saveMessage
- SaveMessage saveMessage = new SaveMessage();
- saveMessage.setRole("user");
- saveMessage.setContent(question);
- saveMessage.setHasVoice(hasVoice);
- if (hasVoice == 1){
- saveMessage.setVoiceUrl(params.get("voiceUrl").toString());
- }
-
- com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
- jsonObject.put("query", question);
- List plugins = new ArrayList<>();
- plugins.add("uuid-zhishiku");
- //plugins.add("uuid-weatherforecast");
- //jsonObject.put("plugins", plugins);
- //jsonObject.put("verbose", false);
-
-
- // 创建存储类
- SaveChatRequestMessage saveChatRequestMessage = new SaveChatRequestMessage();
- ArrayList historyList = new ArrayList<>();
- // 查询是否有记录
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
- saveChatRequestMessage = JSONUtil.toBean(json, SaveChatRequestMessage.class);
- // 记录信息复制到请求参数中
- List saveMessageList = saveChatRequestMessage.getSaveMessageList();
-
- if (!saveMessageList.isEmpty()){
- List shortList = new ArrayList<>();
- int size = saveMessageList.size();
- if ( size >= 2){
- shortList.add(saveMessageList.get(size - 2));
- shortList.add(saveMessageList.get(size - 1));
- for (SaveMessage saveMessageHistory : shortList) {
- Message m = BeanUtil.copyProperties(saveMessageHistory, Message.class);
- historyList.add(m);
- }
- }
-
- }
- }
- //将新的问题添加到消息上下文
- //jsonObject.put("history", historyList);
- // 新信息添加保存
- saveChatRequestMessage.addSaveMessage(saveMessage);
-
- String jsonStr = jsonObject.toJSONString();
- MediaType mediaType = MediaType.parse("application/json");
- RequestBody body = RequestBody.create(mediaType, jsonStr);
- Request request = new Request.Builder()
- // .url("https://aip.baidubce.com/rpc/2.0/ai_custom/v2/wenxinworkshop/plugin/jfa2nhi1zap61qy7?access_token="+getQianFanAccessToken())
- .url("https://qianfan.baidubce.com/v2/chat/completions")
- .method("POST", body)
- .addHeader("Content-Type", "application/json")
- .addHeader("Authorization", "Bearer " + getQianFanAccessToken())
- .build();
- try{
- logger.info("千帆AccessToken:{}",getQianFanAccessToken());
- Response response = client.newCall(request).execute();
- String responseJsonStr = response.body().string();
-
- com.alibaba.fastjson.JSONObject data = JSONUtil.toBean(responseJsonStr, com.alibaba.fastjson.JSONObject.class);
- System.out.println("返回的响应结果为:"+responseJsonStr);
- System.out.println("data:"+data);
- System.out.println("result:"+data.getString("result"));
- System.out.println("response:"+response);
- String result = data.getString("result");
- if (StringUtils.isNotBlank(result)){
- String answer = result.replaceAll("\n", "");
-
- //int i = answer.indexOf("\n");
- Message assistant = new Message("assistant", answer);
- //if (i> 0){
- // assistant.setContent(answer.substring(0,i));
- //}
-
-
- // 存储信息
- SaveMessage saveAnswer = BeanUtil.copyProperties(assistant, SaveMessage.class);
- saveAnswer.setHasVoice(hasVoice);
-
- saveChatRequestMessage.addSaveMessage(saveAnswer);
-
- //redis 存储
- if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
- Long expire = redisTemplate.getExpire("ChatWith" + memberUser.getId());
- redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
- }else{
- redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
- }
- logger.info("存入redis:" +redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
- List newChat = new ArrayList<>();
- newChat.add(saveMessage);
- newChat.add(saveAnswer);
-
- return AjaxResult.success(newChat);
- }else{
- logger.error("对话返回结果为空");
- return AjaxResult.error("对话失败!");
- }
-
- }catch (Exception e){
- e.printStackTrace();
- return AjaxResult.error("对话失败!");
- }
-
- }
-
-}
+// package com.ruoyi.web.controller.api;
+//
+// import cn.hutool.core.bean.BeanUtil;
+// import cn.hutool.json.JSONObject;
+// import cn.hutool.json.JSONUtil;
+// import com.github.pagehelper.PageInfo;
+// import com.ruoyi.common.core.domain.AjaxResult;
+// import com.ruoyi.common.utils.StringUtils;
+// import com.ruoyi.mall.domain.Bo.SaveChatRequestMessage;
+// import com.ruoyi.mall.domain.Bo.SaveMessage;
+// import com.ruoyi.mall.domain.Chat.ChatRequestMessage;
+// import com.ruoyi.mall.domain.Chat.ChatResponseMessage;
+// import com.ruoyi.mall.domain.Chat.Message;
+// import com.ruoyi.mall.domain.MallMemberUser;
+// import com.ruoyi.mall.service.IMallMemberUserService;
+// import okhttp3.*;
+// import okhttp3.RequestBody;
+// import org.apache.commons.lang3.ObjectUtils;
+// import org.slf4j.Logger;
+// import org.slf4j.LoggerFactory;
+// import org.springframework.data.redis.core.RedisTemplate;
+// import org.springframework.web.bind.annotation.*;
+//
+// import javax.annotation.Resource;
+// import javax.validation.constraints.NotNull;
+// import java.io.IOException;
+// import java.util.*;
+// import java.util.concurrent.TimeUnit;
+// import java.util.stream.Collectors;
+//
+// /**
+// * @ClassName 智能对话接口
+// * @Description 智能对话接口
+// * @Author LHY
+// * @Date 2023/10/18
+// * @Version 1.0
+// **/
+// @RestController
+// @RequestMapping("/api/chat")
+// public class ApiChatController {
+//
+// private final Logger logger = LoggerFactory.getLogger(this.getClass());
+//
+// @Resource
+// private RedisTemplate redisTemplate;
+//
+// @Resource
+// private IMallMemberUserService mallMemberUserService;
+// //读取超时为60s
+// private static final long READ_TIMEOUT = 60000;
+// //写入超时为60s
+// private static final long WRITE_TIMEOUT = 60000;
+// //连接超时为60s
+// private static final long CONNECT_TIMEOUT = 60000;
+//
+// private OkHttpClient.Builder builder = new OkHttpClient.Builder()
+// .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
+// .writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
+// .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS);
+//
+//
+// private OkHttpClient client = builder.build();
+// private final String ACCESS_TOKEN_URI = "https://aip.baidubce.com/oauth/2.0/token";
+// // private final String CHAT_URI = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions";
+// private final String CHAT_URI = "https://aip.baidubce.com/rpc/2.0/ai_custom/v2/wenxinworkshop/chat/completions";
+//
+// private String apiKey = "hco0U4TGdVpA73F5mGBZliai";
+// private String secretKey = "kBwPxP7PxRy5fTtIalW81GN7A3LFBrEN";
+//
+//
+// //响应超时时间
+// private int responseTimeOut = 5000;
+//
+//
+// /**
+// * 删除旧token
+// *
+// * @return
+// */
+// @GetMapping("/delQFAccessToken")
+// public AjaxResult delQFAccessToken(){
+// try {
+// // 删除原来的token
+// redisTemplate.delete("qianFanAccessToken");
+// return AjaxResult.success("删除token成功");
+// }catch (Exception e){
+// return AjaxResult.error("获取AccessToken异常!");
+// }
+// }
+//
+//
+// /**
+// * 获取千帆AccessToken
+// *
+// * @return
+// */
+// @GetMapping("/getQFAccessToken")
+// public AjaxResult getAccessToken(){
+// try {
+// String token = getQianFanAccessToken();
+// return AjaxResult.success(token);
+// }catch (Exception e){
+// return AjaxResult.error("获取AccessToken异常!");
+// }
+// }
+//
+//
+//
+// /**
+// * 从缓存中拿到千帆AccessToken
+// *
+// * @return
+// */
+// private String getQianFanAccessToken() {
+// String qianFanAccessToken = new String();
+// if(null == redisTemplate.boundValueOps("qianFanAccessToken").get()){
+// MediaType mediaType = MediaType.parse("application/json");
+// // MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
+// RequestBody body = RequestBody.create(mediaType, "");
+// //创建一个请求
+// Request request = new Request.Builder()
+// .url(ACCESS_TOKEN_URI+"?client_id=" + apiKey + "&client_secret=" + secretKey + "&grant_type=client_credentials")
+// .method("POST",body)
+// .addHeader("Content-Type", "application/json")
+// .addHeader("Accept", "application/json")
+// // .addHeader("Content-Type", "application/x-www-form-urlencoded")
+// .build();
+// try {
+// //使用浏览器对象发起请求
+// Response response = client.newCall(request).execute();
+// //只能执行一次response.body().string()。下次再执行会抛出流关闭异常,因此需要一个对象存储返回结果
+// String responseMessage = response.body().string();
+// logger.info("获取accessToken成功");
+// JSONObject jsonObject = JSONUtil.parseObj(responseMessage);
+// String accessToken = (String) jsonObject.get("access_token");
+// redisTemplate.boundValueOps("qianFanAccessToken").set(accessToken, 30, TimeUnit.DAYS);
+//
+// qianFanAccessToken = (String) redisTemplate.boundValueOps("qianFanAccessToken").get();
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }else{
+// qianFanAccessToken = (String) redisTemplate.boundValueOps("qianFanAccessToken").get();
+// }
+// return qianFanAccessToken;
+// }
+//
+// /**对话
+// *
+// * @param params
+// * @return
+// * @throws IOException
+// */
+// @PostMapping("/createPicture")
+// @org.springframework.web.bind.annotation.ResponseBody
+// public AjaxResult chat(@org.springframework.web.bind.annotation.RequestBody Map params) throws IOException {
+// //对用户问题的判断
+// if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
+// return AjaxResult.error("缺少问题");
+// }
+// if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
+// return AjaxResult.error("缺少用户id");
+// }
+// long userId = Long.parseLong(params.get("userId").toString());
+//
+// MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+// if (memberUser == null) {
+// return AjaxResult.error("用户信息异常!!!");
+// }
+//
+// String question = params.get("question").toString();
+// //通过参数获取一个Message
+// Message message = new Message("user",question);
+// //请求参数
+// ChatRequestMessage requestBody = new ChatRequestMessage();
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+// //System.out.println("json:"+json);
+// requestBody = JSONUtil.toBean(json, ChatRequestMessage.class);
+// }
+// //将新的问题添加到消息上下文
+// requestBody.addMessage(message);
+// String jsonStr = JSONUtil.toJsonStr(requestBody);
+// //System.out.println("jsonStr:"+jsonStr);
+// MediaType mediaType = MediaType.parse("application/json");
+// RequestBody body = RequestBody.create(mediaType, jsonStr);
+// Request request = new Request.Builder()
+// .url(CHAT_URI+"?access_token="+getQianFanAccessToken())
+// .method("POST", body)
+// .addHeader("Content-Type", "application/json")
+// .build();
+// try{
+// //logger.info("千帆AccessToken:{}",getQianFanAccessToken());
+// Response response = client.newCall(request).execute();
+// String responseJsonStr = response.body().string();
+// logger.info("发送一次请求,询问问题:{}",question);
+// ChatResponseMessage responseMessage = JSONUtil.toBean(responseJsonStr, ChatResponseMessage.class);
+// System.out.println("返回的响应结果为:"+responseJsonStr);
+// String result = responseMessage.getResult();
+// String answer = result.replaceAll("\n+", "\n");
+// logger.info("{}",answer);
+// Message assistant = new Message("assistant", answer);
+// requestBody.addMessage(assistant);
+// //redis 存储
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// Long expire = redisTemplate.getExpire("ChatWith" + memberUser.getId());
+// redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(requestBody), 30, TimeUnit.DAYS);
+// }else{
+// redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(requestBody), 30, TimeUnit.DAYS);
+// }
+// logger.info("存入redis:" +redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
+// return AjaxResult.success(requestBody);
+// }catch (Exception e){
+// e.printStackTrace();
+// return AjaxResult.error("对话失败!");
+// }
+//
+// }
+//
+// /**对话 只返回最新内容
+// *
+// * @param params
+// * @return
+// * @throws IOException
+// */
+// @PostMapping("/newChat")
+// @org.springframework.web.bind.annotation.ResponseBody
+// public AjaxResult chatNew(@org.springframework.web.bind.annotation.RequestBody Map params) throws IOException {
+// //对用户问题的判断
+// if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
+// return AjaxResult.error("缺少问题");
+// }
+// if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
+// return AjaxResult.error("缺少用户id");
+// }
+// if (!params.containsKey("hasVoice") || ObjectUtils.isEmpty(Integer.valueOf(params.get("hasVoice").toString()))){
+// return AjaxResult.error("缺少语音状态");
+// }
+// long userId = Long.parseLong(params.get("userId").toString());
+// // 是否有语音0-没有,1-有
+// Integer hasVoice = Integer.valueOf(params.get("hasVoice").toString());
+//
+// MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+// if (memberUser == null) {
+// return AjaxResult.error("用户信息异常!!!");
+// }
+//
+// String question = params.get("question").toString();
+// //通过参数获取一个Message
+// Message message = new Message("user",question);
+// // 创建存储用saveMessage
+// SaveMessage saveMessage = new SaveMessage();
+// saveMessage.setRole("user");
+// saveMessage.setContent(question);
+// saveMessage.setHasVoice(hasVoice);
+// if (hasVoice == 1){
+// saveMessage.setVoiceUrl(params.get("voiceUrl").toString());
+// }
+// //请求参数
+// ChatRequestMessage requestBody = new ChatRequestMessage();
+// // 创建存储类
+// SaveChatRequestMessage saveChatRequestMessage = new SaveChatRequestMessage();
+//
+// // 查询是否有记录
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+// //System.out.println("json:"+json);
+// //requestBody = JSONUtil.toBean(json, ChatRequestMessage.class);
+// saveChatRequestMessage = JSONUtil.toBean(json, SaveChatRequestMessage.class);
+// // 记录信息复制到请求参数中
+// BeanUtil.copyProperties(saveChatRequestMessage, requestBody);
+// List saveMessageList = saveChatRequestMessage.getSaveMessageList();
+// ArrayList list = new ArrayList<>();
+// if (!saveMessageList.isEmpty()){
+// for (SaveMessage saveMessageHistory : saveMessageList) {
+// Message m = BeanUtil.copyProperties(saveMessageHistory, Message.class);
+// list.add(m);
+// }
+// requestBody.setMessages(list);
+// }
+// }
+// //将新的问题添加到消息上下文
+// requestBody.addMessage(message);
+// // 新信息添加保存
+// saveChatRequestMessage.addSaveMessage(saveMessage);
+//
+// String jsonStr = JSONUtil.toJsonStr(requestBody);
+// //System.out.println("jsonStr:"+jsonStr);
+// MediaType mediaType = MediaType.parse("application/json");
+// RequestBody body = RequestBody.create(mediaType, jsonStr);
+// Request request = new Request.Builder()
+// .url(CHAT_URI+"?access_token="+getQianFanAccessToken())
+// .method("POST", body)
+// .addHeader("Content-Type", "application/json")
+// .build();
+// try{
+// //logger.info("千帆AccessToken:{}",getQianFanAccessToken());
+// Response response = client.newCall(request).execute();
+// String responseJsonStr = response.body().string();
+// logger.info("发送一次请求,询问问题:{}",question);
+// ChatResponseMessage responseMessage = JSONUtil.toBean(responseJsonStr, ChatResponseMessage.class);
+// System.out.println("返回的响应结果为:"+responseJsonStr);
+// String result = responseMessage.getResult();
+// String answer = result.replaceAll("\n+", "\n");
+// logger.info("{}",answer);
+// Message assistant = new Message("assistant", answer);
+// requestBody.addMessage(assistant);
+//
+// // 存储信息
+// SaveMessage saveAnswer = BeanUtil.copyProperties(assistant, SaveMessage.class);
+// saveAnswer.setHasVoice(hasVoice);
+// saveChatRequestMessage.addSaveMessage(saveAnswer);
+//
+// //redis 存储
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// Long expire = redisTemplate.getExpire("ChatWith" + memberUser.getId());
+// redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
+// }else{
+// redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
+// }
+// logger.info("存入redis:" +redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
+// List newChat = new ArrayList<>();
+// newChat.add(saveMessage);
+// newChat.add(saveAnswer);
+// return AjaxResult.success(newChat);
+// }catch (Exception e){
+// e.printStackTrace();
+// return AjaxResult.error("对话失败!");
+// }
+//
+// }
+//
+// /**对话历史-近到远—分页
+// *
+// * @param userId 当前对话用户id
+// * @return
+// */
+// @GetMapping("/getChatHistory")
+// public AjaxResult getChatHistory(@RequestParam(defaultValue = "1") Integer pageNum,
+// @RequestParam(defaultValue = "10") Integer pageSize,
+// @NotNull(message = "Chat.getChatHistory.userId.isNull") Long userId){
+// try {
+// MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+// if (memberUser == null) {
+// return AjaxResult.error("用户信息异常!!!");
+// }
+// SaveChatRequestMessage requestBody = new SaveChatRequestMessage();
+// List history = new ArrayList<>();
+// //有历史消息
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+// System.out.println("json:"+json);
+// requestBody = JSONUtil.toBean(json, SaveChatRequestMessage.class);
+// if(null != requestBody.getSaveMessageList() && requestBody.getSaveMessageList().size()>0){
+// history = requestBody.getSaveMessageList();
+// Collections.reverse(history);
+// }
+// }
+//
+// //Page page = new Page<>(pageNum,pageSize);
+// ////为Page类中的total属性赋值
+// //int total = history.size();
+// //page.setTotal(total);
+// ////计算当前需要显示的数据下标起始值
+// //int startIndex = (pageNum - 1) * pageSize;
+// //int endIndex = Math.min(startIndex + pageSize,total);
+// ////从链表中截取需要显示的子链表,并加入到Page
+// //page.addAll(history.subList(startIndex,endIndex));
+// ////以Page创建PageInfo
+// //PageInfo pageInfo = new PageInfo<>(page);
+// //return AjaxResult.success().put("data",pageInfo);
+//
+// //java8 stream实现list分页
+//
+// List pageList = history.stream().sorted().skip((pageNum - 1) * pageSize)
+// .limit(pageSize)
+// .collect(Collectors.toList());
+// PageInfo pageInfo = new PageInfo(pageList);
+// //获取PageInfo其他参数
+// pageInfo.setTotal(history.size());
+//
+// int endRow = pageInfo.getEndRow() == 0 ? 0 : (int)((pageNum - 1) * pageSize + pageInfo.getEndRow() + 1);
+// pageInfo.setEndRow(endRow);
+// boolean hasNextPage = history.size() <= pageSize * pageNum ? false : true;
+// pageInfo.setHasNextPage(hasNextPage);
+// boolean hasPreviousPage = pageNum == 1 ? false : true;
+// pageInfo.setHasPreviousPage(hasPreviousPage);
+// pageInfo.setIsFirstPage(!hasPreviousPage);
+// boolean isLastPage = (history.size() > pageSize * (pageNum - 1) && history.size() <= pageSize * pageNum) ? true : false;
+// pageInfo.setIsLastPage(isLastPage);
+// int pages = history.size() % pageSize == 0 ? history.size() / pageSize : (history.size() / pageSize) + 1;
+// pageInfo.setNavigateLastPage(pages);
+// int[] navigatePageNums = new int[pages];
+// for (int i = 1; i < pages; i++) {
+// navigatePageNums[i - 1] = i;
+// }
+// pageInfo.setNavigatepageNums(navigatePageNums);
+// int nextPage = pageNum < pages ? pageNum + 1 : 0;
+// pageInfo.setNextPage(nextPage);
+// pageInfo.setPageNum(pageNum);
+// pageInfo.setPageSize(pageSize);
+// pageInfo.setPages(pages);
+// pageInfo.setPrePage(pageNum - 1);
+// pageInfo.setSize(pageInfo.getList().size());
+// int starRow = history.size() < pageSize * pageNum ? 1 + pageSize * (pageNum - 1) : 0;
+// pageInfo.setStartRow(starRow);
+// return AjaxResult.success().put("data", pageInfo);
+//
+// }catch (Exception e){
+// return AjaxResult.error("获取对话历史异常!");
+// }
+// }
+//
+// /** 最后一页页数
+// *
+// * @param pageNum
+// * @param pageSize
+// * @param userId
+// * @return
+// */
+// @GetMapping("/getLastNum")
+// public AjaxResult getLastNum(@RequestParam(defaultValue = "1") Integer pageNum,
+// @RequestParam(defaultValue = "10") Integer pageSize,
+// @NotNull(message = "Chat.getChatHistory.userId.isNull") Long userId){
+// try {
+// MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+// if (memberUser == null) {
+// return AjaxResult.error("用户信息异常!!!");
+// }
+// SaveChatRequestMessage requestBody = new SaveChatRequestMessage();
+// List history = new ArrayList<>();
+// //有历史消息
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+// System.out.println("json:"+json);
+// requestBody = JSONUtil.toBean(json, SaveChatRequestMessage.class);
+// if(null != requestBody.getSaveMessageList() && requestBody.getSaveMessageList().size()>0){
+// history = requestBody.getSaveMessageList();
+// }
+// int total = history.size();
+// int num = total/pageSize;
+// int remain = total%pageSize;
+// if(num == 0 && remain > 0){
+// return AjaxResult.success().put("lastPage",1);
+// } else if(num > 0 && remain > 0) {
+// return AjaxResult.success().put("lastPage",num+1);
+// }else if(num > 0 && remain == 0) {
+// return AjaxResult.success().put("lastPage",num);
+// }else{
+// return AjaxResult.success().put("lastPage",0);
+// }
+// }else{
+// return AjaxResult.success().put("lastPage",0);
+// }
+//
+//
+// }catch (Exception e){
+// return AjaxResult.error("获取最后页数异常!");
+// }
+// }
+//
+//
+// /**
+// * 调用知识库
+// */
+// @PostMapping("/chatNew")
+// @org.springframework.web.bind.annotation.ResponseBody
+// public AjaxResult newChat(@org.springframework.web.bind.annotation.RequestBody Map params){
+// //对用户问题的判断
+// if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
+// return AjaxResult.error("缺少问题");
+// }
+// if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
+// return AjaxResult.error("缺少用户id");
+// }
+// if (!params.containsKey("hasVoice") || ObjectUtils.isEmpty(Integer.valueOf(params.get("hasVoice").toString()))){
+// return AjaxResult.error("缺少语音状态");
+// }
+// long userId = Long.parseLong(params.get("userId").toString());
+// // 是否有语音0-没有,1-有
+// Integer hasVoice = Integer.valueOf(params.get("hasVoice").toString());
+//
+// MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+// if (memberUser == null) {
+// return AjaxResult.error("用户信息异常!!!");
+// }
+//
+// String question = params.get("question").toString();
+// //通过参数获取一个Message
+// Message message = new Message("user",question);
+// // 创建存储用saveMessage
+// SaveMessage saveMessage = new SaveMessage();
+// saveMessage.setRole("user");
+// saveMessage.setContent(question);
+// saveMessage.setHasVoice(hasVoice);
+// if (hasVoice == 1){
+// saveMessage.setVoiceUrl(params.get("voiceUrl").toString());
+// }
+//
+// com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
+// jsonObject.put("query", question);
+// List plugins = new ArrayList<>();
+// plugins.add("uuid-zhishiku");
+// //plugins.add("uuid-weatherforecast");
+// //jsonObject.put("plugins", plugins);
+// //jsonObject.put("verbose", false);
+//
+//
+// // 创建存储类
+// SaveChatRequestMessage saveChatRequestMessage = new SaveChatRequestMessage();
+// ArrayList historyList = new ArrayList<>();
+// // 查询是否有记录
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+// saveChatRequestMessage = JSONUtil.toBean(json, SaveChatRequestMessage.class);
+// // 记录信息复制到请求参数中
+// List saveMessageList = saveChatRequestMessage.getSaveMessageList();
+//
+// if (!saveMessageList.isEmpty()){
+// List shortList = new ArrayList<>();
+// int size = saveMessageList.size();
+// if ( size >= 2){
+// shortList.add(saveMessageList.get(size - 2));
+// shortList.add(saveMessageList.get(size - 1));
+// for (SaveMessage saveMessageHistory : shortList) {
+// Message m = BeanUtil.copyProperties(saveMessageHistory, Message.class);
+// historyList.add(m);
+// }
+// }
+//
+// }
+// }
+// //将新的问题添加到消息上下文
+// //jsonObject.put("history", historyList);
+// // 新信息添加保存
+// saveChatRequestMessage.addSaveMessage(saveMessage);
+//
+// String jsonStr = jsonObject.toJSONString();
+// MediaType mediaType = MediaType.parse("application/json");
+// RequestBody body = RequestBody.create(mediaType, jsonStr);
+// Request request = new Request.Builder()
+// // .url("https://aip.baidubce.com/rpc/2.0/ai_custom/v2/wenxinworkshop/plugin/jfa2nhi1zap61qy7?access_token="+getQianFanAccessToken())
+// .url("https://qianfan.baidubce.com/v2/chat/completions")
+// .method("POST", body)
+// .addHeader("Content-Type", "application/json")
+// .addHeader("Authorization", "Bearer " + getQianFanAccessToken())
+// .build();
+// try{
+// logger.info("千帆AccessToken:{}",getQianFanAccessToken());
+// Response response = client.newCall(request).execute();
+// String responseJsonStr = response.body().string();
+//
+// com.alibaba.fastjson.JSONObject data = JSONUtil.toBean(responseJsonStr, com.alibaba.fastjson.JSONObject.class);
+// System.out.println("返回的响应结果为:"+responseJsonStr);
+// System.out.println("data:"+data);
+// System.out.println("result:"+data.getString("result"));
+// System.out.println("response:"+response);
+// String result = data.getString("result");
+// if (StringUtils.isNotBlank(result)){
+// String answer = result.replaceAll("\n", "");
+//
+// //int i = answer.indexOf("\n");
+// Message assistant = new Message("assistant", answer);
+// //if (i> 0){
+// // assistant.setContent(answer.substring(0,i));
+// //}
+//
+//
+// // 存储信息
+// SaveMessage saveAnswer = BeanUtil.copyProperties(assistant, SaveMessage.class);
+// saveAnswer.setHasVoice(hasVoice);
+//
+// saveChatRequestMessage.addSaveMessage(saveAnswer);
+//
+// //redis 存储
+// if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+// Long expire = redisTemplate.getExpire("ChatWith" + memberUser.getId());
+// redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
+// }else{
+// redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
+// }
+// logger.info("存入redis:" +redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
+// List newChat = new ArrayList<>();
+// newChat.add(saveMessage);
+// newChat.add(saveAnswer);
+//
+// return AjaxResult.success(newChat);
+// }else{
+// logger.error("对话返回结果为空");
+// return AjaxResult.error("对话失败!");
+// }
+//
+// }catch (Exception e){
+// e.printStackTrace();
+// return AjaxResult.error("对话失败!");
+// }
+//
+// }
+//
+// }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatNewController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatNewController.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd7f5cefc5194bdf58ce38df886490f50b1c6172
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ApiChatNewController.java
@@ -0,0 +1,309 @@
+package com.ruoyi.web.controller.api;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.pagehelper.PageInfo;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.mall.domain.Bo.SaveChatRequestMessage;
+import com.ruoyi.mall.domain.Bo.SaveMessage;
+import com.ruoyi.mall.domain.Chat.*;
+import com.ruoyi.mall.domain.MallMemberUser;
+import com.ruoyi.mall.service.IMallMemberUserService;
+import okhttp3.RequestBody;
+import okhttp3.*;
+import org.apache.commons.lang3.ObjectUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName 智能对话接口
+ * @Description 智能对话接口
+ * @Author LHY
+ * @Date 2023/10/18
+ * @Version 1.0
+ **/
+@RestController
+@RequestMapping("/api/chat")
+public class ApiChatNewController {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Resource
+ private RedisTemplate redisTemplate;
+ @Resource
+ private IMallMemberUserService mallMemberUserService;
+
+ @Value("${baidu.appKey}")
+ private String appKey;
+ @Value("${baidu.appId}")
+ private String appId;
+
+ // 读取超时为60s
+ private static final long READ_TIMEOUT = 60000;
+ // 写入超时为60s
+ private static final long WRITE_TIMEOUT = 60000;
+ // 连接超时为60s
+ private static final long CONNECT_TIMEOUT = 60000;
+
+ private static final long CALL_TIMEOUT = 60000;
+
+ private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder()
+ // 设置调用超时时间
+ .callTimeout(CALL_TIMEOUT, TimeUnit.MILLISECONDS)
+ // 设置读取超时时间
+ .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
+ // 设置写超时时间
+ .writeTimeout(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
+ // 设置连接超时时间
+ .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
+ .build();
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+
+ // 本次对话ID
+ private String conversation_id;
+
+ /**对话历史-近到远—分页
+ *
+ * @param userId 当前对话用户id
+ * @return
+ */
+ @GetMapping("/getChatHistory")
+ public AjaxResult getChatHistory(@RequestParam(defaultValue = "1") Integer pageNum,
+ @RequestParam(defaultValue = "10") Integer pageSize,
+ @NotNull(message = "Chat.getChatHistory.userId.isNull") Long userId){
+ try {
+ MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+ if (memberUser == null) {
+ return AjaxResult.error("用户信息异常!!!");
+ }
+ SaveChatRequestMessage requestBody = new SaveChatRequestMessage();
+ List history = new ArrayList<>();
+ //有历史消息
+ if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+ String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+ System.out.println("json:"+json);
+ requestBody = JSONUtil.toBean(json, SaveChatRequestMessage.class);
+ if(null != requestBody.getSaveMessageList() && requestBody.getSaveMessageList().size()>0){
+ history = requestBody.getSaveMessageList();
+ Collections.reverse(history);
+ }
+ }
+ List pageList = history.stream().sorted().skip((pageNum - 1) * pageSize)
+ .limit(pageSize)
+ .collect(Collectors.toList());
+ PageInfo pageInfo = new PageInfo(pageList);
+ //获取PageInfo其他参数
+ pageInfo.setTotal(history.size());
+
+ int endRow = pageInfo.getEndRow() == 0 ? 0 : (int)((pageNum - 1) * pageSize + pageInfo.getEndRow() + 1);
+ pageInfo.setEndRow(endRow);
+ boolean hasNextPage = history.size() <= pageSize * pageNum ? false : true;
+ pageInfo.setHasNextPage(hasNextPage);
+ boolean hasPreviousPage = pageNum == 1 ? false : true;
+ pageInfo.setHasPreviousPage(hasPreviousPage);
+ pageInfo.setIsFirstPage(!hasPreviousPage);
+ boolean isLastPage = (history.size() > pageSize * (pageNum - 1) && history.size() <= pageSize * pageNum) ? true : false;
+ pageInfo.setIsLastPage(isLastPage);
+ int pages = history.size() % pageSize == 0 ? history.size() / pageSize : (history.size() / pageSize) + 1;
+ pageInfo.setNavigateLastPage(pages);
+ int[] navigatePageNums = new int[pages];
+ for (int i = 1; i < pages; i++) {
+ navigatePageNums[i - 1] = i;
+ }
+ pageInfo.setNavigatepageNums(navigatePageNums);
+ int nextPage = pageNum < pages ? pageNum + 1 : 0;
+ pageInfo.setNextPage(nextPage);
+ pageInfo.setPageNum(pageNum);
+ pageInfo.setPageSize(pageSize);
+ pageInfo.setPages(pages);
+ pageInfo.setPrePage(pageNum - 1);
+ pageInfo.setSize(pageInfo.getList().size());
+ int starRow = history.size() < pageSize * pageNum ? 1 + pageSize * (pageNum - 1) : 0;
+ pageInfo.setStartRow(starRow);
+ return AjaxResult.success().put("data", pageInfo);
+
+ }catch (Exception e){
+ return AjaxResult.error("获取对话历史异常!");
+ }
+ }
+
+ /**
+ * 调用知识库
+ */
+ @PostMapping("/chatNew")
+ @org.springframework.web.bind.annotation.ResponseBody
+ public AjaxResult newChat(@org.springframework.web.bind.annotation.RequestBody Map params){
+ //对用户问题的判断
+ if (!params.containsKey("question") || StringUtils.isEmpty(params.get("question").toString())) {
+ return AjaxResult.error("缺少问题");
+ }
+ if (!params.containsKey("userId") || StringUtils.isEmpty(params.get("userId").toString())) {
+ return AjaxResult.error("缺少用户id");
+ }
+ if (!params.containsKey("hasVoice") || ObjectUtils.isEmpty(Integer.valueOf(params.get("hasVoice").toString()))){
+ return AjaxResult.error("缺少语音状态");
+ }
+ long userId = Long.parseLong(params.get("userId").toString());
+ // 是否有语音0-没有,1-有
+ Integer hasVoice = Integer.valueOf(params.get("hasVoice").toString());
+
+ MallMemberUser memberUser = mallMemberUserService.selectMallMemberUserById(userId);
+ if (memberUser == null) {
+ return AjaxResult.error("用户信息异常!!!");
+ }
+
+ String question = params.get("question").toString();
+ // 创建存储用saveMessage
+ SaveMessage saveMessage = new SaveMessage();
+ saveMessage.setRole("user");
+ saveMessage.setContent(question);
+ saveMessage.setHasVoice(hasVoice);
+ if (hasVoice == 1){
+ saveMessage.setVoiceUrl(params.get("voiceUrl").toString());
+ }
+
+ com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
+ jsonObject.put("query", question);
+ List plugins = new ArrayList<>();
+ plugins.add("uuid-zhishiku");
+ //plugins.add("uuid-weatherforecast");
+ //jsonObject.put("plugins", plugins);
+ //jsonObject.put("verbose", false);
+
+
+ // 创建存储类
+ SaveChatRequestMessage saveChatRequestMessage = new SaveChatRequestMessage();
+ ArrayList historyList = new ArrayList<>();
+ // 查询是否有记录
+ if(redisTemplate.hasKey("ChatWith" + memberUser.getId())){
+ String json = redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString();
+ saveChatRequestMessage = JSONUtil.toBean(json, SaveChatRequestMessage.class);
+ // 记录信息复制到请求参数中
+ List saveMessageList = saveChatRequestMessage.getSaveMessageList();
+
+ if (!saveMessageList.isEmpty()){
+ List shortList = new ArrayList<>();
+ int size = saveMessageList.size();
+ if ( size >= 2){
+ shortList.add(saveMessageList.get(size - 2));
+ shortList.add(saveMessageList.get(size - 1));
+ for (SaveMessage saveMessageHistory : shortList) {
+ Message m = BeanUtil.copyProperties(saveMessageHistory, Message.class);
+ historyList.add(m);
+ }
+ }
+
+ }
+ }
+ //将新的问题添加到消息上下文
+ jsonObject.put("history", historyList);
+ // 新信息添加保存
+ saveChatRequestMessage.addSaveMessage(saveMessage);
+ try {
+ BaiduAppResponse qaq = qaq(question,memberUser);
+ if (StringUtils.isNotBlank(qaq.getAnswer())) {
+ Message assistant = new Message("assistant", qaq.getAnswer());
+ // // 存储信息
+ SaveMessage saveAnswer = BeanUtil.copyProperties(assistant, SaveMessage.class);
+ saveAnswer.setHasVoice(hasVoice);
+
+ saveChatRequestMessage.addSaveMessage(saveAnswer);
+
+ // redis 存储
+ if (redisTemplate.hasKey("ChatWith" + memberUser.getId())) {
+ redisTemplate.getExpire("ChatWith" + memberUser.getId());
+ redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
+ } else {
+ redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).set(JSONUtil.toJsonStr(saveChatRequestMessage), 30, TimeUnit.DAYS);
+ }
+ logger.info("存入redis:" + redisTemplate.boundValueOps("ChatWith" + memberUser.getId()).get().toString());
+ List newChat = new ArrayList<>();
+ newChat.add(saveMessage);
+ newChat.add(saveAnswer);
+ return AjaxResult.success(newChat);
+ } else {
+ logger.error("对话返回结果为空");
+ return AjaxResult.error("对话失败!");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return AjaxResult.error("对话失败!");
+ }
+
+ }
+
+ /**
+ * 提问且获取消息
+ */
+ public BaiduAppResponse qaq(String question,MallMemberUser memberUser) throws Exception {
+ // 没有创建回话则创建。
+ if (conversation_id == null || "".equals(conversation_id)) {
+ createConversation(memberUser.getId());
+ }
+ // 提问
+ logger.info("提问千帆App:" + question);
+ MediaType mediaType = MediaType.parse("application/json");
+ // 消息体
+ String json = objectMapper.writeValueAsString(new BaiduAppRequest(appId, question, conversation_id));
+ RequestBody body = RequestBody.create(mediaType, json);
+ // 请求
+ Request request = new Request.Builder()
+ .url("https://qianfan.baidubce.com/v2/app/conversation/runs")
+ .method("POST", body)
+ .addHeader("Content-Type", "application/json")
+ .addHeader("X-Appbuilder-Authorization", "Bearer " + appKey)
+ .build();
+ Response response = HTTP_CLIENT.newCall(request).execute();
+ // 获取消息
+ String res = response.body().string();
+ logger.info("HTTP请求千帆App回复:" + res);
+ BaiduAppResponse baiduAppResponse = objectMapper.readValue(res, BaiduAppResponse.class);
+ logger.info("千帆App回复对象:" + JSONUtil.toJsonStr(baiduAppResponse));
+ logger.info("千帆App回复:" + baiduAppResponse.getAnswer());
+ return baiduAppResponse;
+ }
+
+ /**
+ * 创建和百度千帆AppBuilder的对话
+ */
+ private void createConversation(Long userId) throws IOException {
+
+ Object object = redisTemplate.boundValueOps("conversation_id_" + userId).get();
+ if (ObjectUtils.isNotEmpty(object)){
+ conversation_id = object.toString();
+ }else {
+ MediaType mediaType = MediaType.parse("application/json");
+ RequestBody body = RequestBody.create(mediaType, "{\"appId\":\"" + appId + "\"}");
+ Request request = new Request.Builder()
+ .url("https://qianfan.baidubce.com/v2/app/conversation")
+ .method("POST", body)
+ .addHeader("Content-Type", "application/json")
+ .addHeader("X-Appbuilder-Authorization", "Bearer " + appKey)
+ .build();
+ Response response = HTTP_CLIENT.newCall(request).execute();
+ String res = response.body().string();
+ logger.info("百度千帆AppBuilder 创建对话响应:" + res);
+ conversation_id = objectMapper.readTree(res).get("conversation_id").asText();
+ }
+ redisTemplate.boundValueOps("conversation_id_" + userId).set(conversation_id, 30, TimeUnit.DAYS);
+ }
+
+}
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 84a09a111ce255083b12cf757014e69bb26dca07..937c520e6680292228d6e70c822d3bc497b99352 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -142,3 +142,7 @@ qiNiu:
secretKey: tWJjsaYPBBACuyw8CfaF9h2BRUziuje_zwrz4GyE
bucketName: xiaoniu666666
baseUrl: https://image.xnszz.com/
+
+baidu:
+ appId: a7234eb3-fc6b-4e8a-baae-e7f2df86a1f3
+ appKey: bce-v3/ALTAK-SJq4Dnyo31QJlajmyMT40/d806d48c7b7f2ec9675c7cbf2171e6dd0676b274
\ No newline at end of file
diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml
index 2f419a407b6294169b2ee5c7f480fd73dadbac3e..4950795168a37e077a9d348f34a1fd3c7ee28128 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -22,7 +22,13 @@
com.ruoyi
ruoyi-common
-
+
+
+ org.projectlombok
+ lombok
+ 1.18.4
+ provided
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Chat/BaiduAppRequest.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Chat/BaiduAppRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1aceb7420a03e251935e4a1cf84348a02b988311
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Chat/BaiduAppRequest.java
@@ -0,0 +1,66 @@
+package com.ruoyi.mall.domain.Chat;
+
+import lombok.Data;
+
+/**
+ * 请求体 用于请求百度千帆
+ */
+public class BaiduAppRequest {
+
+ private String app_id;
+
+ private String query;
+
+ private boolean stream;
+
+ private String conversation_id;
+
+ public BaiduAppRequest(String app_id, String query, String conversation_id) {
+ this.app_id = app_id;
+ this.query = query;
+ this.conversation_id = conversation_id;
+ }
+
+ public String getApp_id() {
+ return app_id;
+ }
+
+ public void setApp_id(String app_id) {
+ this.app_id = app_id;
+ }
+
+ public String getQuery() {
+ return query;
+ }
+
+ public void setQuery(String query) {
+ this.query = query;
+ }
+
+ public boolean isStream() {
+ return stream;
+ }
+
+ public void setStream(boolean stream) {
+ this.stream = stream;
+ }
+
+ public String getConversation_id() {
+ return conversation_id;
+ }
+
+ public void setConversation_id(String conversation_id) {
+ this.conversation_id = conversation_id;
+ }
+
+ @Override
+ public String toString() {
+ return "BaiduAppRequest{" +
+ "app_id='" + app_id + '\'' +
+ ", query='" + query + '\'' +
+ ", stream=" + stream +
+ ", conversation_id='" + conversation_id + '\'' +
+ '}';
+ }
+}
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Chat/BaiduAppResponse.java b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Chat/BaiduAppResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..74b01bfe2a6bee5f3af465a2b41226e22b29256c
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/mall/domain/Chat/BaiduAppResponse.java
@@ -0,0 +1,97 @@
+package com.ruoyi.mall.domain.Chat;
+
+import lombok.Data;
+
+import java.util.List;
+
+
+/**
+ * 响应体 接收消息用
+ */
+
+public class BaiduAppResponse {
+
+ private String request_id;
+
+ private String date;
+
+ private String answer;
+
+ private String conversation_id;
+
+ private String message_id;
+
+ private Boolean is_completion;
+
+ private List