Przeglądaj źródła

补充缺少的接口

15376779826 5 dni temu
rodzic
commit
a33fd8d767

+ 59 - 0
fs-service/src/main/java/com/fs/aiChat/domain/InterestAiChatMsg.java

@@ -0,0 +1,59 @@
+package com.fs.aiChat.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+@Data
+public class InterestAiChatMsg extends BaseEntity {
+    /** $column.columnComment */
+    private Long msgId;
+
+    /** 消息id */
+    @Excel(name = "消息id")
+    private Long sessionId;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private String userId;
+
+    /** 消息内容 */
+    @Excel(name = "消息内容")
+    private String content;
+
+    /** 发送类型 1用户发送 2ai发送 */
+    @Excel(name = "发送类型 1用户发送 2ai发送")
+    private Integer sendType;
+
+    /** 角色ID */
+    @Excel(name = "角色ID")
+    private Long roleId;
+
+    /** 角色名称 */
+    @Excel(name = "角色名称")
+    private String roleName;
+
+    /** 昵称 */
+    @Excel(name = "昵称")
+    private String nickName;
+
+    /** 头像 */
+    @Excel(name = "头像")
+    private String avatar;
+
+    /** 用户输入的令牌数量 */
+    @Excel(name = "用户输入的令牌数量")
+    private Long promptTokens;
+
+    /** 生成的回复中使用的令牌 */
+    @Excel(name = "生成的回复中使用的令牌")
+    private Long completionTokens;
+
+    /** 总令牌数量 */
+    @Excel(name = "总令牌数量")
+    private Long totalTokens;
+
+    /** 角色头像 */
+    @Excel(name = "角色头像")
+    private String roleAvatar;
+}

+ 73 - 0
fs-service/src/main/java/com/fs/aiChat/domain/InterestAiSession.java

