Browse Source

考试任务管理

master
luoweijian 1 month ago
parent
commit
ab7ef76cf3
  1. 2
      src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java
  2. 18
      src/main/java/com/project/task/application/TaskApplicationService.java
  3. 48
      src/main/java/com/project/task/application/impl/TaskApplicationServiceImpl.java
  4. 30
      src/main/java/com/project/task/config/ExamScoreRatioConfig.java
  5. 46
      src/main/java/com/project/task/controller/TaskController.java
  6. 41
      src/main/java/com/project/task/domain/dto/TaskDTO.java
  7. 83
      src/main/java/com/project/task/domain/entity/ExamRecordEntity.java
  8. 144
      src/main/java/com/project/task/domain/entity/TaskEntity.java
  9. 46
      src/main/java/com/project/task/domain/entity/TaskUserEntity.java
  10. 17
      src/main/java/com/project/task/domain/enums/QuestionTypeEnum.java
  11. 15
      src/main/java/com/project/task/domain/enums/TaskStatusEnum.java
  12. 18
      src/main/java/com/project/task/domain/enums/TaskUserStatusEnum.java
  13. 13
      src/main/java/com/project/task/domain/param/TaskParam.java
  14. 11
      src/main/java/com/project/task/domain/service/DeleteTaskDomainService.java
  15. 9
      src/main/java/com/project/task/domain/service/SaveOrUpdateTaskDomainService.java
  16. 12
      src/main/java/com/project/task/domain/service/SearchTaskDomainService.java
  17. 8
      src/main/java/com/project/task/domain/service/TaskBaseService.java
  18. 7
      src/main/java/com/project/task/domain/service/TaskUserBaseService.java
  19. 31
      src/main/java/com/project/task/domain/service/impl/DeleteTaskDomainServiceImpl.java
  20. 157
      src/main/java/com/project/task/domain/service/impl/SaveOrUpdateTaskDomainServiceImpl.java
  21. 65
      src/main/java/com/project/task/domain/service/impl/SearchTaskDomainServiceImpl.java
  22. 12
      src/main/java/com/project/task/domain/service/impl/TaskBaseServiceImpl.java
  23. 11
      src/main/java/com/project/task/domain/service/impl/TaskUserBaseServiceImpl.java
  24. 9
      src/main/java/com/project/task/mapper/TaskMapper.java
  25. 9
      src/main/java/com/project/task/mapper/TaskUserMapper.java

2
src/main/java/com/project/ding/domain/service/impl/SearchUserDomainServiceImpl.java

@ -48,7 +48,7 @@ public class SearchUserDomainServiceImpl implements SearchUserDomainService {
// todo 构建考试信息 // todo 构建考试信息
return entity.toDTO(UserDTO::new); return dto;
} }
@Override @Override

18
src/main/java/com/project/task/application/TaskApplicationService.java

@ -0,0 +1,18 @@
package com.project.task.application;
import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.param.TaskParam;
import java.util.List;
public interface TaskApplicationService {
Result<TaskDTO> saveOrUpdate(TaskDTO dto) throws Exception;
Result<String> batchDelete(List<Long> idList) throws Exception;
Result<PageResult<TaskDTO>> search(TaskParam param) throws Exception;
Result<TaskDTO> getDetail(Long id) throws Exception;
}

48
src/main/java/com/project/task/application/impl/TaskApplicationServiceImpl.java

@ -0,0 +1,48 @@
package com.project.task.application.impl;
import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result;
import com.project.task.application.TaskApplicationService;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.param.TaskParam;
import com.project.task.domain.service.DeleteTaskDomainService;
import com.project.task.domain.service.SaveOrUpdateTaskDomainService;
import com.project.task.domain.service.SearchTaskDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TaskApplicationServiceImpl implements TaskApplicationService {
@Autowired
private SaveOrUpdateTaskDomainService saveOrUpdateTaskDomainService;
@Autowired
private DeleteTaskDomainService deleteTaskDomainService;
@Autowired
private SearchTaskDomainService searchTaskDomainService;
@Override
public Result<TaskDTO> saveOrUpdate(TaskDTO dto) throws Exception {
return saveOrUpdateTaskDomainService.saveOrUpdate(dto);
}
@Override
public Result<String> batchDelete(List<Long> idList) throws Exception {
return deleteTaskDomainService.batchDelete(idList);
}
@Override
public Result<PageResult<TaskDTO>> search(TaskParam param) throws Exception {
return searchTaskDomainService.search(param);
}
@Override
public Result<TaskDTO> getDetail(Long id) throws Exception {
return searchTaskDomainService.getDetail(id);
}
}

30
src/main/java/com/project/task/config/ExamScoreRatioConfig.java

@ -0,0 +1,30 @@
package com.project.task.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "exam.score-ratio")
public class ExamScoreRatioConfig {
/**
* 单选题权重默认 2
*/
private Integer single = 2;
/**
* 多选题权重默认 3
*/
private Integer multiple = 3;
/**
* 判断题权重默认 1
*/
private Integer trueFalse = 1;
/**
* 总分固定 100
*/
private Integer totalScore = 100;
}

46
src/main/java/com/project/task/controller/TaskController.java

@ -0,0 +1,46 @@
package com.project.task.controller;
import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result;
import com.project.task.application.TaskApplicationService;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.param.TaskParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Slf4j
@RequestMapping("/api/admin/task")
public class TaskController {
@Autowired
private TaskApplicationService taskApplicationService;
@GetMapping("/search")
public Result<PageResult<TaskDTO>> search(TaskParam param) throws Exception {
return taskApplicationService.search(param);
}
@GetMapping("/getDetail")
public Result<TaskDTO> getDetail(Long id) throws Exception {
return taskApplicationService.getDetail(id);
}
@PostMapping("/saveOrUpdate")
public Result<TaskDTO> save(TaskDTO dto) throws Exception {
return taskApplicationService.saveOrUpdate(dto);
}
@PostMapping("/batchDelete")
public Result<String> batchDelete(List<Long> idList) throws Exception {
return taskApplicationService.batchDelete(idList);
}
}

41
src/main/java/com/project/task/domain/dto/TaskDTO.java

@ -0,0 +1,41 @@
package com.project.task.domain.dto;
import com.project.base.domain.dto.BaseDTO;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class TaskDTO extends BaseDTO {
private Long id;
private String name;
private Date startTime;
private Date endTime;
private Long lineId;
private String lineName;
private Long subLineId;
private String subLineName;
private Integer accurateGraspNum;
private Integer vagueGraspNum;
private Integer duration;
private Integer passScore;
private String note;
private List<Long> relatedDocumentList;
private Integer singleChoiceNum;
private Double singleChoiceScore;
private Integer multipleChoiceNum;
private Double multipleChoiceScore;
private Integer trueFalseNum;
private Double trueFalseScore;
private Double totalScore;
private Integer participantNum;
private Integer passNum;
private Boolean needAiGrading;
private List<String> participantUserIdList;
private String statusText;
}

83
src/main/java/com/project/task/domain/entity/ExamRecordEntity.java

@ -0,0 +1,83 @@
package com.project.task.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.project.base.domain.entity.BaseEntity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Data
@Table(name = "evaluator_exam_record" , indexes = {@Index(name = "Idx_parentId", columnList = "parent_id")})
@Entity
@TableName(value = "evaluator_exam_record" , autoResultMap = true)
@EqualsAndHashCode(callSuper = true)
public class ExamRecordEntity extends BaseEntity {
@TableId(type = IdType.ASSIGN_ID)
@Id
private Long id;
@TableField("task_user_id")
@Column(name = "task_user_id" , columnDefinition="bigint(20) comment '关联TaskUserEntity'")
private Long taskUserId;
@Comment("分数")
@Column(name = "score")
private Double score;
@Column(name = "pass")
@Comment("是否通过")
private Boolean pass;
@Comment("开始时间")
@Column(name = "start_time")
@TableField("start_time")
private Date startTime;
@Comment("提交时间")
@Column(name = "submit_time")
@TableField("submit_time")
private Date submitTime;
/**
* 考试快照包含题干当时乱序后的选项内容用户答案正确答案解析是否正确
*/
@TableField(value = "answer_snapshot" , typeHandler = JacksonTypeHandler.class)
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "answer_snapshot", columnDefinition = "json")
private List<QuestionSnapshot> answerSnapshot;
@Data
public static class QuestionSnapshot {
private Long questionId;
// 题干原文
private String questionContent;
// 题型
private Integer type;
// 用户看的选项:{"A":"xxx", "B":"yyy"}
private Map<String, String> options;
// 正确项
private String rightAnswer;
// 用户选的
private String userAnswer;
// 判定正确
private Boolean isRight;
// AI解析
private String analysis;
// 该题是否已发起申诉
private Boolean hasAppealed = false;
}
}

144
src/main/java/com/project/task/domain/entity/TaskEntity.java

@ -0,0 +1,144 @@
package com.project.task.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.project.base.domain.entity.BaseEntity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.util.Date;
import java.util.List;
@Data
@Table(name = "evaluator_task" ,
indexes = {@Index(name = "Idx_startTime_endTime" , columnList = "start_time,end_time") ,
@Index(name = "Idx_endTime" , columnList = "end_time") ,
@Index(name = "Idx_subLineId" , columnList = "sub_line_id")
})
@Entity
@TableName(value = "evaluator_task", autoResultMap = true)
@EqualsAndHashCode(callSuper = true)
public class TaskEntity extends BaseEntity {
@TableId(value = "id" , type = IdType.ASSIGN_ID)
@Id
private Long id;
@Column(name = "name" , columnDefinition="varchar(50) comment '考试任务名称'")
private String name;
@Comment("开始时间")
@Column(name = "start_time")
@TableField("start_time")
private Date startTime;
@Comment("结束时间")
@Column(name = "end_time")
@TableField("end_time")
private Date endTime;
@Column(name = "line_id")
@Comment("产品线ID")
@TableField("line_id")
private Long lineId;
@Column(name = "line_name" , columnDefinition="varchar(550) comment '所属产品线名称'")
@Comment("产品线名称")
@TableField("line_name")
private String lineName;
@Column(name = "sub_line_id")
@Comment("所属子产品线ID")
@TableField("sub_line_id")
private Long subLineId;
@Column(name = "sub_line_name" , columnDefinition="varchar(550) comment '所属子产品线名称'")
@Comment("所属子产品线名称")
@TableField("sub_line_name")
private String subLineName;
@Column(name = "accurate_grasp_num")
@Comment("精准掌握知识点数量")
private Integer accurateGraspNum;
@Column(name = "vague_grasp_num")
@Comment("模糊掌握知识点数量")
private Integer vagueGraspNum;
@Column(name = "duration")
@Comment("考试时长")
private Integer duration;
@Column(name = "pass_score")
@Comment("通过考试分数线")
private Integer passScore;
@Column(name = "note" , columnDefinition="TEXT comment '注意事项'")
private String note;
/**
* 关联文档idList
* 存储为 JSON 数组: [1, 10, 101]
*/
@TableField(value = "related_document_list" , typeHandler = JacksonTypeHandler.class)
@Column(name = "related_document_list", columnDefinition = "json comment '关联文档列表'")
@JdbcTypeCode(SqlTypes.JSON)
private List<Long> relatedDocumentList;
@Column(name = "single_choice_num")
@TableField("single_choice_num")
@Comment("单选题数量")
private Integer singleChoiceNum;
@Column(name = "single_choice_score")
@TableField("single_choice_score")
@Comment("单选题分数")
private Double singleChoiceScore;
@Column(name = "multiple_choice_num")
@TableField("multiple_choice_num")
@Comment("多选题数量")
private Integer multipleChoiceNum;
@Column(name = "multiple_choice_score")
@TableField("multiple_choice_score")
@Comment("多选题分数")
private Double multipleChoiceScore;
@Column(name = "true_false_num")
@TableField("true_false_num")
@Comment("判断题数量")
private Integer trueFalseNum;
@Column(name = "true_false_score")
@TableField("true_false_score")
@Comment("判断题分数")
private Double trueFalseScore;
@Column(name = "total_score")
@Comment("总分")
private Double totalScore;
@Column(name = "participant_num")
@Comment("参与用户人数")
private Integer participantNum;
@Column(name = "pass_num")
@Comment("及格人数")
private Integer passNum = 0;
@Column(name = "need_ai_grading")
@Comment("是否包含需要AI判分的题目")
private Boolean needAiGrading = false;
}

