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/AiMemberServiceImpl.java | 205 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 184 insertions(+), 21 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberServiceImpl.java index f09837b..ac90ba3 100644 --- a/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberServiceImpl.java @@ -1,17 +1,22 @@ package cc.mrbird.febs.ai.service.impl; -import cc.mrbird.febs.ai.entity.AiMember; -import cc.mrbird.febs.ai.entity.AiMemberTalk; +import cc.mrbird.febs.ai.entity.*; import cc.mrbird.febs.ai.mapper.AiMemberMapper; -import cc.mrbird.febs.ai.req.member.ApiMemberPageDto; -import cc.mrbird.febs.ai.res.member.ApiMemberPageVo; -import cc.mrbird.febs.ai.service.AiMemberService; -import cc.mrbird.febs.ai.service.AiMemberTalkService; +import cc.mrbird.febs.ai.req.member.ApiMemberTeamPageDto; +import cc.mrbird.febs.ai.req.member.ApiMemberTeamPracticeDto; +import cc.mrbird.febs.ai.req.member.ApiMemberTeamStudyDto; +import cc.mrbird.febs.ai.res.member.ApiMemberTeamPageVo; +import cc.mrbird.febs.ai.res.member.ApiMemberTeamPracticeVo; +import cc.mrbird.febs.ai.res.member.ApiMemberTeamStudyVo; +import cc.mrbird.febs.ai.res.productPoint.ApiProductPointListVo; +import cc.mrbird.febs.ai.service.*; import cc.mrbird.febs.common.entity.FebsResponse; +import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.LoginUserUtil; import cc.mrbird.febs.mall.entity.MallMember; import cc.mrbird.febs.mall.mapper.MallMemberMapper; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -20,10 +25,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -37,16 +39,25 @@ private final AiMemberMapper aiMemberMapper; private final MallMemberMapper mallMemberMapper; private final AiMemberTalkService aiMemberTalkService; + private final AiMemberAnswerService aiMemberAnswerService; + private final AiMemberPointService aiMemberPointService; + private final AiProductService aiProductService; + private final AiProductPointService aiProductPointService; @Override public AiMember getById(String id) { return aiMemberMapper.selectById( id); } @Override - public FebsResponse myTeam(ApiMemberPageDto dto) { - List<ApiMemberPageVo> objects = new ArrayList<>(); + public FebsResponse myTeam(ApiMemberTeamPageDto dto) { + List<ApiMemberTeamPageVo> objects = new ArrayList<>(); String companyId = LoginUserUtil.getLoginUser().getCompanyId(); + String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); + Integer checkOrder = LoginUserUtil.getLoginUser().getCheckOrder(); + if (1 != checkOrder){ + throw new FebsException("非管理员,无权限查看"); + } // 创建分页对象,传入当前页和每页大小 Page<AiMember> page = new Page<>(dto.getPageNow(), dto.getPageSize()); @@ -56,12 +67,12 @@ Page<AiMember> pageListByQuery = aiMemberMapper.selectPage(page, queryWrapper); List<AiMember> records = pageListByQuery.getRecords(); if (CollUtil.isNotEmpty( records)){ - objects = buildMemberPages(companyId,records,objects); + objects = buildMemberPages(memberUuid,companyId,records,objects); } return new FebsResponse().success().data(objects); } - private List<ApiMemberPageVo> buildMemberPages(String companyId,List<AiMember> records,List<ApiMemberPageVo> objects) { + private List<ApiMemberTeamPageVo> buildMemberPages(String memberUuid, String companyId, List<AiMember> records, List<ApiMemberTeamPageVo> objects) { /** * 获取用户信息 */ @@ -78,24 +89,176 @@ Map<String, MallMember> mallMemberMap = mallMembers.stream().collect(Collectors.toMap(MallMember::getMemberUuid, mallMember -> mallMember)); /** - * 获取用户联系次数 + * 获取用户练习次数 * ai陪练 * ai答题 */ List<AiMemberTalk> aiMemberTalks = aiMemberTalkService.getListByCompanyId(companyId); - //Stream流操作aiMemberTalks,获取一个map<memberUuid,aiMemberTalk>的对象 + //stream流操作aiMemberTalks,获取一个Map<memberId,Integer>的对象,integer代表按照memberId分组的数量 + Map<String, Integer> memberIdToCntMapTalk = aiMemberTalks.stream() + .collect(Collectors.groupingBy( + AiMemberTalk::getMemberId, + Collectors.summingInt(t -> 1) + )); + + List<AiMemberAnswer> aiMemberAnswers = aiMemberAnswerService.getListByCompanyId(companyId); + //stream流操作aiMemberAnswers,获取一个Map<memberId,Integer>的对象,integer代表按照memberId分组的数量 + Map<String, Integer> memberIdToCntMapAnswer = aiMemberAnswers.stream() + .collect(Collectors.groupingBy( + AiMemberAnswer::getMemberId, + Collectors.summingInt(a -> 1) + )); + /** + * 用户学习总时长 + */ + List<AiMemberPoint> aiMemberPoints = aiMemberPointService.getListByCompanyId(companyId); + Map<String, Integer> memberStudyTimeMap = aiMemberPoints.stream().collect(Collectors.groupingBy( + AiMemberPoint::getMemberId, + Collectors.summingInt(AiMemberPoint::getTotalTime) + )); for (AiMember aiMember : records){ - ApiMemberPageVo apiMemberPageVo = new ApiMemberPageVo(); - apiMemberPageVo.setMemberUuid(aiMember.getId()); + String aiMemberId = aiMember.getId(); + ApiMemberTeamPageVo apiMemberTeamPageVo = new ApiMemberTeamPageVo(); + apiMemberTeamPageVo.setType(0); + apiMemberTeamPageVo.setMemberUuid(aiMemberId); + if (memberUuid.equals(aiMemberId)){ + apiMemberTeamPageVo.setType(1); + } //判断mallMemberMap中是否存在该会员 - apiMemberPageVo.setMemberName(mallMemberMap.containsKey(aiMember.getId()) ? mallMemberMap.get(aiMember.getId()).getName() : ""); - apiMemberPageVo.setNickName(mallMemberMap.containsKey(aiMember.getId()) ? mallMemberMap.get(aiMember.getId()).getName() : ""); + apiMemberTeamPageVo.setNickName(mallMemberMap.containsKey(aiMemberId) ? mallMemberMap.get(aiMemberId).getName() : ""); + apiMemberTeamPageVo.setMemberName(mallMemberMap.containsKey(aiMemberId) ? mallMemberMap.get(aiMemberId).getName() : ""); + Integer practiceCnt = 0; + if (memberIdToCntMapTalk.containsKey(aiMemberId)){ + practiceCnt = memberIdToCntMapTalk.get(aiMemberId); + } + if (memberIdToCntMapAnswer.containsKey(aiMemberId)){ + practiceCnt = memberIdToCntMapAnswer.get(aiMemberId) + practiceCnt; + } + apiMemberTeamPageVo.setPracticeCnt(practiceCnt); - objects.add(apiMemberPageVo); + Integer studyTime = 0; + if (memberStudyTimeMap.containsKey(aiMemberId)){ + studyTime = memberStudyTimeMap.get(aiMemberId); + } + apiMemberTeamPageVo.setStudyTime(DateUtil.secondToTime(studyTime)); + objects.add(apiMemberTeamPageVo); } return objects; } + + + + @Override + public FebsResponse practice(ApiMemberTeamPracticeDto dto) { + List<ApiMemberTeamPracticeVo> vos = new ArrayList<>(); + + String companyId = LoginUserUtil.getLoginUser().getCompanyId(); + String memberUuid = dto.getMemberUuid(); + + List<AiMemberTalk> aiMemberTalks = aiMemberTalkService.getListByCompanyIdAndMemberUuid(companyId, memberUuid); + Map<String, List<AiMemberTalk>> aiMemberTalkMap = new HashMap<>(); + if (CollUtil.isNotEmpty(aiMemberTalks)){ + //stream操作aiMemberTalks,返回一个根据productId分组的集合 + aiMemberTalkMap = aiMemberTalks.stream().collect(Collectors.groupingBy(AiMemberTalk::getProductId)); + } + + List<AiMemberAnswer> aiMemberAnswers = aiMemberAnswerService.getListByCompanyIdAndMemberUuid(companyId, memberUuid); + Map<String, List<AiMemberAnswer>> aiMemberAnswerMap = new HashMap<>(); + if (CollUtil.isNotEmpty(aiMemberAnswers)){ + aiMemberAnswerMap = aiMemberAnswers.stream().collect(Collectors.groupingBy(AiMemberAnswer::getProductId)); + } + + // 获取aiMemberTalkMap和aiMemberAnswerMap的全部的key,并且去重 + Set<String> productIds = new HashSet<>(); + if (aiMemberTalkMap != null) { + productIds.addAll(aiMemberTalkMap.keySet()); + } + if (aiMemberAnswerMap != null) { + productIds.addAll(aiMemberAnswerMap.keySet()); + } + if (CollUtil.isEmpty(productIds)){ + return new FebsResponse().success().data(vos); + } + + List<AiProduct> aiProducts = aiProductService.getProductListByQuery( + Wrappers.lambdaQuery(AiProduct.class) + .select(AiProduct::getId,AiProduct::getName, AiProduct::getTarget) + .in(AiProduct::getId, productIds) + ); + if (CollUtil.isEmpty(aiProducts)){ + return new FebsResponse().success().data(vos); + } + + for (AiProduct aiProduct : aiProducts){ + + String productId = aiProduct.getId(); + ApiMemberTeamPracticeVo vo = new ApiMemberTeamPracticeVo(); + vo.setName(aiProduct.getName()); + vo.setTarget(aiProduct.getTarget()); + + Integer answerCnt = 0; + if (aiMemberAnswerMap.containsKey(productId)){ + answerCnt = aiMemberAnswerMap.get(productId).size(); + } + vo.setAnswerCnt(answerCnt); + + Integer talkCnt = 0; + if (aiMemberTalkMap.containsKey(productId)){ + talkCnt = aiMemberTalkMap.get(productId).size(); + } + vo.setTalkCnt(talkCnt); + + vos.add( vo); + } + + + return new FebsResponse().success().data(vos); + } + + @Override + public FebsResponse study(ApiMemberTeamStudyDto dto) { + + List<ApiMemberTeamStudyVo> vos = new ArrayList<>(); + + String companyId = LoginUserUtil.getLoginUser().getCompanyId(); + String memberUuid = dto.getMemberUuid(); + + List<AiMemberPoint> aiMemberPoints = aiMemberPointService.getListByCompanyIdAndMemberUuid(companyId, memberUuid); + if (CollUtil.isEmpty(aiMemberPoints)){ + return new FebsResponse().success().data(vos); + } + Map<String, AiMemberPoint> aiMemberPointMap = new HashMap<>(); + if (CollUtil.isNotEmpty(aiMemberPoints)){ + aiMemberPoints.forEach(aiMemberPoint -> aiMemberPointMap.put(aiMemberPoint.getProductPointId(),aiMemberPoint)); + } + + //stream流操作aiMemberPoints,返回一个productPointId的set集合 + Set<String> productPointIdSet = aiMemberPoints.stream().map(AiMemberPoint::getProductPointId).collect(Collectors.toSet()); + + List<AiProductPoint> aiProductPoints = aiProductPointService.getBaseMapper().selectList( + Wrappers.lambdaQuery(AiProductPoint.class) + .select(AiProductPoint::getId,AiProductPoint::getTitle) + .in(AiProductPoint::getId, productPointIdSet) + ); + if (CollUtil.isEmpty(aiProductPoints)){ + return new FebsResponse().success().data(vos); + } + + for (AiProductPoint aiProductPoint : aiProductPoints){ + ApiMemberTeamStudyVo vo = new ApiMemberTeamStudyVo(); + vo.setTitle(aiProductPoint.getTitle()); + Integer totalTime = 0; + if (aiMemberPointMap.containsKey(aiProductPoint.getId())){ + totalTime = aiMemberPointMap.get(aiProductPoint.getId()).getTotalTime(); + } + vo.setTotalTime(DateUtil.secondToTime(totalTime)); + + vos.add(vo); + } + + return new FebsResponse().success().data(vos); + } } -- Gitblit v1.9.1