package cc.mrbird.febs.yinhe.service.impl; import cc.mrbird.febs.ai.res.product.ApiProductVo; import cc.mrbird.febs.ai.strategy.LlmStrategyFactory; import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyEnum; import cc.mrbird.febs.ai.utils.UUID; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.AppContants; import cc.mrbird.febs.common.utils.RedisUtils; import cc.mrbird.febs.common.utils.YHLoginUserUtil; import cc.mrbird.febs.rabbit.producter.AgentProducer; import cc.mrbird.febs.yinhe.entity.*; import cc.mrbird.febs.yinhe.mapper.*; import cc.mrbird.febs.yinhe.req.*; import cc.mrbird.febs.yinhe.res.*; import cc.mrbird.febs.yinhe.service.YhAiService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.dashscope.common.Message; import com.alibaba.dashscope.common.Role; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import java.util.ArrayList; import java.util.Date; import java.util.List; @Slf4j @Service @RequiredArgsConstructor public class YhAiServiceImpl extends ServiceImpl implements YhAiService { private final YhAiMemberMapper yhAiMemberMapper; private final YHAiCompanyMapper yhAiCompanyMapper; private final YHAiBannerMapper yhAiBannerMapper; private final YHAiLogoMapper yhAiLogoMapper; private final YHAiAgentCategoryMapper yhAiAgentCategoryMapper; private final YHAiAgentMapper yhAiAgentMapper; private final YHAiAgentStartQuestionMapper yhAiAgentStartQuestionMapper; private final YHAiAgentKnowledgeMapper yhAiAgentKnowledgeMapper; private final YHAiKnowledgeMapper yhAiKnowledgeMapper; private final YhSysAgentCategoryMapper yhSysAgentCategoryMapper; private final YHSysAgentStartQuestionMapper yhSysAgentStartQuestionMapper; private final YHSysAgentMapper yhSysAgentMapper; private final YHSysCompanyLevelMapper yhSysCompanyLevelMapper; private final YHAiTalkMapper yhAiTalkMapper; private final YHAiTalkItemMapper yhAiTalkItemMapper; private final RedisUtils redisUtils; private final AgentProducer agentProducer; private final LlmStrategyFactory llmStrategyFactory; @Override public FebsResponse memberInfo() { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YHMemberVo yhMemberVo = new YHMemberVo(); YhAiMember yhAiMember = yhAiMemberMapper.selectOne( Wrappers.lambdaQuery(YhAiMember.class) .eq(YhAiMember::getMemberUuid, memberUuid) ); if (ObjectUtil.isNotEmpty(yhAiMember)){ String companyId = yhAiMember.getCompanyId(); YHAiCompany yhAiCompany = yhAiCompanyMapper.selectById(companyId); yhMemberVo.setMemberUuid(yhAiMember.getMemberUuid()); yhMemberVo.setAvatar(yhAiMember.getAvatar()); yhMemberVo.setName(yhAiMember.getName()); yhMemberVo.setRealName(yhAiMember.getRealName()); yhMemberVo.setSex(yhAiMember.getSex()); yhMemberVo.setCompanyId(yhAiCompany.getId()); yhMemberVo.setCompanyName(yhAiCompany.getName()); yhMemberVo.setPhone(yhAiMember.getPhone()); } return new FebsResponse().success().data(yhMemberVo); } @Override public FebsResponse categoryList(YHCategoryDto dto) { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YhAiMember yhAiMember = yhAiMemberMapper.selectOne(Wrappers.lambdaQuery(YhAiMember.class).eq(YhAiMember::getMemberUuid, memberUuid)); String companyId = yhAiMember.getCompanyId(); List yhCategoryVos = new ArrayList<>(); LambdaQueryWrapper query = Wrappers.lambdaQuery(YHAiAgentCategory.class); query.eq(YHAiAgentCategory::getCompanyId,companyId); query.eq(YHAiAgentCategory::getState,1); if (ObjectUtil.isNotEmpty(dto.getHotState())){ query.eq(YHAiAgentCategory::getHotState,dto.getHotState()); } query.orderByAsc(YHAiAgentCategory::getSort); List yhAiAgentCategories = yhAiAgentCategoryMapper.selectList(query); if (CollUtil.isNotEmpty(yhAiAgentCategories)){ for (YHAiAgentCategory yhAiAgentCategory : yhAiAgentCategories) { YHCategoryVo yhCategoryVo = new YHCategoryVo(); yhCategoryVo.setName(yhAiAgentCategory.getName()); yhCategoryVo.setId(yhAiAgentCategory.getId()); yhCategoryVos.add(yhCategoryVo); } } return new FebsResponse().success().data(yhCategoryVos); } @Override public FebsResponse agentList(YHAgentDto dto) { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YhAiMember yhAiMember = yhAiMemberMapper.selectOne(Wrappers.lambdaQuery(YhAiMember.class).eq(YhAiMember::getMemberUuid, memberUuid)); String companyId = yhAiMember.getCompanyId(); ArrayList yhAgentVos = new ArrayList<>(); LambdaQueryWrapper query = Wrappers.lambdaQuery(YHAiAgent.class); query.eq(YHAiAgent::getCompanyId,companyId); query.eq(YHAiAgent::getState,1); if (ObjectUtil.isNotEmpty(dto.getAgentCategoryId())){ query.eq(YHAiAgent::getAgentCategoryId,dto.getAgentCategoryId()); } query.orderByDesc(YHAiAgent::getCreateTime); List yhAiAgents = yhAiAgentMapper.selectList(query); if (CollUtil.isNotEmpty(yhAiAgents)){ for (YHAiAgent yhAiAgent : yhAiAgents) { YHAgentVo yhAgentVo = new YHAgentVo(); yhAgentVo.setId(yhAiAgent.getId()); yhAgentVo.setName(yhAiAgent.getName()); yhAgentVo.setDescription(yhAiAgent.getDescription()); yhAgentVo.setIconImg(yhAiAgent.getIconImg()); yhAgentVos.add(yhAgentVo); } } return new FebsResponse().success().data(yhAgentVos); } @Override public FebsResponse agentInfo(YHAgentInitDto dto) { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YHAgentInitVo yhAgentInitVo = new YHAgentInitVo(); String id = dto.getId(); YHAiAgent yhAiAgent = yhAiAgentMapper.selectById(id); if (ObjectUtil.isNotEmpty(yhAiAgent)){ yhAgentInitVo.setId(yhAiAgent.getId()); yhAgentInitVo.setName(yhAiAgent.getName()); yhAgentInitVo.setDescription(yhAiAgent.getDescription()); yhAgentInitVo.setIconImg(yhAiAgent.getIconImg()); yhAgentInitVo.setIntroduct(yhAiAgent.getIntroduct()); List yhAiAgentStartQuestions = yhAiAgentStartQuestionMapper.selectList( Wrappers.lambdaQuery(YHAiAgentStartQuestion.class).eq(YHAiAgentStartQuestion::getAgentId, id) ); if (CollUtil.isNotEmpty(yhAiAgentStartQuestions)){ List questions = new ArrayList<>(); for (YHAiAgentStartQuestion yhAiAgentStartQuestion : yhAiAgentStartQuestions) { questions.add(yhAiAgentStartQuestion.getTitle()); } yhAgentInitVo.setItems(questions); } } return new FebsResponse().success().data(yhAgentInitVo); } @Override public FebsResponse categorySysList(YHSysCategoryDto dto) { List vos = new ArrayList<>(); LambdaQueryWrapper query = Wrappers.lambdaQuery(YhSysAgentCategory.class); query.eq(YhSysAgentCategory::getState,1); if (ObjectUtil.isNotEmpty(dto.getHotState())){ query.eq(YhSysAgentCategory::getHotState,dto.getHotState()); } query.orderByAsc(YhSysAgentCategory::getSort); List yhSysAgentCategories = yhSysAgentCategoryMapper.selectList(query); if (CollUtil.isNotEmpty(yhSysAgentCategories)){ for (YhSysAgentCategory yhSysAgentCategory : yhSysAgentCategories) { YHSysCategoryVo vo = new YHSysCategoryVo(); vo.setId(yhSysAgentCategory.getId()); vo.setName(yhSysAgentCategory.getName()); vos.add(vo); } } return new FebsResponse().success().data(vos); } @Override public FebsResponse agentSysList(YHSysAgentDto dto) { // 创建分页对象,传入当前页和每页大小 Page page = new Page<>(dto.getPageNow(), dto.getPageSize()); Page pageListByQuery = yhSysAgentMapper.getPageListByQuery(page, dto); return new FebsResponse().success().data(pageListByQuery); } @Override public FebsResponse agentSysInfo(YHSysAgentInitDto dto) { YHSysAgentInitVo vo = new YHSysAgentInitVo(); String id = dto.getId(); YHSysAgent entity = yhSysAgentMapper.selectById(id); if (ObjectUtil.isNotEmpty(entity)){ vo.setId(entity.getId()); vo.setName(entity.getName()); vo.setDescription(entity.getDescription()); vo.setIconImg(entity.getIconImg()); vo.setIntroduct(entity.getIntroduct()); List questionList = yhSysAgentStartQuestionMapper.selectList( Wrappers.lambdaQuery(YHSysAgentStartQuestion.class).eq(YHSysAgentStartQuestion::getAgentId, id) ); if (CollUtil.isNotEmpty(questionList)){ List questions = new ArrayList<>(); for (YHSysAgentStartQuestion question : questionList) { questions.add(question.getTitle()); } vo.setItems(questions); } } return new FebsResponse().success().data(vo); } @Override public FebsResponse logout() { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); String redisKey = AppContants.XCX_LOGIN_PREFIX + memberUuid; String existToken = redisUtils.getString(redisKey); if (StrUtil.isNotBlank(existToken)) { Object o = redisUtils.get(existToken); if (ObjectUtil.isNotEmpty(o)) { redisUtils.del(existToken); } } redisUtils.del(AppContants.XCX_LOGIN_PREFIX + memberUuid); return new FebsResponse().success().message("退出登录"); } @Override public FebsResponse initSend(YHSendInitDto dto) { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YHSendInitVo vo = new YHSendInitVo(); String agentId = dto.getId(); //获取智能体信息 YHAiAgent yhAiAgent = yhAiAgentMapper.selectById(agentId); if (yhAiAgent == null) { throw new FebsException("智能体不存在"); } if (yhAiAgent.getState() != 1){ throw new FebsException("智能体未启用"); } String companyId = yhAiAgent.getCompanyId(); /** * 新增一个会话记录 */ YHAiTalk entity = new YHAiTalk(); entity.setId(UUID.getSimpleUUIDString()); entity.setCompanyId(companyId); entity.setCustomerId(memberUuid); entity.setAgentId(yhAiAgent.getId()); entity.setType(2); entity.setCreateTime(new Date()); yhAiTalkMapper.insert(entity); vo.setTalkId(entity.getId()); return new FebsResponse().success().data(vo); } @Override public FebsResponse saveContext(YHSaveContextDto dto) { String talkId = dto.getTalkId(); String type = dto.getType(); String content = dto.getContent(); YHAiTalk aiTalk = yhAiTalkMapper.selectById(talkId); if (aiTalk == null) { throw new FebsException("会话不存在"); } //保存会话记录 YHAiTalkItem aiTalkItem = new YHAiTalkItem(); aiTalkItem.setId(UUID.getSimpleUUIDString()); aiTalkItem.setCompanyId(aiTalk.getCompanyId()); aiTalkItem.setTalkId(aiTalk.getId()); aiTalkItem.setType(type); aiTalkItem.setContext(content); aiTalkItem.setTokenNum(content.length()); aiTalkItem.setCreateTime(new Date()); yhAiTalkItemMapper.insert(aiTalkItem); agentProducer.sendAddCompanyToken(aiTalkItem.getId()); return new FebsResponse().success(); } @Override public Flux aiAnswer(YHAitalkItemStreamDto dto) { String talkId = dto.getTalkId(); String reqContext = dto.getReqContext(); YHAiTalk aiTalk = yhAiTalkMapper.selectById(talkId); if (aiTalk == null) { throw new FebsException("会话不存在"); } //获取智能体的信息 String agentId = aiTalk.getAgentId(); YHAiAgent aiAgent = yhAiAgentMapper.selectById(agentId); if (aiAgent == null) { throw new FebsException("智能体异常"); } //判断字符是否足够 String companyId = aiTalk.getCompanyId(); YHAiCompany aiCompany = yhAiCompanyMapper.selectById(companyId); if (aiCompany == null) { throw new FebsException("知识库异常"); } Integer useToken = aiCompany.getUseToken(); YHSysCompanyLevel sysCompanyLevel = yhSysCompanyLevelMapper.selectOne( Wrappers.lambdaQuery(YHSysCompanyLevel.class) .select(YHSysCompanyLevel::getToken) .eq(YHSysCompanyLevel::getCode, aiCompany.getLevelCode()) ); if (useToken > sysCompanyLevel.getToken()) { throw new FebsException("字符已消耗完"); } //获取智能体绑定的知识库 List knowledgeIds = new ArrayList<>(); String knowledgeId = aiCompany.getKnowledgeId(); knowledgeIds.add(knowledgeId); //获取智能体绑定的查询文件 List fileIds = new ArrayList<>(); List aiAgentKnowledges = yhAiAgentKnowledgeMapper.selectList( Wrappers.lambdaQuery(YHAiAgentKnowledge.class) .select(YHAiAgentKnowledge::getKnowledgeId) .eq(YHAiAgentKnowledge::getAgentId, agentId) .eq(YHAiAgentKnowledge::getCompanyId, companyId) ); if (CollUtil.isNotEmpty(aiAgentKnowledges)){ List aiKnowledgeIds = new ArrayList<>(); for (YHAiAgentKnowledge aiAgentKnowledge : aiAgentKnowledges){ aiKnowledgeIds.add(aiAgentKnowledge.getKnowledgeId()); } if (CollUtil.isNotEmpty(aiKnowledgeIds)){ List aiKnowledges = yhAiKnowledgeMapper.selectList( Wrappers.lambdaQuery(YHAiKnowledge.class) .select(YHAiKnowledge::getFileId) .in(YHAiKnowledge::getId, aiKnowledgeIds) ); if (CollUtil.isNotEmpty(aiKnowledges)){ for (YHAiKnowledge aiKnowledge : aiKnowledges){ fileIds.add(aiKnowledge.getFileId()); } } } } AiRequestDto aiRequestDto = new AiRequestDto(); aiRequestDto.setTalkId(talkId); String prompt = aiAgent.getPrompt(); aiRequestDto.setRolePrompt(prompt); // List messages = new ArrayList<>(); // messages.add(Message.builder().role(Role.SYSTEM.getValue()).content(prompt).build()); //获取对话记录 List messages = new ArrayList<>(); List aiTalkItemList = yhAiTalkItemMapper.selectList( Wrappers.lambdaQuery(YHAiTalkItem.class) .eq(YHAiTalkItem::getTalkId, talkId) .orderByAsc(YHAiTalkItem::getCreateTime) ); if (CollUtil.isNotEmpty(aiTalkItemList)){ messages = getMessages(messages,aiTalkItemList); } for ( Message message : messages ){ log.info("上下文内容:{},{}", message.getRole(),message.getContent()); } aiRequestDto.setMessages(messages); aiRequestDto.setKnowledgeIds(knowledgeIds); aiRequestDto.setFileIds(fileIds); aiRequestDto.setPrompt(reqContext); aiRequestDto.setCompanyId(companyId); //日志输出详细的请求参数的每一个属性 log.info("请求参数:{}", aiRequestDto.getPrompt()); log.info("请求参数:{}", aiRequestDto); String modelName = LlmStrategyEnum.getName(2); return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(aiRequestDto); } private List getMessages(List messages,List aiTalkItemList) { for (YHAiTalkItem item : aiTalkItemList){ if (StrUtil.equals(item.getType(), Role.USER.getValue())){ messages.add(Message.builder() .role(Role.USER.getValue()) .content(item.getContext()) .build()); } if (StrUtil.equals(item.getType(),Role.ASSISTANT.getValue())){ messages.add(Message.builder() .role(Role.ASSISTANT.getValue()) .content(item.getContext()) .build()); } } return messages; } @Override public FebsResponse bannerList() { List vos = new ArrayList<>(); List list = yhAiBannerMapper.selectList( Wrappers.lambdaQuery(YHAiBanner.class) .eq(YHAiBanner::getState, 1) .isNull(YHAiBanner::getCompanyId) .orderByDesc(YHAiBanner::getSort) ); if (CollUtil.isNotEmpty(list)){ for (YHAiBanner aiBanner : list){ YHBannerVo vo = new YHBannerVo(); vo.setName(aiBanner.getName()); vo.setImageUrl(aiBanner.getImageUrl()); vo.setSort(aiBanner.getSort()); vos.add(vo); } } return new FebsResponse().success().data(vos); } @Override public FebsResponse logoInfo() { YHLogoVo yhLogoVo = new YHLogoVo(); List yhAiLogos = yhAiLogoMapper.selectList( Wrappers.lambdaQuery(YHAiLogo.class) .eq(YHAiLogo::getState, 1) .isNull(YHAiLogo::getCompanyId) ); if (CollUtil.isNotEmpty(yhAiLogos)){ YHAiLogo yhAiLogo = yhAiLogos.get(0); yhLogoVo.setName(yhAiLogo.getName()); yhLogoVo.setImageUrl(yhAiLogo.getImageUrl()); yhLogoVo.setDesription(yhAiLogo.getDesription()); } return new FebsResponse().success().data(yhLogoVo); } @Override public FebsResponse loginBannerList() { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YhAiMember yhAiMember = yhAiMemberMapper.selectOne(Wrappers.lambdaQuery(YhAiMember.class).eq(YhAiMember::getMemberUuid, memberUuid)); String companyId = yhAiMember.getCompanyId(); List vos = new ArrayList<>(); List list = yhAiBannerMapper.selectList( Wrappers.lambdaQuery(YHAiBanner.class) .eq(YHAiBanner::getState, 1) .eq(YHAiBanner::getCompanyId, companyId) .orderByAsc(YHAiBanner::getSort) ); if (CollUtil.isNotEmpty(list)){ for (YHAiBanner aiBanner : list){ YHBannerVo vo = new YHBannerVo(); vo.setName(aiBanner.getName()); vo.setImageUrl(aiBanner.getImageUrl()); vo.setSort(aiBanner.getSort()); vos.add(vo); } } return new FebsResponse().success().data(vos); } @Override public FebsResponse loginLogoInfo() { String memberUuid = YHLoginUserUtil.getLoginUser().getMemberUuid(); YhAiMember yhAiMember = yhAiMemberMapper.selectOne(Wrappers.lambdaQuery(YhAiMember.class).eq(YhAiMember::getMemberUuid, memberUuid)); String companyId = yhAiMember.getCompanyId(); YHLogoVo yhLogoVo = new YHLogoVo(); List yhAiLogos = yhAiLogoMapper.selectList( Wrappers.lambdaQuery(YHAiLogo.class) .eq(YHAiLogo::getState, 1) .eq(YHAiLogo::getCompanyId, companyId) ); if (CollUtil.isNotEmpty(yhAiLogos)){ YHAiLogo yhAiLogo = yhAiLogos.get(0); yhLogoVo.setName(yhAiLogo.getName()); yhLogoVo.setImageUrl(yhAiLogo.getImageUrl()); yhLogoVo.setDesription(yhAiLogo.getDesription()); } return new FebsResponse().success().data(yhLogoVo); } }