From 8130bed63a505cf718481c0d95d3fcf7b037db96 Mon Sep 17 00:00:00 2001 From: Administrator <15274802129@163.com> Date: Tue, 16 Sep 2025 15:11:45 +0800 Subject: [PATCH] refactor(ai): 优化代码结构和更新时间处理 --- src/main/java/cc/mrbird/febs/ai/service/impl/ApiMemberTalkStreamServiceImpl.java | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 221 insertions(+), 9 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/ApiMemberTalkStreamServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/ApiMemberTalkStreamServiceImpl.java index e620a93..c25e496 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/impl/ApiMemberTalkStreamServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/ai/service/impl/ApiMemberTalkStreamServiceImpl.java @@ -1,29 +1,36 @@ package cc.mrbird.febs.ai.service.impl; -import cc.mrbird.febs.ai.entity.AiMemberTalk; -import cc.mrbird.febs.ai.entity.AiMemberTalkItem; -import cc.mrbird.febs.ai.entity.AiProductQuestion; -import cc.mrbird.febs.ai.entity.AiProductRoleLink; +import cc.mrbird.febs.ai.entity.*; +import cc.mrbird.febs.ai.enumerates.AiTalkOutputEnum; import cc.mrbird.febs.ai.enumerates.AiTypeEnum; import cc.mrbird.febs.ai.mapper.AiMemberTalkMapper; import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto; -import cc.mrbird.febs.ai.req.memberTalkStream.ApiMemberTalkReloadStreamDto; -import cc.mrbird.febs.ai.req.memberTalkStream.ApiMemberTalkStreamDto; +import cc.mrbird.febs.ai.req.memberTalkStream.*; import cc.mrbird.febs.ai.res.memberTalkStream.ApiMemberTalkReloadStreamVo; import cc.mrbird.febs.ai.res.memberTalkStream.ApiMemberTalkStreamVo; import cc.mrbird.febs.ai.service.*; +import cc.mrbird.febs.ai.strategy.LlmStrategyFactory; +import cc.mrbird.febs.ai.strategy.enumerates.LlmStrategyEnum; +import cc.mrbird.febs.ai.strategy.param.LlmStrategyDto; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.LoginUserUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +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.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.HashMap; +import java.util.List; /** * AI用户对话训练记录 Service实现类 @@ -38,9 +45,11 @@ private final AiMemberTalkMapper aiMemberTalkMapper; private final AiProductRoleLinkService aiProductRoleLinkService; + private final AiProductRoleService aiProductRoleService; private final AiMemberTalkService aiMemberTalkService; private final AiMemberTalkItemService aiMemberTalkItemService; private final AiProductQuestionService aiProductQuestionService; + private final LlmStrategyFactory llmStrategyFactory; private final AiService aiService; @@ -57,6 +66,8 @@ throw new FebsException("产品AI陪练不存在"); } + String companyId = aiProductRoleLink.getCompanyId(); + Date nowTime = new Date(); LambdaQueryWrapper<AiMemberTalk> query = Wrappers.lambdaQuery(AiMemberTalk.class); query.eq(AiMemberTalk::getMemberId,memberUuid); @@ -64,17 +75,17 @@ query.last("limit 1"); AiMemberTalk aiMemberTalk = aiMemberTalkService.getByQuery(query); if (ObjectUtil.isNull(aiMemberTalk)){ - aiMemberTalk = aiMemberTalkService.add(memberUuid,productId,nowTime); + aiMemberTalk = aiMemberTalkService.add(memberUuid,companyId,productId,nowTime); } ApiMemberTalkStreamVo apiMemberTalkVo = new ApiMemberTalkStreamVo(); String title = "加载时间过程,请重试!"; AiProductQuestion question = aiProductQuestionService.createQuestion(productId); if (ObjectUtil.isNotNull(question)){ - AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.add(memberUuid, aiMemberTalk.getId(), 1, title, nowTime); + title = question.getTitle(); + AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.add(memberUuid, aiMemberTalk.getId(),companyId, 1, title, nowTime); apiMemberTalkVo.setMemberTalkItemId(aiMemberTalkItem.getId()); aiMemberTalkService.updateTimeUpdate(nowTime,aiMemberTalk.getId()); - question.getTitle(); } apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId()); apiMemberTalkVo.setType(1); @@ -108,4 +119,205 @@ dto.setMemberUuid(memberUuid); return new FebsResponse().success().data(aiMemberTalkItemService.historyPage(dto)); } + + @Override + public FebsResponse saveMemberAnswer(ApiMemberTalkMemberAnswerSavaDto dto) { + String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); + String memberTalkId = dto.getMemberTalkId(); + String content = dto.getContent(); + + AiMemberTalk aiMemberTalk = this.getById(memberTalkId); + if (ObjectUtil.isNull(aiMemberTalk)){ + throw new FebsException("对话不存在"); + } + this.updateMemberTalkUpdateTime(aiMemberTalk.getId(), new Date()); + + String companyId = aiMemberTalk.getCompanyId(); + aiMemberTalkItemService.add(memberUuid,aiMemberTalk.getId(),companyId,2,content,new Date()); + return new FebsResponse().success(); + } + + @Override + public Flux<FebsResponse> answer(AiTalkAnswerStreamDto dto) { + + String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); + Integer type = dto.getType(); + String memberTalkId = dto.getId(); + AiMemberTalk aiMemberTalk = this.getById(memberTalkId); + if (ObjectUtil.isNull(aiMemberTalk)){ + throw new FebsException("对话不存在"); + } + + LambdaQueryWrapper<AiProductRoleLink> productLinkQuery = Wrappers.lambdaQuery(AiProductRoleLink.class); + productLinkQuery.eq(AiProductRoleLink::getProductId,aiMemberTalk.getProductId()); + productLinkQuery.last("limit 1"); + AiProductRoleLink aiProductRoleLink = aiProductRoleLinkService.getByQuery(productLinkQuery); + if(ObjectUtil.isNull(aiProductRoleLink)){ + throw new FebsException("产品没有关联AI陪练"); + } + + String productRoleId = aiProductRoleLink.getProductRoleId(); + AiProductRole aiProductRole = aiProductRoleService.getById(productRoleId); + if (ObjectUtil.isNull(aiProductRole)){ + throw new FebsException("产品AI陪练不存在"); + } + + String reqContext = dto.getReqContext(); + LambdaQueryWrapper<AiMemberTalkItem> memberTalkItemQuery = Wrappers.lambdaQuery(AiMemberTalkItem.class); + memberTalkItemQuery.eq(AiMemberTalkItem::getMemberId,memberUuid); + memberTalkItemQuery.eq(AiMemberTalkItem::getMemberTalkId,memberTalkId); + memberTalkItemQuery.eq(AiMemberTalkItem::getType,1); + memberTalkItemQuery.orderByDesc(AiMemberTalkItem::getCreatedTime); + memberTalkItemQuery.last("limit 1"); + AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getByQuery(memberTalkItemQuery); + String question = aiMemberTalkItem.getContext(); + + String prompt = this.buildPrompt(question,reqContext,aiProductRole.getPromptHead(), aiProductRole.getPromptTemplate(), type); + + + List<LlmStrategyDto> llmStrategyDtoList = new ArrayList<>(); + LlmStrategyDto llmStrategyDto = this.buildLlmStrategyDtoList(prompt, 1); + llmStrategyDtoList.add(llmStrategyDto); + llmStrategyDto = this.buildLlmStrategyDtoList(question, 3); + llmStrategyDtoList.add(llmStrategyDto); + llmStrategyDto = this.buildLlmStrategyDtoList(reqContext, 2); + llmStrategyDtoList.add(llmStrategyDto); + String modelName = LlmStrategyEnum.getName(aiService.getSystemSetAiType()); + + return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(llmStrategyDtoList); + } + + @Override + public Flux<FebsResponse> answerV2(AiTalkAnswerStreamDto dto) { + + + String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); + Integer type = dto.getType(); + String memberTalkId = dto.getId(); + AiMemberTalk aiMemberTalk = this.getById(memberTalkId); + if (ObjectUtil.isNull(aiMemberTalk)){ + throw new FebsException("对话不存在"); + } + + LambdaQueryWrapper<AiProductRoleLink> productLinkQuery = Wrappers.lambdaQuery(AiProductRoleLink.class); + productLinkQuery.eq(AiProductRoleLink::getProductId,aiMemberTalk.getProductId()); + productLinkQuery.last("limit 1"); + AiProductRoleLink aiProductRoleLink = aiProductRoleLinkService.getByQuery(productLinkQuery); + if(ObjectUtil.isNull(aiProductRoleLink)){ + throw new FebsException("产品没有关联AI陪练"); + } + + String productRoleId = aiProductRoleLink.getProductRoleId(); + AiProductRole aiProductRole = aiProductRoleService.getById(productRoleId); + if (ObjectUtil.isNull(aiProductRole)){ + throw new FebsException("产品AI陪练不存在"); + } + LambdaQueryWrapper<AiMemberTalkItem> memberTalkItemQuery = Wrappers.lambdaQuery(AiMemberTalkItem.class); + memberTalkItemQuery.eq(AiMemberTalkItem::getMemberId,memberUuid); + memberTalkItemQuery.eq(AiMemberTalkItem::getMemberTalkId,memberTalkId); + memberTalkItemQuery.eq(AiMemberTalkItem::getType,1); + memberTalkItemQuery.orderByDesc(AiMemberTalkItem::getCreatedTime); + memberTalkItemQuery.last("limit 1"); + AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getByQuery(memberTalkItemQuery); + + String question = aiMemberTalkItem.getContext(); + String promptHead = aiProductRole.getPromptHead(); + String answer = dto.getReqContext(); + + List<LlmStrategyDto> llmStrategyDtoList = new ArrayList<>(); + LlmStrategyDto llmStrategyDto = this.buildLlmStrategyDtoList(promptHead, 1); + llmStrategyDtoList.add(llmStrategyDto); + llmStrategyDto = this.buildLlmStrategyDtoList(question, 3); + llmStrategyDtoList.add(llmStrategyDto); + llmStrategyDto = this.buildLlmStrategyDtoList(answer, 2); + llmStrategyDtoList.add(llmStrategyDto); + llmStrategyDto = this.buildLlmStrategyDtoList(String.valueOf(type), 4); + llmStrategyDtoList.add(llmStrategyDto); + String modelName = LlmStrategyEnum.getName(aiService.getSystemSetAiType()); + + return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(llmStrategyDtoList); + } + + private String buildPrompt(String question,String answer,String promptHead, String promptTemplate,Integer type){ + AiPromptJsonReq aiPromptJsonReq = new AiPromptJsonReq(); +// aiPromptJsonReq.setQuestion( question); + aiPromptJsonReq.setTask( promptHead); + aiPromptJsonReq.setRule( promptTemplate); + String contentByCode = AiTalkOutputEnum.HIGH_LIGHT.getContentByType(type); + aiPromptJsonReq.setOutputFormat(contentByCode); + + return JSONUtil.toJsonStr(aiPromptJsonReq); + } + + private LlmStrategyDto buildLlmStrategyDtoList(String Str, Integer type){ + LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); + if (type == 1){ + llmStrategyDto.setRole(Role.SYSTEM.getValue()); + } + if (type == 2){ + llmStrategyDto.setRole(Role.USER.getValue()); + } + if (type == 3){ + llmStrategyDto.setRole(Role.ASSISTANT.getValue()); + } + if (type == 4){ + llmStrategyDto.setRole(Role.TOOL.getValue()); + } + llmStrategyDto.setContent(Str); + + return llmStrategyDto; + } + + @Override + public FebsResponse saveAnswer(ApiMemberTalkAnswerSavaDto dto) { + + String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); + String memberTalkId = dto.getMemberTalkId(); + String content = dto.getContent(); + + AiMemberTalk aiMemberTalk = this.getById(memberTalkId); + if (ObjectUtil.isNull(aiMemberTalk)){ + throw new FebsException("对话不存在"); + } + + this.updateMemberTalkUpdateTime(aiMemberTalk.getId(), new Date()); + + String companyId = aiMemberTalk.getCompanyId(); + Integer type = dto.getType(); + String memberTalkItemId; + String contentByCode = AiTalkOutputEnum.HIGH_LIGHT.getCodeByType(type); + if(StrUtil.isEmpty(dto.getMemberTalkItemId())){ + HashMap<String, String> stringStringHashMap = new HashMap<>(); + stringStringHashMap.put(contentByCode,content); + AiMemberTalkItem add = aiMemberTalkItemService.add(memberUuid, memberTalkId,companyId, 3, JSONUtil.toJsonStr(stringStringHashMap), new Date()); + memberTalkItemId = add.getId(); + }else{ + memberTalkItemId = dto.getMemberTalkItemId(); + AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getById(memberTalkItemId); + String context = aiMemberTalkItem.getContext(); + HashMap<String, String> stringStringHashMap = JSONUtil.toBean(context, HashMap.class); + stringStringHashMap.put(contentByCode,content); + aiMemberTalkItemService.update(null, + Wrappers.lambdaUpdate(AiMemberTalkItem.class) + .set(AiMemberTalkItem::getContext,JSONUtil.toJsonStr(stringStringHashMap)) + .set(AiMemberTalkItem::getUpdatedTime,new Date()) + .set(AiMemberTalkItem::getRevision,aiMemberTalkItem.getRevision()+1) + .eq(AiMemberTalkItem::getId,memberTalkItemId) + ); + } + + HashMap<String, String> stringStringHashMap = new HashMap<>(); + stringStringHashMap.put("memberTalkItemId",memberTalkItemId); + return new FebsResponse().success().data(stringStringHashMap); + } + + @Override + public void updateMemberTalkUpdateTime(String memberTalkId, Date updateTime) { + aiMemberTalkMapper.update(null, + Wrappers.lambdaUpdate(AiMemberTalk.class) + .set(AiMemberTalk::getUpdatedTime,updateTime) + .eq(AiMemberTalk::getId,memberTalkId) + ); + } + } -- Gitblit v1.9.1