46
src/main/java/com/project/task/domain/entity/TaskUserEntity.java

@ -0,0 +1,46 @@
package com.project.task.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.project.base.domain.entity.BaseEntity;
import com.project.task.domain.enums.TaskUserStatusEnum;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Comment;
@Data
@Table(name = "evaluator_task_user" , indexes = {@Index(name = "Idx_parentId", columnList = "parent_id")})
@Entity
@TableName(value = "evaluator_task_user" , autoResultMap = true)
@EqualsAndHashCode(callSuper = true)
public class TaskUserEntity extends BaseEntity {
@TableId(type = IdType.ASSIGN_ID)
@Id
private Long id;
@TableField("task_id")
@Column(name = "task_id" , columnDefinition="bigint(20) comment '考试任务id'")
private Long taskId;
@TableField("user_id")
@Column(name = "user_id" , columnDefinition="varchar(255) comment '用户id'")
private String userId;
@Column(name = "status")
@Comment("考试状态:0-未考, 1-不通过, 2-已通过")
private Integer status = TaskUserStatusEnum.Not_Start.getValue();
@Comment("最近一次考试记录ID")
@Column(name = "last_record_id")
@TableField("last_record_id")
private Long lastRecordId;
@Comment("累计考试次数")
@Column(name = "attempt_num")
@TableField("attempt_num")
private Integer attemptNum = 0;
}

17
src/main/java/com/project/task/domain/enums/QuestionTypeEnum.java

@ -0,0 +1,17 @@
package com.project.task.domain.enums;
import com.project.base.domain.enums.HasValueEnum;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum QuestionTypeEnum implements HasValueEnum<Integer> {
SINGLE_CHOICE(1, "单选题"), // 对应黄色背景
MULTIPLE_CHOICE(2, "多选题"), // 对应黄色背景
TRUE_FALSE(3, "判断题"); // 对应绿色背景
private final Integer value;
private final String description;
}

15
src/main/java/com/project/task/domain/enums/TaskStatusEnum.java

@ -0,0 +1,15 @@
package com.project.task.domain.enums;
import com.project.base.domain.enums.HasValueEnum;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum TaskStatusEnum implements HasValueEnum<String> {
Not_Start("未开考") ,
In_Progress("已开考") ,
Cut_Off("已截止");
@Getter
private final String value;
}

18
src/main/java/com/project/task/domain/enums/TaskUserStatusEnum.java

@ -0,0 +1,18 @@
package com.project.task.domain.enums;
import com.project.base.domain.enums.HasValueEnum;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum TaskUserStatusEnum implements HasValueEnum<Integer> {
Not_Start(0 , "未参加") ,
Fail(1 , "未通过") ,
Pass(2 ,"已通过");
private final Integer value;
private final String description;
}

13
src/main/java/com/project/task/domain/param/TaskParam.java

@ -0,0 +1,13 @@
package com.project.task.domain.param;
import com.project.base.domain.param.BaseParam;
import lombok.Data;
@Data
public class TaskParam extends BaseParam {
private String name;
private Long lineId;
private Long subLineId;
}

11
src/main/java/com/project/task/domain/service/DeleteTaskDomainService.java

@ -0,0 +1,11 @@
package com.project.task.domain.service;
import com.project.base.domain.result.Result;
import java.util.List;
public interface DeleteTaskDomainService {
Result<String> batchDelete(List<Long> idList) throws Exception;
}

9
src/main/java/com/project/task/domain/service/SaveOrUpdateTaskDomainService.java

@ -0,0 +1,9 @@
package com.project.task.domain.service;
import com.project.base.domain.result.Result;
import com.project.task.domain.dto.TaskDTO;
public interface SaveOrUpdateTaskDomainService {
Result<TaskDTO> saveOrUpdate(TaskDTO dto) throws Exception;
}

12
src/main/java/com/project/task/domain/service/SearchTaskDomainService.java

@ -0,0 +1,12 @@
package com.project.task.domain.service;
import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.param.TaskParam;
public interface SearchTaskDomainService {
Result<PageResult<TaskDTO>> search(TaskParam param) throws Exception;
Result<TaskDTO> getDetail(Long id) throws Exception;
}

