src/main/java/cc/mrbird/febs/ai/controller/memberAnswer/ApiMemberAnswerController.java
@@ -1,8 +1,14 @@ package cc.mrbird.febs.ai.controller.memberAnswer; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerInsureDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiQuestionAnswerDto; import cc.mrbird.febs.ai.req.product.ApiProductInfoDto; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerInsureVo; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerPreviousVo; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerVo; import cc.mrbird.febs.ai.res.memberAnswer.ApiQuestionItemInfoVo; import cc.mrbird.febs.ai.res.product.ApiProductInfoVo; import cc.mrbird.febs.ai.service.AiMemberAnswerService; import cc.mrbird.febs.common.entity.FebsResponse; @@ -31,7 +37,7 @@ private final AiMemberAnswerService apiMemberAnswerService; @ApiOperation(value = "开始练习", notes = "开始练习") @ApiOperation(value = "开始答题", notes = "开始答题") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiMemberAnswerVo.class) }) @@ -40,4 +46,34 @@ return apiMemberAnswerService.startAnswer(dto); } @ApiOperation(value = "答题", notes = "答题") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiQuestionItemInfoVo.class) }) @PostMapping(value = "/answer") public FebsResponse answer(@RequestBody @Validated ApiQuestionAnswerDto dto) { return apiMemberAnswerService.answer(dto); } @ApiOperation(value = "提交", notes = "提交") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiMemberAnswerInsureVo.class) }) @PostMapping(value = "/insure") public FebsResponse insure(@RequestBody @Validated ApiMemberAnswerInsureDto dto) { return apiMemberAnswerService.insure(dto); } @ApiOperation(value = "上一题(分页大小为1)", notes = "上一题") @ApiResponses({ @ApiResponse(code = 200, message = "success", response = ApiMemberAnswerPreviousVo.class) }) @PostMapping(value = "/previous") public FebsResponse previous(@RequestBody @Validated ApiMemberAnswerPreviousDto dto) { return apiMemberAnswerService.previous(dto); } } src/main/java/cc/mrbird/febs/ai/mapper/AiMemberAnswerItemMapper.java
@@ -1,7 +1,11 @@ package cc.mrbird.febs.ai.mapper; import cc.mrbird.febs.ai.entity.AiMemberAnswerItem; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerPreviousVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; /** * AI用户答题记录子表 Mapper接口 @@ -11,4 +15,5 @@ */ public interface AiMemberAnswerItemMapper extends BaseMapper<AiMemberAnswerItem> { Page<ApiMemberAnswerPreviousVo> selectPageListByQuery(Page<ApiMemberAnswerPreviousVo> page, @Param("record") ApiMemberAnswerPreviousDto dto); } src/main/java/cc/mrbird/febs/ai/req/memberAnswer/ApiMemberAnswerInsureDto.java
New file @@ -0,0 +1,20 @@ package cc.mrbird.febs.ai.req.memberAnswer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; /** * @author Administrator */ @Data @ApiModel(value = "ApiMemberAnswerInsureDto", description = "参数") public class ApiMemberAnswerInsureDto { @NotBlank(message = "答题记录ID不能为空") @ApiModelProperty(value = "答题记录ID") private String memberAnswerId; } src/main/java/cc/mrbird/febs/ai/req/memberAnswer/ApiMemberAnswerPreviousDto.java
New file @@ -0,0 +1,30 @@ package cc.mrbird.febs.ai.req.memberAnswer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; /** * @author Administrator */ @Data @ApiModel(value = "ApiMemberAnswerPreviousDto", description = "参数") public class ApiMemberAnswerPreviousDto { @NotNull(message = "页码不能为空") @ApiModelProperty(value = "页码", example = "1") private Integer pageNow; @NotNull(message = "每页数量不能为空") @ApiModelProperty(value = "每页数量", example = "10") private Integer pageSize; @NotBlank(message = "答题记录ID不能为空") @ApiModelProperty(value = "答题记录ID") private String memberAnswerId; } src/main/java/cc/mrbird/febs/ai/req/memberAnswer/ApiQuestionAnswerDto.java
New file @@ -0,0 +1,27 @@ package cc.mrbird.febs.ai.req.memberAnswer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; /** * @author Administrator */ @Data @ApiModel(value = "ApiQuestionAnswerDto", description = "参数") public class ApiQuestionAnswerDto { @NotBlank(message = "选项ID不能为空") @ApiModelProperty(value = "选项ID", example = "10") private String id; @NotBlank(message = "答题记录ID不能为空") @ApiModelProperty(value = "答题记录ID") private String memberAnswerId; @NotBlank(message = "题目ID不能为空") @ApiModelProperty(value = "题目ID") private String productQuestionId; } src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiMemberAnswerInsureVo.java
New file @@ -0,0 +1,24 @@ package cc.mrbird.febs.ai.res.memberAnswer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * @author Administrator */ @Data @ApiModel(value = "ApiMemberAnswerInsureVo", description = "参数") public class ApiMemberAnswerInsureVo { @ApiModelProperty(value = "答对数量") private Integer correctCnt; @ApiModelProperty(value = "正确度") private String correctCntPercent; @ApiModelProperty(value = "用时") private Long useTime; } src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiMemberAnswerPreviousItemVo.java
New file @@ -0,0 +1,25 @@ package cc.mrbird.febs.ai.res.memberAnswer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author Administrator */ @Data @ApiModel(value = "ApiMemberAnswerPreviousItemVo", description = "参数") public class ApiMemberAnswerPreviousItemVo { @ApiModelProperty(value = "选项ID") private String id; @ApiModelProperty(value = "答案") private String answer; @ApiModelProperty(value = "答案解析") private String answerAnalysis; @ApiModelProperty(value = "是否是正确答案 0-否 1-是") private Integer correctAnswer; } src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiMemberAnswerPreviousVo.java
New file @@ -0,0 +1,49 @@ package cc.mrbird.febs.ai.res.memberAnswer; import cc.mrbird.febs.ai.res.productQuestionItem.ApiMemberAnswerItemVo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * @author Administrator */ @Data @ApiModel(value = "ApiMemberAnswerPreviousVo", description = "参数") public class ApiMemberAnswerPreviousVo { @ApiModelProperty(value = "用户答题记录ID") private String memberAnswerItemId; @ApiModelProperty(value = "用户答题ID") private String memberAnswerId; @ApiModelProperty(value = "产品题目ID") private String productQuestionId; @ApiModelProperty(value = "产品名称") private String name; @ApiModelProperty(value = "题目数量") private Integer questionCnt; @ApiModelProperty(value = "题目") private String title; @ApiModelProperty(value = "难度:1-简单,2-中等,3-困难") private Integer difficulty; @ApiModelProperty(value = "用户答题答案ID") private String memberAnswerQuestionId; @ApiModelProperty(value = "答案解析") private String answerAnalysis; @ApiModelProperty(value = "用户回答状态 0-未回答 1-答对了 2-答错了") private Integer memberAnswerState; @ApiModelProperty(value = "选项") private List<ApiMemberAnswerPreviousItemVo> answerList; } src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiMemberAnswerVo.java
@@ -14,38 +14,33 @@ @ApiModel(value = "ApiMemberAnswerVo", description = "参数") public class ApiMemberAnswerVo { @ApiModelProperty(value = "答题记录ID") private String memberAnswerId; @ApiModelProperty(value = "产品ID") private String productId; @ApiModelProperty(value = "题目ID") private String productQuestionId; @ApiModelProperty(value = "产品名称") private String name; @ApiModelProperty(value = "题目数量") private String questionCnt; private Integer questionCnt; @ApiModelProperty(value = "答题数量") private String questionDoneCnt; private Integer doneCnt; @ApiModelProperty(value = "答对数量") private String correctCnt; private Integer correctCnt; /** * 题目 */ @ApiModelProperty(value = "题目") private String title; /** * 难度:1-简单,2-中等,3-困难 */ @ApiModelProperty(value = "难度:1-简单,2-中等,3-困难") private Integer difficulty; /** * 答案 */ @ApiModelProperty(value = "答案") private List<ApiMemberAnswerItemVo> answer; @ApiModelProperty(value = "选项") private List<ApiMemberAnswerItemVo> answerList; } src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiQuestionItemInfoVo.java
New file @@ -0,0 +1,23 @@ package cc.mrbird.febs.ai.res.memberAnswer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author Administrator */ @Data @ApiModel(value = "ApiQuestionItemInfoVo", description = "参数") public class ApiQuestionItemInfoVo { @ApiModelProperty(value = "答案") private String answer; @ApiModelProperty(value = "答案解析") private String answerAnalysis; @ApiModelProperty(value = "用户回答状态 0-未回答 1-答对了 2-答错了") private Integer memberAnswerState; } src/main/java/cc/mrbird/febs/ai/res/productQuestionItem/ApiMemberAnswerItemVo.java
@@ -11,27 +11,15 @@ @ApiModel(value = "ApiMemberAnswerItemVo", description = "参数") public class ApiMemberAnswerItemVo { /** * 答案 */ @ApiModelProperty(value = "答案ID") @ApiModelProperty(value = "选项ID") private String id; /** * 答案 */ @ApiModelProperty(value = "答案") private String answer; /** * 是否是正确答案 0-否 1-是 */ @ApiModelProperty(value = "是否是正确答案 0-否 1-是") private Integer correctAnswer; /** * 答案解析 */ @ApiModelProperty(value = "答案解析") private String answerAnalysis; @ApiModelProperty(value = "是否是正确答案 0-否 1-是") private Integer correctAnswer; } src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerItemService.java
@@ -1,8 +1,10 @@ package cc.mrbird.febs.ai.service; import cc.mrbird.febs.ai.entity.AiMemberAnswerItem; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerPreviousVo; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; /** * AI用户答题记录子表 Service接口 @@ -13,4 +15,5 @@ public interface AiMemberAnswerItemService extends IService<AiMemberAnswerItem> { Page<ApiMemberAnswerPreviousVo> getPageListByQuery(Page<ApiMemberAnswerPreviousVo> page, ApiMemberAnswerPreviousDto dto); } src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java
@@ -2,7 +2,11 @@ import cc.mrbird.febs.ai.entity.AiMemberAnswer; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerInsureDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiQuestionAnswerDto; import cc.mrbird.febs.common.entity.FebsResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -14,6 +18,15 @@ */ public interface AiMemberAnswerService extends IService<AiMemberAnswer> { AiMemberAnswer getOneByQuery(LambdaQueryWrapper<AiMemberAnswer> aiMemberAnswerLambdaQueryWrapper); FebsResponse startAnswer(ApiMemberAnswerDto dto); boolean checkMemberAnswerDone(AiMemberAnswer aiMemberAnswer); FebsResponse answer(ApiQuestionAnswerDto dto); FebsResponse insure(ApiMemberAnswerInsureDto dto); FebsResponse previous(ApiMemberAnswerPreviousDto dto); } src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionItemService.java
@@ -1,7 +1,10 @@ package cc.mrbird.febs.ai.service; import cc.mrbird.febs.ai.entity.AiProductQuestionItem; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; /** * AI产品题目子表 Service接口 @@ -11,4 +14,5 @@ */ public interface AiProductQuestionItemService extends IService<AiProductQuestionItem> { List<AiProductQuestionItem> getListByQuery(LambdaQueryWrapper<AiProductQuestionItem> productQuestionItemLambdaQueryWrapper); } src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionLinkService.java
@@ -1,6 +1,7 @@ package cc.mrbird.febs.ai.service; import cc.mrbird.febs.ai.entity.AiProductQuestionLink; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -13,4 +14,5 @@ public interface AiProductQuestionLinkService extends IService<AiProductQuestionLink> { List<AiProductQuestionLink> getListByQuery(LambdaQueryWrapper<AiProductQuestionLink> aiProductQuestionLinkLambdaQueryWrapper); } src/main/java/cc/mrbird/febs/ai/service/AiProductQuestionService.java
@@ -13,6 +13,14 @@ */ public interface AiProductQuestionService extends IService<AiProductQuestion> { AiProductQuestion getById(String id); List<AiProductQuestion> getListByQuery(LambdaQueryWrapper<AiProductQuestion> questionLambdaQueryWrapper); /** * 生成一个产品题目 * @param productId * @return */ AiProductQuestion createQuestion(String productId); } src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerItemServiceImpl.java
@@ -1,18 +1,15 @@ package cc.mrbird.febs.ai.service.impl; import cc.mrbird.febs.ai.entity.AiMemberAnswerItem; import cc.mrbird.febs.ai.entity.AiProduct; import cc.mrbird.febs.ai.mapper.AiMemberAnswerItemMapper; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerPreviousVo; import cc.mrbird.febs.ai.service.AiMemberAnswerItemService; import cc.mrbird.febs.ai.service.AiProductService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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 java.util.List; /** * AI用户答题记录子表 Service实现类 @@ -26,4 +23,9 @@ public class AiMemberAnswerItemServiceImpl extends ServiceImpl<AiMemberAnswerItemMapper, AiMemberAnswerItem> implements AiMemberAnswerItemService { private final AiMemberAnswerItemMapper aiMemberAnswerItemMapper; @Override public Page<ApiMemberAnswerPreviousVo> getPageListByQuery(Page<ApiMemberAnswerPreviousVo> page, ApiMemberAnswerPreviousDto dto) { return aiMemberAnswerItemMapper.selectPageListByQuery(page, dto); } } src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java
@@ -1,28 +1,35 @@ package cc.mrbird.febs.ai.service.impl; import cc.mrbird.febs.ai.entity.AiMemberAnswer; import cc.mrbird.febs.ai.entity.AiMemberAnswerItem; import cc.mrbird.febs.ai.entity.AiProduct; import cc.mrbird.febs.ai.entity.AiProductQuestion; import cc.mrbird.febs.ai.entity.*; import cc.mrbird.febs.ai.mapper.AiMemberAnswerMapper; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerDto; import cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerVo; import cc.mrbird.febs.ai.service.AiMemberAnswerItemService; import cc.mrbird.febs.ai.service.AiMemberAnswerService; import cc.mrbird.febs.ai.service.AiProductQuestionService; import cc.mrbird.febs.ai.service.AiProductService; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerInsureDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiMemberAnswerPreviousDto; import cc.mrbird.febs.ai.req.memberAnswer.ApiQuestionAnswerDto; import cc.mrbird.febs.ai.res.memberAnswer.*; import cc.mrbird.febs.ai.res.product.ApiProductVo; import cc.mrbird.febs.ai.res.productQuestionItem.ApiMemberAnswerItemVo; import cc.mrbird.febs.ai.service.*; import cc.mrbird.febs.ai.utils.UUID; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.utils.LoginUserUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUnit; 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.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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 java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Date; import java.util.List; /** @@ -40,6 +47,14 @@ private final AiMemberAnswerItemService aiMemberAnswerItemService; private final AiProductService aiProductService; private final AiProductQuestionService aiProductQuestionService; private final AiProductQuestionItemService aiProductQuestionItemService; @Override public AiMemberAnswer getOneByQuery(LambdaQueryWrapper<AiMemberAnswer> aiMemberAnswerLambdaQueryWrapper) { aiMemberAnswerLambdaQueryWrapper.last("limit 1"); return aiMemberAnswerMapper.selectOne(aiMemberAnswerLambdaQueryWrapper); } @Override @@ -62,18 +77,202 @@ // todo 没有题目采用AI生成题目 throw new RuntimeException("产品没有题目"); } ApiMemberAnswerVo apiMemberAnswerVo = new ApiMemberAnswerVo(); AiMemberAnswer aiMemberAnswer = new AiMemberAnswer(); aiMemberAnswer.setProductId(aiProduct.getId()); aiMemberAnswer.setMemberId(memberUuid); aiMemberAnswer.setQuestionCnt(aiProduct.getQuestionCount()); aiMemberAnswer.setScore(0); aiMemberAnswer.setCorrectCnt(0); aiMemberAnswer.setState(0); aiMemberAnswerMapper.insert(aiMemberAnswer); //判断该产品是否有正在进行的练习 LambdaQueryWrapper<AiMemberAnswer> aiMemberAnswerLambdaQueryWrapper = Wrappers.lambdaQuery(AiMemberAnswer.class); aiMemberAnswerLambdaQueryWrapper.eq(AiMemberAnswer::getMemberId,memberUuid); aiMemberAnswerLambdaQueryWrapper.eq(AiMemberAnswer::getProductId,aiProduct.getId()); aiMemberAnswerLambdaQueryWrapper.eq(AiMemberAnswer::getState,0); AiMemberAnswer aiMemberAnswer = this.getOneByQuery(aiMemberAnswerLambdaQueryWrapper); if(ObjectUtil.isNull(aiMemberAnswer)){ aiMemberAnswer = new AiMemberAnswer(); aiMemberAnswer.setId(UUID.getSimpleUUIDString()); Date createdTime = new Date(); aiMemberAnswer.setCreatedTime(createdTime); aiMemberAnswer.setUpdatedTime(createdTime); aiMemberAnswer.setProductId(aiProduct.getId()); aiMemberAnswer.setMemberId(memberUuid); aiMemberAnswer.setState(0); aiMemberAnswer.setScore(0); aiMemberAnswer.setQuestionCnt(aiProduct.getQuestionCount()); aiMemberAnswer.setDoneCnt(0); aiMemberAnswer.setCorrectCnt(0); aiMemberAnswerMapper.insert(aiMemberAnswer); } boolean checkMemberAnswerDone = this.checkMemberAnswerDone(aiMemberAnswer); if(!checkMemberAnswerDone){ return new FebsResponse().fail().message("您已完成本次答题"); } // apiMemberAnswerVo.setTitle(); ApiMemberAnswerVo apiMemberAnswerVo = new ApiMemberAnswerVo(); apiMemberAnswerVo.setName(aiProduct.getName()); apiMemberAnswerVo.setQuestionCnt(aiMemberAnswer.getQuestionCnt()); apiMemberAnswerVo.setDoneCnt(aiMemberAnswer.getDoneCnt()); apiMemberAnswerVo.setCorrectCnt(aiMemberAnswer.getCorrectCnt()); apiMemberAnswerVo.setProductId(aiMemberAnswer.getProductId()); AiProductQuestion aiProductQuestion = aiProductQuestionService.createQuestion(aiProduct.getId()); if(ObjectUtil.isNotNull(aiProductQuestion)){ apiMemberAnswerVo.setProductQuestionId(aiProductQuestion.getId()); apiMemberAnswerVo.setTitle(aiProductQuestion.getTitle()); apiMemberAnswerVo.setDifficulty(aiProductQuestion.getDifficulty()); List<ApiMemberAnswerItemVo> answerList = new ArrayList<>(); LambdaQueryWrapper<AiProductQuestionItem> productQuestionItemLambdaQueryWrapper = Wrappers.lambdaQuery(AiProductQuestionItem.class); productQuestionItemLambdaQueryWrapper.eq(AiProductQuestionItem::getProductQuestionId,aiProductQuestion.getId()); productQuestionItemLambdaQueryWrapper.orderByAsc(AiProductQuestionItem::getCreatedTime); List<AiProductQuestionItem> aiProductQuestionItems = aiProductQuestionItemService.getListByQuery(productQuestionItemLambdaQueryWrapper); if (CollUtil.isNotEmpty(aiProductQuestionItems)){ for (AiProductQuestionItem aiProductQuestionItem : aiProductQuestionItems){ ApiMemberAnswerItemVo apiMemberAnswerItemVo = new ApiMemberAnswerItemVo(); apiMemberAnswerItemVo.setId(aiProductQuestionItem.getId()); apiMemberAnswerItemVo.setAnswer(aiProductQuestionItem.getAnswer()); apiMemberAnswerItemVo.setAnswerAnalysis(aiProductQuestionItem.getAnswerAnalysis()); apiMemberAnswerItemVo.setCorrectAnswer(aiProductQuestionItem.getCorrectAnswer()); answerList.add(apiMemberAnswerItemVo); } } apiMemberAnswerVo.setAnswerList(answerList); } return new FebsResponse().success().data(apiMemberAnswerVo); } @Override public boolean checkMemberAnswerDone(AiMemberAnswer aiMemberAnswer) { Integer doneCnt = aiMemberAnswer.getDoneCnt(); Integer questionCnt = aiMemberAnswer.getQuestionCnt(); if (questionCnt > doneCnt){ return true; } return false; } @Override public FebsResponse answer(ApiQuestionAnswerDto dto) { String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); ApiQuestionItemInfoVo apiQuestionItemInfoVo = new ApiQuestionItemInfoVo(); String productQuestionItemId = dto.getId(); String productQuestionId = dto.getProductQuestionId(); String memberAnswerId = dto.getMemberAnswerId(); AiMemberAnswer aiMemberAnswer = this.getById(memberAnswerId); if(ObjectUtil.isNull(aiMemberAnswer)){ throw new RuntimeException("答题记录不存在"); } Date createdTime = new Date(); AiMemberAnswerItem aiMemberAnswerItem = new AiMemberAnswerItem(); aiMemberAnswerItem.setId(UUID.getSimpleUUIDString()); aiMemberAnswerItem.setCreatedTime(createdTime); aiMemberAnswerItem.setAnswerId(aiMemberAnswer.getId()); aiMemberAnswerItem.setProductId(aiMemberAnswer.getProductId()); aiMemberAnswerItem.setMemberId(memberUuid); aiMemberAnswerItem.setProductQuestionId(productQuestionId); AiProductQuestion aiProductQuestion = aiProductQuestionService.getById(productQuestionId); aiMemberAnswerItem.setTitle(aiProductQuestion.getTitle()); aiMemberAnswerItem.setDifficulty(aiProductQuestion.getDifficulty()); LambdaQueryWrapper<AiProductQuestionItem> productQuestionItemLambdaQueryWrapper = Wrappers.lambdaQuery(AiProductQuestionItem.class); productQuestionItemLambdaQueryWrapper.eq(AiProductQuestionItem::getProductQuestionId,aiProductQuestion.getId()); productQuestionItemLambdaQueryWrapper.eq(AiProductQuestionItem::getCorrectAnswer,1); List<AiProductQuestionItem> listByQuery = aiProductQuestionItemService.getListByQuery(productQuestionItemLambdaQueryWrapper); if(CollUtil.isNotEmpty(listByQuery)){ AiProductQuestionItem aiProductQuestionItem = listByQuery.get(0); aiMemberAnswerItem.setAnswer(aiProductQuestionItem.getId()); aiMemberAnswerItem.setCorrectAnswer(aiProductQuestionItem.getCorrectAnswer()); aiMemberAnswerItem.setAnswerAnalysis(aiProductQuestionItem.getAnswerAnalysis()); } aiMemberAnswerItem.setMemberAnswerQuestionId(productQuestionItemId); aiMemberAnswerItem.setMemberAnswerState( ObjectUtil.equal(aiMemberAnswerItem.getMemberAnswerQuestionId(),aiMemberAnswerItem.getAnswer()) ? 1 : 2 ); if (aiMemberAnswerItem.getMemberAnswerState() == 2){ aiMemberAnswerItem.setIsCollected(1); } aiMemberAnswerItemService.save(aiMemberAnswerItem); aiMemberAnswer.setDoneCnt(aiMemberAnswer.getDoneCnt() + 1); if (aiMemberAnswerItem.getMemberAnswerState() == 1){ aiMemberAnswer.setCorrectCnt(aiMemberAnswer.getCorrectCnt() + 1); } aiMemberAnswer.setUpdatedTime(createdTime); this.updateById(aiMemberAnswer); apiQuestionItemInfoVo.setAnswer(aiMemberAnswerItem.getAnswer()); apiQuestionItemInfoVo.setAnswerAnalysis(aiMemberAnswerItem.getAnswerAnalysis()); apiQuestionItemInfoVo.setMemberAnswerState(aiMemberAnswerItem.getMemberAnswerState()); return new FebsResponse().success().data(apiQuestionItemInfoVo); } @Override public FebsResponse insure(ApiMemberAnswerInsureDto dto) { String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); ApiMemberAnswerInsureVo apiMemberAnswerInsureVo = new ApiMemberAnswerInsureVo(); String memberAnswerId = dto.getMemberAnswerId(); AiMemberAnswer aiMemberAnswer = this.getById(memberAnswerId); Integer questionCnt = aiMemberAnswer.getQuestionCnt(); Integer correctCnt = aiMemberAnswer.getCorrectCnt(); Date createdTime = aiMemberAnswer.getCreatedTime(); Date updatedTime = aiMemberAnswer.getUpdatedTime(); apiMemberAnswerInsureVo.setCorrectCnt(correctCnt); BigDecimal divide = new BigDecimal(correctCnt).divide(new BigDecimal(questionCnt), 2, RoundingMode.HALF_DOWN); // 转换为百分比字符串 BigDecimal percentage = divide.multiply(new BigDecimal(100)); String percentageStr = percentage.setScale(2, RoundingMode.HALF_DOWN).toString() + "%"; apiMemberAnswerInsureVo.setCorrectCntPercent(percentageStr); long between = DateUtil.between(createdTime, updatedTime, DateUnit.MINUTE); apiMemberAnswerInsureVo.setUseTime(between); return new FebsResponse().success().data(apiMemberAnswerInsureVo); } @Override public FebsResponse previous(ApiMemberAnswerPreviousDto dto) { String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid(); ApiMemberAnswerPreviousVo apiMemberAnswerPreviousVo = new ApiMemberAnswerPreviousVo(); // 创建分页对象,传入当前页和每页大小 Page<ApiMemberAnswerPreviousVo> page = new Page<>(dto.getPageNow(), dto.getPageSize()); Page<ApiMemberAnswerPreviousVo> pageListByQuery = aiMemberAnswerItemService.getPageListByQuery(page, dto); List<ApiMemberAnswerPreviousVo> records = pageListByQuery.getRecords(); if (CollUtil.isNotEmpty(records)){ apiMemberAnswerPreviousVo = records.get(0); String memberAnswerId = apiMemberAnswerPreviousVo.getMemberAnswerId(); AiMemberAnswer aiMemberAnswer = this.getById(memberAnswerId); String productId = aiMemberAnswer.getProductId(); AiProduct aiProduct = aiProductService.getById(productId); apiMemberAnswerPreviousVo.setName(aiProduct.getName()); apiMemberAnswerPreviousVo.setQuestionCnt(aiMemberAnswer.getQuestionCnt()); String productQuestionId = apiMemberAnswerPreviousVo.getProductQuestionId(); AiProductQuestion aiProductQuestion = aiProductQuestionService.getById(productQuestionId); apiMemberAnswerPreviousVo.setTitle(aiProductQuestion.getTitle()); apiMemberAnswerPreviousVo.setDifficulty(aiProductQuestion.getDifficulty()); List<ApiMemberAnswerPreviousItemVo> answerList = new ArrayList<>(); LambdaQueryWrapper<AiProductQuestionItem> productQuestionItemLambdaQueryWrapper = Wrappers.lambdaQuery(AiProductQuestionItem.class); productQuestionItemLambdaQueryWrapper.eq(AiProductQuestionItem::getProductQuestionId,productQuestionId); productQuestionItemLambdaQueryWrapper.orderByAsc(AiProductQuestionItem::getCreatedTime); List<AiProductQuestionItem> listByQuery = aiProductQuestionItemService.getListByQuery(productQuestionItemLambdaQueryWrapper); if(CollUtil.isNotEmpty(listByQuery)){ for (AiProductQuestionItem aiProductQuestionItem : listByQuery){ ApiMemberAnswerPreviousItemVo apiMemberAnswerPreviousItemVo = new ApiMemberAnswerPreviousItemVo(); apiMemberAnswerPreviousItemVo.setId(aiProductQuestionItem.getId()); apiMemberAnswerPreviousItemVo.setAnswer(aiProductQuestionItem.getAnswer()); apiMemberAnswerPreviousItemVo.setAnswerAnalysis(aiProductQuestionItem.getAnswerAnalysis()); apiMemberAnswerPreviousItemVo.setCorrectAnswer(aiProductQuestionItem.getCorrectAnswer()); answerList.add(apiMemberAnswerPreviousItemVo); } apiMemberAnswerPreviousVo.setAnswerList(answerList); } } return new FebsResponse().success().data(apiMemberAnswerPreviousVo); } } src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionItemServiceImpl.java
@@ -3,10 +3,13 @@ import cc.mrbird.febs.ai.entity.AiProductQuestionItem; import cc.mrbird.febs.ai.mapper.AiProductQuestionItemMapper; import cc.mrbird.febs.ai.service.AiProductQuestionItemService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * AI产品题目子表 Service实现类 @@ -19,4 +22,10 @@ @Transactional public class AiProductQuestionItemServiceImpl extends ServiceImpl<AiProductQuestionItemMapper, AiProductQuestionItem> implements AiProductQuestionItemService { private final AiProductQuestionItemMapper aiProductQuestionItemMapper; @Override public List<AiProductQuestionItem> getListByQuery(LambdaQueryWrapper<AiProductQuestionItem> productQuestionItemLambdaQueryWrapper) { return aiProductQuestionItemMapper.selectList(productQuestionItemLambdaQueryWrapper); } } src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionLinkServiceImpl.java
@@ -26,4 +26,8 @@ private final AiProductQuestionLinkMapper aiProductQuestionLinkMapper; @Override public List<AiProductQuestionLink> getListByQuery(LambdaQueryWrapper<AiProductQuestionLink> aiProductQuestionLinkLambdaQueryWrapper) { return aiProductQuestionLinkMapper.selectList(aiProductQuestionLinkLambdaQueryWrapper); } } src/main/java/cc/mrbird/febs/ai/service/impl/AiProductQuestionServiceImpl.java
@@ -1,9 +1,14 @@ package cc.mrbird.febs.ai.service.impl; import cc.mrbird.febs.ai.entity.AiProductQuestion; import cc.mrbird.febs.ai.entity.AiProductQuestionLink; import cc.mrbird.febs.ai.mapper.AiProductQuestionMapper; import cc.mrbird.febs.ai.service.AiProductQuestionLinkService; import cc.mrbird.febs.ai.service.AiProductQuestionService; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.RandomUtil; 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; @@ -11,6 +16,8 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * AI产品题目 Service实现类 @@ -24,10 +31,33 @@ public class AiProductQuestionServiceImpl extends ServiceImpl<AiProductQuestionMapper, AiProductQuestion> implements AiProductQuestionService { private final AiProductQuestionMapper aiProductQuestionMapper; private final AiProductQuestionLinkService aiProductQuestionLinkService; @Override public AiProductQuestion getById(String id) { return aiProductQuestionMapper.selectById( id); } @Override public List<AiProductQuestion> getListByQuery(LambdaQueryWrapper<AiProductQuestion> questionLambdaQueryWrapper) { return aiProductQuestionMapper.selectList(questionLambdaQueryWrapper); } @Override public AiProductQuestion createQuestion(String productId) { AiProductQuestion aiProductQuestion = new AiProductQuestion(); LambdaQueryWrapper<AiProductQuestionLink> aiProductQuestionLinkLambdaQueryWrapper = Wrappers.lambdaQuery(AiProductQuestionLink.class); aiProductQuestionLinkLambdaQueryWrapper.eq(AiProductQuestionLink::getProductId, productId); List<AiProductQuestionLink> linkList = aiProductQuestionLinkService.getListByQuery(aiProductQuestionLinkLambdaQueryWrapper); if(CollUtil.isNotEmpty(linkList)){ List<String> collect = linkList.stream().map(AiProductQuestionLink::getProductQuestionId).collect(Collectors.toList()); if(CollUtil.isNotEmpty( collect)){ String questionId = RandomUtil.randomEle(collect); aiProductQuestion = this.getById(questionId); } } return aiProductQuestion; } } src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml
@@ -1,4 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="cc.mrbird.febs.ai.mapper.AiMemberAnswerItemMapper"> <select id="selectPageListByQuery" resultType="cc.mrbird.febs.ai.res.memberAnswer.ApiMemberAnswerPreviousVo"> select a.id as memberAnswerItemId, a.answer_id as memberAnswerId, a.product_question_id as productQuestionId, a.member_answer_question_id as memberAnswerQuestionId, a.answer_analysis as answerAnalysis, a.member_answer_state as memberAnswerState from ai_member_answer_item a where a.answer_id = #{record.memberAnswerId} order by a.CREATED_TIME desc </select> </mapper>