6 changed files with 164 additions and 7 deletions
@ -0,0 +1,5 @@ |
|||
package com.project.question.domain.service; |
|||
|
|||
public interface QuestionInventoryDomainService { |
|||
void checkAndReplenish(Long taskId) throws Exception; |
|||
} |
|||
@ -0,0 +1,105 @@ |
|||
package com.project.question.domain.service.impl; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.project.question.domain.entity.TaskKnowledgeClusterEntity; |
|||
import com.project.question.domain.entity.TaskKnowledgePointEntity; |
|||
import com.project.question.domain.enums.QuestionSourceTypeEnum; |
|||
import com.project.question.domain.service.GenerateQuestionDomainService; |
|||
import com.project.question.domain.service.QuestionInventoryDomainService; |
|||
import com.project.question.mapper.QuestionKpRelMapper; |
|||
import com.project.question.mapper.TaskKnowledgeClusterMapper; |
|||
import com.project.question.mapper.TaskKnowledgePointMapper; |
|||
import com.project.task.domain.entity.TaskEntity; |
|||
import com.project.task.domain.enums.QuestionTypeEnum; |
|||
import com.project.task.mapper.TaskMapper; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
public class QuestionInventoryDomainServiceImpl implements QuestionInventoryDomainService { |
|||
@Autowired |
|||
private TaskKnowledgePointMapper taskKpMapper; |
|||
|
|||
@Autowired |
|||
private TaskKnowledgeClusterMapper clusterMapper; |
|||
|
|||
@Autowired |
|||
private QuestionKpRelMapper questionKpMapper; |
|||
|
|||
@Autowired |
|||
private TaskMapper taskMapper; |
|||
|
|||
@Autowired |
|||
private GenerateQuestionDomainService generateQuestionDomainService; |
|||
|
|||
@Override |
|||
public void checkAndReplenish(Long taskId) { |
|||
TaskEntity task = taskMapper.selectById(taskId); |
|||
if (task == null || task.getEndTime().before(new Date())) { |
|||
return; |
|||
} |
|||
int u = (task.getParticipantNum() == null ? 0 : task.getParticipantNum()) |
|||
- (task.getPassNum() == null ? 0 : task.getPassNum()); |
|||
if (u <= 0) { |
|||
return; |
|||
} |
|||
int watermark = (int) Math.ceil(1.0 * u); |
|||
int targetLine = (int) Math.ceil(1.2 * u); |
|||
// 针对每个知识点遍历每种题型
|
|||
List<TaskKnowledgePointEntity> kpList = taskKpMapper.selectList( |
|||
new LambdaQueryWrapper<TaskKnowledgePointEntity>().eq(TaskKnowledgePointEntity::getTaskId , taskId)); |
|||
for (TaskKnowledgePointEntity kp : kpList) { |
|||
for (QuestionTypeEnum questionType : QuestionTypeEnum.values()) { |
|||
checkAndProduce(kp.getId() , questionType , watermark , targetLine); |
|||
} |
|||
} |
|||
// 针对每一个簇
|
|||
List<TaskKnowledgeClusterEntity> clusterList = clusterMapper.selectList( |
|||
new LambdaQueryWrapper<TaskKnowledgeClusterEntity>().eq(TaskKnowledgeClusterEntity::getTaskId, taskId)); |
|||
|
|||
for (TaskKnowledgeClusterEntity cluster : clusterList) { |
|||
int w = cluster.getClusterSize(); |
|||
// 簇水位线: 1.0 * U * W
|
|||
int clusterWatermark = watermark * w; |
|||
// 簇目标线: 1.2 * U * W
|
|||
int clusterTargetLine = targetLine * w; |
|||
|
|||
checkClusterProduce(cluster.getId(), clusterWatermark, clusterTargetLine); |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 单知识点补货判定 |
|||
*/ |
|||
private void checkAndProduce(Long kpId, QuestionTypeEnum type, int watermark , int targetLine) { |
|||
int currentStock = questionKpMapper.countAvailableByKp(kpId, type.getValue()); |
|||
|
|||
if (currentStock < watermark) { |
|||
int gap = targetLine - currentStock; |
|||
log.info(">>> [自动补库] KP: {}, 题型: {}, 当前库存: {}, 需补货: {}", kpId, type.getDescription(), currentStock, gap); |
|||
// 触发异步生产逻辑 (内部带 30 分钟冷却锁)
|
|||
generateQuestionDomainService.produce(kpId , type , QuestionSourceTypeEnum.Single_Concept , gap); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 知识点簇补货判定 |
|||
*/ |
|||
private void checkClusterProduce(Long clusterId, int watermark, int targetLine) { |
|||
int currentStock = questionKpMapper.countAvailableByCluster(clusterId); |
|||
|
|||
if (currentStock < watermark) { |
|||
int gap = targetLine - currentStock; |
|||
log.info(">>> [自动补库] 簇: {}, 类型: 复合多选, 当前库存: {}, 需补货: {}", clusterId, currentStock, gap); |
|||
// 簇维度触发,触发异步生产逻辑
|
|||
generateQuestionDomainService.produce(clusterId , QuestionTypeEnum.MULTIPLE_CHOICE , QuestionSourceTypeEnum.Single_Concept , gap); |
|||
} |
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue