|
@@ -0,0 +1,1357 @@
|
|
|
|
+package com.fs.fastGpt.service.impl;
|
|
|
|
+
|
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
+import com.fs.common.annotation.Excel;
|
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
|
+import com.fs.common.core.redis.RedisCache;
|
|
|
|
+import com.fs.course.domain.FsUserCourseVideo;
|
|
|
|
+import com.fs.course.mapper.FsCourseWatchLogMapper;
|
|
|
|
+import com.fs.course.mapper.FsUserCourseVideoMapper;
|
|
|
|
+import com.fs.course.param.FsCourseLinkCreateParam;
|
|
|
|
+import com.fs.course.service.IFsCourseLinkService;
|
|
|
|
+import com.fs.course.vo.FsCourseWatchLogVO;
|
|
|
|
+import com.fs.fastGpt.config.ModeConfig;
|
|
|
|
+import com.fs.fastGpt.domain.*;
|
|
|
|
+import com.fs.fastGpt.mapper.FastGptChatReplaceWordsMapper;
|
|
|
|
+import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
|
|
|
|
+import com.fs.fastGpt.mapper.FastgptChatVoiceHomoMapper;
|
|
|
|
+import com.fs.fastGpt.param.SendAIParam;
|
|
|
|
+import com.fs.fastGpt.service.AiHookService;
|
|
|
|
+import com.fs.fastGpt.service.IFastGptChatMsgService;
|
|
|
|
+import com.fs.fastGpt.service.IFastGptRoleService;
|
|
|
|
+import com.fs.fastgptApi.param.ChatParam;
|
|
|
|
+import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
|
|
|
|
+import com.fs.fastgptApi.service.ChatService;
|
|
|
|
+import com.fs.fastgptApi.service.Impl.AudioServiceImpl;
|
|
|
|
+import com.fs.fastgptApi.vo.AudioVO;
|
|
|
|
+import com.fs.qw.domain.*;
|
|
|
|
+import com.fs.qw.mapper.*;
|
|
|
|
+import com.fs.qw.service.*;
|
|
|
|
+import com.fs.qwApi.param.QwSendMsgParam;
|
|
|
|
+import com.fs.qwApi.service.QwApiService;
|
|
|
|
+import com.fs.qwHookApi.param.QwHookSendMsgParam;
|
|
|
|
+import com.fs.qwHookApi.vo.QwHookMsgVO;
|
|
|
|
+import com.fs.qwHookApi.vo.QwHookVO;
|
|
|
|
+import com.fs.sop.domain.QwSopLogs;
|
|
|
|
+import com.fs.sop.mapper.QwSopLogsMapper;
|
|
|
|
+import com.fs.wxwork.dto.*;
|
|
|
|
+import com.fs.wxwork.service.WxWorkService;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+import java.lang.reflect.Field;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+
|
|
|
|
+@Slf4j
|
|
|
|
+@Service
|
|
|
|
+public class AiHookServiceImpl implements AiHookService {
|
|
|
|
+ @Autowired
|
|
|
|
+ private FastGptChatSessionMapper fastGptChatSessionMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ private ChatService chatService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QwUserMapper qwUserMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IFastGptRoleService roleService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QwExternalContactInfoMapper qwExternalContactInfoMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IFastGptChatMsgService fastGptChatMsgService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IQwContactWayService qwContactWayService;
|
|
|
|
+ @Autowired
|
|
|
|
+ QwApiService qwApiService;
|
|
|
|
+ @Autowired
|
|
|
|
+ QwCompanyMapper qwCompanyMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ FsCourseWatchLogMapper fsCourseWatchLogMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ FsUserCourseVideoMapper fsUserCourseVideoMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ FsCourseWatchLogMapper watchLogMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ IQwJsApiService qwGetJsapiTicketService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IFsCourseLinkService iFsCourseLinkService;
|
|
|
|
+ @Autowired
|
|
|
|
+ FastgptChatVoiceHomoMapper fastgptChatVoiceHomoMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ RedisCache redisCache;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IQwUserService qwUserService;
|
|
|
|
+ @Autowired
|
|
|
|
+ IQwWorkTaskService qwWorkTaskService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private QwExternalContactMapper qwExternalContactMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IQwMsgService qwMsgService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private IQwTagGroupService qwTagGroupService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private FastGptChatReplaceWordsMapper fastGptChatReplaceWordsMapper;
|
|
|
|
+ @Autowired
|
|
|
|
+ RedisTemplate<String, String> redisTemplate;
|
|
|
|
+ @Autowired
|
|
|
|
+ WxWorkService wxWorkService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private QwSessionMapper qwSessionMapper;
|
|
|
|
+ @Resource
|
|
|
|
+ private QwMsgMapper qwMsgMapper;
|
|
|
|
+
|
|
|
|
+ /** Ai半小时未回复提醒 **/
|
|
|
|
+ @Override
|
|
|
|
+ public void AiRemind() {
|
|
|
|
+ List<FastGptChatSession> fastGptChatSessions = fastGptChatSessionMapper.selectFastGptChatSessionByRemind();
|
|
|
|
+ for (FastGptChatSession fastGptChatSession : fastGptChatSessions) {
|
|
|
|
+ FastGptRole role=roleService.selectFastGptRoleTypeByRoleId(Long.parseLong(fastGptChatSession.getKfId()) );
|
|
|
|
+ if (role!=null){
|
|
|
|
+ String modeConfig=role.getModeConfigJson();
|
|
|
|
+ if (modeConfig==null|| modeConfig.isEmpty()){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ ModeConfig config= JSONUtil.toBean(modeConfig,ModeConfig.class);
|
|
|
|
+ String timeCount="用户未回复";
|
|
|
|
+ ChatParam param=new ChatParam();
|
|
|
|
+ param.setChatId(fastGptChatSession.getChatId());
|
|
|
|
+ param.setStream(false);
|
|
|
|
+ param.setDetail(true);
|
|
|
|
+ ChatParam.Variables variables=new ChatParam.Variables();
|
|
|
|
+ variables.setUid(fastGptChatSession.getKfId());
|
|
|
|
+ variables.setName("test");
|
|
|
|
+ param.setVariables(variables);
|
|
|
|
+ List<ChatParam.Message> messageList=new ArrayList<ChatParam.Message>();
|
|
|
|
+ param.setMessages(messageList);
|
|
|
|
+ addPromptWord(messageList,timeCount,fastGptChatSession.getQwExtId(),role.getReminderWords(), role.getContactInfo(),fastGptChatSession.getSessionId());
|
|
|
|
+ R r = chatService.initiatingTakeChat(param,"http://154.8.194.176:3000/api",config.getAPPKey());
|
|
|
|
+ if(r.get("code").equals(200)){
|
|
|
|
+ ChatDetailTStreamFResult result=(ChatDetailTStreamFResult)r.get("data");
|
|
|
|
+ String content = result.getChoices().get(0).getMessage().getContent();
|
|
|
|
+ String count = replace(result.getChoices().get(0).getMessage().getContent()).trim();
|
|
|
|
+ QwUser qwUser = qwUserMapper.selectQwUserById(fastGptChatSession.getQwUserId());
|
|
|
|
+ if(count!=null&& !count.isEmpty()) {
|
|
|
|
+ QwHookSendMsgParam sendMsgParam = new QwHookSendMsgParam();
|
|
|
|
+ QwHookSendMsgParam.QwHookSendMsgData sendMsgData = new QwHookSendMsgParam.QwHookSendMsgData();
|
|
|
|
+ sendMsgParam.setType(101003);
|
|
|
|
+ sendMsgData.setMsg(count);
|
|
|
|
+ sendMsgData.setSendId(fastGptChatSession.getUserId());
|
|
|
|
+ sendMsgData.setSyncKey("1");
|
|
|
|
+ sendMsgParam.setData(sendMsgData);
|
|
|
|
+ SendAIParam sendAIParam = new SendAIParam();
|
|
|
|
+ sendAIParam.setCmd("aiReplyMsg");
|
|
|
|
+ sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
|
|
|
|
+ sendAIParam.setKey(qwUser.getAppKey());
|
|
|
|
+ redisTemplate.opsForList().leftPush("AiMsg:" + qwUser.getAppKey(), JSON.toJSONString(sendAIParam));
|
|
|
|
+ }
|
|
|
|
+ FastGptChatMsg fastGptChatMsgAi = new FastGptChatMsg();
|
|
|
|
+ fastGptChatMsgAi.setContent(result.getChoices().get(0).getMessage().getContent());
|
|
|
|
+ fastGptChatMsgAi.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ fastGptChatMsgAi.setRoleId(role.getRoleId());
|
|
|
|
+ fastGptChatMsgAi.setSendType(2);
|
|
|
|
+ fastGptChatMsgAi.setCompanyId(qwUser.getCompanyId());
|
|
|
|
+ fastGptChatMsgAi.setUserId(fastGptChatSession.getQwExtId().toString());
|
|
|
|
+ fastGptChatMsgAi.setCompanyUserId(qwUser.getCompanyUserId());
|
|
|
|
+ fastGptChatMsgAi.setUserType(1);
|
|
|
|
+ fastGptChatMsgAi.setMsgType(1);
|
|
|
|
+ fastGptChatMsgAi.setStatus(0);
|
|
|
|
+ fastGptChatMsgAi.setAvatar(fastGptChatSession.getAvatar());
|
|
|
|
+ fastGptChatMsgAi.setNickName(fastGptChatSession.getNickName());
|
|
|
|
+ fastGptChatMsgAi.setCreateTime(new Date());
|
|
|
|
+ fastGptChatMsgAi.setPromptTokens(result.getUsage().prompt_tokens);
|
|
|
|
+ fastGptChatMsgAi.setCompletionTokens(result.getUsage().completion_tokens);
|
|
|
|
+ List<ChatDetailTStreamFResult.ResponseNode> responseData = result.getResponseData();
|
|
|
|
+ int token=0;
|
|
|
|
+ for (ChatDetailTStreamFResult.ResponseNode responseDatum : responseData) {
|
|
|
|
+ int tokens = responseDatum.getTokens();
|
|
|
|
+ token+=tokens;
|
|
|
|
+ }
|
|
|
|
+ fastGptChatMsgAi.setTotalTokens(token);
|
|
|
|
+ fastGptChatMsgService.insertFastGptChatMsg(fastGptChatMsgAi);
|
|
|
|
+ addUserInfo(result.getChoices().get(0).getMessage().getContent(), fastGptChatSession.getQwExtId(),fastGptChatSession);
|
|
|
|
+ addUserInfo(content, fastGptChatSession.getQwExtId(),fastGptChatSession);
|
|
|
|
+ sendTaskUrlLink(content,fastGptChatSession.getUserId(),qwUser,fastGptChatSession);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ FastGptChatSession ss = new FastGptChatSession();
|
|
|
|
+ ss.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ ss.setRemindStatus(0);
|
|
|
|
+ ss.setRemindCount(0);
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(ss);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ /** Ai回复 **/
|
|
|
|
+ @Async
|
|
|
|
+ @Override
|
|
|
|
+ public R qwHookNotifyAiReply(Long qwUserId, Long sender,String qwContent,String uid,Integer type) {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (qwContent.contains("我已经添加了你")){
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ QwUser user = qwUserMapper.selectQwUserById(qwUserId);
|
|
|
|
+ //查询接收人
|
|
|
|
+ if(user==null){
|
|
|
|
+ System.out.println("查询接收人为空");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ if(user.getFastGptRoleId()==null){
|
|
|
|
+ System.out.println("未绑定角色");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ Long serverId = user.getServerId();
|
|
|
|
+ System.out.println("服务器id"+serverId);
|
|
|
|
+ if (serverId == null) {
|
|
|
|
+ System.out.println("服务id为空");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ FastGptRole role=roleService.selectFastGptRoleTypeByRoleId(user.getFastGptRoleId());
|
|
|
|
+ //没用ai角色跳过
|
|
|
|
+ if(role==null){
|
|
|
|
+ System.out.println("没用ai角色跳过");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ String modeConfig=role.getModeConfigJson();
|
|
|
|
+ //key不为空
|
|
|
|
+ if(StringUtils.isEmpty(modeConfig)){
|
|
|
|
+ System.out.println("没有aiKey");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ ModeConfig config=JSONUtil.toBean(modeConfig,ModeConfig.class);
|
|
|
|
+ if(StringUtils.isEmpty(config.getAPPKey())){
|
|
|
|
+ System.out.println("没有aiKey");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
|
|
|
|
+ wxWorkVid2UserIdDTO.setUser_id(Arrays.asList(sender));
|
|
|
|
+ wxWorkVid2UserIdDTO.setUuid(uid);
|
|
|
|
+ WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.Vid2UserId(wxWorkVid2UserIdDTO,serverId);
|
|
|
|
+ List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
|
|
|
|
+ if (data==null|| data.isEmpty()){
|
|
|
|
+
|
|
|
|
+ System.out.println("未获取到extId"+wxWorkVid2UserIdDTO);
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);
|
|
|
|
+
|
|
|
|
+ QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(dto.getOpenid(), user.getCorpId(),user.getQwUserId());
|
|
|
|
+ if (qwExternalContacts==null){
|
|
|
|
+ System.out.println("没有外部联系人");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ if(qwExternalContacts.getType()!=null&&qwExternalContacts.getType()==1){
|
|
|
|
+ FastGptChatSession fastGptChatSession= getFastGptSession(qwExternalContacts,user);
|
|
|
|
+ String contentEmj = replaceWxEmo(qwContent);
|
|
|
|
+ if(!contentEmj.isEmpty()){
|
|
|
|
+ addSaveAiMsg(1,1,contentEmj,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
|
|
|
|
+ }
|
|
|
|
+ //判断是否转人工
|
|
|
|
+ if (fastGptChatSession.getIsArtificial()==1){
|
|
|
|
+ System.out.println("转人工了");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ if (contentEmj.isEmpty()){
|
|
|
|
+ contentEmj ="用户发送表情:"+qwContent;
|
|
|
|
+ }
|
|
|
|
+ //获取是用户是否发送消息
|
|
|
|
+ Integer reply = redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
|
|
|
|
+ Integer replyI=1;
|
|
|
|
+ //用户正在发送消息 不发
|
|
|
|
+ if (reply!=null&&reply!=0){
|
|
|
|
+ //更新用户发送消息次数
|
|
|
|
+ redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),reply+1,5, TimeUnit.MINUTES);
|
|
|
|
+ //获取用户之前发送的消息
|
|
|
|
+ String msg = redisCache.getCacheObject("msg:" + fastGptChatSession.getSessionId());
|
|
|
|
+ if (!msg.isEmpty()){
|
|
|
|
+ //更新用户发送消息内容
|
|
|
|
+ redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),msg+","+contentEmj,5,TimeUnit.MINUTES);
|
|
|
|
+ }
|
|
|
|
+ //本次跳过
|
|
|
|
+ System.out.println("正在对话");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ //用户首次发送消息
|
|
|
|
+ redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),1,5,TimeUnit.MINUTES);
|
|
|
|
+ redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),contentEmj,5,TimeUnit.MINUTES);
|
|
|
|
+ System.out.println("等待");
|
|
|
|
+ R r= sendAiMsg(replyI,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts);
|
|
|
|
+ System.out.println(r);
|
|
|
|
+ //完成对话 删除消息记录
|
|
|
|
+ redisCache.deleteObject("reply:" + fastGptChatSession.getSessionId());
|
|
|
|
+ redisCache.deleteObject("msg:" + fastGptChatSession.getSessionId());
|
|
|
|
+ if(!r.get("code").equals(200)){
|
|
|
|
+ log.info("ai报错转人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
|
|
|
|
+ notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai报错转人工",qwExternalContacts.getId());
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ ChatDetailTStreamFResult result=(ChatDetailTStreamFResult)r.get("data");
|
|
|
|
+ //是否转人工
|
|
|
|
+ if(result.getChoices().isEmpty()){
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ String contentKh = result.getChoices().get(0).getMessage().getContent();
|
|
|
|
+ String content = replace(result.getChoices().get(0).getMessage().getContent()).trim();
|
|
|
|
+ //计算token
|
|
|
|
+ List<ChatDetailTStreamFResult.ResponseNode> responseData = result.getResponseData();
|
|
|
|
+ int token=0;
|
|
|
|
+ for (ChatDetailTStreamFResult.ResponseNode responseDatum : responseData) {
|
|
|
|
+ int tokens = responseDatum.getTokens();
|
|
|
|
+ token+=tokens;
|
|
|
|
+ }
|
|
|
|
+ //存聊天记录
|
|
|
|
+ addSaveAiMsg(2,2,contentKh,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),result.getUsage().prompt_tokens,result.getUsage().completion_tokens,token);
|
|
|
|
+ if (!content.isEmpty()){
|
|
|
|
+ addSaveAiMsg(1,2,content,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
|
|
|
|
+ //从fastgpt_chat_artificial_words表中查询所有转人工文本
|
|
|
|
+ List<FastgptChatArtificialWords> chatArtificialWords = qwExternalContactMapper.selectChatGptChatArtificialWords();
|
|
|
|
+ List<String> collect = chatArtificialWords.stream().map(m -> m.getContent()).collect(Collectors.toList());
|
|
|
|
+ if (collect.stream().allMatch(contentKh::contains)){
|
|
|
|
+ notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 触发关键词",qwExternalContacts.getId());
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ if (result.isLongText()){
|
|
|
|
+ //新增用户信息
|
|
|
|
+ addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
|
|
|
|
+ if (type==16){
|
|
|
|
+ sendAiVoiceMsg(content,sender,uid,serverId,user);
|
|
|
|
+ }else {
|
|
|
|
+ sendAiMsg(content,sender,uid,serverId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }else {
|
|
|
|
+ String sa = contentKh.replaceAll("】\n", "】").replaceAll("\n【", "【");
|
|
|
|
+ String nr = replace(sa);
|
|
|
|
+ String[] split = nr.split("\n");
|
|
|
|
+ if (split.length>6){
|
|
|
|
+ notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName(),"回复长度异常",qwExternalContacts.getId());
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ List<String> countList = countString(content);
|
|
|
|
+ //新增用户信息
|
|
|
|
+ addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
|
|
|
|
+ for (String msg : countList) {
|
|
|
|
+ if (type==16){
|
|
|
|
+ sendAiVoiceMsg(msg,sender,uid,serverId,user);
|
|
|
|
+ }else {
|
|
|
|
+ sendAiMsg(msg,sender,uid,serverId);
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ Thread.sleep(15000);
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ Integer replyH = redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
|
|
|
|
+ //用户正在发送消息 后面的消息不发了
|
|
|
|
+ if (replyH!=null&&replyH!=0){
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //发送短链
|
|
|
|
+
|
|
|
|
+ if (result.isArtificial()){
|
|
|
|
+ notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai请求人工协助",qwExternalContacts.getId());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void sendAiVoiceMsg(String content, Long sendId , String uuid,Long serverId,QwUser user) {
|
|
|
|
+ if (content == null || content.trim().isEmpty()){
|
|
|
|
+ System.out.println("输出为空格");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ content = voiceHomo(content);
|
|
|
|
+ System.out.println("过滤后的文字:"+content);
|
|
|
|
+ if (content.isEmpty()){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WxwSilkVoceDTO silkVoice = wxWorkService.getSilkVoice(content, user.getCompanyUserId());
|
|
|
|
+ if (silkVoice == null){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (silkVoice.getCode()!=200){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ WxwSilkVoceDTO.Data data = silkVoice.getData();
|
|
|
|
+ WxwUploadCdnLinkFileDTO wxwUploadCdnLinkFileDTO = new WxwUploadCdnLinkFileDTO();
|
|
|
|
+ wxwUploadCdnLinkFileDTO.setUrl(data.getUrl());
|
|
|
|
+ wxwUploadCdnLinkFileDTO.setFilename(data.getUrl());
|
|
|
|
+ wxwUploadCdnLinkFileDTO.setUuid(uuid);
|
|
|
|
+ WxWorkResponseDTO<WxwUploadCdnLinkFileRespDTO> dto = wxWorkService.uploadCdnLinkFile(wxwUploadCdnLinkFileDTO, serverId);
|
|
|
|
+ WxwUploadCdnLinkFileRespDTO voice = dto.getData();
|
|
|
|
+ WxwSendCDNVoiceMsgDTO wxwSendCDNVoiceMsgDTO = new WxwSendCDNVoiceMsgDTO();
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setSend_userid(sendId);
|
|
|
|
+ System.out.println("语音size"+voice.getSize());
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setVoice_time(data.getDuration());
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setIsRoom(false);
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setCdnkey(voice.getCdn_key());
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setAeskey(voice.getAes_key());
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setMd5(voice.getMd5());
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setFileSize(voice.getSize());
|
|
|
|
+ wxwSendCDNVoiceMsgDTO.setUuid(uuid);
|
|
|
|
+ WxWorkResponseDTO<WxwSendCDNVoiceMsgRespDTO> wxwSendCDNVoiceMsgRespDTOWxWorkResponseDTO = wxWorkService.SendCDNVoiceMsg(wxwSendCDNVoiceMsgDTO, serverId);
|
|
|
|
+ System.out.println(wxwSendCDNVoiceMsgRespDTOWxWorkResponseDTO);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ QwSopLogsMapper qwSopLogsMapper;
|
|
|
|
+ private void sendAiMsg(String content, Long sendId , String uuid,Long serverId) {
|
|
|
|
+ if (content == null || content.trim().isEmpty()){
|
|
|
|
+ System.out.println("输出为空格");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ WxWorkSendTextMsgDTO wxWorkSendTextMsgDTO = new WxWorkSendTextMsgDTO();
|
|
|
|
+ wxWorkSendTextMsgDTO.setSend_userid(sendId);
|
|
|
|
+ wxWorkSendTextMsgDTO.setUuid(uuid);
|
|
|
|
+ wxWorkSendTextMsgDTO.setContent(content);
|
|
|
|
+ wxWorkSendTextMsgDTO.setIsRoom(false);
|
|
|
|
+ WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> wxWorkSendTextMsgRespDTOWxWorkResponseDTO = wxWorkService.SendTextMsg(wxWorkSendTextMsgDTO,serverId);
|
|
|
|
+ WxWorkSendTextMsgRespDTO data = wxWorkSendTextMsgRespDTOWxWorkResponseDTO.getData();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /** 回调转人工 **/
|
|
|
|
+ private void notifyArtificial(Long sessionId, QwUser user, String name,String reason,Long extId) {
|
|
|
|
+ FastGptChatSession s = new FastGptChatSession();
|
|
|
|
+ s.setIsArtificial(1);
|
|
|
|
+ s.setRemindStatus(0);
|
|
|
|
+ s.setIsReply(0);
|
|
|
|
+ s.setSessionId(sessionId);
|
|
|
|
+ s.setLastTime(new Date());
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(s);
|
|
|
|
+ log.info("转人工:"+name);
|
|
|
|
+ QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(user.getCorpId());
|
|
|
|
+ sendQwAppMsg(user.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),"您的客户:"+name+"因"+reason+" 需要转人工,请及时回复");
|
|
|
|
+ sendQwAppMsg(user.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),name);
|
|
|
|
+ qwWorkTaskService.addQwWorkByAiNotifyArtificial(user,extId,"Ai转人工");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void sendQwAppMsg(String corpId, Integer agentId,String qwUserId,String content){
|
|
|
|
+ QwSendMsgParam qwSendMsgParam = new QwSendMsgParam();
|
|
|
|
+ qwSendMsgParam.setAgentid(agentId);
|
|
|
|
+ qwSendMsgParam.setTouser(qwUserId);
|
|
|
|
+ QwSendMsgParam.Text text = new QwSendMsgParam.Text();
|
|
|
|
+ text.setContent(content);
|
|
|
|
+ qwSendMsgParam.setText(text);
|
|
|
|
+ qwSendMsgParam.setMsgtype("text");
|
|
|
|
+ qwApiService.sendMsg(qwSendMsgParam, corpId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private void saveQwUserMsg(FastGptChatSession fastGptChatSession,Integer sendType,String content) {
|
|
|
|
+ content = replaceWxEmo(content);
|
|
|
|
+ if(content.isEmpty()){
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ FastGptChatMsg fastGptChatMsgAi = new FastGptChatMsg();
|
|
|
|
+ fastGptChatMsgAi.setContent(content);
|
|
|
|
+ fastGptChatMsgAi.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ fastGptChatMsgAi.setRoleId(Long.parseLong(fastGptChatSession.getKfId()));
|
|
|
|
+ fastGptChatMsgAi.setSendType(sendType);
|
|
|
|
+ fastGptChatMsgAi.setCompanyId(fastGptChatSession.getCompanyId());
|
|
|
|
+ fastGptChatMsgAi.setUserId(fastGptChatSession.getUserId());
|
|
|
|
+ fastGptChatMsgAi.setUserType(1);
|
|
|
|
+ fastGptChatMsgAi.setMsgType(1);
|
|
|
|
+ fastGptChatMsgAi.setStatus(0);
|
|
|
|
+ fastGptChatMsgAi.setAvatar(fastGptChatSession.getAvatar());
|
|
|
|
+ fastGptChatMsgAi.setNickName(fastGptChatSession.getNickName());
|
|
|
|
+ fastGptChatMsgAi.setCreateTime(new Date());
|
|
|
|
+ fastGptChatMsgAi.setExtId(fastGptChatSession.getQwExtId()+"");
|
|
|
|
+ fastGptChatMsgService.insertFastGptChatMsg(fastGptChatMsgAi);
|
|
|
|
+ log.info("新增消息:"+fastGptChatMsgAi);
|
|
|
|
+ }
|
|
|
|
+ /** 存聊天记录 **/
|
|
|
|
+ private void addSaveAiMsg(Integer msgType,Integer sendType,String content, QwUser user, Long sessionId, Long roleId, QwExternalContact qwExternalContacts, String userId, Integer promptTokens, Integer completionTokens, Integer token) {
|
|
|
|
+
|
|
|
|
+ FastGptChatMsg fastGptChatMsgAi = new FastGptChatMsg();
|
|
|
|
+ fastGptChatMsgAi.setContent(content);
|
|
|
|
+ fastGptChatMsgAi.setSessionId(sessionId);
|
|
|
|
+ fastGptChatMsgAi.setRoleId(roleId);
|
|
|
|
+ fastGptChatMsgAi.setSendType(sendType);
|
|
|
|
+ fastGptChatMsgAi.setCompanyId(user.getCompanyId());
|
|
|
|
+ fastGptChatMsgAi.setUserId(userId);
|
|
|
|
+ fastGptChatMsgAi.setCompanyUserId(user.getCompanyUserId());
|
|
|
|
+ fastGptChatMsgAi.setUserType(1);
|
|
|
|
+ fastGptChatMsgAi.setMsgType(msgType);
|
|
|
|
+ fastGptChatMsgAi.setStatus(0);
|
|
|
|
+ fastGptChatMsgAi.setAvatar(qwExternalContacts.getAvatar());
|
|
|
|
+ fastGptChatMsgAi.setNickName(qwExternalContacts.getName());
|
|
|
|
+ fastGptChatMsgAi.setCreateTime(new Date());
|
|
|
|
+ fastGptChatMsgAi.setExtId(qwExternalContacts.getId()+"");
|
|
|
|
+ fastGptChatMsgAi.setPromptTokens(promptTokens);
|
|
|
|
+ fastGptChatMsgAi.setCompletionTokens(completionTokens);
|
|
|
|
+ fastGptChatMsgAi.setTotalTokens(token);
|
|
|
|
+ fastGptChatMsgService.insertFastGptChatMsg(fastGptChatMsgAi);
|
|
|
|
+ }
|
|
|
|
+ /** 获取会话 **/
|
|
|
|
+ private FastGptChatSession getFastGptSession(QwExternalContact qwExternalContacts, QwUser user) {
|
|
|
|
+ FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(qwExternalContacts.getId(), user.getId());
|
|
|
|
+ if (fastGptChatSession==null){
|
|
|
|
+ fastGptChatSession = new FastGptChatSession();
|
|
|
|
+ String chatId = UUID.randomUUID().toString();
|
|
|
|
+ fastGptChatSession.setChatId(chatId);
|
|
|
|
+ fastGptChatSession.setKfId(user.getFastGptRoleId().toString());
|
|
|
|
+ fastGptChatSession.setStatus(1);
|
|
|
|
+ fastGptChatSession.setRemindCount(0);
|
|
|
|
+ fastGptChatSession.setRemindStatus(0);
|
|
|
|
+ fastGptChatSession.setCreateTime(new Date());
|
|
|
|
+ fastGptChatSession.setQwExtId(qwExternalContacts.getId());
|
|
|
|
+ fastGptChatSession.setQwUserId(user.getId());
|
|
|
|
+ fastGptChatSession.setIsArtificial(0);
|
|
|
|
+ fastGptChatSession.setAvatar(qwExternalContacts.getAvatar());
|
|
|
|
+ fastGptChatSession.setNickName(qwExternalContacts.getName());
|
|
|
|
+ fastGptChatSession.setCompanyId(user.getCompanyId());
|
|
|
|
+ fastGptChatSession.setLastTime(new Date());
|
|
|
|
+ fastGptChatSession.setIsReply(0);
|
|
|
|
+ fastGptChatSessionMapper.insertFastGptChatSession(fastGptChatSession);
|
|
|
|
+ addUserSex(qwExternalContacts);
|
|
|
|
+ }else {
|
|
|
|
+ if (fastGptChatSession.getRemindStatus()==1){
|
|
|
|
+ FastGptChatSession ss = new FastGptChatSession();
|
|
|
|
+ ss.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ ss.setRemindStatus(0);
|
|
|
|
+ ss.setIsReply(0);
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(ss);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return fastGptChatSession;
|
|
|
|
+ }
|
|
|
|
+ /** 特殊转人工 **/
|
|
|
|
+ @Override
|
|
|
|
+ public void artificial(QwHookVO vo) {
|
|
|
|
+ QwHookMsgVO msgVo= JSONUtil.toBean(vo.getData(),QwHookMsgVO.class);
|
|
|
|
+ if (msgVo.getIs_room()!=null&&msgVo.getIs_room()==0){
|
|
|
|
+ QwUser user=qwUserService.selectQwUserByAppKey(msgVo.getKey());
|
|
|
|
+ if(user!=null&&user.getFastGptRoleId()!=null) {
|
|
|
|
+ FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByUserIdAndKfId(msgVo.getSender(), user.getId());
|
|
|
|
+ if (fastGptChatSession!=null&&fastGptChatSession.getIsArtificial()!=1){
|
|
|
|
+ QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(msgVo.getSender_openid(), user.getCorpId(),user.getQwUserId());
|
|
|
|
+ if (qwExternalContacts!=null){
|
|
|
|
+ FastGptChatSession s = new FastGptChatSession();
|
|
|
|
+ s.setIsArtificial(1);
|
|
|
|
+ s.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(s);
|
|
|
|
+ QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(user.getCorpId());
|
|
|
|
+ qwSendAppMsg(qwCompany.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),"您的客户:"+qwExternalContacts.getName()+" 因发送图片或视频,需要转人工,请及时回复");
|
|
|
|
+ qwSendAppMsg(qwCompany.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),qwExternalContacts.getName());
|
|
|
|
+ if (fastGptChatSession.getRemindStatus()==1){
|
|
|
|
+ FastGptChatSession ss = new FastGptChatSession();
|
|
|
|
+ ss.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ ss.setRemindStatus(0);
|
|
|
|
+ ss.setIsReply(0);
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(ss);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void qwSendAppMsg(String corpId,Integer agentId, String qwUserId,String content){
|
|
|
|
+ QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(corpId);
|
|
|
|
+ QwSendMsgParam qwSendMsgParam2 = new QwSendMsgParam();
|
|
|
|
+ qwSendMsgParam2.setAgentid(agentId);
|
|
|
|
+ qwSendMsgParam2.setTouser(qwUserId);
|
|
|
|
+ QwSendMsgParam.Text text2 = new QwSendMsgParam.Text();
|
|
|
|
+ text2.setContent(content);
|
|
|
|
+ qwSendMsgParam2.setText(text2);
|
|
|
|
+ qwSendMsgParam2.setMsgtype("text");
|
|
|
|
+ qwApiService.sendMsg(qwSendMsgParam2, qwCompany.getCorpId());
|
|
|
|
+ }
|
|
|
|
+ /** 添加企微性别 **/
|
|
|
|
+ private void addUserSex(QwExternalContact qwExternalContacts) {
|
|
|
|
+
|
|
|
|
+ QwExternalContactInfo info = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(qwExternalContacts.getId());
|
|
|
|
+ if (qwExternalContacts.getGender()!=0){
|
|
|
|
+ if (info!=null){
|
|
|
|
+ info.setSex(qwExternalContacts.getGender()==1?"男":"女");
|
|
|
|
+ qwExternalContactInfoMapper.updateQwExternalContactInfo(info);
|
|
|
|
+
|
|
|
|
+ }else {
|
|
|
|
+ QwExternalContactInfo qwExternalContactInfo = new QwExternalContactInfo();
|
|
|
|
+ qwExternalContactInfo.setExternalContactId(qwExternalContacts.getId());
|
|
|
|
+ qwExternalContactInfo.setSex(qwExternalContacts.getGender()==1?"男":"女");
|
|
|
|
+ qwExternalContactInfo.setCreateTime(new Date());
|
|
|
|
+ qwExternalContactInfoMapper.insertQwExternalContactInfo(qwExternalContactInfo);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ /** Ai发送课程链接 **/
|
|
|
|
+ private void sendUrlLink(String content, QwHookMsgVO msgVo, QwUser user, QwSession session) {
|
|
|
|
+ if (content.contains("【发送课程:当天课程】")){
|
|
|
|
+ FsCourseWatchLogVO fsCourseWatchLogVO = watchLogMapper.selectFsCourseWatchLogByExtIdAndQwUserId(session.getQwExtId(), user.getId());
|
|
|
|
+ if (fsCourseWatchLogVO!=null){
|
|
|
|
+ FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
|
|
|
|
+ param.setVideoId(fsCourseWatchLogVO.getVideoId());
|
|
|
|
+ param.setQwUserId(String.valueOf(user.getId()));
|
|
|
|
+ param.setDays(1);
|
|
|
|
+ param.setCorpId(user.getCorpId());
|
|
|
|
+ param.setCourseId(fsCourseWatchLogVO.getCourseId());
|
|
|
|
+ param.setCompanyUserId(user.getCompanyUserId());
|
|
|
|
+ param.setCompanyId(user.getCompanyId());
|
|
|
|
+ param.setQwExternalId(Long.parseLong(session.getQwExtId()));
|
|
|
|
+ param.setSendTime(new Date());
|
|
|
|
+ R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
|
|
|
|
+ qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsCourseWatchLogVO.getVideoId()+""),
|
|
|
|
+ Integer.valueOf(fsCourseWatchLogVO.getCourseId()+""),
|
|
|
|
+ String.valueOf(user.getId()),
|
|
|
|
+ String.valueOf(user.getCompanyUserId()),
|
|
|
|
+ String.valueOf(user.getCompanyId()),
|
|
|
|
+ String.valueOf(session.getQwExtId()));
|
|
|
|
+ if (linkUrl != null && linkUrl.get("url") != null) {
|
|
|
|
+ String s = (String)linkUrl.get("url");
|
|
|
|
+ sendWebSocketMsg(s,msgVo,user,session);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (content.contains("【发送课程")){
|
|
|
|
+ Pattern c = Pattern.compile("【发送课程:(.*?)】", Pattern.DOTALL);
|
|
|
|
+ Matcher cMatcher = c.matcher(content);
|
|
|
|
+ while (cMatcher.find()) {
|
|
|
|
+ String trim = cMatcher.group(1).trim();
|
|
|
|
+ if(trim!=null&&!trim.equals("")){
|
|
|
|
+ FsUserCourseVideo fsUserCourseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoStringId(trim);
|
|
|
|
+ if (fsUserCourseVideo==null){
|
|
|
|
+ FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
|
|
|
|
+ param.setVideoId(fsUserCourseVideo.getVideoId());
|
|
|
|
+ param.setQwUserId(String.valueOf(user.getId()));
|
|
|
|
+ param.setDays(1);
|
|
|
|
+ param.setCorpId(user.getCorpId());
|
|
|
|
+ param.setCourseId(fsUserCourseVideo.getCourseId());
|
|
|
|
+ param.setCompanyUserId(user.getCompanyUserId());
|
|
|
|
+ param.setCompanyId(user.getCompanyId());
|
|
|
|
+ param.setQwExternalId(Long.parseLong(session.getQwExtId()));
|
|
|
|
+ param.setSendTime(new Date());
|
|
|
|
+ R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
|
|
|
|
+ qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsUserCourseVideo.getVideoId()+""),
|
|
|
|
+ Integer.valueOf(fsUserCourseVideo.getCourseId()+""),
|
|
|
|
+ String.valueOf(user.getId()),
|
|
|
|
+ String.valueOf(user.getCompanyUserId()),
|
|
|
|
+ String.valueOf(user.getCompanyId()),
|
|
|
|
+ String.valueOf(session.getQwExtId()));
|
|
|
|
+ if (linkUrl != null && linkUrl.get("url") != null) {
|
|
|
|
+ String s = (String)linkUrl.get("url");
|
|
|
|
+ sendWebSocketMsg(s,msgVo,user,session);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }else {
|
|
|
|
+ log.error("发送课程不存在:"+trim);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /** 发送Ai消息 **/
|
|
|
|
+ private R sendAiMsg(Integer i,FastGptChatSession fastGptChatSession, FastGptRole role,QwUser user,Long qwExternalContactsId,String appKey,QwExternalContact qwExternalContacts){
|
|
|
|
+ //等待5秒
|
|
|
|
+ try {
|
|
|
|
+ Thread.sleep(15000); // 5000 毫秒 = 5 秒
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ //获取现在的次数
|
|
|
|
+ Integer reply = (Integer)redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
|
|
|
|
+ if (reply!=i){
|
|
|
|
+ //次数变动 重新等待5秒
|
|
|
|
+ return sendAiMsg(reply,fastGptChatSession,role,user,qwExternalContactsId,appKey,qwExternalContacts);
|
|
|
|
+ }else {
|
|
|
|
+ System.out.println("开始ai回答");
|
|
|
|
+ ChatParam param=new ChatParam();
|
|
|
|
+ param.setChatId(fastGptChatSession.getChatId());
|
|
|
|
+ param.setStream(false);
|
|
|
|
+ param.setDetail(true);
|
|
|
|
+ ChatParam.Variables variables=new ChatParam.Variables();
|
|
|
|
+ variables.setUid(user.getFastGptRoleId().toString());
|
|
|
|
+ variables.setName("test");
|
|
|
|
+ param.setVariables(variables);
|
|
|
|
+ List<ChatParam.Message> messageList=new ArrayList<ChatParam.Message>();
|
|
|
|
+ param.setMessages(messageList);
|
|
|
|
+ //添加看客记录
|
|
|
|
+ addCourseWatchLog(qwExternalContactsId);
|
|
|
|
+ String msgC = (String)redisCache.getCacheObject("msg:" + fastGptChatSession.getSessionId());
|
|
|
|
+ //添加关键词
|
|
|
|
+ addPromptWord(messageList,msgC,qwExternalContactsId,role.getReminderWords(), role.getContactInfo(),fastGptChatSession.getSessionId());
|
|
|
|
+ R r = chatService.initiatingTakeChat(param,"http://154.8.194.176:3000/api",appKey);
|
|
|
|
+ Integer reply2 = (Integer)redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
|
|
|
|
+ //次数变动 重新等待5秒
|
|
|
|
+ if (reply2!=i){
|
|
|
|
+ System.out.println("等待");
|
|
|
|
+ return sendAiMsg(reply,fastGptChatSession,role,user,qwExternalContactsId,appKey,qwExternalContacts);
|
|
|
|
+ }
|
|
|
|
+ addSaveAiMsg(2,1,messageList.get(0).getContent(),user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
|
|
|
|
+ return r;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ /** 增加课程信息 **/
|
|
|
|
+ private void addCourseWatchLog(Long id) {
|
|
|
|
+ FsCourseWatchLogVO log = fsCourseWatchLogMapper.selectFsCourseWatchLogByExtId(id);
|
|
|
|
+ if (log!=null){
|
|
|
|
+ QwExternalContactInfo qwExternalContactInfo = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(id);
|
|
|
|
+ QwExternalContactInfo info = new QwExternalContactInfo();
|
|
|
|
+// Date dateToCheck = log.getCreateTime(); // 假设这是你要检查的日期
|
|
|
|
+// Date today = new Date(); // 获取当前日期
|
|
|
|
+ // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 格式化日期
|
|
|
|
+ String name = log.getCourseName() + log.getTitle();
|
|
|
|
+ name = name.replaceAll("[【】]", "");
|
|
|
|
+// if (sdf.format(dateToCheck).equals(sdf.format(today))) {
|
|
|
|
+ info.setStudy(name);
|
|
|
|
+ info.setCourseStatus(log.getLogType()==3?"待看课":log.getLogType()==1?"已完课":log.getLogType()==2?"已完课":"看课中断");
|
|
|
|
+
|
|
|
|
+// }else {
|
|
|
|
+// info.setStudy(name);
|
|
|
|
+// info.setCourseStatus("待看课");
|
|
|
|
+//
|
|
|
|
+//
|
|
|
|
+// }
|
|
|
|
+ if(qwExternalContactInfo!=null){
|
|
|
|
+ info.setId(qwExternalContactInfo.getId());
|
|
|
|
+ qwExternalContactInfoMapper.updateQwExternalContactInfo(info);
|
|
|
|
+ }else {
|
|
|
|
+ info.setExternalContactId(id);
|
|
|
|
+ info.setCreateTime(new Date());
|
|
|
|
+ qwExternalContactInfoMapper.insertQwExternalContactInfo(info);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /** 组装发送AI内容 **/
|
|
|
|
+ private void addPromptWord(List<ChatParam.Message> messageList,String count,Long extId,String words,String countInfo,Long sessionId){
|
|
|
|
+
|
|
|
|
+ String str="";
|
|
|
|
+ List<FastGptChatMsg> msgs=fastGptChatMsgService.selectFastGptChatMsgByMsgSessionId(sessionId);
|
|
|
|
+ if (!msgs.isEmpty()){
|
|
|
|
+ Collections.reverse(msgs);
|
|
|
|
+ str="【历史聊天内容:\n";
|
|
|
|
+ for (FastGptChatMsg msg : msgs) {
|
|
|
|
+ Integer sendType = msg.getSendType();
|
|
|
|
+ String content = msg.getContent();
|
|
|
|
+ if(sendType!=1){
|
|
|
|
+ if (content!=null&&content.length()>150){
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ str +=(sendType==1?"用户:":"AI:")+content+"\n";
|
|
|
|
+ }
|
|
|
|
+ str+="】\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 这里获取后台的提示词进行匹配
|
|
|
|
+ QwExternalContactInfo info = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(extId);
|
|
|
|
+ if(info==null){
|
|
|
|
+ info=new QwExternalContactInfo();
|
|
|
|
+ }
|
|
|
|
+ if (info!=null){
|
|
|
|
+ str+="【用户状态信息\n";
|
|
|
|
+ Field[] fields = info.getClass().getDeclaredFields();
|
|
|
|
+ for (Field field : fields) {
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
+ Excel annotation = field.getAnnotation(Excel.class);
|
|
|
|
+ if (annotation != null) {
|
|
|
|
+ String name = field.getName();
|
|
|
|
+ String fieldName = annotation.name();
|
|
|
|
+ String[] split = countInfo.split(",");
|
|
|
|
+ for (String zName : split) {
|
|
|
|
+ if (zName.equals(name)) {
|
|
|
|
+ Object value = null;
|
|
|
|
+ try {
|
|
|
|
+ value = field.get(info);
|
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
|
+ }
|
|
|
|
+ if (value != null) {
|
|
|
|
+ str += fieldName + ": " + value.toString() + "\n";
|
|
|
|
+ }else {
|
|
|
|
+ str += fieldName + ": \n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ str+="】\n";
|
|
|
|
+ if (words!=null&&!"".equals(words)){
|
|
|
|
+ str+="【你的角色信息:以下内容为你的信息状态的补充而非用户信息,相当于放在角色任务里面,问到了需要知晓,但是如果无关的时候请无视此段内容 "+"\""+words+"\""+"】\n";
|
|
|
|
+ }
|
|
|
|
+ if (count!=null&&!"".equals(count)){
|
|
|
|
+ str+="【用户说的话内容(之前的内容仅仅为背景,你知道即可,以下才是用户真实说的话的内容)\n" +
|
|
|
|
+ "\""+count+"\""+"\n" +
|
|
|
|
+ "】";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ ChatParam.Message message1=new ChatParam.Message();
|
|
|
|
+ message1.setRole("user");
|
|
|
|
+ message1.setContent(str);
|
|
|
|
+ messageList.add(message1);
|
|
|
|
+ }
|
|
|
|
+ /** 组装表情 **/
|
|
|
|
+ public static List<String> countString(String input) {
|
|
|
|
+
|
|
|
|
+ List<String> stringList = new ArrayList<>();
|
|
|
|
+ // 所有的回车都分段发送
|
|
|
|
+ String[] split = input.split("\n");
|
|
|
|
+ for (String s : split) {
|
|
|
|
+ List<String> sList = subCount(s);
|
|
|
|
+ stringList.addAll(sList);
|
|
|
|
+ }
|
|
|
|
+// if (isEmoji){
|
|
|
|
+// Random random = new Random();
|
|
|
|
+// String[] emojiMorning = new String[] {
|
|
|
|
+// "😊", // 微笑
|
|
|
|
+// "☀️", // 太阳
|
|
|
|
+// "🌹", // 玫瑰
|
|
|
|
+// "☕️", // 茶杯
|
|
|
|
+// "💪", // 强壮
|
|
|
|
+// "❤️" // 爱心
|
|
|
|
+// };
|
|
|
|
+// String[] emojiEvening = new String[] {
|
|
|
|
+// "😊", // 微笑
|
|
|
|
+// "🌟", // 星星
|
|
|
|
+// "🌹", // 玫瑰
|
|
|
|
+// "☕️", // 茶杯
|
|
|
|
+// "💪", // 强壮
|
|
|
|
+// "❤️" // 爱心
|
|
|
|
+// };
|
|
|
|
+// List<String> sebdList = new ArrayList<>();
|
|
|
|
+// for (String segment : stringList) {
|
|
|
|
+// if(!segment.trim().equals("")){
|
|
|
|
+// LocalTime currentTime = LocalTime.now();
|
|
|
|
+// LocalTime startTime = LocalTime.of(5, 0);
|
|
|
|
+// LocalTime endTime = LocalTime.of(18, 0);
|
|
|
|
+// int sj = random.nextInt(2);
|
|
|
|
+// // 判断当前时间是否在5点到18点之间
|
|
|
|
+// String emj="";
|
|
|
|
+// if (sj==0){
|
|
|
|
+// if (currentTime.isAfter(startTime) && currentTime.isBefore(endTime)) {
|
|
|
|
+// int i = random.nextInt(1);
|
|
|
|
+// emj=emojiMorning[random.nextInt(emojiMorning.length-1)];
|
|
|
|
+// } else {
|
|
|
|
+// emj=emojiEvening[random.nextInt(emojiEvening.length-1)];
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// sebdList.add(segment+emj) ;
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// }
|
|
|
|
+// return sebdList;
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ return stringList;
|
|
|
|
+ }
|
|
|
|
+ /** 内容分段 **/
|
|
|
|
+ static List<String> subCount(String s){
|
|
|
|
+ ArrayList<String> a = new ArrayList<>();
|
|
|
|
+ if (s.length()>30){
|
|
|
|
+ String substring = s.substring(30);
|
|
|
|
+ Pattern pattern = Pattern.compile("([~。!?]+)");
|
|
|
|
+ String[] segments = pattern.split(substring);
|
|
|
|
+ Matcher matcher = pattern.matcher(substring);
|
|
|
|
+ if (matcher.find()&&segments.length>1) {
|
|
|
|
+ int dh=0;
|
|
|
|
+ String group = matcher.group();
|
|
|
|
+ if (group.equals("。")){
|
|
|
|
+ group="";
|
|
|
|
+ dh=1;
|
|
|
|
+ }
|
|
|
|
+ String s1 = s.substring(0, 30) + segments[0] + group;
|
|
|
|
+ a.addAll(Arrays.asList(s1));
|
|
|
|
+ if (s.substring(s1.length())!=null&&!s.substring(s1.length()+dh).equals("")){
|
|
|
|
+ List<String> add = subCount(s.substring(s1.length()+dh));
|
|
|
|
+ a.addAll(add);
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ a.add(s);
|
|
|
|
+ return a;
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ a.add(s);
|
|
|
|
+ }
|
|
|
|
+ return a;
|
|
|
|
+ }
|
|
|
|
+ /** 增加用户信息以及打标签 **/
|
|
|
|
+ private void addUserInfo(String word,Long extId,FastGptChatSession fastGptChatSession) {
|
|
|
|
+ Pattern pattern = Pattern.compile("【用户状态信息(.*?)】", Pattern.DOTALL);
|
|
|
|
+ Matcher matcher = pattern.matcher(word);
|
|
|
|
+
|
|
|
|
+ while (matcher.find()) {
|
|
|
|
+ QwExternalContactInfo info = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(extId);
|
|
|
|
+ String trim = matcher.group(1).trim();
|
|
|
|
+ String[] zd = trim.split("\n");
|
|
|
|
+ boolean b=false;
|
|
|
|
+
|
|
|
|
+ if (info==null){
|
|
|
|
+ info=new QwExternalContactInfo();
|
|
|
|
+ b=true;
|
|
|
|
+ }
|
|
|
|
+ Field[] fields = info.getClass().getDeclaredFields();
|
|
|
|
+ for (Field field : fields) {
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
+ Excel annotation = field.getAnnotation(Excel.class);
|
|
|
|
+ if (annotation != null) {
|
|
|
|
+ //中文名称
|
|
|
|
+ String fieldName = annotation.name();
|
|
|
|
+ String valueName ="";
|
|
|
|
+ Object value = null;
|
|
|
|
+ try {
|
|
|
|
+ value = field.get(info);
|
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
|
+ }
|
|
|
|
+ if (value != null) {
|
|
|
|
+ valueName= value.toString();
|
|
|
|
+ }
|
|
|
|
+ for (String s : zd) {
|
|
|
|
+ String[] zdName=null;
|
|
|
|
+ if (s.contains(":")){
|
|
|
|
+ zdName = s.split(":");
|
|
|
|
+ }
|
|
|
|
+ if (s.contains(":")){
|
|
|
|
+ zdName = s.split(":");
|
|
|
|
+ }
|
|
|
|
+ if (zdName!=null&&zdName.length==2){
|
|
|
|
+ String name1 = zdName[0];
|
|
|
|
+ String name2 = zdName[1];
|
|
|
|
+ if (name1.trim().equals(fieldName)){
|
|
|
|
+ String name2Trim = name2.trim();
|
|
|
|
+ if (!name2Trim.isEmpty()){
|
|
|
|
+ if(name1.equals("交流状态")){
|
|
|
|
+ if (name2Trim.equals("非首次交流")){
|
|
|
|
+ if (fastGptChatSession.getRemindStatus()!=null&&fastGptChatSession.getRemindStatus()==1){
|
|
|
|
+ FastGptChatSession s1 = new FastGptChatSession();
|
|
|
|
+ s1.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ s1.setRemindStatus(0);
|
|
|
|
+ s1.setRemindCount(0);
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(s1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!valueName.trim().equals(name2Trim)){
|
|
|
|
+ if(name1.equals("学习到的章节")||name1.equals("今日课程完成情况")){
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (name2Trim.contains("delete")&&name2Trim.contains(";")){
|
|
|
|
+ name2Trim = name2Trim.replaceAll("delete.*?;", "");
|
|
|
|
+ }else if (name2Trim.contains("delete")){
|
|
|
|
+ name2Trim=" ";
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ // 允许修改私有属性
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
+ // 修改 name 属性的值
|
|
|
|
+ field.set(info, name2Trim);
|
|
|
|
+ b=true;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ System.out.println("修改错误");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (b){
|
|
|
|
+ if (info.getId()!=null){
|
|
|
|
+ qwExternalContactInfoMapper.updateQwExternalContactInfo(info);
|
|
|
|
+ }else {
|
|
|
|
+ info.setExternalContactId(extId);
|
|
|
|
+ info.setCreateTime(new Date());
|
|
|
|
+ qwExternalContactInfoMapper.insertQwExternalContactInfo(info);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Pattern tag = Pattern.compile("【标签:(.*?)】", Pattern.DOTALL);
|
|
|
|
+ Matcher TagMatcher = tag.matcher(word);
|
|
|
|
+ while (TagMatcher.find()) {
|
|
|
|
+ String trimTag = TagMatcher.group(1).trim();
|
|
|
|
+ if(trimTag!=null&&!trimTag.equals("")){
|
|
|
|
+ qwTagGroupService.addQwTagByAi(trimTag,extId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Pattern delTag = Pattern.compile("【移除标签:(.*?)】", Pattern.DOTALL);
|
|
|
|
+ Matcher delTagMatcher = delTag.matcher(word);
|
|
|
|
+ while (delTagMatcher.find()) {
|
|
|
|
+ String deTag = delTagMatcher.group(1).trim();
|
|
|
|
+ if(deTag!=null&&!deTag.equals("")){
|
|
|
|
+ qwTagGroupService.delQwTagByAi(deTag,extId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Pattern addTime = Pattern.compile("【开始计时:(.*?)】", Pattern.DOTALL);
|
|
|
|
+ Matcher addTimeMather = addTime.matcher(word);
|
|
|
|
+ while (addTimeMather.find()) {
|
|
|
|
+ try {
|
|
|
|
+ String time = addTimeMather.group(1).trim();
|
|
|
|
+ int t = Integer.parseInt(time);
|
|
|
|
+ FastGptChatSession s1 = new FastGptChatSession();
|
|
|
|
+ s1.setSessionId(fastGptChatSession.getSessionId());
|
|
|
|
+ Calendar calendar = Calendar.getInstance(); // 获取当前时间
|
|
|
|
+ calendar.add(Calendar.MINUTE, t); // 增加t分钟
|
|
|
|
+ s1.setRemindTime(calendar.getTime());
|
|
|
|
+ s1.setRemindStatus(1);
|
|
|
|
+ s1.setRemindCount(0);
|
|
|
|
+ fastGptChatSessionMapper.updateFastGptChatSession(s1);
|
|
|
|
+
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ log.info("ai计时错误"+word);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /** 过滤[] **/
|
|
|
|
+ private static String replace(String s){
|
|
|
|
+
|
|
|
|
+ if(org.springframework.util.StringUtils.isEmpty(s)) return "";
|
|
|
|
+
|
|
|
|
+ String regex1 = "<llnnerThoughtBeginl>[\\s\\S]*?<lnnerThoughtEnd|>";
|
|
|
|
+ // 创建 Pattern 对象
|
|
|
|
+ Pattern pattern1 = Pattern.compile(regex1);
|
|
|
|
+ // 创建 Matcher 对象
|
|
|
|
+ Matcher matcher1 = pattern1.matcher(s);
|
|
|
|
+ s = matcher1.replaceAll("");
|
|
|
|
+
|
|
|
|
+ String regex = "【[\\s\\S]*?】";
|
|
|
|
+ // 创建 Pattern 对象
|
|
|
|
+ Pattern pattern = Pattern.compile(regex);
|
|
|
|
+ // 创建 Matcher 对象
|
|
|
|
+ Matcher matcher = pattern.matcher(s);
|
|
|
|
+ // 替换匹配到的内容
|
|
|
|
+ return matcher.replaceAll("");
|
|
|
|
+ }
|
|
|
|
+ /** 过滤[] **/
|
|
|
|
+ private static String replaceWxEmo(String s){
|
|
|
|
+
|
|
|
|
+ if(org.springframework.util.StringUtils.isEmpty(s)) return "";
|
|
|
|
+ // 替换匹配到的内容
|
|
|
|
+ return s.replaceAll("\\[.*?]", "").trim();
|
|
|
|
+ }
|
|
|
|
+ /** 发送语音过滤 */
|
|
|
|
+ private String voiceHomo(String content){
|
|
|
|
+ List<FastgptChatVoiceHomo> homos = fastgptChatVoiceHomoMapper.selectFastgptChatVoiceHomoList(new FastgptChatVoiceHomo());
|
|
|
|
+ for (FastgptChatVoiceHomo homo : homos) {
|
|
|
|
+ if (content.contains(homo.getContent())) {
|
|
|
|
+ // 如果包含目标字段,则替换
|
|
|
|
+ content= content.replace(homo.getContent(), homo.getChangeCount());
|
|
|
|
+ } else {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ content = content.replaceAll("[a-zA-Z]", "")
|
|
|
|
+ .replaceAll("\\s", "");
|
|
|
|
+ return content;
|
|
|
|
+ }
|
|
|
|
+ /** 替换违禁词 **/
|
|
|
|
+ private String replaceWords(String content){
|
|
|
|
+ List<FastGptChatReplaceWords> words = fastGptChatReplaceWordsMapper.selectAllFastGptChatReplaceWords();
|
|
|
|
+ for (FastGptChatReplaceWords word : words) {
|
|
|
|
+ if (content.contains(word.getContent())) {
|
|
|
|
+ // 如果包含目标字段,则替换
|
|
|
|
+ content= content.replace(word.getContent(), word.getChangeCount());
|
|
|
|
+ } else {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return content;
|
|
|
|
+ }
|
|
|
|
+ /** 发送语音回复 */
|
|
|
|
+ private static AudioVO getSilk(String count,Long userId) {
|
|
|
|
+ AudioServiceImpl audioService = new AudioServiceImpl();
|
|
|
|
+ AudioVO Silk = audioService.TextToVoice(count,userId);
|
|
|
|
+ return Silk;
|
|
|
|
+ }
|
|
|
|
+ /** 发送普通消息 */
|
|
|
|
+ private void sendWebSocketMsg(String count, QwHookMsgVO msgVo, QwUser user,QwSession session) {
|
|
|
|
+ //发送socket
|
|
|
|
+ if (count!=null&& !count.trim().isEmpty()){
|
|
|
|
+ qwMsgService.addAiMsg(session,count,1,user);
|
|
|
|
+ QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
|
|
|
|
+ QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
|
|
|
|
+ sendMsgParam.setType(101003);
|
|
|
|
+ sendMsgData.setMsg(replaceWords(count));
|
|
|
|
+ sendMsgData.setSendId(msgVo.getSender());
|
|
|
|
+ sendMsgData.setSyncKey("1");
|
|
|
|
+ sendMsgParam.setData(sendMsgData);
|
|
|
|
+ SendAIParam sendAIParam = new SendAIParam();
|
|
|
|
+ sendAIParam.setCmd("aiReplyMsg");
|
|
|
|
+ sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
|
|
|
|
+ sendAIParam.setKey(user.getAppKey());
|
|
|
|
+ redisTemplate.opsForList().leftPush("AiMsg:"+user.getAppKey(), JSON.toJSONString(sendAIParam));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /** 发送定时任务课程链接 */
|
|
|
|
+ private void sendTaskUrlLink(String content, String sendId, QwUser user, FastGptChatSession session) {
|
|
|
|
+ if (content.contains("【发送课程:当天课程】")){
|
|
|
|
+ FsCourseWatchLogVO fsCourseWatchLogVO = watchLogMapper.selectFsCourseWatchLogByExtIdAndQwUserId(session.getQwExtId().toString(), user.getId());
|
|
|
|
+ if (fsCourseWatchLogVO!=null){
|
|
|
|
+ FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
|
|
|
|
+ param.setVideoId(fsCourseWatchLogVO.getVideoId());
|
|
|
|
+ param.setQwUserId(String.valueOf(user.getId()));
|
|
|
|
+ param.setDays(1);
|
|
|
|
+ param.setCorpId(user.getCorpId());
|
|
|
|
+ param.setCourseId(fsCourseWatchLogVO.getCourseId());
|
|
|
|
+ param.setCompanyUserId(user.getCompanyUserId());
|
|
|
|
+ param.setCompanyId(user.getCompanyId());
|
|
|
|
+ param.setQwExternalId(session.getQwExtId());
|
|
|
|
+ param.setSendTime(new Date());
|
|
|
|
+ R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
|
|
|
|
+ qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsCourseWatchLogVO.getVideoId()+""),
|
|
|
|
+ Integer.valueOf(fsCourseWatchLogVO.getCourseId()+""),
|
|
|
|
+ String.valueOf(user.getId()),
|
|
|
|
+ String.valueOf(user.getCompanyUserId()),
|
|
|
|
+ String.valueOf(user.getCompanyId()),
|
|
|
|
+ String.valueOf(session.getQwExtId()));
|
|
|
|
+ if (linkUrl != null && linkUrl.get("url") != null) {
|
|
|
|
+ String s = (String)linkUrl.get("url");
|
|
|
|
+ sendWebTaskSocketMsg(s,sendId,user);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (content.contains("【发送课程")){
|
|
|
|
+ Pattern c = Pattern.compile("【发送课程:(.*?)】", Pattern.DOTALL);
|
|
|
|
+ Matcher cMatcher = c.matcher(content);
|
|
|
|
+ while (cMatcher.find()) {
|
|
|
|
+ String trim = cMatcher.group(1).trim();
|
|
|
|
+ if(trim!=null&&!trim.equals("")){
|
|
|
|
+ FsUserCourseVideo fsUserCourseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoStringId(trim);
|
|
|
|
+ System.out.println("课程:"+fsUserCourseVideo);
|
|
|
|
+ FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
|
|
|
|
+ param.setVideoId(fsUserCourseVideo.getVideoId());
|
|
|
|
+ param.setQwUserId(String.valueOf(user.getId()));
|
|
|
|
+ param.setDays(1);
|
|
|
|
+ param.setCorpId(user.getCorpId());
|
|
|
|
+ param.setCourseId(fsUserCourseVideo.getCourseId());
|
|
|
|
+ param.setCompanyUserId(user.getCompanyUserId());
|
|
|
|
+ param.setCompanyId(user.getCompanyId());
|
|
|
|
+ param.setQwExternalId(session.getQwExtId());
|
|
|
|
+ param.setSendTime(new Date());
|
|
|
|
+ R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
|
|
|
|
+ qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsUserCourseVideo.getVideoId()+""),
|
|
|
|
+ Integer.valueOf(fsUserCourseVideo.getCourseId()+""),
|
|
|
|
+ String.valueOf(user.getId()),
|
|
|
|
+ String.valueOf(user.getCompanyUserId()),
|
|
|
|
+ String.valueOf(user.getCompanyId()),
|
|
|
|
+ String.valueOf(session.getQwExtId()));
|
|
|
|
+ if (linkUrl != null && linkUrl.get("url") != null) {
|
|
|
|
+ String s = (String)linkUrl.get("url");
|
|
|
|
+ sendWebTaskSocketMsg(s,sendId,user);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ /** 发送定时任务消息 */
|
|
|
|
+ private void sendWebTaskSocketMsg(String count, String sendId, QwUser user) {
|
|
|
|
+ //发送socket
|
|
|
|
+ //文本消息
|
|
|
|
+ QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
|
|
|
|
+ QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
|
|
|
|
+ sendMsgParam.setType(101003);
|
|
|
|
+ sendMsgData.setMsg(count);
|
|
|
|
+ sendMsgData.setSendId(sendId);
|
|
|
|
+ sendMsgData.setSyncKey("1");
|
|
|
|
+ sendMsgParam.setData(sendMsgData);
|
|
|
|
+ SendAIParam sendAIParam = new SendAIParam();
|
|
|
|
+ sendAIParam.setCmd("aiReplyMsg");
|
|
|
|
+ sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
|
|
|
|
+ sendAIParam.setKey(user.getAppKey());
|
|
|
|
+ redisTemplate.opsForList().leftPush("AiMsg:"+user.getAppKey(), JSON.toJSONString(sendAIParam));
|
|
|
|
+ }
|
|
|
|
+ @Override
|
|
|
|
+ public R qwHookNotifyAddMsg(Long qwUserID, Long sender,String count,String uid) {
|
|
|
|
+ QwUser sendUser = qwUserMapper.selectQwUserById(qwUserID);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (sendUser!=null){
|
|
|
|
+
|
|
|
|
+ String extId = getExtId(sender, uid, sendUser.getServerId());
|
|
|
|
+ QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(extId, sendUser.getCorpId(),sendUser.getQwUserId());
|
|
|
|
+ if (qwExternalContacts==null){
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(qwExternalContacts.getId(), sendUser.getId());
|
|
|
|
+ if (fastGptChatSession!=null){
|
|
|
|
+ saveQwUserMsg(fastGptChatSession,2,count);
|
|
|
|
+ }else {
|
|
|
|
+
|
|
|
|
+ if(qwExternalContacts.getType()!=null&&qwExternalContacts.getType()==1){
|
|
|
|
+ if(sendUser.getFastGptRoleId()!=null){
|
|
|
|
+ fastGptChatSession = new FastGptChatSession();
|
|
|
|
+ String chatId = UUID.randomUUID().toString();
|
|
|
|
+ fastGptChatSession.setChatId(chatId);
|
|
|
|
+ fastGptChatSession.setKfId(sendUser.getFastGptRoleId().toString());
|
|
|
|
+ fastGptChatSession.setStatus(1);
|
|
|
|
+ fastGptChatSession.setRemindCount(0);
|
|
|
|
+ fastGptChatSession.setRemindStatus(0);
|
|
|
|
+ fastGptChatSession.setCreateTime(new Date());
|
|
|
|
+ fastGptChatSession.setQwExtId(qwExternalContacts.getId());
|
|
|
|
+ fastGptChatSession.setQwUserId(sendUser.getId());
|
|
|
|
+ fastGptChatSession.setIsArtificial(0);
|
|
|
|
+ fastGptChatSession.setAvatar(qwExternalContacts.getAvatar());
|
|
|
|
+ fastGptChatSession.setNickName(qwExternalContacts.getName());
|
|
|
|
+ fastGptChatSession.setCompanyId(sendUser.getCompanyId());
|
|
|
|
+ fastGptChatSession.setLastTime(new Date());
|
|
|
|
+ fastGptChatSession.setIsReply(0);
|
|
|
|
+ fastGptChatSessionMapper.insertFastGptChatSession(fastGptChatSession);
|
|
|
|
+ addUserSex(qwExternalContacts);
|
|
|
|
+ saveQwUserMsg(fastGptChatSession,2,count);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void expireAiMsg() {
|
|
|
|
+ List<QwSopLogs> qwSopLogs = qwSopLogsMapper.selectExpireAiMsg();
|
|
|
|
+ if (qwSopLogs==null|| qwSopLogs.isEmpty()){
|
|
|
|
+ System.out.println("无");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ qwSopLogsMapper.batchUpdateQwSopLogsById(qwSopLogs);
|
|
|
|
+ List<QwSopLogs> distinctList = new ArrayList<>(qwSopLogs.stream()
|
|
|
|
+ .collect(Collectors.toMap(
|
|
|
|
+ QwSopLogs::getExternalId, // 以 extId 作为 Key
|
|
|
|
+ log -> log, // Value 是对象本身
|
|
|
|
+ (existing, replacement) -> existing // 遇到重复时保留已有值(第一个)
|
|
|
|
+ ))
|
|
|
|
+ .values());
|
|
|
|
+ for (QwSopLogs logs : distinctList) {
|
|
|
|
+ log.info("转人工:"+logs.getCorpId());
|
|
|
|
+ QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(logs.getCorpId());
|
|
|
|
+ sendQwAppMsg(logs.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),logs.getQwUserid(),"您的客户:"+logs.getExternalUserName()+"因 AI回复内容过期转人工,请及时登录插件确定定位配置准确");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 保存企微聊天信息
|
|
|
|
+ * @param qwUserId 企微用户ID
|
|
|
|
+ * @param userId 用户ID
|
|
|
|
+ * @param content 聊天内容
|
|
|
|
+ * @param uuid UUID
|
|
|
|
+ * @param sendType 发送者类型 1用户 2客服
|
|
|
|
+ */
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
+ @Override
|
|
|
|
+ public void saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType) {
|
|
|
|
+ // 查询企微用户
|
|
|
|
+ QwUser qwUser = qwUserService.selectQwUserById(qwUserId);
|
|
|
|
+ if (Objects.isNull(qwUser)){
|
|
|
|
+ log.warn("企微用户不存在 qwUserId: {}", qwUserId);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询外部联系人
|
|
|
|
+ QwExternalContact qwExternalContact = getExternalContact(userId, uuid, qwUser.getServerId(), qwUser.getCorpId(), qwUser.getQwUserId());
|
|
|
|
+ if (Objects.isNull(qwExternalContact)){
|
|
|
|
+ log.warn("外部联系人不存在 userId: {}, uuid: {}, serverId: {}, corpId: {}, qwUserId: {}", userId, uuid, qwUser.getServerId(), qwUser.getCorpId(), qwUser.getQwUserId());
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询会话
|
|
|
|
+ QwSession qwSession = qwSessionMapper.selectQwSessionByExtIdAndQwUserId(qwExternalContact.getId(), qwUser.getId());
|
|
|
|
+ if (qwSession == null) {
|
|
|
|
+ qwSession = new QwSession();
|
|
|
|
+ String chatId = UUID.randomUUID().toString();
|
|
|
|
+ qwSession.setChatId(chatId);
|
|
|
|
+ qwSession.setCorpId(qwUser.getCorpId());
|
|
|
|
+ qwSession.setQwExtWxId(String.valueOf(userId));
|
|
|
|
+ qwSession.setQwExtId(qwExternalContact.getId().toString());
|
|
|
|
+ qwSession.setQwUserId(qwUser.getId().toString());
|
|
|
|
+ qwSession.setStatus(1);
|
|
|
|
+ qwSession.setAvatar(qwExternalContact.getAvatar());
|
|
|
|
+ qwSession.setNickName(qwExternalContact.getRemark());
|
|
|
|
+ qwSession.setCompanyId(qwUser.getCompanyId());
|
|
|
|
+ qwSession.setCompanyUserId(qwUser.getCompanyUserId());
|
|
|
|
+ qwSession.setCreateTime(new Date());
|
|
|
|
+ qwSession.setUpdateTime(new Date());
|
|
|
|
+ qwSessionMapper.insertQwSession(qwSession);
|
|
|
|
+ }else {
|
|
|
|
+ qwSession.setUpdateTime(new Date());
|
|
|
|
+ qwSession.setNickName(qwExternalContact.getRemark());
|
|
|
|
+ qwSessionMapper.updateQwSession(qwSession);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 保存聊天消息
|
|
|
|
+ QwMsg qwMsg = new QwMsg();
|
|
|
|
+ qwMsg.setContent(content);
|
|
|
|
+ qwMsg.setSessionId(qwSession.getSessionId());
|
|
|
|
+ qwMsg.setSendType(sendType);
|
|
|
|
+ qwMsg.setCompanyId(qwUser.getCompanyId());
|
|
|
|
+ qwMsg.setCompanyUserId(qwUser.getCompanyUserId());
|
|
|
|
+ qwMsg.setMsgType(1);
|
|
|
|
+ qwMsg.setStatus(0);
|
|
|
|
+ qwMsg.setQwUserId(qwSession.getQwUserId());
|
|
|
|
+ qwMsg.setQwExtId(qwSession.getQwExtId());
|
|
|
|
+ qwMsg.setAvatar(qwExternalContact.getAvatar());
|
|
|
|
+ qwMsg.setNickName(qwExternalContact.getRemark());
|
|
|
|
+ qwMsg.setCreateTime(new Date());
|
|
|
|
+ qwMsgMapper.insertQwMsg(qwMsg);
|
|
|
|
+ log.debug("保存企微聊天记录 msgId: {}", qwMsg.getMsgId());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询外部联系人
|
|
|
|
+ * @param userId 用户ID
|
|
|
|
+ * @param uuid UUID
|
|
|
|
+ * @param serverId 服务ID
|
|
|
|
+ * @param corpId 企微ID
|
|
|
|
+ * @param qwUserId 企微用户ID
|
|
|
|
+ * @return QwExternalContact
|
|
|
|
+ */
|
|
|
|
+ private QwExternalContact getExternalContact(Long userId, String uuid, Long serverId, String corpId, String qwUserId) {
|
|
|
|
+ return qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(getExtId(userId, uuid, serverId), corpId, qwUserId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String getExtId(Long id,String uid,Long serverId){
|
|
|
|
+ WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
|
|
|
|
+ wxWorkVid2UserIdDTO.setUser_id(Arrays.asList(id));
|
|
|
|
+ wxWorkVid2UserIdDTO.setUuid(uid);
|
|
|
|
+ WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.Vid2UserId(wxWorkVid2UserIdDTO,serverId);
|
|
|
|
+ List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
|
|
|
|
+ if (data==null&& data.isEmpty()){
|
|
|
|
+ System.out.println("未获取到extId");
|
|
|
|
+ return "";
|
|
|
|
+ }
|
|
|
|
+ com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);
|
|
|
|
+ return dto.getOpenid();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|