package cc.mrbird.febs.ai.service.impl;
|
|
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.*;
|
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实现类
|
*
|
* @author yourname
|
* @date 2025-07-29
|
*/
|
@Slf4j
|
@Service
|
@RequiredArgsConstructor
|
public class ApiMemberTalkStreamServiceImpl extends ServiceImpl<AiMemberTalkMapper, AiMemberTalk> implements ApiMemberTalkStreamService {
|
|
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;
|
|
|
@Override
|
public FebsResponse start(ApiMemberTalkStreamDto dto) {
|
|
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)){
|
throw new FebsException("产品AI陪练不存在");
|
}
|
|
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.last("limit 1");
|
AiMemberTalk aiMemberTalk = aiMemberTalkService.getByQuery(query);
|
if (ObjectUtil.isNull(aiMemberTalk)){
|
aiMemberTalk = aiMemberTalkService.add(memberUuid,companyId,productId,nowTime);
|
}
|
|
ApiMemberTalkStreamVo apiMemberTalkVo = new ApiMemberTalkStreamVo();
|
String title = "加载时间过程,请重试!";
|
AiProductQuestion question = aiProductQuestionService.createQuestion(productId);
|
if (ObjectUtil.isNotNull(question)){
|
title = question.getTitle();
|
AiMemberTalkItem aiMemberTalkItem = aiMemberTalkItemService.add(memberUuid, aiMemberTalk.getId(),companyId, 1, title, nowTime);
|
apiMemberTalkVo.setMemberTalkItemId(aiMemberTalkItem.getId());
|
aiMemberTalkService.updateTimeUpdate(nowTime,aiMemberTalk.getId());
|
}
|
apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId());
|
apiMemberTalkVo.setType(1);
|
apiMemberTalkVo.setContext(title);
|
return new FebsResponse().success().data(apiMemberTalkVo);
|
}
|
|
@Override
|
public FebsResponse reload(ApiMemberTalkReloadStreamDto dto) {
|
|
String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid();
|
ApiMemberTalkReloadStreamVo apiMemberTalkReloadVo = new ApiMemberTalkReloadStreamVo();
|
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 FebsResponse historyPage(ApiMemberTalkItemPageDto dto) {
|
String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid();
|
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)
|
);
|
}
|
|
}
|