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