13 changed files with 582 additions and 0 deletions
@ -1,9 +1,19 @@ |
|||||
package com.project.statistics.application; |
package com.project.statistics.application; |
||||
|
|
||||
import com.project.base.domain.result.Result; |
import com.project.base.domain.result.Result; |
||||
|
import com.project.exam.domain.entity.ExamRecordEntity; |
||||
|
import com.project.statistics.domain.dto.ErrorProneStatisticsDTO; |
||||
import com.project.statistics.domain.dto.ExamTaskStatisticsDTO; |
import com.project.statistics.domain.dto.ExamTaskStatisticsDTO; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
public interface StatisticsApplicationService { |
public interface StatisticsApplicationService { |
||||
|
|
||||
Result<ExamTaskStatisticsDTO> examTaskStatistics(Long taskId); |
Result<ExamTaskStatisticsDTO> examTaskStatistics(Long taskId); |
||||
|
|
||||
|
void collectErrorProneStatistics(Long id, Integer examMode, List<ExamRecordEntity.QuestionSnapshot> answerSnapshot); |
||||
|
|
||||
|
Result<List<ErrorProneStatisticsDTO>> searchErrorProneTop(Long taskId); |
||||
|
|
||||
|
void singleExamStatistics(Long examRecordId) throws Exception; |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,91 @@ |
|||||
|
package com.project.statistics.domain.dto; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollUtil; |
||||
|
import com.project.base.domain.dto.BaseDTO; |
||||
|
import com.project.statistics.domain.entity.ErrorProneStatisticsEntity; |
||||
|
import lombok.Data; |
||||
|
import org.springframework.beans.BeanUtils; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.function.Supplier; |
||||
|
|
||||
|
@Data |
||||
|
public class ErrorProneStatisticsDTO extends BaseDTO { |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 考试模式:0-生成式,1-经典套题 |
||||
|
*/ |
||||
|
private Integer examMode; |
||||
|
|
||||
|
/** |
||||
|
* 考试ID |
||||
|
*/ |
||||
|
private Long taskId; |
||||
|
|
||||
|
/** |
||||
|
* 关联题目ID列表 |
||||
|
*/ |
||||
|
private List<Long> questionIdList; |
||||
|
|
||||
|
/** |
||||
|
* 知识点ID |
||||
|
*/ |
||||
|
private Long kpId; |
||||
|
|
||||
|
/** |
||||
|
* 内容:生成式为知识点内容,经典套题为题目内容 |
||||
|
*/ |
||||
|
private String content; |
||||
|
|
||||
|
/** |
||||
|
* 题目类型 |
||||
|
*/ |
||||
|
private Integer questionType; |
||||
|
|
||||
|
/** |
||||
|
* 错误次数 |
||||
|
*/ |
||||
|
private Integer errorCount; |
||||
|
|
||||
|
/** |
||||
|
* 出现次数 |
||||
|
*/ |
||||
|
private Integer appearCount; |
||||
|
|
||||
|
/** |
||||
|
* 占比(%):错误次数/出现次数*100 |
||||
|
*/ |
||||
|
private String proportion; |
||||
|
|
||||
|
/** |
||||
|
* 选项详情(经典套题才有) |
||||
|
*/ |
||||
|
private List<OptionDetailDTO> optionDetailDTOS; |
||||
|
|
||||
|
@Data |
||||
|
public static class OptionDetailDTO { |
||||
|
private String option; // 选项
|
||||
|
private String optionContent; // 选项内容
|
||||
|
private Integer choosenCount; // 选择次数
|
||||
|
private Boolean right;//正确选项
|
||||
|
private String proportion; // 占比(%):选择次数/出现次数*100
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public <T> T toEntity(Supplier<T> supplier) { |
||||
|
T result = super.toEntity(supplier); |
||||
|
if (result instanceof ErrorProneStatisticsEntity entity) { |
||||
|
// 处理内部列表快照的转换
|
||||
|
if (CollUtil.isNotEmpty(this.optionDetailDTOS)) { |
||||
|
List<ErrorProneStatisticsEntity.OptionDetail> optionDetails = this.optionDetailDTOS.stream().map(dto -> { |
||||
|
ErrorProneStatisticsEntity.OptionDetail optionDetail = new ErrorProneStatisticsEntity.OptionDetail(); |
||||
|
BeanUtils.copyProperties(dto, optionDetail); |
||||
|
return optionDetail; |
||||
|
}).toList(); |
||||
|
entity.setOptionDetails(optionDetails); |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,120 @@ |
|||||
|
package com.project.statistics.domain.entity; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollUtil; |
||||
|
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 com.project.statistics.domain.dto.ErrorProneStatisticsDTO; |
||||
|
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 org.springframework.beans.BeanUtils; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.function.Supplier; |
||||
|
|
||||
|
|
||||
|
@Data |
||||
|
@Table(name = "evaluator_error_prone_statistics") |
||||
|
@Entity |
||||
|
@TableName(value = "evaluator_error_prone_statistics", autoResultMap = true) |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
public class ErrorProneStatisticsEntity extends BaseEntity { |
||||
|
@TableId(type = IdType.ASSIGN_ID) |
||||
|
@Id |
||||
|
private Long id; |
||||
|
|
||||
|
@Column(name = "exam_mode") |
||||
|
@Comment("考试模式:0-生成式,1-经典套题") |
||||
|
@TableField("exam_mode") |
||||
|
private Integer examMode = 0; |
||||
|
|
||||
|
@Column(name = "task_id") |
||||
|
@TableField("task_id") |
||||
|
@Comment("考试任务ID") |
||||
|
private Long taskId; |
||||
|
|
||||
|
/** |
||||
|
* 关联题目idList |
||||
|
* 存储为 JSON 数组: [1, 10, 101] |
||||
|
* 生成式:多个题目ID,经典套题:只有一个题目ID |
||||
|
*/ |
||||
|
@TableField(value = "question_id_list" , typeHandler = JacksonTypeHandler.class) |
||||
|
@Column(name = "question_id_list", columnDefinition = "json comment '关联题目列表'") |
||||
|
@JdbcTypeCode(SqlTypes.JSON) |
||||
|
private List<Long> questionIdList; |
||||
|
|
||||
|
@Column(name = "kp_id") |
||||
|
@TableField("kp_id") |
||||
|
@Comment("知识点ID") |
||||
|
private Long kpId; |
||||
|
|
||||
|
@Column(name = "content", columnDefinition = "TEXT comment '内容:生成式为知识点内容,经典套题为题目内容'") |
||||
|
private String content; |
||||
|
|
||||
|
@Column(name = "question_type") |
||||
|
@Comment("题目类型") |
||||
|
@TableField("question_type") |
||||
|
private Integer questionType; |
||||
|
|
||||
|
@Column(name = "error_count") |
||||
|
@Comment("错误次数") |
||||
|
@TableField("error_count") |
||||
|
private Integer errorCount; // 错误次数
|
||||
|
|
||||
|
@Column(name = "appear_count") |
||||
|
@Comment("出现次数") |
||||
|
@TableField("appear_count") |
||||
|
private Integer appearCount; // 出现次数
|
||||
|
|
||||
|
@TableField(value = "option_detail" , typeHandler = JacksonTypeHandler.class) |
||||
|
@JdbcTypeCode(SqlTypes.JSON) |
||||
|
@Column(name = "option_detail", columnDefinition = "json comment '选项内容'") |
||||
|
private List<OptionDetail> optionDetails; |
||||
|
|
||||
|
@Data |
||||
|
public static class OptionDetail { |
||||
|
private String option; // 选项
|
||||
|
private String optionContent; // 选项内容
|
||||
|
private Integer choosenCount; // 选择次数
|
||||
|
private Boolean right;//正确选项
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public <T> T toDTO(Supplier<T> supplier) { |
||||
|
T result = super.toDTO(supplier); |
||||
|
if (result instanceof ErrorProneStatisticsDTO dto) { |
||||
|
// 计算主实体占比:错误次数/出现次数*100,保留整数
|
||||
|
int appear = this.appearCount == null ? 0 : this.appearCount; |
||||
|
int error = this.errorCount == null ? 0 : this.errorCount; |
||||
|
dto.setProportion(calculateProportion(error, appear)); |
||||
|
|
||||
|
// 处理内部快照列表从 Entity 到 DTO 的转换
|
||||
|
if (CollUtil.isNotEmpty(this.optionDetails)) { |
||||
|
List<ErrorProneStatisticsDTO.OptionDetailDTO> dtoList = this.optionDetails.stream().map(optionDetail -> { |
||||
|
ErrorProneStatisticsDTO.OptionDetailDTO optionDetailDTO = new ErrorProneStatisticsDTO.OptionDetailDTO(); |
||||
|
BeanUtils.copyProperties(optionDetail, optionDetailDTO); |
||||
|
// 计算选项占比:选择次数/出现次数*100,保留整数
|
||||
|
int chosen = optionDetail.getChoosenCount() == null ? 0 : optionDetail.getChoosenCount(); |
||||
|
optionDetailDTO.setProportion(calculateProportion(chosen, appear)); |
||||
|
return optionDetailDTO; |
||||
|
}).toList(); |
||||
|
dto.setOptionDetailDTOS(dtoList); |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
private String calculateProportion(int numerator, int denominator) { |
||||
|
if (denominator == 0) { |
||||
|
return "0"; |
||||
|
} |
||||
|
return String.valueOf(Math.round(numerator * 100.0 / denominator)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
package com.project.statistics.domain.service; |
||||
|
|
||||
|
import com.project.base.domain.service.IBaseService; |
||||
|
import com.project.statistics.domain.entity.ErrorProneStatisticsEntity; |
||||
|
|
||||
|
public interface ErrorProneStatisticsBaseService extends IBaseService<ErrorProneStatisticsEntity> { |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
package com.project.statistics.domain.service; |
||||
|
|
||||
|
import com.project.exam.domain.entity.ExamRecordEntity; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface SaveErrorProneStatisticsDomainService { |
||||
|
|
||||
|
/** |
||||
|
* 异步收集易错统计 |
||||
|
* |
||||
|
* @param taskId 考试任务ID |
||||
|
* @param examMode 考试模式 |
||||
|
* @param snapshots 答题快照 |
||||
|
*/ |
||||
|
void collectErrorProneStatistics(Long taskId, Integer examMode, List<ExamRecordEntity.QuestionSnapshot> snapshots); |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
package com.project.statistics.domain.service; |
||||
|
|
||||
|
import com.project.base.domain.result.Result; |
||||
|
import com.project.statistics.domain.dto.ErrorProneStatisticsDTO; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface SearchErrorProneStatisticsDomainService { |
||||
|
|
||||
|
Result<List<ErrorProneStatisticsDTO>> searchTopByTaskId(Long taskId); |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
package com.project.statistics.domain.service.impl; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import com.project.statistics.domain.entity.ErrorProneStatisticsEntity; |
||||
|
import com.project.statistics.domain.service.ErrorProneStatisticsBaseService; |
||||
|
import com.project.statistics.mapper.ErrorProneStatisticsMapper; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
@Service |
||||
|
public class ErrorProneStatisticsBaseServiceImpl extends ServiceImpl<ErrorProneStatisticsMapper, ErrorProneStatisticsEntity> implements ErrorProneStatisticsBaseService { |
||||
|
} |
||||
@ -0,0 +1,212 @@ |
|||||
|
package com.project.statistics.domain.service.impl; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollUtil; |
||||
|
import cn.hutool.core.collection.CollectionUtil; |
||||
|
import cn.hutool.core.util.StrUtil; |
||||
|
import com.project.exam.domain.entity.ExamRecordEntity; |
||||
|
import com.project.question.domain.entity.QuestionEntity; |
||||
|
import com.project.question.domain.entity.TaskKnowledgePointEntity; |
||||
|
import com.project.question.domain.service.QuestionBaseService; |
||||
|
import com.project.question.domain.service.TaskKnowledgePointBaseService; |
||||
|
import com.project.statistics.domain.entity.ErrorProneStatisticsEntity; |
||||
|
import com.project.statistics.domain.service.ErrorProneStatisticsBaseService; |
||||
|
import com.project.statistics.domain.service.SaveErrorProneStatisticsDomainService; |
||||
|
import com.project.task.domain.enums.ExamModeEnum; |
||||
|
import com.project.task.domain.enums.QuestionTypeEnum; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.scheduling.annotation.Async; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class SaveSaveErrorProneStatisticsDomainServiceImpl implements SaveErrorProneStatisticsDomainService { |
||||
|
|
||||
|
@Autowired |
||||
|
private ErrorProneStatisticsBaseService errorProneStatisticsBaseService; |
||||
|
|
||||
|
@Autowired |
||||
|
private QuestionBaseService questionBaseService; |
||||
|
|
||||
|
@Autowired |
||||
|
private TaskKnowledgePointBaseService taskKnowledgePointBaseService; |
||||
|
|
||||
|
@Override |
||||
|
@Async |
||||
|
public void collectErrorProneStatistics(Long taskId, Integer examMode, List<ExamRecordEntity.QuestionSnapshot> snapshots) { |
||||
|
if (taskId == null || CollUtil.isEmpty(snapshots)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
if (ExamModeEnum.GENERATIVE.getValue().equals(examMode)) { |
||||
|
collectGenerativeStatistics(taskId, snapshots); |
||||
|
} else if (ExamModeEnum.CLASSIC.getValue().equals(examMode)) { |
||||
|
collectClassicStatistics(taskId, snapshots); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("[易错统计] 收集失败, taskId={}", taskId, e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成式套题:以知识点为单位统计 |
||||
|
*/ |
||||
|
private void collectGenerativeStatistics(Long taskId, List<ExamRecordEntity.QuestionSnapshot> snapshots) { |
||||
|
for (ExamRecordEntity.QuestionSnapshot snapshot : snapshots) { |
||||
|
// 跳过简答题
|
||||
|
if (isShortAnswer(snapshot.getType())) { |
||||
|
continue; |
||||
|
} |
||||
|
Long questionId = snapshot.getQuestionId(); |
||||
|
if (questionId == null) { |
||||
|
continue; |
||||
|
} |
||||
|
QuestionEntity question = questionBaseService.getById(questionId); |
||||
|
if (question == null || CollUtil.isEmpty(question.getKpIdList())) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
List<TaskKnowledgePointEntity> kpList = taskKnowledgePointBaseService.listByIds(question.getKpIdList()); |
||||
|
for (TaskKnowledgePointEntity kp : kpList) { |
||||
|
if (kp == null || StrUtil.isBlank(kp.getContent())) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
ErrorProneStatisticsEntity entity = errorProneStatisticsBaseService.lambdaQuery() |
||||
|
.eq(ErrorProneStatisticsEntity::getTaskId, taskId) |
||||
|
.eq(ErrorProneStatisticsEntity::getKpId, kp.getId()) |
||||
|
.one(); |
||||
|
|
||||
|
if (entity == null) { |
||||
|
entity = new ErrorProneStatisticsEntity(); |
||||
|
entity.setTaskId(taskId); |
||||
|
entity.setExamMode(ExamModeEnum.GENERATIVE.getValue()); |
||||
|
entity.setContent(kp.getContent()); |
||||
|
entity.setKpId(kp.getId()); |
||||
|
entity.setErrorCount(0); |
||||
|
entity.setAppearCount(0); |
||||
|
} |
||||
|
|
||||
|
List<Long> questionIdList = CollectionUtil.isEmpty(entity.getQuestionIdList()) ? new ArrayList<>() : entity.getQuestionIdList(); |
||||
|
questionIdList.add(questionId); |
||||
|
entity.setQuestionIdList(questionIdList); |
||||
|
entity.setAppearCount(entity.getAppearCount() + 1); |
||||
|
if (Boolean.FALSE.equals(snapshot.getIsRight())) { |
||||
|
entity.setErrorCount(entity.getErrorCount() + 1); |
||||
|
} |
||||
|
|
||||
|
errorProneStatisticsBaseService.saveOrUpdate(entity); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 经典套题:以题目为单位统计,并统计选项选择情况 |
||||
|
*/ |
||||
|
private void collectClassicStatistics(Long taskId, List<ExamRecordEntity.QuestionSnapshot> snapshots) { |
||||
|
for (ExamRecordEntity.QuestionSnapshot snapshot : snapshots) { |
||||
|
// 跳过简答题
|
||||
|
if (isShortAnswer(snapshot.getType())) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
String content = snapshot.getQuestionContent(); |
||||
|
if (StrUtil.isBlank(content)) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
ErrorProneStatisticsEntity entity = errorProneStatisticsBaseService.lambdaQuery() |
||||
|
.eq(ErrorProneStatisticsEntity::getTaskId, taskId) |
||||
|
.eq(ErrorProneStatisticsEntity::getExamMode, snapshot.getQuestionId()) |
||||
|
.one(); |
||||
|
|
||||
|
if (entity == null) { |
||||
|
entity = new ErrorProneStatisticsEntity(); |
||||
|
entity.setTaskId(taskId); |
||||
|
entity.setQuestionIdList(List.of(snapshot.getQuestionId())); |
||||
|
entity.setExamMode(ExamModeEnum.CLASSIC.getValue()); |
||||
|
entity.setContent(content); |
||||
|
entity.setQuestionType(snapshot.getType()); |
||||
|
entity.setErrorCount(0); |
||||
|
entity.setAppearCount(0); |
||||
|
entity.setOptionDetails(buildOptionDetail(snapshot)); |
||||
|
} |
||||
|
|
||||
|
entity.setAppearCount(entity.getAppearCount() + 1); |
||||
|
if (Boolean.FALSE.equals(snapshot.getIsRight())) { |
||||
|
entity.setErrorCount(entity.getErrorCount() + 1); |
||||
|
} |
||||
|
|
||||
|
updateOptionDetail(entity, snapshot.getUserAnswer()); |
||||
|
|
||||
|
errorProneStatisticsBaseService.saveOrUpdate(entity); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建选项详情 |
||||
|
*/ |
||||
|
private List<ErrorProneStatisticsEntity.OptionDetail> buildOptionDetail(ExamRecordEntity.QuestionSnapshot snapshot) { |
||||
|
List<ErrorProneStatisticsEntity.OptionDetail> list = new ArrayList<>(); |
||||
|
Map<String, String> options = snapshot.getOptions(); |
||||
|
if (options == null) { |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
String normalizedRightAnswer = normalizeAnswer(snapshot.getRightAnswer()); |
||||
|
|
||||
|
for (Map.Entry<String, String> entry : options.entrySet()) { |
||||
|
ErrorProneStatisticsEntity.OptionDetail od = new ErrorProneStatisticsEntity.OptionDetail(); |
||||
|
od.setOption(entry.getKey()); |
||||
|
od.setOptionContent(entry.getValue()); |
||||
|
od.setChoosenCount(0); |
||||
|
od.setRight(normalizedRightAnswer.contains(entry.getKey().toUpperCase())); |
||||
|
list.add(od); |
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新选项被选择次数 |
||||
|
*/ |
||||
|
private void updateOptionDetail(ErrorProneStatisticsEntity entity, String userAnswer) { |
||||
|
String normalizedUserAnswer = normalizeAnswer(userAnswer); |
||||
|
if (StrUtil.isBlank(normalizedUserAnswer)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
List<ErrorProneStatisticsEntity.OptionDetail> optionDetailList = entity.getOptionDetails(); |
||||
|
if (CollUtil.isEmpty(optionDetailList)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
for (ErrorProneStatisticsEntity.OptionDetail od : optionDetailList) { |
||||
|
if (normalizedUserAnswer.contains(od.getOption().toUpperCase())) { |
||||
|
od.setChoosenCount((od.getChoosenCount() == null ? 0 : od.getChoosenCount()) + 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 标准化答案:去除非字母数字字符并转大写 |
||||
|
*/ |
||||
|
private String normalizeAnswer(String answer) { |
||||
|
if (StrUtil.isBlank(answer)) { |
||||
|
return ""; |
||||
|
} |
||||
|
return answer.replaceAll("[^a-zA-Z0-9]", "").toUpperCase(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 是否为简答题 |
||||
|
*/ |
||||
|
private boolean isShortAnswer(Integer type) { |
||||
|
return Objects.equals(type, QuestionTypeEnum.SHORT_ANSWER.getValue()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
package com.project.statistics.domain.service.impl; |
||||
|
|
||||
|
import com.project.base.domain.result.Result; |
||||
|
import com.project.statistics.domain.dto.ErrorProneStatisticsDTO; |
||||
|
import com.project.statistics.domain.entity.ErrorProneStatisticsEntity; |
||||
|
import com.project.statistics.domain.service.ErrorProneStatisticsBaseService; |
||||
|
import com.project.statistics.domain.service.SearchErrorProneStatisticsDomainService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
@Service |
||||
|
public class SearchErrorProneStatisticsDomainServiceImpl implements SearchErrorProneStatisticsDomainService { |
||||
|
|
||||
|
@Autowired |
||||
|
private ErrorProneStatisticsBaseService errorProneStatisticsBaseService; |
||||
|
|
||||
|
@Override |
||||
|
public Result<List<ErrorProneStatisticsDTO>> searchTopByTaskId(Long taskId) { |
||||
|
List<ErrorProneStatisticsEntity> entityList = errorProneStatisticsBaseService.lambdaQuery() |
||||
|
.eq(ErrorProneStatisticsEntity::getTaskId, taskId) |
||||
|
.orderByDesc(ErrorProneStatisticsEntity::getErrorCount) |
||||
|
.last("LIMIT 10") |
||||
|
.list(); |
||||
|
|
||||
|
List<ErrorProneStatisticsDTO> dtoList = entityList.stream().map(entity -> entity.toDTO(ErrorProneStatisticsDTO::new)).collect(Collectors.toList()); |
||||
|
return Result.success(dtoList); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
package com.project.statistics.mapper; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import com.project.statistics.domain.entity.ErrorProneStatisticsEntity; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
|
||||
|
@Mapper |
||||
|
public interface ErrorProneStatisticsMapper extends BaseMapper<ErrorProneStatisticsEntity> { |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue