From 0325d413502474062e1d400df319bfd390e94956 Mon Sep 17 00:00:00 2001 From: Administrator <15274802129@163.com> Date: Wed, 17 Sep 2025 16:12:40 +0800 Subject: [PATCH] feat(ai): 新增 AI 陪练相关功能 --- src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkStreamServiceImpl.java | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 105 insertions(+), 10 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkStreamServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkStreamServiceImpl.java index 00411bc..8b8d056 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkStreamServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkStreamServiceImpl.java @@ -6,6 +6,7 @@ import cc.mrbird.febs.ai.mapper.AiMemberTalkMapper; import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto; import cc.mrbird.febs.ai.req.memberTalkStream.*; +import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkMemberAnswerSavaVo; import cc.mrbird.febs.ai.res.memberTalkStream.ApiMemberTalkReloadStreamVo; import cc.mrbird.febs.ai.res.memberTalkStream.ApiMemberTalkStreamVo; import cc.mrbird.febs.ai.service.*; @@ -15,6 +16,7 @@ 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.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; @@ -25,6 +27,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import reactor.core.publisher.Flux; import java.util.ArrayList; @@ -44,6 +47,7 @@ public class AiMemberTalkStreamServiceImpl extends ServiceImpl<AiMemberTalkMapper, AiMemberTalk> implements AiMemberTalkStreamService { private final AiMemberTalkMapper aiMemberTalkMapper; + private final AiProductService aiProductService; private final AiProductRoleLinkService aiProductRoleLinkService; private final AiProductRoleService aiProductRoleService; private final AiMemberTalkService aiMemberTalkService; @@ -54,6 +58,7 @@ @Override + @Transactional public FebsResponse start(ApiMemberTalkStreamDto dto) { String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); @@ -66,16 +71,20 @@ throw new FebsException("产品AI陪练不存在"); } + AiProduct aiProduct = aiProductService.getById(productId); + Integer questionCount = aiProduct.getQuestionCount(); + String companyId = aiProductRoleLink.getCompanyId(); Date nowTime = new Date(); LambdaQueryWrapper<AiMemberTalk> query = Wrappers.lambdaQuery(AiMemberTalk.class); query.eq(AiMemberTalk::getMemberId,memberUuid); query.eq(AiMemberTalk::getProductId,productId); + query.eq(AiMemberTalk::getState,AiTypeEnum.AI_MEMBER_TALK_STATE_ING.getCode()); query.last("limit 1"); AiMemberTalk aiMemberTalk = aiMemberTalkService.getByQuery(query); if (ObjectUtil.isNull(aiMemberTalk)){ - aiMemberTalk = aiMemberTalkService.add(memberUuid,companyId,productId,nowTime); + aiMemberTalk = aiMemberTalkService.add(memberUuid,companyId,productId,nowTime,questionCount); } ApiMemberTalkStreamVo apiMemberTalkVo = new ApiMemberTalkStreamVo(); @@ -90,6 +99,8 @@ apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId()); apiMemberTalkVo.setType(1); apiMemberTalkVo.setContext(title); + apiMemberTalkVo.setQuestionCnt(aiMemberTalk.getQuestionCnt()); + apiMemberTalkVo.setDoneCnt(aiMemberTalk.getDoneCnt() + 1); return new FebsResponse().success().data(apiMemberTalkVo); } @@ -104,7 +115,7 @@ queryWrapper.eq(AiMemberTalkItem::getType,AiTypeEnum.QUESTION_ANSWER.getCode()); queryWrapper.orderByDesc(AiMemberTalkItem::getCreatedTime); queryWrapper.last("limit 1"); - AiMemberTalkItem byQuery = aiMemberTalkItemService.getByQuery(queryWrapper); + AiMemberTalkItem byQuery = aiMemberTalkItemService.getOneByQuery(queryWrapper); if (ObjectUtil.isNotNull(byQuery)){ apiMemberTalkReloadVo.setContext(byQuery.getContext()); apiMemberTalkReloadVo.setMemberTalkId(memberTalkId); @@ -121,6 +132,7 @@ } @Override + @Transactional public FebsResponse saveMemberAnswer(ApiMemberTalkMemberAnswerSavaDto dto) { String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); String memberTalkId = dto.getMemberTalkId(); @@ -130,11 +142,18 @@ if (ObjectUtil.isNull(aiMemberTalk)){ throw new FebsException("对话不存在"); } - this.updateMemberTalkUpdateTime(aiMemberTalk.getId(), new Date()); + int doneCnt = aiMemberTalk.getDoneCnt() + 1; + Integer state = aiMemberTalk.getState(); + Integer questionCnt = aiMemberTalk.getQuestionCnt(); + this.updateMemberTalkUpdateTime(state,doneCnt,aiMemberTalk.getId(), new Date()); String companyId = aiMemberTalk.getCompanyId(); aiMemberTalkItemService.add(memberUuid,aiMemberTalk.getId(),companyId,2,content,new Date()); - return new FebsResponse().success(); + + ApiMemberTalkMemberAnswerSavaVo apiMemberTalkMemberAnswerSavaVo = new ApiMemberTalkMemberAnswerSavaVo(); + apiMemberTalkMemberAnswerSavaVo.setQuestionCnt(questionCnt); + apiMemberTalkMemberAnswerSavaVo.setDoneCnt(doneCnt); + return new FebsResponse().success().data(apiMemberTalkMemberAnswerSavaVo); } @Override @@ -169,7 +188,7 @@ memberTalkItemQuery.eq(AiMemberTalkItem::getType,1); memberTalkItemQuery.orderByDesc(AiMemberTalkItem::getCreatedTime); memberTalkItemQuery.last("limit 1"); - AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getByQuery(memberTalkItemQuery); + AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getOneByQuery(memberTalkItemQuery); String question = aiMemberTalkItem.getContext(); String prompt = this.buildPrompt(question,reqContext,aiProductRole.getPromptHead(), aiProductRole.getPromptTemplate(), type); @@ -194,6 +213,7 @@ String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); Integer type = dto.getType(); String memberTalkId = dto.getId(); + Integer state = ObjectUtil.defaultIfNull(dto.getState(),0); AiMemberTalk aiMemberTalk = this.getById(memberTalkId); if (ObjectUtil.isNull(aiMemberTalk)){ throw new FebsException("对话不存在"); @@ -218,7 +238,7 @@ memberTalkItemQuery.eq(AiMemberTalkItem::getType,1); memberTalkItemQuery.orderByDesc(AiMemberTalkItem::getCreatedTime); memberTalkItemQuery.last("limit 1"); - AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getByQuery(memberTalkItemQuery); + AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.getOneByQuery(memberTalkItemQuery); String question = aiMemberTalkItem.getContext(); String promptHead = aiProductRole.getPromptHead(); @@ -233,9 +253,48 @@ llmStrategyDtoList.add(llmStrategyDto); llmStrategyDto = this.buildLlmStrategyDtoList(String.valueOf(type), 4); llmStrategyDtoList.add(llmStrategyDto); + + LlmStrategyDto llmStrategyDtoMessage = buildMessages(state, memberTalkId); + llmStrategyDtoList.add(llmStrategyDtoMessage); String modelName = LlmStrategyEnum.getName(aiService.getSystemSetAiType()); return llmStrategyFactory.getCalculationStrategyMap().get(modelName).llmInvokeStreamingNoThink(llmStrategyDtoList); + } + + private LlmStrategyDto buildMessages(Integer state, String memberTalkId) { + + LlmStrategyDto message = new LlmStrategyDto(); + if (1!= state){ + return message; + } + LambdaQueryWrapper<AiMemberTalkItem> memberTalkItemQuery = Wrappers.lambdaQuery(AiMemberTalkItem.class); + memberTalkItemQuery.eq(AiMemberTalkItem::getMemberTalkId,memberTalkId); + memberTalkItemQuery.orderByAsc(AiMemberTalkItem::getCreatedTime); + List<AiMemberTalkItem> aiMemberTalkItems = aiMemberTalkItemService.getListByQuery(memberTalkItemQuery); + if (CollUtil.isEmpty(aiMemberTalkItems)){ + return message; + } + + List<LlmStrategyDto> messages = new ArrayList<>(); + for (AiMemberTalkItem aiMemberTalkItem : aiMemberTalkItems){ + LlmStrategyDto llmStrategyDto = new LlmStrategyDto(); + if (aiMemberTalkItem.getType() == 1){ + llmStrategyDto.setRole(Role.ASSISTANT.getValue()); + } + if (aiMemberTalkItem.getType() == 2){ + llmStrategyDto.setRole(Role.USER.getValue()); + } + if (aiMemberTalkItem.getType() == 3){ + llmStrategyDto.setRole(Role.ASSISTANT.getValue()); + } + llmStrategyDto.setContent(aiMemberTalkItem.getContext()); + messages.add(llmStrategyDto); + } + + message.setRole(AiTypeEnum.MESSAGES.getName()); + message.setMessages(messages); + + return message; } private String buildPrompt(String question,String answer,String promptHead, String promptTemplate,Integer type){ @@ -280,7 +339,7 @@ throw new FebsException("对话不存在"); } - this.updateMemberTalkUpdateTime(aiMemberTalk.getId(), new Date()); + this.updateMemberTalkUpdateTime(aiMemberTalk.getState(),aiMemberTalk.getDoneCnt(),aiMemberTalk.getId(), new Date()); String companyId = aiMemberTalk.getCompanyId(); Integer type = dto.getType(); @@ -312,12 +371,48 @@ } @Override - public void updateMemberTalkUpdateTime(String memberTalkId, Date updateTime) { + public void updateMemberTalkUpdateTime(Integer state,Integer doneCnt,String memberTalkId, Date updateTime) { aiMemberTalkMapper.update(null, Wrappers.lambdaUpdate(AiMemberTalk.class) - .set(AiMemberTalk::getUpdatedTime,updateTime) - .eq(AiMemberTalk::getId,memberTalkId) + .set(AiMemberTalk::getUpdatedTime,updateTime) + .set(AiMemberTalk::getDoneCnt,doneCnt) + .set(AiMemberTalk::getState,state) + .eq(AiMemberTalk::getId,memberTalkId) ); } + @Override + public FebsResponse saveReport(ApiMemberTalkReportSavaDto 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(AiTypeEnum.AI_MEMBER_TALK_STATE_DONE.getCode(), aiMemberTalk.getDoneCnt(),aiMemberTalk.getId(), new Date()); + + Integer type = dto.getType(); + String contentByCode = AiTalkOutputEnum.HIGH_LIGHT.getCodeByType(type); + String analysis = aiMemberTalk.getAnalysis(); + HashMap<String, String> stringStringHashMap = new HashMap<>(); + if(StrUtil.isEmpty(analysis)){ + stringStringHashMap.put(contentByCode,content); + }else{ + stringStringHashMap = JSONUtil.toBean(analysis, HashMap.class); + stringStringHashMap.put(contentByCode,content); + } + + aiMemberTalkMapper.update( + null, + Wrappers.lambdaUpdate(AiMemberTalk.class) + .set(AiMemberTalk::getAnalysis,JSONUtil.toJsonStr(stringStringHashMap)) + .eq(AiMemberTalk::getId,aiMemberTalk.getId()) + ); + + return new FebsResponse().success(); + } + } -- Gitblit v1.9.1