8
src/main/java/com/project/task/domain/service/TaskBaseService.java

@ -0,0 +1,8 @@
package com.project.task.domain.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.project.task.domain.entity.TaskEntity;
public interface TaskBaseService extends IService<TaskEntity> {
}

7
src/main/java/com/project/task/domain/service/TaskUserBaseService.java

@ -0,0 +1,7 @@
package com.project.task.domain.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.project.task.domain.entity.TaskUserEntity;
public interface TaskUserBaseService extends IService<TaskUserEntity> {
}

31
src/main/java/com/project/task/domain/service/impl/DeleteTaskDomainServiceImpl.java

@ -0,0 +1,31 @@
package com.project.task.domain.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.domain.result.Result;
import com.project.task.domain.entity.TaskEntity;
import com.project.task.domain.service.DeleteTaskDomainService;
import com.project.task.domain.service.TaskBaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class DeleteTaskDomainServiceImpl implements DeleteTaskDomainService {
@Autowired
private TaskBaseService taskBaseService;
@Override
public Result<String> batchDelete(List<Long> idList) throws Exception {
long count = taskBaseService.count(new LambdaQueryWrapper<TaskEntity>()
.in(TaskEntity::getId, idList)
.ge(TaskEntity::getStartTime, DateUtil.beginOfDay(new Date())));
if (count > 0) {
throw new BusinessErrorException("已开考 、 已截止的考试任务不允许删除");
}
taskBaseService.removeBatchByIds(idList);
return Result.success("删除成功");
}
}

157
src/main/java/com/project/task/domain/service/impl/SaveOrUpdateTaskDomainServiceImpl.java

