|
|
|
@ -5,6 +5,7 @@ import com.project.information.domain.dto.KnowledgePointDTO; |
|
|
|
import com.project.information.domain.entity.KnowledgePointEntity; |
|
|
|
import com.project.information.domain.service.KnowledgePointBaseService; |
|
|
|
import com.project.interaction.domain.dto.ClusterCallbackDTO; |
|
|
|
import com.project.interaction.domain.dto.ProduceDTO; |
|
|
|
import com.project.interaction.domain.service.SaveClusterDomainService; |
|
|
|
import com.project.question.domain.entity.TaskKnowledgeClusterEntity; |
|
|
|
import com.project.question.domain.entity.TaskKnowledgePointEntity; |
|
|
|
@ -19,10 +20,7 @@ import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
@Service |
|
|
|
@Slf4j |
|
|
|
@ -43,8 +41,10 @@ public class SaveClusterDomainServiceImpl implements SaveClusterDomainService { |
|
|
|
@Autowired |
|
|
|
private GenerateQuestionDomainService generateQuestionDomainService; |
|
|
|
|
|
|
|
private final Integer ROUND_NUM = 2; |
|
|
|
|
|
|
|
@Override |
|
|
|
public void saveCluster(Long taskId, List<ClusterCallbackDTO.ClusterItem> clusters) throws Exception { |
|
|
|
public void saveCluster(Long taskId, List<ClusterCallbackDTO.ClusterItem> clusters) { |
|
|
|
TaskEntity taskEntity = taskBaseService.getById(taskId); |
|
|
|
int u = 0; |
|
|
|
if (Objects.isNull(taskEntity) || Objects.isNull(taskEntity.getParticipantNum()) || taskEntity.getParticipantNum() <= 0) { |
|
|
|
@ -52,6 +52,9 @@ public class SaveClusterDomainServiceImpl implements SaveClusterDomainService { |
|
|
|
} |
|
|
|
u = taskEntity.getParticipantNum(); |
|
|
|
log.info(">>> [回调处理] 开始持久化任务[{}]聚类结果,计划人数U={}", taskId, u); |
|
|
|
|
|
|
|
List<ProduceDTO> produceDTOList = new ArrayList<>(); |
|
|
|
|
|
|
|
for (ClusterCallbackDTO.ClusterItem cluster : clusters) { |
|
|
|
// 1.保存任务知识点簇
|
|
|
|
TaskKnowledgeClusterEntity clusterEntity = new TaskKnowledgeClusterEntity(); |
|
|
|
@ -87,15 +90,92 @@ public class SaveClusterDomainServiceImpl implements SaveClusterDomainService { |
|
|
|
|
|
|
|
for (TaskKnowledgePointEntity kp : taskKpList) { |
|
|
|
// 调用题目生成方法
|
|
|
|
for (QuestionTypeEnum value : QuestionTypeEnum.values()) { |
|
|
|
generateQuestionDomainService.produce(kp.getId(), value , QuestionSourceTypeEnum.Single_Concept , (int) Math.ceil(targetNum * questionTypeMap.get(value.name()))); |
|
|
|
} |
|
|
|
produceDTOList.add(buildDTO(kp.getId() , QuestionSourceTypeEnum.Single_Concept, |
|
|
|
(int) Math.ceil(targetNum * questionTypeMap.get(QuestionTypeEnum.TRUE_FALSE.name())), |
|
|
|
(int) Math.ceil(targetNum * questionTypeMap.get(QuestionTypeEnum.SINGLE_CHOICE.name())), |
|
|
|
(int) Math.ceil(targetNum * questionTypeMap.get(QuestionTypeEnum.MULTIPLE_CHOICE.name())))); |
|
|
|
} |
|
|
|
if (clusterEntity.getClusterSize() > 1) { |
|
|
|
// 簇生成目标量
|
|
|
|
int clusterTargetNum = (int) Math.ceil(1.2 * u * clusterEntity.getClusterSize() * questionTypeMap.get(QuestionTypeEnum.MULTIPLE_CHOICE.name())); |
|
|
|
generateQuestionDomainService.produce(clusterEntity.getId(), QuestionTypeEnum.MULTIPLE_CHOICE , QuestionSourceTypeEnum.Multi_Concept , clusterTargetNum); |
|
|
|
produceDTOList.add(buildDTO(clusterEntity.getId(), QuestionSourceTypeEnum.Multi_Concept ,0,0, clusterTargetNum)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//生成题目
|
|
|
|
produce(produceDTOList); |
|
|
|
} |
|
|
|
|
|
|
|
private void produce(List<ProduceDTO> produceDTOList) { |
|
|
|
if (produceDTOList == null || produceDTOList.isEmpty()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
//打乱顺序
|
|
|
|
Collections.shuffle(produceDTOList); |
|
|
|
|
|
|
|
boolean hasUnfinished; |
|
|
|
do { |
|
|
|
hasUnfinished = false; |
|
|
|
// 遍历所有DTO,逐一生成
|
|
|
|
for (ProduceDTO produceDTO : produceDTOList) { |
|
|
|
// 跳过已完成的DTO,减少无效遍历
|
|
|
|
if (produceDTO.isCompleted()) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
// 存在未完成的DTO,需要继续循环
|
|
|
|
hasUnfinished = true; |
|
|
|
|
|
|
|
//生成单选题
|
|
|
|
generateSingleTypeQuestion(produceDTO, QuestionTypeEnum.SINGLE_CHOICE, |
|
|
|
produceDTO.getNeedSingleCount(), produceDTO::setNeedSingleCount); |
|
|
|
|
|
|
|
//生成判断题
|
|
|
|
generateSingleTypeQuestion(produceDTO, QuestionTypeEnum.TRUE_FALSE, |
|
|
|
produceDTO.getNeedJudgmentCount(), produceDTO::setNeedJudgmentCount); |
|
|
|
|
|
|
|
//生成多选题
|
|
|
|
generateSingleTypeQuestion(produceDTO, QuestionTypeEnum.MULTIPLE_CHOICE, |
|
|
|
produceDTO.getNeedMultipleCount(), produceDTO::setNeedMultipleCount); |
|
|
|
} |
|
|
|
} while (hasUnfinished); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 抽取通用方法:生成单种题型的题目,避免重复代码 |
|
|
|
* @param dto DTO对象 |
|
|
|
* @param type 题型 |
|
|
|
* @param needCount 需生成数量 |
|
|
|
* @param setNeedCount 设置剩余数量的方法 |
|
|
|
*/ |
|
|
|
private void generateSingleTypeQuestion(ProduceDTO dto, QuestionTypeEnum type, |
|
|
|
int needCount, java.util.function.Consumer<Integer> setNeedCount) { |
|
|
|
// 校验:需生成数量≤0时,直接返回
|
|
|
|
if (needCount <= 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 计算本轮生成数量:最多ROUND_NUM道,不超过剩余数量
|
|
|
|
int generateNum = Math.min(ROUND_NUM, needCount); |
|
|
|
|
|
|
|
// 调用生成方法
|
|
|
|
generateQuestionDomainService.produce(dto.getSourceId(), type, dto.getSourceType(), generateNum); |
|
|
|
|
|
|
|
// 更新剩余数量
|
|
|
|
int remainCount = needCount - generateNum; |
|
|
|
setNeedCount.accept(Math.max(0, remainCount)); // 确保剩余数量≥0
|
|
|
|
|
|
|
|
// 更新已生成总数量
|
|
|
|
dto.setGenerateCount(dto.getGenerateCount() + generateNum); |
|
|
|
} |
|
|
|
|
|
|
|
private ProduceDTO buildDTO(Long sourceId , QuestionSourceTypeEnum sourceType, int needJudgmentCount,int needSingleCount, int needMultipleCount) { |
|
|
|
ProduceDTO produceDTO = new ProduceDTO(); |
|
|
|
produceDTO.setSourceId(sourceId); |
|
|
|
produceDTO.setSourceType(sourceType); |
|
|
|
produceDTO.setNeedJudgmentCount(needJudgmentCount); |
|
|
|
produceDTO.setNeedSingleCount(needSingleCount); |
|
|
|
produceDTO.setNeedMultipleCount(needMultipleCount); |
|
|
|
return produceDTO; |
|
|
|
} |
|
|
|
} |
|
|
|
|