| | |
| | | package cc.mrbird.febs.ai.service.impl; |
| | | |
| | | import cc.mrbird.febs.ai.enumerates.AiTypeEnum; |
| | | import cc.mrbird.febs.ai.entity.AiMemberTalk; |
| | | import cc.mrbird.febs.ai.entity.AiMemberTalkItem; |
| | | import cc.mrbird.febs.ai.entity.AiProductRoleLink; |
| | | import cc.mrbird.febs.ai.mapper.AiMemberTalkMapper; |
| | | import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkAnswerDto; |
| | | import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkDto; |
| | | import cc.mrbird.febs.ai.req.ai.AiMessage; |
| | | import cc.mrbird.febs.ai.req.ai.AiRequest; |
| | | import cc.mrbird.febs.ai.req.memberTalk.*; |
| | | import cc.mrbird.febs.ai.res.ai.AiResponse; |
| | | import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkReloadVo; |
| | | import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkVo; |
| | | import cc.mrbird.febs.ai.service.AiMemberTalkItemService; |
| | | import cc.mrbird.febs.ai.service.AiMemberTalkService; |
| | |
| | | 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.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 org.springframework.transaction.annotation.Transactional; |
| | | import reactor.core.publisher.Flux; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.function.Consumer; |
| | | |
| | | /** |
| | | * AI用户对话训练记录 Service实现类 |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public FebsResponse start(ApiMemberTalkDto dto) { |
| | | |
| | | String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | |
| | | aiMemberTalk = this.add(memberUuid,productId,nowTime); |
| | | } |
| | | |
| | | AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(),"<strong>\"生成题目\"</strong>"); |
| | | if(aiResponse.getCode().equals("200")){ |
| | | aiMemberTalkItemService.add(memberUuid,aiMemberTalk.getId(),1,aiResponse.getResContext(),nowTime); |
| | | this.updateTimeUpdate(nowTime,aiMemberTalk.getId()); |
| | | }else{ |
| | | throw new FebsException(aiResponse.getDescription()); |
| | | } |
| | | List<AiMessage> aiMessageDtoList = aiMemberTalkItemService.getQuestionUpDownContext(aiMemberTalk.getId(),AiTypeEnum.QUESTION.getCode()); |
| | | |
| | | AiResponse aiResponse = aiService.start(aiMessageDtoList,AiTypeEnum.QUESTION.getCode(),aiProductRoleLink.getProductRoleId(),AiTypeEnum.QUESTION.getName(), null); |
| | | |
| | | ApiMemberTalkVo apiMemberTalkVo = new ApiMemberTalkVo(); |
| | | apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId()); |
| | | apiMemberTalkVo.setType(1); |
| | | apiMemberTalkVo.setContext(aiResponse.getResContext()); |
| | | apiMemberTalkVo.setReport(aiResponse.getReport()); |
| | | |
| | | if(aiResponse.getCode().equals("200")){ |
| | | AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.add(memberUuid, aiMemberTalk.getId(), 1, aiResponse.getResContext(), nowTime); |
| | | apiMemberTalkVo.setMemberTalkItemId(aiMemberTalkItem.getId()); |
| | | this.updateTimeUpdate(nowTime,aiMemberTalk.getId()); |
| | | }else{ |
| | | throw new FebsException(aiResponse.getDescription()); |
| | | } |
| | | return new FebsResponse().success().data(apiMemberTalkVo); |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse reload(ApiMemberTalkReloadDto dto) { |
| | | |
| | | String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | | ApiMemberTalkReloadVo apiMemberTalkReloadVo = new ApiMemberTalkReloadVo(); |
| | | String memberTalkId = dto.getMemberTalkId(); |
| | | LambdaQueryWrapper<AiMemberTalkItem> queryWrapper = Wrappers.lambdaQuery(AiMemberTalkItem.class); |
| | | queryWrapper.eq(AiMemberTalkItem::getMemberTalkId,memberTalkId); |
| | | queryWrapper.eq(AiMemberTalkItem::getType,AiTypeEnum.QUESTION_ANSWER.getCode()); |
| | | queryWrapper.orderByDesc(AiMemberTalkItem::getCreatedTime); |
| | | queryWrapper.last("limit 1"); |
| | | AiMemberTalkItem byQuery = aiMemberTalkItemService.getByQuery(queryWrapper); |
| | | if (ObjectUtil.isNotNull(byQuery)){ |
| | | apiMemberTalkReloadVo.setContext(byQuery.getContext()); |
| | | apiMemberTalkReloadVo.setMemberTalkId(memberTalkId); |
| | | apiMemberTalkReloadVo.setType(AiTypeEnum.QUESTION_ANSWER.getCode()); |
| | | } |
| | | return new FebsResponse().success().data(apiMemberTalkReloadVo); |
| | | } |
| | | |
| | | @Override |
| | | public void startStream(ApiMemberTalkDto dto, Consumer<AiResponse> callback) { |
| | | try { |
| | | String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | | String productId = dto.getId(); |
| | | |
| | | LambdaQueryWrapper<AiProductRoleLink> productLinkQuery = Wrappers.lambdaQuery(AiProductRoleLink.class); |
| | | productLinkQuery.eq(AiProductRoleLink::getProductId, productId); |
| | | productLinkQuery.last("limit 1"); |
| | | AiProductRoleLink aiProductRoleLink = aiProductRoleLinkService.getByQuery(productLinkQuery); |
| | | if (ObjectUtil.isNull(aiProductRoleLink)) { |
| | | AiResponse aiResponse = new AiResponse(); |
| | | aiResponse.setCode("500"); |
| | | aiResponse.setDescription("产品AI陪练不存在"); |
| | | callback.accept(aiResponse); |
| | | return; |
| | | } |
| | | |
| | | // 构造AI请求 |
| | | AiRequest aiRequest = new AiRequest(); |
| | | aiRequest.setLinkId(aiProductRoleLink.getProductRoleId()); |
| | | aiRequest.setPromptTemplate(aiProductRoleLink.getProductRoleId()); |
| | | aiRequest.setContent("<strong>\"生成题目\"</strong>"); |
| | | |
| | | // 定义AI服务回调处理 |
| | | Consumer<AiResponse> aiCallback = aiResponse -> { |
| | | Date nowTime = new Date(); |
| | | LambdaQueryWrapper<AiMemberTalk> query = Wrappers.lambdaQuery(AiMemberTalk.class); |
| | | query.eq(AiMemberTalk::getMemberId, memberUuid); |
| | | query.eq(AiMemberTalk::getProductId, productId); |
| | | query.last("limit 1"); |
| | | AiMemberTalk aiMemberTalk = this.getByQuery(query); |
| | | if (ObjectUtil.isNull(aiMemberTalk)) { |
| | | aiMemberTalk = this.add(memberUuid, productId, nowTime); |
| | | } |
| | | try { |
| | | if (aiResponse.getCode().equals("200")) { |
| | | // 如果是最终结果(包含报告) |
| | | if (aiResponse.getReport() != null) { |
| | | // 保存完整响应到数据库 |
| | | aiMemberTalkItemService.add(memberUuid, aiMemberTalk.getId(), 1, aiResponse.getResContext(), nowTime); |
| | | this.updateTimeUpdate(nowTime, aiMemberTalk.getId()); |
| | | |
| | | callback.accept(aiResponse); |
| | | } else { |
| | | // 流式响应片段 |
| | | callback.accept(aiResponse); |
| | | } |
| | | } else { |
| | | callback.accept(aiResponse); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("处理AI响应异常", e); |
| | | callback.accept(aiResponse); |
| | | } |
| | | }; |
| | | |
| | | // 调用AI服务的流式接口 |
| | | aiService.streamQuestion(aiRequest, aiCallback); |
| | | |
| | | } catch (Exception e) { |
| | | log.error("流式调用start方法异常", e); |
| | | |
| | | AiResponse aiResponse = new AiResponse(); |
| | | aiResponse.setCode("500"); |
| | | aiResponse.setDescription("流式调用start方法异常"); |
| | | callback.accept(aiResponse); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | |
| | | public static final String ANSWER_FORMAT = "{}/n[回答]{}/n"; |
| | | public static final String ANSWER_FORMAT = "###题目:{}###用户回答:{}"; |
| | | @Override |
| | | @Transactional |
| | | public FebsResponse answer(ApiMemberTalkAnswerDto dto) { |
| | | String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | | String memberTalkId = dto.getId(); |
| | |
| | | |
| | | String format = StrUtil.format(ANSWER_FORMAT, aiMemberTalkItem.getContext(), reqContext); |
| | | log.info("format:{}",format); |
| | | AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), format); |
| | | // AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), reqContext); |
| | | if(aiResponse.getCode().equals("200")){ |
| | | Date nowTime = new Date(); |
| | | aiMemberTalkItemService.add(memberUuid,aiMemberTalk.getId(),3,aiResponse.getResContext(),nowTime); |
| | | this.updateTimeUpdate(nowTime,aiMemberTalk.getId()); |
| | | }else{ |
| | | throw new FebsException(aiResponse.getDescription()); |
| | | } |
| | | // AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), format); |
| | | |
| | | |
| | | ApiMemberTalkVo apiMemberTalkVo = new ApiMemberTalkVo(); |
| | | apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId()); |
| | | apiMemberTalkVo.setType(3); |
| | | apiMemberTalkVo.setContext(aiResponse.getResContext()); |
| | | apiMemberTalkVo.setReport(aiResponse.getReport()); |
| | | List<AiMessage> aiMessageDtoList = aiMemberTalkItemService.getQuestionUpDownContext(aiMemberTalk.getId(),AiTypeEnum.ANSWER.getCode()); |
| | | AiResponse aiResponse = aiService.start(aiMessageDtoList,AiTypeEnum.ANSWER.getCode(),aiProductRoleLink.getProductRoleId(), reqContext,aiMemberTalkItem.getContext()); |
| | | String context = null; |
| | | if(aiResponse.getCode().equals("200")){ |
| | | Date nowTime = new Date(); |
| | | context = String.valueOf(JSONUtil.parse(aiResponse.getReport())); |
| | | if ("null".equals( context)){ |
| | | context = aiResponse.getResContext(); |
| | | } |
| | | AiMemberTalkItem talkItem = aiMemberTalkItemService.add(memberUuid, aiMemberTalk.getId(), 3, context, nowTime); |
| | | this.updateTimeUpdate(nowTime,aiMemberTalk.getId()); |
| | | |
| | | |
| | | apiMemberTalkVo.setContext(context); |
| | | apiMemberTalkVo.setMemberTalkItemId(talkItem.getId()); |
| | | }else{ |
| | | throw new FebsException(aiResponse.getDescription()); |
| | | } |
| | | return new FebsResponse().success().data(apiMemberTalkVo); |
| | | } |
| | | @Override |
| | |
| | | aiMemberTalkMapper.insert(aiMemberTalk); |
| | | return aiMemberTalk; |
| | | } |
| | | |
| | | @Override |
| | | public FebsResponse historyPage(ApiMemberTalkItemPageDto dto) { |
| | | String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | | dto.setMemberUuid(memberUuid); |
| | | return new FebsResponse().success().data(aiMemberTalkItemService.historyPage(dto)); |
| | | } |
| | | |
| | | @Override |
| | | public Flux<FebsResponse> answerStream(String question) { |
| | | |
| | | // String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); |
| | | return aiService.answerStream(question); |
| | | } |
| | | |
| | | } |