PaperBasicInfo
parent
8e55eda450
commit
a4e5283f86
|
|
@ -6,10 +6,7 @@ import io.swagger.annotations.ApiOperation;
|
||||||
import io.swagger.annotations.ApiParam;
|
import io.swagger.annotations.ApiParam;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.qinan.cedu.model.dto.*;
|
import org.qinan.cedu.model.dto.*;
|
||||||
import org.qinan.cedu.model.vo.PaperImportVO;
|
import org.qinan.cedu.model.vo.*;
|
||||||
import org.qinan.cedu.model.vo.PaperExamInfoVO;
|
|
||||||
import org.qinan.cedu.model.vo.PaperPageVO;
|
|
||||||
import org.qinan.cedu.model.vo.PaperQuestionVO;
|
|
||||||
import org.qinan.cedu.service.PaperService;
|
import org.qinan.cedu.service.PaperService;
|
||||||
import org.qinan.cedu.service.QuestionService;
|
import org.qinan.cedu.service.QuestionService;
|
||||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||||
|
|
@ -69,6 +66,12 @@ public class PaperController {
|
||||||
return SingleResponse.success(paperService.importQuestionsTemplate());
|
return SingleResponse.success(paperService.importQuestionsTemplate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("新建试卷-自动生成试卷")
|
||||||
|
@PostMapping("/courseware/question/rule")
|
||||||
|
public SingleResponse<PaperBasicInfoVO> coursewareQuestionRule(@Validated @RequestBody PaperCoursewareQuestionRuleDTO dto) {
|
||||||
|
return SingleResponse.success(paperService.coursewareQuestionRule(dto));
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("试卷试题分页查询")
|
@ApiOperation("试卷试题分页查询")
|
||||||
@GetMapping("/paper/question/page")
|
@GetMapping("/paper/question/page")
|
||||||
public PageResponse<PaperQuestionVO> page(@Validated PaperQuestionPageQueryDTO query) {
|
public PageResponse<PaperQuestionVO> page(@Validated PaperQuestionPageQueryDTO query) {
|
||||||
|
|
|
||||||
|
|
@ -51,4 +51,16 @@ public interface QuestionMapper extends BaseMapper<QuestionDO> {
|
||||||
* @return 各题型的试题数量
|
* @return 各题型的试题数量
|
||||||
*/
|
*/
|
||||||
List<QuestionTypeCountVO> countQuestionType(@Param("dto") QuestionTypeCountQueryDTO dto);
|
List<QuestionTypeCountVO> countQuestionType(@Param("dto") QuestionTypeCountQueryDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按课件id集合+题型随机抽取指定数量的试题id
|
||||||
|
*
|
||||||
|
* @param coursewareManagementIdList 课件管理id列表
|
||||||
|
* @param questionType 题型编码
|
||||||
|
* @param num 抽取数量
|
||||||
|
* @return 随机试题id列表
|
||||||
|
*/
|
||||||
|
List<Long> listRandomQuestionIds(@Param("coursewareManagementIdList") List<Long> coursewareManagementIdList,
|
||||||
|
@Param("questionType") String questionType,
|
||||||
|
@Param("num") Integer num);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,38 @@
|
||||||
package org.qinan.cedu.model.dto;
|
package org.qinan.cedu.model.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.Range;
|
||||||
|
import org.qinan.cedu.enums.QuestionTypeEnum;
|
||||||
|
|
||||||
|
import javax.validation.constraints.DecimalMax;
|
||||||
|
import javax.validation.constraints.DecimalMin;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class PaperConfigRuleDTO {
|
public class PaperConfigRuleDTO {
|
||||||
|
|
||||||
// private
|
// private
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class QuestionTypeRule {
|
||||||
|
@ApiModelProperty(QuestionTypeEnum.REMARKS)
|
||||||
|
@NotNull(message = QuestionTypeEnum.REMARKS)
|
||||||
|
@Pattern(regexp = QuestionTypeEnum.PATTERN)
|
||||||
|
private String questionType;
|
||||||
|
|
||||||
|
@ApiModelProperty("需要的试题数量")
|
||||||
|
@NotNull(message = "试题数量1-1024")
|
||||||
|
@Range(min = 1, max = 1024, message = "试题数量1-1024")
|
||||||
|
private Integer num;
|
||||||
|
|
||||||
|
@ApiModelProperty("每题的分数")
|
||||||
|
@NotNull(message = "每题的分数")
|
||||||
|
@DecimalMin(value = "0.1")
|
||||||
|
@DecimalMax(value = "999.9")
|
||||||
|
private BigDecimal score;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.qinan.cedu.model.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.Range;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.*;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建试卷-导入试题 请求对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "PaperImportDTO", description = "新建试卷-导入试题请求")
|
||||||
|
public class PaperCoursewareQuestionRuleDTO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "试卷名称", required = true)
|
||||||
|
@NotBlank(message = "试卷名称 不能为空")
|
||||||
|
@Size(max = 128, message = "试卷名称长度不能超过128个字符")
|
||||||
|
private String paperName;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "试卷总分", required = true)
|
||||||
|
@NotNull(message = "试卷总分不能为空")
|
||||||
|
@DecimalMin(value = "0.1", message = "试卷总分必须大于0")
|
||||||
|
@DecimalMax(value = "9999.9", message = "试卷总分不能超过9999.99")
|
||||||
|
private BigDecimal paperTotalScore;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合格分数", required = true)
|
||||||
|
@NotNull(message = "合格分数不能为空")
|
||||||
|
@DecimalMin(value = "0", message = "合格分数不能小于0")
|
||||||
|
@DecimalMax(value = "9999.9", message = "合格分数不能超过9999.99")
|
||||||
|
private BigDecimal paperPassScore;
|
||||||
|
|
||||||
|
@ApiModelProperty("考试时长(分钟)")
|
||||||
|
@Range(min = 1, max = 3600, message = "考试时长必须大于0小于3600")
|
||||||
|
private Integer examTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("课件id")
|
||||||
|
@NotNull(message = "请选择课程课件")
|
||||||
|
@Size(min = 1, max = 1024, message = "请选择课程课件")
|
||||||
|
private List<Long> coursewareManagementIdList;
|
||||||
|
|
||||||
|
@NotNull(message = "试题规则不能为空")
|
||||||
|
@Valid
|
||||||
|
private List<PaperConfigRuleDTO.QuestionTypeRule> questionTypeRuleList;
|
||||||
|
}
|
||||||
|
|
@ -3,13 +3,10 @@ package org.qinan.cedu.model.dto;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.hibernate.validator.constraints.Range;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.validation.constraints.DecimalMax;
|
import javax.validation.constraints.*;
|
||||||
import javax.validation.constraints.DecimalMin;
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,7 +34,7 @@ public class PaperImportDTO {
|
||||||
private BigDecimal paperPassScore;
|
private BigDecimal paperPassScore;
|
||||||
|
|
||||||
@ApiModelProperty("考试时长(分钟)")
|
@ApiModelProperty("考试时长(分钟)")
|
||||||
@Min(value = 1, message = "考试时长必须大于0")
|
@Range(min = 1, max = 3600, message = "考试时长必须大于0小于3600")
|
||||||
private Integer examTime;
|
private Integer examTime;
|
||||||
|
|
||||||
@ApiModelProperty(value = "试题Excel文件(第一个sheet单选题,第二个sheet多选题,第三个sheet判断题)", required = true)
|
@ApiModelProperty(value = "试题Excel文件(第一个sheet单选题,第二个sheet多选题,第三个sheet判断题)", required = true)
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ package org.qinan.cedu.service;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.qinan.cedu.model.dto.PaperCopyDTO;
|
import org.qinan.cedu.model.dto.PaperCopyDTO;
|
||||||
|
import org.qinan.cedu.model.dto.PaperCoursewareQuestionRuleDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperImportDTO;
|
import org.qinan.cedu.model.dto.PaperImportDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperPageQueryDTO;
|
import org.qinan.cedu.model.dto.PaperPageQueryDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperUpdateDTO;
|
import org.qinan.cedu.model.dto.PaperUpdateDTO;
|
||||||
import org.qinan.cedu.model.entity.PaperDO;
|
import org.qinan.cedu.model.entity.PaperDO;
|
||||||
|
import org.qinan.cedu.model.vo.PaperBasicInfoVO;
|
||||||
import org.qinan.cedu.model.vo.PaperImportVO;
|
import org.qinan.cedu.model.vo.PaperImportVO;
|
||||||
import org.qinan.cedu.model.vo.PaperExamInfoVO;
|
import org.qinan.cedu.model.vo.PaperExamInfoVO;
|
||||||
import org.qinan.cedu.model.vo.PaperPageVO;
|
import org.qinan.cedu.model.vo.PaperPageVO;
|
||||||
|
|
@ -89,6 +91,15 @@ public interface PaperService extends IService<PaperDO> {
|
||||||
*/
|
*/
|
||||||
String importQuestionsTemplate();
|
String importQuestionsTemplate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建试卷-自动生成试卷:按题型规则从关联课件下随机抽题,某题型数量不足直接报错,
|
||||||
|
* 全部满足后创建试卷(规则试卷)并绑定试卷试题关系
|
||||||
|
*
|
||||||
|
* @param dto 试卷信息+课件id列表+题型抽题规则
|
||||||
|
* @return 试卷基础信息
|
||||||
|
*/
|
||||||
|
PaperBasicInfoVO coursewareQuestionRule(PaperCoursewareQuestionRuleDTO dto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询试卷考试信息(试卷基础信息+试题列表含选项)
|
* 查询试卷考试信息(试卷基础信息+试题列表含选项)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package org.qinan.cedu.service.impl;
|
package org.qinan.cedu.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
|
@ -14,11 +15,14 @@ import org.qinan.cedu.convertor.QuestionConvertor;
|
||||||
import org.qinan.cedu.enums.DeleteEnum;
|
import org.qinan.cedu.enums.DeleteEnum;
|
||||||
import org.qinan.cedu.enums.PaperStatusEnum;
|
import org.qinan.cedu.enums.PaperStatusEnum;
|
||||||
import org.qinan.cedu.enums.PaperTypeEnum;
|
import org.qinan.cedu.enums.PaperTypeEnum;
|
||||||
|
import org.qinan.cedu.enums.QuestionTypeEnum;
|
||||||
import org.qinan.cedu.mapper.PaperMapper;
|
import org.qinan.cedu.mapper.PaperMapper;
|
||||||
import org.qinan.cedu.mapper.PaperQuestionRelMapper;
|
import org.qinan.cedu.mapper.PaperQuestionRelMapper;
|
||||||
import org.qinan.cedu.mapper.QuestionMapper;
|
import org.qinan.cedu.mapper.QuestionMapper;
|
||||||
import org.qinan.cedu.mapper.QuestionOptionMapper;
|
import org.qinan.cedu.mapper.QuestionOptionMapper;
|
||||||
|
import org.qinan.cedu.model.dto.PaperConfigRuleDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperCopyDTO;
|
import org.qinan.cedu.model.dto.PaperCopyDTO;
|
||||||
|
import org.qinan.cedu.model.dto.PaperCoursewareQuestionRuleDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperImportDTO;
|
import org.qinan.cedu.model.dto.PaperImportDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperPageQueryDTO;
|
import org.qinan.cedu.model.dto.PaperPageQueryDTO;
|
||||||
import org.qinan.cedu.model.dto.PaperUpdateDTO;
|
import org.qinan.cedu.model.dto.PaperUpdateDTO;
|
||||||
|
|
@ -26,6 +30,7 @@ import org.qinan.cedu.model.entity.PaperDO;
|
||||||
import org.qinan.cedu.model.entity.PaperQuestionRelDO;
|
import org.qinan.cedu.model.entity.PaperQuestionRelDO;
|
||||||
import org.qinan.cedu.model.entity.QuestionDO;
|
import org.qinan.cedu.model.entity.QuestionDO;
|
||||||
import org.qinan.cedu.model.entity.QuestionOptionDO;
|
import org.qinan.cedu.model.entity.QuestionOptionDO;
|
||||||
|
import org.qinan.cedu.model.vo.PaperBasicInfoVO;
|
||||||
import org.qinan.cedu.model.vo.PaperExamInfoVO;
|
import org.qinan.cedu.model.vo.PaperExamInfoVO;
|
||||||
import org.qinan.cedu.model.vo.PaperImportVO;
|
import org.qinan.cedu.model.vo.PaperImportVO;
|
||||||
import org.qinan.cedu.model.vo.PaperPageVO;
|
import org.qinan.cedu.model.vo.PaperPageVO;
|
||||||
|
|
@ -278,6 +283,48 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implemen
|
||||||
return paperImportUrl;
|
return paperImportUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public PaperBasicInfoVO coursewareQuestionRule(PaperCoursewareQuestionRuleDTO dto) {
|
||||||
|
// 1. 循环题型规则从关联课件下随机抽题,某题型数量不足直接报错
|
||||||
|
List<Long> questionIds = new ArrayList<>();
|
||||||
|
for (PaperConfigRuleDTO.QuestionTypeRule rule : dto.getQuestionTypeRuleList()) {
|
||||||
|
List<Long> ids = questionMapper.listRandomQuestionIds(
|
||||||
|
dto.getCoursewareManagementIdList(), rule.getQuestionType(), rule.getNum());
|
||||||
|
if (ids.size() < rule.getNum()) {
|
||||||
|
QuestionTypeEnum typeEnum = QuestionTypeEnum.fromCode(rule.getQuestionType());
|
||||||
|
String typeDesc = typeEnum != null ? typeEnum.getDesc() : rule.getQuestionType();
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
typeDesc + "题数量不足:需要" + rule.getNum() + "道,当前仅有" + ids.size() + "道");
|
||||||
|
}
|
||||||
|
questionIds.addAll(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 创建试卷(规则试卷,保存抽题规则)
|
||||||
|
PaperDO paper = new PaperDO();
|
||||||
|
paper.setPaperName(dto.getPaperName().trim());
|
||||||
|
paper.setPaperTotalScore(dto.getPaperTotalScore());
|
||||||
|
paper.setPaperPassScore(dto.getPaperPassScore());
|
||||||
|
paper.setExamTime(dto.getExamTime());
|
||||||
|
paper.setPaperType(PaperTypeEnum.CONFIG_RULE.getValue());
|
||||||
|
paper.setConfigRule(JSONUtil.toJsonStr(dto.getQuestionTypeRuleList()));
|
||||||
|
InsertFieldDefaults.applyIgnoreOrgId(paper);
|
||||||
|
this.savePaper(paper);
|
||||||
|
|
||||||
|
// 3. 绑定试卷试题关系(含试题号)
|
||||||
|
List<PaperQuestionRelDO> rels = new ArrayList<>(questionIds.size());
|
||||||
|
for (int i = 0; i < questionIds.size(); i++) {
|
||||||
|
PaperQuestionRelDO rel = new PaperQuestionRelDO();
|
||||||
|
rel.setPaperId(paper.getId());
|
||||||
|
rel.setQuestionId(questionIds.get(i));
|
||||||
|
rel.setQuestionNum(i + 1);
|
||||||
|
InsertFieldDefaults.applyIgnoreOrgId(rel);
|
||||||
|
rels.add(rel);
|
||||||
|
}
|
||||||
|
Db.saveBatch(rels);
|
||||||
|
return paperConvertor.convertEToBasicVo(paper);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaperExamInfoVO paperExamInfo(Long paperId) {
|
public PaperExamInfoVO paperExamInfo(Long paperId) {
|
||||||
// 1. 查询试卷基础信息
|
// 1. 查询试卷基础信息
|
||||||
|
|
|
||||||
|
|
@ -55,4 +55,17 @@
|
||||||
AND q.delete_enum = 'false'
|
AND q.delete_enum = 'false'
|
||||||
GROUP BY q.question_type
|
GROUP BY q.question_type
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="listRandomQuestionIds" resultType="java.lang.Long">
|
||||||
|
SELECT q.id
|
||||||
|
FROM question q
|
||||||
|
WHERE q.courseware_management_id IN
|
||||||
|
<foreach collection="coursewareManagementIdList" item="coursewareManagementId" open="(" separator="," close=")">
|
||||||
|
#{coursewareManagementId}
|
||||||
|
</foreach>
|
||||||
|
AND q.delete_enum = 'false'
|
||||||
|
AND q.question_type = #{questionType}
|
||||||
|
ORDER BY RAND()
|
||||||
|
LIMIT #{num}
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue