src/main/java/cc/mrbird/febs/ai/controller/member/ApiMemberController.java
@@ -88,4 +88,34 @@ return aiMemberService.study(dto); } @ApiOperation(value = "学习成果", notes = "学习成果") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiCompanyStudyVo.class) }) @PostMapping(value = "/studyList") public FebsResponse studyList(@RequestBody @Validated ApiCompanyStudyDto dto) { return aiMemberService.studyList(dto); } @ApiOperation(value = "学习成果-题目正确率", notes = "学习成果-题目正确率") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiCompanyStudyPercentVo.class) }) @PostMapping(value = "/studyPercentList") public FebsResponse studyPercentList(@RequestBody @Validated ApiCompanyStudyPercentDto dto) { return aiMemberService.studyPercentList(dto); } @ApiOperation(value = "学习成果-题目正确详情", notes = "学习成果-题目正确详情") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiCompanyStudyInfoVo.class) }) @PostMapping(value = "/studyInfoList") public FebsResponse studyInfoList(@RequestBody @Validated ApiCompanyStudyInfoDto dto) { return aiMemberService.studyInfoList(dto); } } src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerMapper.java
@@ -1,11 +1,14 @@ package cc.mrbird.febs.ai.mapper; import cc.mrbird.febs.ai.entity.AiMemberAnswer; import cc.mrbird.febs.ai.req.member.ApiCompanyStudyDto; import cc.mrbird.febs.ai.req.member.ApiMemberAnswerPageDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberProductWorkPageDto; import cc.mrbird.febs.ai.res.member.ApiCompanyStudyVo; import cc.mrbird.febs.ai.res.member.ApiMemberAnswerPageVo; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberProductWorkVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; @@ -20,4 +23,6 @@ Page<ApiMemberProductWorkVo> getPageMyWorkListByQuery(Page<ApiMemberProductWorkVo> page, @Param("record")ApiMemberProductWorkPageDto dto); Page<ApiMemberAnswerPageVo> getAnswerPage(Page<ApiMemberAnswerPageVo> page, @Param("record")ApiMemberAnswerPageDto dto); IPage<ApiCompanyStudyVo> selectProductListPage(Page<ApiCompanyStudyVo> page, @Param("record")ApiCompanyStudyDto dto); } src/main/java/cc/mrbird/febs/ai/mapper/AiMemberMapper.java
@@ -1,7 +1,11 @@ package cc.mrbird.febs.ai.mapper; import cc.mrbird.febs.ai.entity.AiMember; import cc.mrbird.febs.ai.req.member.ApiCompanyStudyDto; import cc.mrbird.febs.ai.res.member.ApiCompanyStudyVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; public interface AiMemberMapper extends BaseMapper<AiMember> { } src/main/java/cc/mrbird/febs/ai/req/member/ApiCompanyStudyDto.java
New file @@ -0,0 +1,27 @@ package cc.mrbird.febs.ai.req.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data @ApiModel(value = "ApiCompanyStudyDto", description = "参数") public class ApiCompanyStudyDto { @NotNull(message = "页码不能为空") @ApiModelProperty(value = "页码", example = "1") private Integer pageNow; @NotNull(message = "每页数量不能为空") @ApiModelProperty(value = "每页数量", example = "10") private Integer pageSize; @ApiModelProperty(value = "用户ID") private String memberUuid; @ApiModelProperty(value = "公司ID") private String companyId; } src/main/java/cc/mrbird/febs/ai/req/member/ApiCompanyStudyInfoDto.java
New file @@ -0,0 +1,19 @@ package cc.mrbird.febs.ai.req.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; @Data @ApiModel(value = "ApiCompanyStudyInfoDto", description = "参数") public class ApiCompanyStudyInfoDto { @NotBlank(message = "题目ID不能为空") @ApiModelProperty(value = "题目ID") private String productQuestionId; @ApiModelProperty(hidden = true) private String companyId; } src/main/java/cc/mrbird/febs/ai/req/member/ApiCompanyStudyPercentDto.java
New file @@ -0,0 +1,16 @@ package cc.mrbird.febs.ai.req.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; @Data @ApiModel(value = "ApiCompanyStudyPercentDto", description = "参数") public class ApiCompanyStudyPercentDto { @NotBlank(message = "产品ID不能为空") @ApiModelProperty(value = "产品ID") private String productId; } src/main/java/cc/mrbird/febs/ai/res/member/ApiCompanyStudyInfoVo.java
New file @@ -0,0 +1,19 @@ package cc.mrbird.febs.ai.res.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "ApiCompanyStudyInfoVo", description = "参数") public class ApiCompanyStudyInfoVo { @ApiModelProperty(value = "微信名") private String nickName; @ApiModelProperty(value = "用户姓名") private String memberName; @ApiModelProperty(value = "用户回答状态 0-未回答 1-答对了 2-答错了") private Integer memberAnswerState; } src/main/java/cc/mrbird/febs/ai/res/member/ApiCompanyStudyPercentItemVo.java
New file @@ -0,0 +1,28 @@ package cc.mrbird.febs.ai.res.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author Administrator */ @Data @ApiModel(value = "ApiCompanyStudyPercentItemVo", description = "参数") public class ApiCompanyStudyPercentItemVo { @ApiModelProperty(value = "选项ID") private String id; @ApiModelProperty(value = "答案") private String answer; @ApiModelProperty(value = "答案解析") private String answerAnalysis; @ApiModelProperty(value = "是否是正确答案 0-否 1-是") private Integer correctAnswer; @ApiModelProperty(value = "选择本项人数") private Long memberCnt; } src/main/java/cc/mrbird/febs/ai/res/member/ApiCompanyStudyPercentVo.java
New file @@ -0,0 +1,25 @@ package cc.mrbird.febs.ai.res.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; import java.util.List; @Data @ApiModel(value = "ApiCompanyStudyPercentVo", description = "参数") public class ApiCompanyStudyPercentVo { @ApiModelProperty(value = "题目") private String title; @ApiModelProperty(value = "难度:1-简单,2-中等,3-困难") private Integer difficulty; @ApiModelProperty(value = "题目ID") private String productQuestionId; @ApiModelProperty(value = "选项") private List<ApiCompanyStudyPercentItemVo> answerList; } src/main/java/cc/mrbird/febs/ai/res/member/ApiCompanyStudyVo.java
New file @@ -0,0 +1,23 @@ package cc.mrbird.febs.ai.res.member; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "ApiCompanyStudyVo", description = "参数") public class ApiCompanyStudyVo { @ApiModelProperty(value = "产品ID") private String productId; @ApiModelProperty(value = "名称") private String name; @ApiModelProperty(value = "目标") private String target; @ApiModelProperty(value = "练习人数") private Integer practiceCnt; } src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerItemService.java
@@ -1,12 +1,16 @@ package cc.mrbird.febs.ai.service; import cc.mrbird.febs.ai.entity.AiMemberAnswerItem; import cc.mrbird.febs.ai.entity.AiProductQuestionItem; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerWrongPageDto; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerPreviousVo; import cc.mrbird.febs.common.entity.FebsResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; /** * AI用户答题记录子表 Service接口 @@ -19,5 +23,7 @@ Page<ApiMemberAnswerPreviousVo> getPageListByQuery(Page<ApiMemberAnswerPreviousVo> page, ApiMemberAnswerPreviousDto dto); List<AiMemberAnswerItem> getListByQuery(LambdaQueryWrapper<AiMemberAnswerItem> wrapper); FebsResponse wrongPage(ApiMemberAnswerWrongPageDto dto); } src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java
@@ -1,11 +1,14 @@ package cc.mrbird.febs.ai.service; import cc.mrbird.febs.ai.entity.AiMemberAnswer; import cc.mrbird.febs.ai.req.member.ApiCompanyStudyDto; import cc.mrbird.febs.ai.req.member.ApiMemberAnswerPageDto; import cc.mrbird.febs.ai.req.memberAnswer.*; import cc.mrbird.febs.ai.res.member.ApiCompanyStudyVo; import cc.mrbird.febs.ai.res.member.ApiMemberAnswerPageVo; import cc.mrbird.febs.common.entity.FebsResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; @@ -45,4 +48,6 @@ List<AiMemberAnswer> getListByCompanyIdAndMemberUuid(String companyId, String memberUuid); Page<ApiMemberAnswerPageVo> getAnswerPage(Page<ApiMemberAnswerPageVo> page, ApiMemberAnswerPageDto dto); IPage<ApiCompanyStudyVo> selectListPage(ApiCompanyStudyDto dto, Page<ApiCompanyStudyVo> page); } src/main/java/cc/mrbird/febs/ai/service/AiMemberService.java
@@ -20,4 +20,10 @@ FebsResponse answerPage(ApiMemberAnswerPageDto dto); FebsResponse answerInfo(ApiMemberAnswerInfoDto dto); FebsResponse studyList(ApiCompanyStudyDto dto); FebsResponse studyPercentList(ApiCompanyStudyPercentDto dto); FebsResponse studyInfoList(ApiCompanyStudyInfoDto dto); } src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerItemServiceImpl.java
@@ -47,6 +47,11 @@ } @Override public List<AiMemberAnswerItem> getListByQuery(LambdaQueryWrapper<AiMemberAnswerItem> wrapper) { return aiMemberAnswerItemMapper.selectList( wrapper); } @Override public FebsResponse wrongPage(ApiMemberAnswerWrongPageDto dto) { // 创建分页对象,传入当前页和每页大小 Page<ApiMemberAnswerWrongVo> page = new Page<>(dto.getPageNow(), dto.getPageSize()); src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java
@@ -3,8 +3,10 @@ import cc.mrbird.febs.ai.entity.*; import cc.mrbird.febs.ai.enumerates.AiTypeEnum; import cc.mrbird.febs.ai.mapper.AiMemberAnswerMapper; import cc.mrbird.febs.ai.req.member.ApiCompanyStudyDto; import cc.mrbird.febs.ai.req.member.ApiMemberAnswerPageDto; import cc.mrbird.febs.ai.req.memberAnswer.*; import cc.mrbird.febs.ai.res.member.ApiCompanyStudyVo; import cc.mrbird.febs.ai.res.member.ApiMemberAnswerPageVo; import cc.mrbird.febs.ai.res.memberAnswer.*; import cc.mrbird.febs.ai.res.product.ApiProductVo; @@ -19,6 +21,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -455,4 +458,9 @@ return aiMemberAnswerMapper.getAnswerPage(page,dto); } @Override public IPage<ApiCompanyStudyVo> selectListPage(ApiCompanyStudyDto dto, Page<ApiCompanyStudyVo> page) { return aiMemberAnswerMapper.selectProductListPage(page,dto); } } src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberServiceImpl.java
@@ -11,10 +11,12 @@ 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.entity.MallMemberCollection; 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.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -41,7 +43,9 @@ private final AiMemberPointService aiMemberPointService; private final AiProductService aiProductService; private final AiProductPointService aiProductPointService; private final AiProductQuestionService aiProductQuestionService; private final AiProductQuestionItemService aiProductQuestionItemService; private final AiProductQuestionLinkService aiProductQuestionLinkService; @Override public AiMember getById(String id) { return aiMemberMapper.selectById( id); @@ -371,4 +375,131 @@ return new FebsResponse().success().data(vos); } @Override public FebsResponse studyList(ApiCompanyStudyDto dto) { List<ApiCompanyStudyVo> objects = new ArrayList<>(); String companyId = LoginUserUtil.getLoginUser().getCompanyId(); String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); Integer checkOrder = LoginUserUtil.getLoginUser().getCheckOrder(); if (1 != checkOrder){ throw new FebsException("非管理员,无权限查看"); } dto.setMemberUuid( memberUuid); dto.setCompanyId( companyId); // 创建分页对象,传入当前页和每页大小 Page<ApiCompanyStudyVo> page = new Page<>(dto.getPageNow(), dto.getPageSize()); IPage<ApiCompanyStudyVo> result = aiMemberAnswerService.selectListPage(dto, page); return new FebsResponse().success().data(objects); } @Override public FebsResponse studyPercentList(ApiCompanyStudyPercentDto dto) { List<ApiCompanyStudyPercentVo> objects = new ArrayList<>(); String companyId = LoginUserUtil.getLoginUser().getCompanyId(); String productId = dto.getProductId(); LambdaQueryWrapper<AiProductQuestionLink> aiProductQuestionLinkLambdaQueryWrapper = Wrappers.lambdaQuery(AiProductQuestionLink.class); aiProductQuestionLinkLambdaQueryWrapper.eq(AiProductQuestionLink::getProductId, productId); aiProductQuestionLinkLambdaQueryWrapper.eq(AiProductQuestionLink::getCompanyId, companyId); List<AiProductQuestionLink> listByQuery = aiProductQuestionLinkService.getListByQuery(aiProductQuestionLinkLambdaQueryWrapper); if ( CollUtil.isEmpty(listByQuery)){ return new FebsResponse().success().data(objects); } Set<String> productQuestionIdSet = listByQuery.stream().map(AiProductQuestionLink::getProductQuestionId).collect(Collectors.toSet()); LambdaQueryWrapper<AiProductQuestion> questionQuery = Wrappers.lambdaQuery(AiProductQuestion.class); questionQuery.in(AiProductQuestion::getId,productQuestionIdSet); List<AiProductQuestion> aiProductQuestionList = aiProductQuestionService.getListByQuery(questionQuery); //利用stream流,操作集合aiProductQuestionList,返回一个map对象,key为productQuestionId,valueAiProductQuestion对象 Map<String, AiProductQuestion> questionMap = aiProductQuestionList.stream().collect(Collectors.toMap(AiProductQuestion::getId, AiProductQuestion -> AiProductQuestion)); LambdaQueryWrapper<AiProductQuestionItem> questionItemQuery = Wrappers.lambdaQuery(AiProductQuestionItem.class); questionItemQuery.in(AiProductQuestionItem::getProductQuestionId,productQuestionIdSet); questionItemQuery.eq(AiProductQuestionItem::getCompanyId,companyId); List<AiProductQuestionItem> aiProductQuestionItemList = aiProductQuestionItemService.getListByQuery(questionItemQuery); //利用stream流,操作集合listByQuery,返回一个map对象,key为productQuestionId,value为List<AiProductQuestionItem>对象 Map<String, List<AiProductQuestionItem>> questionItemMap = aiProductQuestionItemList.stream().collect(Collectors.groupingBy(AiProductQuestionItem::getProductQuestionId)); //stream流,aiProductQuestionItemList返回ID的set集合 Set<String> questionItemIdSet = aiProductQuestionItemList.stream().map(AiProductQuestionItem::getId).collect(Collectors.toSet()); LambdaQueryWrapper<AiMemberAnswerItem> memberAnswerItemLambdaQueryWrapper = Wrappers.lambdaQuery(AiMemberAnswerItem.class); memberAnswerItemLambdaQueryWrapper.in(AiMemberAnswerItem::getMemberAnswerQuestionId,questionItemIdSet); memberAnswerItemLambdaQueryWrapper.eq(AiMemberAnswerItem::getCompanyId,companyId); List<AiMemberAnswerItem> memberAnswerItemList = aiMemberAnswerItemService.getListByQuery(memberAnswerItemLambdaQueryWrapper); //利用stream流,操作集合memberAnswerItemList,返回一个map对象,key为memberAnswerQuestionId,value为按照memberAnswerQuestionId分组的集合的大小,默认值为0 Map<String, Long> memberAnswerItemCountMap = memberAnswerItemList .stream() .collect(Collectors.groupingBy( AiMemberAnswerItem::getMemberAnswerQuestionId, Collectors.counting() )); for (String productQuestionId : productQuestionIdSet){ ApiCompanyStudyPercentVo vo = new ApiCompanyStudyPercentVo(); vo.setProductQuestionId(productQuestionId); AiProductQuestion record = questionMap.get(productQuestionId); vo.setTitle(record.getTitle()); vo.setDifficulty(record.getDifficulty()); List<AiProductQuestionItem> questionItemList = questionItemMap.get(productQuestionId); List<ApiCompanyStudyPercentItemVo> answerList = new ArrayList<>(); if (CollUtil.isNotEmpty(questionItemList)){ for (AiProductQuestionItem questionItem : questionItemList){ ApiCompanyStudyPercentItemVo itemVo = new ApiCompanyStudyPercentItemVo(); itemVo.setId(questionItem.getId()); itemVo.setAnswer(questionItem.getAnswer()); itemVo.setAnswerAnalysis(questionItem.getAnswerAnalysis()); itemVo.setCorrectAnswer(questionItem.getCorrectAnswer()); itemVo.setMemberCnt(memberAnswerItemCountMap.getOrDefault(questionItem.getId(),0L)); answerList.add(itemVo); } } vo.setAnswerList(answerList); objects.add( vo); } return new FebsResponse().success().data(objects); } @Override public FebsResponse studyInfoList(ApiCompanyStudyInfoDto dto) { List<ApiCompanyStudyInfoVo> objects = new ArrayList<>(); String companyId = LoginUserUtil.getLoginUser().getCompanyId(); String productQuestionId = dto.getProductQuestionId(); LambdaQueryWrapper<AiMemberAnswerItem> memberAnswerItemLambdaQueryWrapper = Wrappers.lambdaQuery(AiMemberAnswerItem.class); memberAnswerItemLambdaQueryWrapper.eq(AiMemberAnswerItem::getProductQuestionId,productQuestionId); memberAnswerItemLambdaQueryWrapper.eq(AiMemberAnswerItem::getCompanyId,companyId); List<AiMemberAnswerItem> memberAnswerItemList = aiMemberAnswerItemService.getListByQuery(memberAnswerItemLambdaQueryWrapper); if ( CollUtil.isEmpty(memberAnswerItemList)){ return new FebsResponse().success().data(objects); } Set<String> memberIdSet = memberAnswerItemList.stream().map(AiMemberAnswerItem::getMemberId).collect(Collectors.toSet()); List<MallMember> mallMembers = mallMemberMapper.selectList( Wrappers.lambdaQuery(MallMember.class) .select(MallMember::getMemberUuid, MallMember::getName, MallMember::getRealName) .in(MallMember::getMemberUuid, memberIdSet) .eq(MallMember::getCompanyId, companyId) ); //Stream流操作mallMembers,获取一个map<memberUuid,mallMember>的对象 Map<String, MallMember> mallMemberMap = mallMembers.stream().collect(Collectors.toMap(MallMember::getMemberUuid, mallMember -> mallMember)); for (AiMemberAnswerItem memberAnswerItem : memberAnswerItemList){ ApiCompanyStudyInfoVo vo = new ApiCompanyStudyInfoVo(); vo.setMemberName(mallMemberMap.get(memberAnswerItem.getMemberId()).getName()); vo.setNickName(mallMemberMap.get(memberAnswerItem.getMemberId()).getRealName()); vo.setMemberAnswerState(memberAnswerItem.getMemberAnswerState()); objects.add(vo); } return new FebsResponse().success().data(objects); } } src/main/resources/mapper/modules/AiMemberAnswerMapper.xml
@@ -42,4 +42,21 @@ and a.company_id = #{record.companyId} order by a.CREATED_TIME desc </select> <select id="selectProductListPage" resultType="cc.mrbird.febs.ai.res.member.ApiCompanyStudyVo"> select a.id as productId, a.name as name, a.target as target from ai_member_answer b left join ai_product a on b.product_id = a.id and a.state = 1 where b.member_id = #{record.memberUuid} and b.company_id = #{record.companyId} and b.state = 1 group by b.product_id order by b.CREATED_TIME desc </select> </mapper>