@ -0,0 +1,157 @@
package com.project.task.domain.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.domain.result.Result;
import com.project.information.domain.entity.ProductLineEntity;
import com.project.information.domain.service.ProductLineBaseService;
import com.project.task.config.ExamScoreRatioConfig;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.entity.TaskEntity;
import com.project.task.domain.entity.TaskUserEntity;
import com.project.task.domain.service.SaveOrUpdateTaskDomainService;
import com.project.task.domain.service.TaskBaseService;
import com.project.task.domain.service.TaskUserBaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service
public class SaveOrUpdateTaskDomainServiceImpl implements SaveOrUpdateTaskDomainService {
@Autowired
private ExamScoreRatioConfig examScoreRatioConfig;
@Autowired
private ProductLineBaseService productLineBaseService;
@Autowired
private TaskUserBaseService taskUserBaseService;
@Autowired
private TaskBaseService taskBaseService;
@Override
@Transactional(rollbackFor = Exception.class)
public Result<TaskDTO> saveOrUpdate(TaskDTO dto) throws Exception {
checkDTO(dto);
// 计算各题型赋分
// 1. 计算总权重份额
int totalUnit = dto.getSingleChoiceNum() * examScoreRatioConfig.getSingle()
+ dto.getMultipleChoiceNum() * examScoreRatioConfig.getMultiple()
+ dto.getTrueFalseNum() * examScoreRatioConfig.getTrueFalse();
double base = examScoreRatioConfig.getTotalScore() * 1.0 / totalUnit;
// 2. 基础赋值:按比例初步分配并保留2位小数
dto.setSingleChoiceScore(dto.getSingleChoiceNum() > 0 ? Math.round(base * examScoreRatioConfig.getSingle() * 100) / 100.0 : 0.0);
dto.setMultipleChoiceScore(dto.getMultipleChoiceNum() > 0 ? Math.round(base * examScoreRatioConfig.getMultiple() * 100) / 100.0 : 0.0);
dto.setTrueFalseScore(dto.getTrueFalseNum() > 0 ? Math.round(base * examScoreRatioConfig.getTrueFalse() * 100) / 100.0 : 0.0);
// 3. 余数平差:从配置中读取总分进行逆向补齐,确保总分 100% 对应配置
double configTotal = examScoreRatioConfig.getTotalScore().doubleValue();
if (dto.getTrueFalseNum() > 0) {
dto.setTrueFalseScore(Math.round((configTotal - dto.getSingleChoiceNum() * dto.getSingleChoiceScore() - dto.getMultipleChoiceNum() * dto.getMultipleChoiceScore()) / dto.getTrueFalseNum() * 100) / 100.0);
} else if (dto.getMultipleChoiceNum() > 0) {
dto.setMultipleChoiceScore(Math.round((configTotal - dto.getSingleChoiceNum() * dto.getSingleChoiceScore()) / dto.getMultipleChoiceNum() * 100) / 100.0);
} else if (dto.getSingleChoiceNum() > 0) {
dto.setSingleChoiceScore(Math.round(configTotal / dto.getSingleChoiceNum() * 100) / 100.0);
}
dto.setTotalScore(configTotal);
// 补全冗余字段
ProductLineEntity subProductLine = productLineBaseService.getById(dto.getSubLineId());
dto.setSubLineName(subProductLine.getName());
dto.setLineId(subProductLine.getParentId());
dto.setLineName(subProductLine.getParentName());
// todo 知识点分簇,预出题
// 保存
TaskEntity saveEntity = dto.toEntity(TaskEntity::new);
taskBaseService.saveOrUpdate(saveEntity);
// 保存关联表 TaskUserEntity
taskUserBaseService.remove(new LambdaQueryWrapper<TaskUserEntity>()
.eq(TaskUserEntity::getTaskId , saveEntity.getId()));
List<TaskUserEntity> taskUserEntityList = new ArrayList<>();
for (String userId : dto.getParticipantUserIdList()) {
TaskUserEntity taskUserEntity = new TaskUserEntity();
taskUserEntity.setTaskId(saveEntity.getId());
taskUserEntity.setUserId(userId);
taskUserEntityList.add(taskUserEntity);
}
taskUserBaseService.saveBatch(taskUserEntityList);
return Result.success(saveEntity.toDTO(TaskDTO::new));
}
private void checkDTO(TaskDTO dto) throws Exception {
if (StrUtil.isBlank(dto.getName())) {
throw new BusinessErrorException("考试任务名称不能为空");
}
if (StrUtil.length(dto.getName()) > 10) {
throw new BusinessErrorException("考试任务名称过长");
}
if (Objects.isNull(dto.getStartTime())) {
throw new BusinessErrorException("开始时间不能为空");
}
if (Objects.isNull(dto.getEndTime())) {
throw new BusinessErrorException("截止时间不能为空");
}
if (DateUtil.between(dto.getStartTime() , dto.getEndTime() , DateUnit.DAY) < 0) {
throw new BusinessErrorException("截止时间不能早于开始时间");
}
if (Objects.isNull(dto.getSubLineId())) {
throw new BusinessErrorException("关联产品线不能为空");
}
if (Objects.isNull(dto.getDuration())) {
throw new BusinessErrorException("考试时长不能为空");
}
if (Objects.isNull(dto.getPassScore())) {
throw new BusinessErrorException("通过考试分数线不能为空");
}
if (!Validator.isBetween(dto.getPassScore(), 1, 100)) {
throw new BusinessErrorException("通过考试分数线设置错误");
}
if (StrUtil.isBlank(dto.getNote())) {
throw new BusinessErrorException("注意事项不能为空");
}
if (Objects.isNull(dto.getSingleChoiceNum())) {
throw new BusinessErrorException("单选题数量不能为空");
}
if (Objects.isNull(dto.getMultipleChoiceNum())) {
throw new BusinessErrorException("多选题数量不能为空");
}
if (Objects.isNull(dto.getTrueFalseNum())) {
throw new BusinessErrorException("判断题数量不能为空");
}
if (!Validator.isBetween(dto.getSingleChoiceNum() +
dto.getMultipleChoiceNum() +
dto.getTrueFalseNum() , 1, 100)) {
throw new BusinessErrorException("题目数量设置错误");
}
if (CollUtil.isEmpty(dto.getParticipantUserIdList())) {
throw new BusinessErrorException("参与用户不能为空");
}
if (CollUtil.isEmpty(dto.getRelatedDocumentList())) {
throw new BusinessErrorException("关联文档列表不能为空");
}
if (Objects.isNull(dto.getAccurateGraspNum())) {
throw new BusinessErrorException("精准掌握知识点数量不能为空");
}
if (Objects.isNull(dto.getVagueGraspNum())) {
throw new BusinessErrorException("模糊掌握知识点数量不能为空");
}
}
}