@@ -0,0 +1,73 @@
+package com.fs.aiChat.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class InterestAiSession extends BaseEntity {
+
+
+    /** 会话ID */
+    private Long sessionId;
+
+    /** 会话标识 */
+    @Excel(name = "会话标识")
+    private String chatId;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 客服ID */
+    @Excel(name = "客服ID")
+    private Long roleId;
+
+    /** 客服名称 */
+    @Excel(name = "客服名称")
+    private String roleName;
+
+    /** 状态 1会话中 2已结束 */
+    @Excel(name = "状态 1会话中 2已结束")
+    private Integer status;
+
+    /** 客户昵称 */
+    @Excel(name = "客户昵称")
+    private String nickName;
+
+    /** 头像 */
+    @Excel(name = "头像")
+    private String avatar;
+
+    /**
+     * 当前会话最后一条消息记录
+     */
+    @Excel(name = "最后一条消息记录")
+    private String lastContent;
+
+    /**
+     * 角色头像
+     */
+    @Excel(name = "角色头像")
+    private String roleAvatar;
+
+    /**
+     * 标签
+     */
+    @Excel(name = "标签")
+    private String roleTag;
+
+    @Excel(name = "欢迎语")
+    private String welcomeMessage;
+
+    @Excel(name = "文本说明")
+    private String textDescription;
+
+    @Excel(name = "最后回复时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date lastCreateTime;
+
+}

+ 54 - 0
fs-service/src/main/java/com/fs/aiChat/domain/SessionRoleInfo.java

@@ -0,0 +1,54 @@
+package com.fs.aiChat.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+@Data
+public class SessionRoleInfo extends BaseEntity {
+
+    /** ID */
+    private Long roleId;
+
+    /** 角色名称 */
+    @Excel(name = "角色名称")
+    private String roleName;
+
+    /** 标签 */
+    @Excel(name = "标签")
+    private String roleTag;
+
+    /** 模型key */
+    @Excel(name = "模型key")
+    private String appKey;
+
+    /** 客服头像 */
+    @Excel(name = "客服头像")
+    private String avatar;
+
+    /** 欢迎语 */
+    @Excel(name = "欢迎语")
+    private String welcomeMessage;
+
+    @Excel(name = "封面图片")
+    private String imageUrl;
+
+    @Excel(name = "文本描述")
+    private String textDescription;
+
+    /** 提示词列表 */
+    @Excel(name = "提示词列表")
+    private String wordList;
+
+    @Excel(name = "标题")
+    private String title;
+
+    @Excel(name = "是否推荐")
+    private int isRecommend;
+
+    @Excel(name = "推荐图")
+    private String recommendImgUrl;
+
+    @Excel(name = "会话ID")
+    private Long sessionId;
+}

+ 59 - 0
fs-service/src/main/java/com/fs/aiChat/mapper/InterestAiChatSessionMapper.java

@@ -0,0 +1,59 @@
+package com.fs.aiChat.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.aiChat.domain.DoctorAiChatLog;
+import com.fs.aiChat.domain.InterestAiChatMsg;
+import com.fs.aiChat.domain.InterestAiSession;
+import com.fs.aiChat.domain.SessionRoleInfo;
+import com.fs.his.domain.FsInterestAiMsg;
+import com.fs.his.domain.FsInterestAiRole;
+import com.fs.his.domain.FsInterestAiSession;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+
+public interface InterestAiChatSessionMapper extends BaseMapper<DoctorAiChatLog> {
+
+    /**
+     * 查询用户对话列表
+     * @param userId
+     * @return
+     */
+    List<InterestAiSession> getSessionListByUserId(Long userId);
+
+    /**
+     * 根据roleid获取会话角色信息
+     * @param roleId
+     * @return
+     */
+    SessionRoleInfo getSessionRoleInfoByRoleId(Long roleId);
+
+    /**
+     * 获取聊天记录
+     * @param sessionId
+     * @return
+     */
+    List<InterestAiChatMsg> getSessionChatList(String sessionId);
+
+    /**
+     * 获取会话
+     * @param roleId
+     * @param userId
+     * @return
+     */
+    @Select("  select session_id,chat_id,user_id,role_id,role_name, status, nick_name,avatar,create_time,update_time\n" +
+            "            from fs_interest_ai_session where role_id = #{roleId} and user_id = #{userId} limit 1")
+    FsInterestAiSession getInterestAiSessionByRoleIdAndUserId(@Param(value =  "roleId")Long roleId,@Param(value = "userId") Long userId);
+
+
+    int insertFsInterestAiSession(FsInterestAiSession fsInterestAiSession);
+
+    int insertFsInterestAiMsg(FsInterestAiMsg fsInterestAiMsg);
+
+    List<SessionRoleInfo> getRecommendRoleList(String userId);
+
+
+    FsInterestAiRole selectFsInterestAiRoleByRoleId(Long roleId);
+}

+ 15 - 0
fs-service/src/main/java/com/fs/aiChat/param/InterestAiMessage.java

@@ -0,0 +1,15 @@
+package com.fs.aiChat.param;
+
+import lombok.Data;
+
+@Data
+public class InterestAiMessage {
+    Long userId;
+    String nickName;
+    String avatar;
+    Long roleId;
+    String roleName;
+    String message;
+    Long sessionId;
+//    Integer isWelcome;
+}

+ 71 - 0
fs-service/src/main/java/com/fs/his/domain/FsInterestAiMsg.java

@@ -0,0 +1,71 @@
+package com.fs.his.domain;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 兴趣聊天记录对象 fs_interest_ai_msg
+ *
+ * @author fs
+ * @date 2025-05-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsInterestAiMsg extends BaseEntity {
+
+    /** $column.columnComment */
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long msgId;
+
+    /** 消息id */
+    @Excel(name = "会话id")
+    private Long sessionId;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private String userId;
+
+    /** 消息内容 */
+    @Excel(name = "消息内容")
+    private String content;
+
+    /** 发送类型 1用户发送 2ai发送 */
+    @Excel(name = "发送类型 1用户发送 2ai发送")
+    private Integer sendType;
+
+    /** 角色ID */
+    @Excel(name = "角色ID")
+    private Long roleId;
+
+    /** 角色名称 */
+    @Excel(name = "角色名称")
+    private String roleName;
+
+    /** 昵称 */
+    @Excel(name = "昵称")
+    private String nickName;
+
+    /** 头像 */
+    @Excel(name = "头像")
+    private String avatar;
+
+    /** 用户输入的令牌数量 */
+    @Excel(name = "用户输入的令牌数量")
+    private Long promptTokens;
+
+    /** 生成的回复中使用的令牌 */
+    @Excel(name = "生成的回复中使用的令牌")
+    private Long completionTokens;
+
+    /** 总令牌数量 */
+    @Excel(name = "总令牌数量")
+    private Long totalTokens;
+
+    private String msgIdStr;
+
+
+}

+ 56 - 0
fs-service/src/main/java/com/fs/his/domain/FsInterestAiRole.java

@@ -0,0 +1,56 @@
+package com.fs.his.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 兴趣ai角色对象 fs_interest_ai_role
+ *
+ * @author fs
+ * @date 2025-05-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsInterestAiRole extends BaseEntity{
+
+    /** ID */
+    private Long roleId;
+
+    /** 角色名称 */
+    @Excel(name = "角色名称")
+    private String roleName;
+
+    /** 标签 */
+    @Excel(name = "标签")
+    private String roleTag;
+
+    /** 模型key */
+    @Excel(name = "模型key")
+    private String appKey;
+
+    /** 客服头像 */
+    @Excel(name = "客服头像")
+    private String avatar;
+
+    /** 欢迎语 */
+    @Excel(name = "欢迎语")
+    private String welcomeMessage;
+
+    @Excel(name = "封面图片")
+    private String imageUrl;
+
+    @Excel(name = "文本描述")
+    private String textDescription;
+
+    @Excel(name = "标题")
+    private String title;
+
+    @Excel(name = "是否推荐")
+    private int isRecommend;
+
+    @Excel(name = "推荐图")
+    private String recommendImgUrl;
+
+}

+ 50 - 0
fs-service/src/main/java/com/fs/his/domain/FsInterestAiSession.java

@@ -0,0 +1,50 @@
+package com.fs.his.domain;
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 兴趣对话关系对象 fs_interest_ai_session
+ *
+ * @author fs
+ * @date 2025-05-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsInterestAiSession extends BaseEntity{
+
+    /** 会话ID */
+    private Long sessionId;
+
+    /** 会话标识 */
+    @Excel(name = "会话标识")
+    private String chatId;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 客服ID */
+    @Excel(name = "客服ID")
+    private Long roleId;
+
+    /** 客服名称 */
+    @Excel(name = "客服名称")
+    private String roleName;
+
+    /** 状态 1会话中 2已结束 */
+    @Excel(name = "状态 1会话中 2已结束")
+    private Integer status;
+
+    /** 客户昵称 */
+    @Excel(name = "客户昵称")
+    private String nickName;
+
+    /** 头像 */
+    @Excel(name = "头像")
+    private String avatar;
+
+
+}

+ 69 - 0
fs-service/src/main/java/com/fs/his/mapper/FsInterestAiSessionMapper.java

@@ -0,0 +1,69 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsInterestAiMsg;
+import com.fs.his.domain.FsInterestAiSession;
+
+import java.util.List;
+
+/**
+ * 兴趣对话关系Mapper接口
+ *
+ * @author fs
+ * @date 2025-05-09
+ */
+public interface FsInterestAiSessionMapper extends BaseMapper<FsInterestAiSession>{
+    /**
+     * 查询兴趣对话关系
+     *
+     * @param sessionId 兴趣对话关系主键
+     * @return 兴趣对话关系
+     */
+    FsInterestAiSession selectFsInterestAiSessionBySessionId(Long sessionId);
+
+    /**
+     * 查询聊天记录list
+     * @param sessionId
+     * @return
+     */
+    List<FsInterestAiMsg> selectFsInterestAiMsgList(Long sessionId);
+    /**
+     * 查询兴趣对话关系列表
+     *
+     * @param fsInterestAiSession 兴趣对话关系
+     * @return 兴趣对话关系集合
+     */
+    List<FsInterestAiSession> selectFsInterestAiSessionList(FsInterestAiSession fsInterestAiSession);
+
+    /**
+     * 新增兴趣对话关系
+     *
+     * @param fsInterestAiSession 兴趣对话关系
+     * @return 结果
+     */
+    int insertFsInterestAiSession(FsInterestAiSession fsInterestAiSession);
+
+    /**
+     * 修改兴趣对话关系
+     *
+     * @param fsInterestAiSession 兴趣对话关系
+     * @return 结果
+     */
+    int updateFsInterestAiSession(FsInterestAiSession fsInterestAiSession);
+
+    /**
+     * 删除兴趣对话关系
+     *
+     * @param sessionId 兴趣对话关系主键
+     * @return 结果
+     */
+    int deleteFsInterestAiSessionBySessionId(Long sessionId);
+
+    /**
+     * 批量删除兴趣对话关系
+     *
+     * @param sessionIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsInterestAiSessionBySessionIds(Long[] sessionIds);
+}

+ 48 - 0
fs-service/src/main/java/com/fs/his/service/IHisInterestAiChatSessionService.java

@@ -0,0 +1,48 @@
+package com.fs.his.service;
+
+import com.fs.aiChat.domain.InterestAiChatMsg;
+import com.fs.aiChat.domain.InterestAiSession;
+import com.fs.aiChat.domain.SessionRoleInfo;
+import com.fs.aiChat.param.InterestAiMessage;
+import com.fs.his.domain.FsInterestAiSession;
+
+import java.util.List;
+
+public interface IHisInterestAiChatSessionService {
+
+    /**
+     * 根据当前用户获取用户的会话列表
+     * @param session
+     * @return
+     */
+    List<InterestAiSession> getAllRolesListByUserId(InterestAiSession session);
+
+    /**
+     * 根据角色id获取会话角色信息
+     * @param roleId
+     * @return
+     */
+    SessionRoleInfo getSessionRoleInfoByRoleId(Long roleId);
+
+    /**
+     * 根据会话id获取会话聊天记录
+     * @param sessionId
+     * @return
+     */
+    List<InterestAiChatMsg> getSessionChatList(String sessionId);
+
+    /**
+     * 创建会话
+     * @param fsInterestAiSession
+     * @return
+     */
+    FsInterestAiSession createSession(FsInterestAiSession fsInterestAiSession);
+
+    String chatByUser(InterestAiMessage message);
+
+    /**
+     * 获取推荐角色列表
+     * @return
+     */
+    List<SessionRoleInfo> getRecommendRoleList(String userId);
+}

+ 240 - 0
fs-service/src/main/java/com/fs/his/service/impl/InterestAiChatSessionServiceImpl.java

@@ -0,0 +1,240 @@
+package com.fs.his.service.impl;
+
+import com.fs.aiChat.domain.InterestAiChatMsg;
+import com.fs.aiChat.domain.InterestAiSession;
+import com.fs.aiChat.domain.SessionRoleInfo;
+import com.fs.aiChat.mapper.InterestAiChatSessionMapper;
+import com.fs.aiChat.param.InterestAiMessage;
+import com.fs.common.core.domain.R;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.DateUtils;
+import com.fs.fastgptApi.param.ChatParam;
+import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
+import com.fs.fastgptApi.service.ChatService;
+import com.fs.his.domain.FsInterestAiMsg;
+import com.fs.his.domain.FsInterestAiRole;
+import com.fs.his.domain.FsInterestAiSession;
+import com.fs.his.mapper.FsInterestAiSessionMapper;
+import com.fs.his.service.IHisInterestAiChatSessionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Service
+public class InterestAiChatSessionServiceImpl implements IHisInterestAiChatSessionService {
+
+    @Autowired
+    FsInterestAiSessionMapper fsInterestAiSessionMapper;
+
+//    @Autowired
+//    FsInterestAiRoleMapper fsInterestAiRoleMapper;
+//
+//    @Autowired
+//    FsInterestAiRoleWordsMapper fsInterestAiRoleWordsMapper;
+
+    @Autowired
+    InterestAiChatSessionMapper interestAiChatSessionMapper;
+
+//    @Autowired
+//    FsInterestAiMsgMapper fsInterestAiMsgMapper;
+
+    @Autowired
+    private ChatService chatService;
+
+
+    /**
+     * 根据当前用户获取用户的会话列表
+     *
+     * @param session
+     * @return
+     */
+    @Override
+    public List<InterestAiSession> getAllRolesListByUserId(InterestAiSession session) {
+
+        Long userId = session.getUserId();
+
+        List<InterestAiSession> list = interestAiChatSessionMapper.getSessionListByUserId(userId);
+
+        return list;
+    }
+
+
+    /**
+     * 根据角色id获取会话角色信息
+     *
+     * @param roleId
+     * @return
+     */
+    @Override
+    public SessionRoleInfo getSessionRoleInfoByRoleId(Long roleId) {
+        SessionRoleInfo sessionRoleInfoByRoleId = interestAiChatSessionMapper.getSessionRoleInfoByRoleId(roleId);
+        return sessionRoleInfoByRoleId;
+    }
+
+    /**
+     * 根据会话id获取会话聊天记录
+     *
+     * @param sessionId
+     * @return
+     */
+    @Override
+    public List<InterestAiChatMsg> getSessionChatList(String sessionId) {
+        List<InterestAiChatMsg> list = interestAiChatSessionMapper.getSessionChatList(sessionId);
+        return list;
+    }
+
+    /**
+     * 创建会话
+     *
+     * @param fsInterestAiSession
+     * @return
+     */
+    @Override
+    public FsInterestAiSession createSession(FsInterestAiSession fsInterestAiSession) {
+        fsInterestAiSession.setCreateTime(DateUtils.getNowDate());
+        fsInterestAiSession.setStatus(1);
+        int sessionId = fsInterestAiSessionMapper.insertFsInterestAiSession(fsInterestAiSession);
+        return fsInterestAiSession;
+    }
+
+    /**
+     * 用户对话
+     *
+     * @param message
+     * @return
+     */
+    @Override
+    @Transactional
+    public String chatByUser(InterestAiMessage message) {
+        //判断message是否为空
+        if (message == null) {
+            return null;
+        }
+
+        if (null == message.getUserId()) {
+            throw new CustomException("用户id不能为空");
+        }
+
+        if (null == message.getRoleId()) {
+            throw new CustomException("角色id不能为空");
+        }
+
+        FsInterestAiSession session = interestAiChatSessionMapper.getInterestAiSessionByRoleIdAndUserId(message.getRoleId(), message.getUserId());
+        // 对话构建
+        if (null == session) {
+            FsInterestAiSession fsInterestAiSession = new FsInterestAiSession();
+            fsInterestAiSession.setCreateTime(DateUtils.getNowDate());
+            fsInterestAiSession.setStatus(1);
+            fsInterestAiSession.setRoleId(message.getRoleId());
+            fsInterestAiSession.setRoleName(message.getRoleName());
+            fsInterestAiSession.setUserId(message.getUserId());
+            fsInterestAiSession.setNickName(message.getNickName());
+            fsInterestAiSession.setAvatar(message.getAvatar());
+            fsInterestAiSession.setChatId(UUID.randomUUID().toString());
+            interestAiChatSessionMapper.insertFsInterestAiSession(fsInterestAiSession);
+            message.setSessionId(fsInterestAiSession.getSessionId());
+        } else {
+            message.setSessionId(session.getSessionId());
+        }
+
+        //写入聊天记录
+        FsInterestAiMsg fsInterestAiMsg = new FsInterestAiMsg();
+        fsInterestAiMsg.setSessionId(message.getSessionId());
+        fsInterestAiMsg.setUserId(message.getUserId().toString());
+        fsInterestAiMsg.setContent(message.getMessage());
+        fsInterestAiMsg.setSendType(1);
+        fsInterestAiMsg.setRoleId(message.getRoleId());
+        fsInterestAiMsg.setRoleName(message.getRoleName());
+        fsInterestAiMsg.setCreateTime(DateUtils.getNowDate());
+        fsInterestAiMsg.setNickName(message.getNickName());
+        fsInterestAiMsg.setAvatar(message.getAvatar());
+//        fsInterestAiMsgMapper.insertFsInterestAiMsg(fsInterestAiMsg);
+        interestAiChatSessionMapper.insertFsInterestAiMsg(fsInterestAiMsg);
+
+        String aiMsg = getAiMsg(fsInterestAiMsg);
+
+        FsInterestAiMsg aiReceiveMsg = new FsInterestAiMsg();
+        aiReceiveMsg.setSessionId(message.getSessionId());
+        aiReceiveMsg.setUserId(message.getUserId().toString());
+        aiReceiveMsg.setContent(aiMsg);
+        aiReceiveMsg.setSendType(2);
+        aiReceiveMsg.setRoleId(message.getRoleId());
+        aiReceiveMsg.setRoleName(message.getRoleName());
+        aiReceiveMsg.setCreateTime(DateUtils.getNowDate());
+        aiReceiveMsg.setNickName(message.getNickName());
+        aiReceiveMsg.setAvatar(message.getAvatar());
+        interestAiChatSessionMapper.insertFsInterestAiMsg(aiReceiveMsg);
+
+        return aiMsg;
+    }
+
+
+    private String getAiMsg(FsInterestAiMsg fsInterestAiMsg) {
+        ChatParam param = new ChatParam();
+        param.setChatId(fsInterestAiMsg.getSessionId().toString());
+        param.setStream(false);
+        param.setDetail(true);
+        ChatParam.Variables variables = new ChatParam.Variables();
+        Long roleId = fsInterestAiMsg.getRoleId();
+        FsInterestAiRole role = interestAiChatSessionMapper.selectFsInterestAiRoleByRoleId(roleId);
+        if (null == role) {
+            return "请联系管理员";
+        }
+        variables.setUid(roleId.toString());
+        variables.setName(role.getRoleName());
+        param.setVariables(variables);
+        List<ChatParam.Message> messageList = new ArrayList<ChatParam.Message>();
+        ChatParam.Message message1=new ChatParam.Message();
+        message1.setRole("user");
+        message1.setContent(fsInterestAiMsg.getContent());
+        messageList.add(message1);
+        param.setMessages(messageList);
+//        FastGptRole role = roleService.selectFastGptRoleByRoleId(doctor.getGptRoleId());
+        if (role == null) {
+            return "请联系配置Ai角色";
+        }
+        String appKey = role.getAppKey();
+//        if (modeConfig == null || modeConfig.equals("")) {
+//            return "请联系配置AiKey";
+//        }
+//        ModeConfig config = JSONUtil.toBean(modeConfig, ModeConfig.class);
+//        addAiDoctorPromptWord(messageList, fsInterestAiMsg.getContent(), role.getReminderWords());
+        R r = chatService.initiatingTakeChat(param, "http://154.8.194.176:3000/api", appKey);
+        if (r.get("code").equals(200)) {
+            ChatDetailTStreamFResult result = (ChatDetailTStreamFResult) r.get("data");
+            String count = replace(result.getChoices().get(0).getMessage().getContent()).trim();
+            return count;
+        } else {
+            return "请稍后再试";
+        }
+
+
+    }
+    private static String replace(String s){
+        if(org.springframework.util.StringUtils.isEmpty(s)) return "";
+        String regex = "【[\\s\\S]*?】";
+        // 创建 Pattern 对象
+        Pattern pattern = Pattern.compile(regex);
+        // 创建 Matcher 对象
+        Matcher matcher = pattern.matcher(s);
+        // 替换匹配到的内容
+        return matcher.replaceAll("");
+    }
+
+
+    /**
+     * 获取推荐角色列表
+     * @return
+     */
+    @Override
+    public List<SessionRoleInfo> getRecommendRoleList(String userId) {
+        List<SessionRoleInfo>  roleList =  interestAiChatSessionMapper.getRecommendRoleList(userId);
+        return roleList;
+    }
+}

+ 2 - 2
fs-service/src/main/resources/application-config-myhk.yml

@@ -48,8 +48,8 @@ wx:
         aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
   # 开放平台app微信授权配置
   open:
-    app-id: wxcb1e78baf03c0662
-    secret: d041d3e2392a68a3e86dc22d976ed4a0
+    app-id: wx1e53f3acc05273fd
+    secret: 07cb2091538e0a0e9c192625db99c145
 aifabu:  #爱链接
   appKey: 7b471be905ab17e00f3b858c6710dd117601d008
 watch:

+ 108 - 0
fs-service/src/main/resources/mapper/his/FsInterestAiSessionMapper.xml

@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsInterestAiSessionMapper">
+    
+    <resultMap type="FsInterestAiSession" id="FsInterestAiSessionResult">
+        <result property="sessionId"    column="session_id"    />
+        <result property="chatId"    column="chat_id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="roleId"    column="role_id"    />
+        <result property="roleName"    column="role_name"    />
+        <result property="status"    column="status"    />
+        <result property="nickName"    column="nick_name"    />
+        <result property="avatar"    column="avatar"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectFsInterestAiSessionVo">
+        select session_id, chat_id, user_id, role_id, role_name, status, nick_name, avatar, create_time, update_time from fs_interest_ai_session
+    </sql>
+
+    <select id="selectFsInterestAiSessionList" parameterType="FsInterestAiSession" resultMap="FsInterestAiSessionResult">
+        <include refid="selectFsInterestAiSessionVo"/>
+        <where>  
+            <if test="chatId != null  and chatId != ''"> and chat_id = #{chatId}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="roleId != null "> and role_id = #{roleId}</if>
+            <if test="roleName != null "> and role_name = #{roleName}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="nickName != null  and nickName != ''"> and nick_name like concat('%', #{nickName}, '%')</if>
+            <if test="avatar != null  and avatar != ''"> and avatar = #{avatar}</if>
+        </where>
+    </select>
+
+    
+    <select id="selectFsInterestAiSessionBySessionId" parameterType="Long" resultMap="FsInterestAiSessionResult">
+        <include refid="selectFsInterestAiSessionVo"/>
+        where session_id = #{sessionId}
+    </select>
+    <resultMap id="FsInterestAiMsgMap" type="FsInterestAiMsg">
+        <result property="sessionId"    column="session_id"    />
+        <result property="msgId"    column="msg_id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="sendType"    column="send_type"    />
+        <result property="roleId"    column="role_id"    />
+        <result property="roleName"    column="role_name"    />
+        <result property="nickName"    column="nick_name"    />
+        <result property="msgId"    column="msg_id"    />
+    </resultMap>
+    <select id="selectFsInterestAiMsgList" parameterType="Long" resultMap="FsInterestAiMsgMap">
+        select msg_id, session_id,user_id, content, send_type, role_id,role_name, create_time,nick_name from fs_interest_ai_msg where session_id = #{sessionId}
+    </select>
+        
+    <insert id="insertFsInterestAiSession" parameterType="FsInterestAiSession" useGeneratedKeys="true" keyProperty="sessionId">
+        insert into fs_interest_ai_session
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="chatId != null">chat_id,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="roleId != null">role_id,</if>
+            <if test="roleName != null">role_name,</if>
+            <if test="status != null">status,</if>
+            <if test="nickName != null">nick_name,</if>
+            <if test="avatar != null">avatar,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="chatId != null">#{chatId},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="roleId != null">#{roleId},</if>
+            <if test="roleName != null">#{roleName},</if>
+            <if test="status != null">#{status},</if>
+            <if test="nickName != null">#{nickName},</if>
+            <if test="avatar != null">#{avatar},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsInterestAiSession" parameterType="FsInterestAiSession">
+        update fs_interest_ai_session
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="chatId != null">chat_id = #{chatId},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="roleId != null">role_id = #{roleId},</if>
+            <if test="roleName != null">role_id = #{roleName},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="nickName != null">nick_name = #{nickName},</if>
+            <if test="avatar != null">avatar = #{avatar},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where session_id = #{sessionId}
+    </update>
+
+    <delete id="deleteFsInterestAiSessionBySessionId" parameterType="Long">
+        delete from fs_interest_ai_session where session_id = #{sessionId}
+    </delete>
+
+    <delete id="deleteFsInterestAiSessionBySessionIds" parameterType="String">
+        delete from fs_interest_ai_session where session_id in 
+        <foreach item="sessionId" collection="array" open="(" separator="," close=")">
+            #{sessionId}
+        </foreach>
+    </delete>
+</mapper>

+ 197 - 0
fs-service/src/main/resources/mapper/his/InterestAiChatSessionMapper.xml

@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.aiChat.mapper.InterestAiChatSessionMapper">
+
+    <resultMap type="InterestAiSession" id="getSessionListByUserIdResultMap">
+        <result property="sessionId"    column="session_id"    />
+        <result property="roleId"    column="role_id"    />
+        <result property="roleName"    column="role_name"    />
+        <result property="welcomeMessage"    column="welcome_message"    />
+        <result property="textDescription"    column="text_description"    />
+        <result property="lastCreateTime"    column="lastCreateTime"    />
+        <result property="lastContent"    column="lastContent"    />
+        <result property="roleAvatar"    column="roleAvatar"    />
+        <result property="roleTag"    column="role_tag"    />
+    </resultMap>
+
+    <select id="getSessionListByUserId" resultMap="getSessionListByUserIdResultMap">
+        select temp.role_id,
+               temp.role_name,
+               temp.role_tag,
+               temp.roleAvatar as roleAvatar,
+               temp.welcome_message,
+               temp.text_description,
+               temp.lastContent,
+               temp.lastCreateTime,
+               temp.session_id
+        from (select t1.role_id,
+                     t1.role_name,
+                     t1.role_tag,
+                     t1.avatar                                            as roleAvatar,
+                     t1.welcome_message,
+                     t1.text_description,
+                     (select content
+                      from (select ROW_NUMBER() over (PARTITION by session_id ORDER BY create_time desc) rowNum, content, session_id, create_time
+                            from fs_interest_ai_msg
+                            where session_id = t3.session_id
+                              and send_type = 2) temp
+                      where temp.rowNum = 1)                              as lastContent
+                      ,
+                     (select max(create_time)
+                      from fs_interest_ai_msg
+                      where session_id = t3.session_id and send_type = 2) as lastCreateTime,
+                     t3.session_id
+              from fs_interest_ai_role t1
+                       left join fs_interest_ai_session t3 on t3.role_id = t1.role_id and t3.user_id = #{userId} ) temp
+        order by temp.lastCreateTime desc
+    </select>
+
+    <resultMap type="SessionRoleInfo" id="getSessionRoleInfoBySessionIdResultMap" >
+        <result property="roleId"    column="role_id"    />
+        <result property="roleName"    column="role_name"    />
+        <result property="roleTag"    column="role_tag"    />
+        <result property="appKey"    column="app_key"    />
+        <result property="avatar"    column="avatar"    />
+        <result property="welcomeMessage"    column="welcome_message"    />
+        <result property="imageUrl"    column="image_url"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="textDescription"    column="text_description"    />
+        <result property="title"    column="title"    />
+        <result property="wordList"    column="wordList"    />
+        <result property="isRecommend"    column="is_recommend"    />
+        <result property="recommendImgUrl"    column="recommend_img_url"    />
+        <result property="sessionId"    column="session_id"    />
+
+    </resultMap>
+
+    <select id="getSessionRoleInfoByRoleId" resultMap="getSessionRoleInfoBySessionIdResultMap">
+        select t1.role_id,
+               t1.role_name,
+               t1.role_tag,
+               t1.app_key,
+               t1.avatar,
+               t1.welcome_message,
+               t1.image_url,
+               t1.create_time,
+               t1.update_time,
+               t1.text_description,
+               t1.title,
+               (select GROUP_CONCAT(t3.content order by t3.sort  SEPARATOR "||")  from  fs_interest_ai_role_words t3 where t3.role_id  = t1.role_id)  as wordList
+        from fs_interest_ai_role t1
+        where t1.role_id = #{roleId}
+    </select>
+
+    <select id="getRecommendRoleList" resultMap="getSessionRoleInfoBySessionIdResultMap">
+        select t1.role_id,
+               t1.role_name,
+               t1.is_recommend,
+               t1.recommend_img_url,
+               (select max(session_id) from fs_interest_ai_session t2 where t2.user_id = #{userId} and t2.role_id = t1.role_id) as session_id
+        from fs_interest_ai_role   t1
+        where t1.is_recommend = 1
+        order by t1.update_time desc,t1.create_time desc
+    </select>
+    <resultMap type="FsInterestAiRole" id="FsInterestAiRoleResult">
+        <result property="roleId"    column="role_id"    />
+        <result property="roleName"    column="role_name"    />
+        <result property="roleTag"    column="role_tag"    />
+        <result property="appKey"    column="app_key"    />
+        <result property="avatar"    column="avatar"    />
+        <result property="welcomeMessage"    column="welcome_message"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+        <result property="imageUrl"    column="image_url"    />
+        <result property="textDescription"    column="text_description"    />
+        <result property="title"    column="title"    />
+        <result property="isRecommend"    column="is_recommend"    />
+        <result property="recommendImgUrl"    column="recommend_img_url"    />
+    </resultMap>
+
+    <sql id="selectFsInterestAiRoleVo">
+        select role_id, role_name, role_tag, app_key, avatar, welcome_message, create_time, update_time, image_url,text_description,title,is_recommend,recommend_img_url from fs_interest_ai_role
+    </sql>
+
+    <select id="selectFsInterestAiRoleByRoleId" parameterType="Long" resultMap="FsInterestAiRoleResult">
+        <include refid="selectFsInterestAiRoleVo"/>
+        where role_id = #{roleId}
+    </select>
+
+    <select id="getSessionChatList" resultType="InterestAiChatMsg">
+        select t1.msg_id,
+               t1.session_id,
+               t1.user_id,
+               t1.role_id,
+               t1.role_name,
+               t1.send_type,
+               t1.content,
+               t1.create_time,
+               t1.nick_name,
+               t1.avatar,
+               t3.avatar as role_avatar
+        from fs_interest_ai_session t2
+        inner join fs_interest_ai_msg t1 on t1.session_id = t2.session_id
+        inner join fs_interest_ai_role t3 on t3.role_id = t2.role_id
+        where t2.session_id = #{sessionId}
+    </select>
+
+    <insert id="insertFsInterestAiSession" parameterType="FsInterestAiSession" useGeneratedKeys="true" keyProperty="sessionId">
+        insert into fs_interest_ai_session
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="chatId != null">chat_id,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="roleId != null">role_id,</if>
+            <if test="roleName != null">role_name,</if>
+            <if test="status != null">status,</if>
+            <if test="nickName != null">nick_name,</if>
+            <if test="avatar != null">avatar,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="chatId != null">#{chatId},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="roleId != null">#{roleId},</if>
+            <if test="roleName != null">#{roleName},</if>
+            <if test="status != null">#{status},</if>
+            <if test="nickName != null">#{nickName},</if>
+            <if test="avatar != null">#{avatar},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+        </trim>
+    </insert>
+
+    <insert id="insertFsInterestAiMsg" parameterType="FsInterestAiMsg" useGeneratedKeys="true" keyProperty="msgId">
+        insert into fs_interest_ai_msg
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="sessionId != null">session_id,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="content != null">content,</if>
+            <if test="sendType != null">send_type,</if>
+            <if test="roleId != null">role_id,</if>
+            <if test="roleName != null">role_name,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="nickName != null">nick_name,</if>
+            <if test="avatar != null">avatar,</if>
+            <if test="promptTokens != null">prompt_tokens,</if>
+            <if test="completionTokens != null">completion_tokens,</if>
+            <if test="totalTokens != null">total_tokens,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="sessionId != null">#{sessionId},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="content != null">#{content},</if>
+            <if test="sendType != null">#{sendType},</if>
+            <if test="roleId != null">#{roleId},</if>
+            <if test="roleName != null">#{roleName},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="nickName != null">#{nickName},</if>
+            <if test="avatar != null">#{avatar},</if>
+            <if test="promptTokens != null">#{promptTokens},</if>
+            <if test="completionTokens != null">#{completionTokens},</if>
+            <if test="totalTokens != null">#{totalTokens},</if>
+        </trim>
+    </insert>
+</mapper>

+ 97 - 0
fs-user-app-ai-chat/src/main/java/com/fs/app/controller/InterestAiController.java

@@ -0,0 +1,97 @@
+package com.fs.app.controller;
+
+import com.fs.aiChat.domain.InterestAiChatMsg;
+import com.fs.aiChat.domain.InterestAiSession;
+import com.fs.aiChat.domain.SessionRoleInfo;
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsInterestAiSession;
+import com.fs.his.service.IHisInterestAiChatSessionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/app/fsInterestAi")
+@Api(tags = "兴趣AI")
+public class InterestAiController extends AppBaseController {
+
+    @Autowired
+    private IHisInterestAiChatSessionService interestAiChatSessionService;
+
+    /**
+     * 创建会话
+     *
+     * @param fsInterestAiSession
+     * @return
+     */
+    @PostMapping("/createSession")
+    @ApiOperation(value = "创建会话")
+    public R createSession(@RequestBody FsInterestAiSession fsInterestAiSession) {
+        FsInterestAiSession session = interestAiChatSessionService.createSession(fsInterestAiSession);
+        return R.ok().put("data", session);
+    }
+
+    /**
+     * 根据当前用户获取用户与所有AI角色的会话列表
+     *
+     * @param session
+     * @return
+     */
+    @GetMapping(value = "/getAllRolesListByUserId")
+    @ApiOperation(value = "根据当前用户获取用户的会话列表")
+    public R getAllRolesListByUserId(InterestAiSession session) {
+        String userId = getUserId();
+        log.info("拿到userId" + userId);
+        if (null != session && session.getUserId() == null) {
+            session.setUserId(Long.valueOf(userId));
+        }
+        startPage();
+        List<InterestAiSession> list = interestAiChatSessionService.getAllRolesListByUserId(session);
+        return R.ok().put("data", list);
+    }
+
+    /**
+     * 根据会话id获取会话的详细信息
+     *
+     * @param sessionId
+     * @return
+     */
+    @GetMapping(value = "/getSessionDetailInfoBySessionIdAndRoleId/{sessionId}/{roleId}")
+    @ApiOperation(value = "根据会话id获取会话的详细信息")
+    public R getSessionDetailInfoBySessionIdAndRoleId(@PathVariable(name = "sessionId") String sessionId,
+                                                      @PathVariable(name = "roleId") Long roleId) {
+
+
+        List<InterestAiChatMsg> chatList = new ArrayList<>();
+        SessionRoleInfo roleInfo = null;
+        if (null != roleId) {
+            roleInfo = interestAiChatSessionService.getSessionRoleInfoByRoleId(roleId);
+        }
+
+        if (StringUtils.isNotBlank(sessionId)) {
+            chatList = interestAiChatSessionService.getSessionChatList(sessionId);
+        }
+        return R.ok().put("roleInfo", roleInfo).put("chatList", chatList);
+    }
+
+    /**
+     * 获取推荐角色列表
+     *
+     * @return
+     */
+    @GetMapping(value = "/getRecommendRoleList")
+    @ApiOperation(value = "获取推荐角色列表")
+    public R getRecommendRoleList() {
+        String userId = getUserId();
+        List<SessionRoleInfo> roleList = interestAiChatSessionService.getRecommendRoleList(userId);
+        return R.ok().put("list", roleList);
+    }
+
+}