Administrator
2025-08-20 de8b3cf7a9b22be7abcb544a53dcea7f1b340760
feat(ai): 新增开始答题V2 接口

- 新增 ApiMemberAnswerVoV2 类用于 V2 接口返回值
- 在 AiMemberAnswerService 中实现 startAnswerV2 方法
- 在 ApiMemberAnswerController 中添加 startV2 接口
- 更新 AiMemberAnswerItemMapper.xml,移除多余的条件
- 在 AiMemberAnswerItem 中添加 sort 字段用于排序
5 files modified
1 files added
104 ■■■■■ changed files
src/main/java/cc/mrbird/febs/ai/controller/memberAnswer/ApiMemberAnswerController.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswerItem.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiMemberAnswerVoV2.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java 70 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml 1 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/memberAnswer/ApiMemberAnswerController.java
@@ -33,6 +33,16 @@
    private final AiMemberAnswerService apiMemberAnswerService;
    @ApiOperation(value = "开始答题V2", notes = "开始答题V2")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiMemberAnswerVoV2.class)
    })
    @PostMapping(value = "/startV2")
    public FebsResponse startV2(@RequestBody @Validated ApiMemberAnswerDto dto) {
        return apiMemberAnswerService.startAnswerV2(dto);
    }
    @ApiOperation(value = "开始答题", notes = "开始答题")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiMemberAnswerVo.class)
src/main/java/cc/mrbird/febs/ai/entity/AiMemberAnswerItem.java
@@ -83,4 +83,9 @@
     * 是否加入错题集:0-否,1-是
     */
    private Integer isCollected;
    /**
     * 排序
     */
    private Integer sort;
}
src/main/java/cc/mrbird/febs/ai/res/memberAnswer/ApiMemberAnswerVoV2.java
New file
@@ -0,0 +1,16 @@
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 = "ApiMemberAnswerVoV2", description = "参数")
public class ApiMemberAnswerVoV2 {
    @ApiModelProperty(value = "当前页")
    private Integer current;
}
src/main/java/cc/mrbird/febs/ai/service/AiMemberAnswerService.java
@@ -17,6 +17,8 @@
    AiMemberAnswer getOneByQuery(LambdaQueryWrapper<AiMemberAnswer> aiMemberAnswerLambdaQueryWrapper);
    FebsResponse startAnswerV2(ApiMemberAnswerDto dto);
    FebsResponse startAnswer(ApiMemberAnswerDto dto);
    boolean checkMemberAnswerDone(AiMemberAnswer aiMemberAnswer);
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberAnswerServiceImpl.java
@@ -53,6 +53,76 @@
        return aiMemberAnswerMapper.selectOne(aiMemberAnswerLambdaQueryWrapper);
    }
    @Override
    public FebsResponse startAnswerV2(ApiMemberAnswerDto dto) {
        String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid();
        ApiMemberAnswerVoV2 apiMemberAnswerVoV2 = new ApiMemberAnswerVoV2();
        Integer current = 1;
        String productId = dto.getId();
        AiProduct aiProduct = aiProductService.getById(productId);
        if(ObjectUtil.isNull(aiProduct)){
            throw new RuntimeException("产品不存在");
        }
        //验证产品分类下是否有题目
        String productCategoryId = aiProduct.getProductCategoryId();
        LambdaQueryWrapper<AiProductQuestion> questionLambdaQueryWrapper = Wrappers.lambdaQuery(AiProductQuestion.class);
        questionLambdaQueryWrapper.eq(AiProductQuestion::getProductCategoryId,productCategoryId);
        questionLambdaQueryWrapper.eq(AiProductQuestion::getState,1);
        questionLambdaQueryWrapper.last("limit 1");
        List<AiProductQuestion> aiProductQuestions = aiProductQuestionService.getListByQuery(questionLambdaQueryWrapper);
        if(CollUtil.isEmpty(aiProductQuestions)){
            // todo 没有题目采用AI生成题目
            throw new RuntimeException("产品没有题目");
        }
        //判断该产品是否有正在进行的练习
        Date createdTime = new Date();
        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)){
            Integer questionCount = aiProduct.getQuestionCount();
            aiMemberAnswer = new AiMemberAnswer();
            aiMemberAnswer.setId(UUID.getSimpleUUIDString());
            aiMemberAnswer.setCreatedTime(createdTime);
            aiMemberAnswer.setUpdatedTime(createdTime);
            aiMemberAnswer.setProductId(aiProduct.getId());
            aiMemberAnswer.setMemberId(memberUuid);
            aiMemberAnswer.setState(0);
            aiMemberAnswer.setScore(0);
            aiMemberAnswer.setQuestionCnt(questionCount);
            aiMemberAnswer.setDoneCnt(0);
            aiMemberAnswer.setCorrectCnt(0);
            aiMemberAnswerMapper.insert(aiMemberAnswer);
            List<AiMemberAnswerItem> aiMemberAnswerItems = new ArrayList<>();
            for (int i = 1; i <= questionCount; i++){
                //初始化答题记录
                AiProductQuestion aiProductQuestion = aiProductQuestionService.createQuestion(aiProduct.getId());
                AiMemberAnswerItem aiMemberAnswerItem = new AiMemberAnswerItem();
                aiMemberAnswerItem.setId(UUID.getSimpleUUIDString());
                aiMemberAnswerItem.setCreatedTime(createdTime);
                aiMemberAnswerItem.setAnswerId(aiMemberAnswer.getId());
                aiMemberAnswerItem.setProductId(aiMemberAnswer.getProductId());
                aiMemberAnswerItem.setMemberId(memberUuid);
                aiMemberAnswerItem.setProductQuestionId(aiProductQuestion.getId());
                aiMemberAnswerItem.setTitle(aiProductQuestion.getTitle());
                aiMemberAnswerItem.setDifficulty(aiProductQuestion.getDifficulty());
                aiMemberAnswerItem.setMemberAnswerState(0);
                aiMemberAnswerItem.setSort( i );
                aiMemberAnswerItems.add(aiMemberAnswerItem);
            }
            aiMemberAnswerItemService.saveBatch(aiMemberAnswerItems);
            current = 1;
        }else{
            current = aiMemberAnswer.getDoneCnt();
        }
        apiMemberAnswerVoV2.setCurrent(current);
        return new FebsResponse().success().data(apiMemberAnswerVoV2);
    }
    @Override
    public FebsResponse startAnswer(ApiMemberAnswerDto dto) {
src/main/resources/mapper/modules/AiMemberAnswerItemMapper.xml
@@ -13,7 +13,6 @@
        from ai_member_answer_item a
        where
              a.answer_id = #{record.memberAnswerId}
        and a.member_answer_state != 0
        order by a.CREATED_TIME desc
    </select>