65
src/main/java/com/project/task/domain/service/impl/SearchTaskDomainServiceImpl.java

@ -0,0 +1,65 @@
package com.project.task.domain.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.project.base.domain.result.PageResult;
import com.project.base.domain.result.Result;
import com.project.base.domain.utils.PageConverter;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.entity.TaskEntity;
import com.project.task.domain.enums.TaskStatusEnum;
import com.project.task.domain.param.TaskParam;
import com.project.task.domain.service.SearchTaskDomainService;
import com.project.task.mapper.TaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Objects;
@Service
public class SearchTaskDomainServiceImpl implements SearchTaskDomainService {
@Autowired
private TaskMapper taskMapper;
@Override
public Result<PageResult<TaskDTO>> search(TaskParam param) throws Exception {
LambdaQueryWrapper<TaskEntity> queryWrapper = new LambdaQueryWrapper<>();
if (StrUtil.isNotBlank(param.getName())) {
queryWrapper.like(TaskEntity::getName , param.getName());
}
if (Objects.nonNull(param.getLineId())) {
queryWrapper.eq(TaskEntity::getLineId , param.getLineId());
}
if (Objects.nonNull(param.getSubLineId())) {
queryWrapper.eq(TaskEntity::getSubLineId , param.getSubLineId());
}
queryWrapper.orderByDesc(TaskEntity::getId);
IPage<TaskEntity> taskEntityPage = taskMapper.selectPage(
PageConverter.toMpPage(param),
queryWrapper);
IPage<TaskDTO> taskDTOIPage = taskEntityPage.convert(this::buildDTO);
return Result.page(taskDTOIPage);
}
private TaskDTO buildDTO(TaskEntity entity) {
TaskDTO dto = entity.toDTO(TaskDTO::new);
// 开始时间晚于当前
if (dto.getStartTime().after(new Date())) {
dto.setStatusText(TaskStatusEnum.Not_Start.getValue());
} else if (DateUtil.isIn(new Date() , dto.getStartTime() , dto.getEndTime())) {
dto.setStatusText(TaskStatusEnum.In_Progress.getValue());
} else {
dto.setStatusText(TaskStatusEnum.Cut_Off.getValue());
}
return dto;
}
@Override
public Result<TaskDTO> getDetail(Long id) throws Exception {
TaskEntity taskEntity = taskMapper.selectById(id);
return Result.success(buildDTO(taskEntity));
}
}

12
src/main/java/com/project/task/domain/service/impl/TaskBaseServiceImpl.java

@ -0,0 +1,12 @@
package com.project.task.domain.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.task.domain.entity.TaskEntity;
import com.project.task.domain.service.TaskBaseService;
import com.project.task.mapper.TaskMapper;
import org.springframework.stereotype.Service;
@Service
public class TaskBaseServiceImpl extends ServiceImpl<TaskMapper, TaskEntity> implements TaskBaseService {
}

11
src/main/java/com/project/task/domain/service/impl/TaskUserBaseServiceImpl.java

@ -0,0 +1,11 @@
package com.project.task.domain.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.task.domain.entity.TaskUserEntity;
import com.project.task.domain.service.TaskUserBaseService;
import com.project.task.mapper.TaskUserMapper;
import org.springframework.stereotype.Service;
@Service
public class TaskUserBaseServiceImpl extends ServiceImpl<TaskUserMapper, TaskUserEntity> implements TaskUserBaseService {
}

9
src/main/java/com/project/task/mapper/TaskMapper.java

@ -0,0 +1,9 @@
package com.project.task.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.project.task.domain.entity.TaskEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TaskMapper extends BaseMapper<TaskEntity> {
}

9
src/main/java/com/project/task/mapper/TaskUserMapper.java

@ -0,0 +1,9 @@
package com.project.task.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.project.task.domain.entity.TaskUserEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TaskUserMapper extends BaseMapper<TaskUserEntity> {
}
Loading…
Cancel
Save