merge: add comprehensive training module

main
chenyuan 4 weeks ago
commit 5c9170887f

@ -1,4 +1,4 @@
package com.sztzjy.linkCommerce.entity.dto; package com.sztzjy.linkCommerce.entity.dto;
import java.math.BigDecimal; import java.math.BigDecimal;
public class StudentExperimentReportModuleDTO { private String moduleName; private BigDecimal weight; private BigDecimal score=BigDecimal.ZERO; private Integer completedTaskCount=0; private Integer totalTaskCount=0; public class StudentExperimentReportModuleDTO { private String moduleName; private BigDecimal weight; private BigDecimal score=BigDecimal.ZERO; private Integer completedTaskCount=0; private Integer totalTaskCount=0; private Boolean participating=Boolean.FALSE;
public String getModuleName(){return moduleName;} public void setModuleName(String v){moduleName=v;} public BigDecimal getWeight(){return weight;} public void setWeight(BigDecimal v){weight=v;} public BigDecimal getScore(){return score;} public void setScore(BigDecimal v){score=v;} public Integer getCompletedTaskCount(){return completedTaskCount;} public void setCompletedTaskCount(Integer v){completedTaskCount=v;} public Integer getTotalTaskCount(){return totalTaskCount;} public void setTotalTaskCount(Integer v){totalTaskCount=v;} } public String getModuleName(){return moduleName;} public void setModuleName(String v){moduleName=v;} public BigDecimal getWeight(){return weight;} public void setWeight(BigDecimal v){weight=v;} public BigDecimal getScore(){return score;} public void setScore(BigDecimal v){score=v;} public Integer getCompletedTaskCount(){return completedTaskCount;} public void setCompletedTaskCount(Integer v){completedTaskCount=v;} public Integer getTotalTaskCount(){return totalTaskCount;} public void setTotalTaskCount(Integer v){totalTaskCount=v;} public Boolean getParticipating(){return participating;} public void setParticipating(Boolean v){participating=v;} }

@ -343,13 +343,16 @@ public class ScoreRankServiceImpl implements ScoreRankService {
} }
TaskAllocationExample allocationExample = new TaskAllocationExample(); TaskAllocationExample allocationExample = new TaskAllocationExample();
allocationExample.createCriteria().andClassIdEqualTo(teachingClassId); allocationExample.createCriteria().andClassIdEqualTo(teachingClassId);
List<TaskAllocation> classAllocations = taskAllocationMapper.selectByExample(allocationExample);
boolean comprehensiveParticipating = hasPublishedComprehensiveTask(classAllocations);
List<TaskAllocation> allocations = schoolDefaultTaskService == null List<TaskAllocation> allocations = schoolDefaultTaskService == null
? taskAllocationMapper.selectByExample(allocationExample) ? classAllocations
: schoolDefaultTaskService.resolveForTeachingClass(teachingClassId); : schoolDefaultTaskService.resolveForTeachingClass(teachingClassId);
Map<String, List<Integer>> scoresByProject = new HashMap<>(); Map<String, List<Integer>> scoresByProject = new HashMap<>();
for (TaskAllocation allocation : allocations == null ? Collections.<TaskAllocation>emptyList() : allocations) { for (TaskAllocation allocation : allocations == null ? Collections.<TaskAllocation>emptyList() : allocations) {
if (allocation.getDisabledStatus() != null && allocation.getDisabledStatus() == 1 if (allocation.getDisabledStatus() != null && allocation.getDisabledStatus() == 1
|| TaskAllocation.PUBLICATION_MARKER.equals(allocation.getModule())) { || TaskAllocation.PUBLICATION_MARKER.equals(allocation.getModule())
|| ("comprehensive-case-training".equals(allocation.getModule()) && !comprehensiveParticipating)) {
continue; continue;
} }
TrainingTask task = trainingTaskMapper.selectByTaskKey(allocation.getModule()); TrainingTask task = trainingTaskMapper.selectByTaskKey(allocation.getModule());
@ -366,7 +369,40 @@ public class ScoreRankServiceImpl implements ScoreRankService {
.add(projectAverage(scoresByProject, "产品开发与测试验证").multiply(weight.getDevelopmentValidationWeight())) .add(projectAverage(scoresByProject, "产品开发与测试验证").multiply(weight.getDevelopmentValidationWeight()))
.add(projectAverage(scoresByProject, "产品上线与运营推广").multiply(weight.getLaunchOperationWeight())) .add(projectAverage(scoresByProject, "产品上线与运营推广").multiply(weight.getLaunchOperationWeight()))
.add(projectAverage(scoresByProject, "综合实训").multiply(weight.getComprehensiveTrainingWeight())) .add(projectAverage(scoresByProject, "综合实训").multiply(weight.getComprehensiveTrainingWeight()))
.setScale(2, BigDecimal.ROUND_HALF_UP); .divide(participatingWeight(weight, comprehensiveParticipating), 2, BigDecimal.ROUND_HALF_UP);
}
private boolean hasPublishedComprehensiveTask(List<TaskAllocation> allocations) {
boolean published = false;
boolean enabled = false;
for (TaskAllocation allocation : allocations == null ? Collections.<TaskAllocation>emptyList() : allocations) {
if (allocation == null) {
continue;
}
if (TaskAllocation.PUBLICATION_MARKER.equals(allocation.getModule())) {
published = true;
} else if ("comprehensive-case-training".equals(allocation.getModule())
&& (allocation.getDisabledStatus() == null || allocation.getDisabledStatus() == 0)) {
enabled = true;
}
}
return published && enabled;
}
private BigDecimal participatingWeight(TeachingClassScoreWeight weight, boolean comprehensiveParticipating) {
BigDecimal total = safeWeight(weight.getFoundationWeight())
.add(safeWeight(weight.getMarketInsightWeight()))
.add(safeWeight(weight.getPlanningDesignWeight()))
.add(safeWeight(weight.getDevelopmentValidationWeight()))
.add(safeWeight(weight.getLaunchOperationWeight()));
if (comprehensiveParticipating) {
total = total.add(safeWeight(weight.getComprehensiveTrainingWeight()));
}
return total.signum() == 0 ? BigDecimal.ONE : total;
}
private BigDecimal safeWeight(BigDecimal weight) {
return weight == null ? BigDecimal.ZERO : weight;
} }
private BigDecimal projectAverage(Map<String, List<Integer>> scoresByProject, String project) { private BigDecimal projectAverage(Map<String, List<Integer>> scoresByProject, String project) {

@ -2,9 +2,10 @@ package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.security.JwtUser; import com.sztzjy.linkCommerce.entity.*; import com.sztzjy.linkCommerce.entity.dto.*; import com.sztzjy.linkCommerce.mapper.*; import com.sztzjy.linkCommerce.service.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.sztzjy.linkCommerce.config.security.JwtUser; import com.sztzjy.linkCommerce.entity.*; import com.sztzjy.linkCommerce.entity.dto.*; import com.sztzjy.linkCommerce.mapper.*; import com.sztzjy.linkCommerce.service.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import java.math.*; import java.util.*; import java.math.*; import java.util.*;
@Service public class StudentExperimentReportServiceImpl implements StudentExperimentReportService { @Service public class StudentExperimentReportServiceImpl implements StudentExperimentReportService {
@Autowired public StudentTeachingClassResolver studentTeachingClassResolver; @Autowired public SchoolDefaultTaskService schoolDefaultTaskService; @Autowired public TrainingTaskMapper trainingTaskMapper; @Autowired public StudentTrainingAnswerMapper studentTrainingAnswerMapper; @Autowired(required=false) public TeachingClassScoreWeightMapper teachingClassScoreWeightMapper; @Autowired public StudentTeachingClassResolver studentTeachingClassResolver; @Autowired public SchoolDefaultTaskService schoolDefaultTaskService; @Autowired public TrainingTaskMapper trainingTaskMapper; @Autowired public StudentTrainingAnswerMapper studentTrainingAnswerMapper; @Autowired(required=false) public TeachingClassScoreWeightMapper teachingClassScoreWeightMapper; @Autowired(required=false) public TaskAllocationMapper taskAllocationMapper;
private static final String[] NAMES={"互联网产品开发基础认知","市场洞察与需求分析","产品规划与设计","产品开发与测试验证","产品上线与运营推广","综合实训"}; private static final String[] NAMES={"互联网产品开发基础认知","市场洞察与需求分析","产品规划与设计","产品开发与测试验证","产品上线与运营推广","综合实训"};
private static final BigDecimal[] DEFAULTS={new BigDecimal("0.10"),new BigDecimal("0.30"),new BigDecimal("0.10"),new BigDecimal("0.10"),new BigDecimal("0.20"),new BigDecimal("0.20")}; private static final BigDecimal[] DEFAULTS={new BigDecimal("0.10"),new BigDecimal("0.30"),new BigDecimal("0.10"),new BigDecimal("0.10"),new BigDecimal("0.20"),new BigDecimal("0.20")};
public StudentExperimentReportDTO getCurrentReport(JwtUser user){ String classId=studentTeachingClassResolver.resolveRequired(user); StudentExperimentReportDTO report=new StudentExperimentReportDTO(); report.setTeachingClassId(classId); List<StudentExperimentReportModuleDTO> modules=new ArrayList<>(); Map<String,StudentExperimentReportModuleDTO> index=new HashMap<>(); BigDecimal[] weights=weights(classId); for(int i=0;i<NAMES.length;i++){StudentExperimentReportModuleDTO m=new StudentExperimentReportModuleDTO();m.setModuleName(NAMES[i]);m.setWeight(weights[i]);modules.add(m);index.put(NAMES[i],m);} List<StudentExperimentReportTaskDTO> tasks=new ArrayList<>(); for(TaskAllocation a: schoolDefaultTaskService.resolveForTeachingClass(classId)){if(a==null||a.getDisabledStatus()!=null&&a.getDisabledStatus()==1||TaskAllocation.PUBLICATION_MARKER.equals(a.getModule()))continue; TrainingTask t=trainingTaskMapper.selectByTaskKey(a.getModule()); if(t==null||!index.containsKey(t.getProjectName()))continue; StudentTrainingAnswer ans=studentTrainingAnswerMapper.selectByStudentClassAndTask(user.getUserId(),classId,t.getId()); StudentExperimentReportModuleDTO m=index.get(t.getProjectName());m.setTotalTaskCount(m.getTotalTaskCount()+1);int score=ans==null||ans.getAiAssessmentScore()==null?0:ans.getAiAssessmentScore();m.setScore(m.getScore().add(BigDecimal.valueOf(score)));if(ans!=null&&(Boolean.TRUE.equals(ans.getSubmitted())||"COMPLETED".equals(ans.getProgressStatus())))m.setCompletedTaskCount(m.getCompletedTaskCount()+1);StudentExperimentReportTaskDTO row=new StudentExperimentReportTaskDTO();row.setTaskName(t.getTaskName());row.setModuleName(t.getProjectName());if(ans!=null){row.setProgressStatus(ans.getProgressStatus());row.setSubmitted(ans.getSubmitted());row.setAiAssessmentScore(ans.getAiAssessmentScore());}tasks.add(row);} BigDecimal total=BigDecimal.ZERO;for(StudentExperimentReportModuleDTO m:modules){BigDecimal score=m.getTotalTaskCount()==0?BigDecimal.ZERO:m.getScore().divide(BigDecimal.valueOf(m.getTotalTaskCount()),2,BigDecimal.ROUND_HALF_UP);m.setScore(score);total=total.add(score.multiply(m.getWeight()));}report.setTotalScore(total.setScale(2,BigDecimal.ROUND_HALF_UP));report.setModules(modules);report.setTasks(tasks);return report; } public StudentExperimentReportDTO getCurrentReport(JwtUser user){ String classId=studentTeachingClassResolver.resolveRequired(user); StudentExperimentReportDTO report=new StudentExperimentReportDTO(); report.setTeachingClassId(classId); List<StudentExperimentReportModuleDTO> modules=new ArrayList<>(); Map<String,StudentExperimentReportModuleDTO> index=new HashMap<>(); BigDecimal[] weights=weights(classId); boolean comprehensiveParticipating=hasPublishedComprehensiveTask(classId); for(int i=0;i<NAMES.length;i++){StudentExperimentReportModuleDTO m=new StudentExperimentReportModuleDTO();m.setModuleName(NAMES[i]);m.setWeight(weights[i]);m.setParticipating(i<NAMES.length-1||comprehensiveParticipating);modules.add(m);index.put(NAMES[i],m);} List<StudentExperimentReportTaskDTO> tasks=new ArrayList<>(); for(TaskAllocation a: schoolDefaultTaskService.resolveForTeachingClass(classId)){if(a==null||a.getDisabledStatus()!=null&&a.getDisabledStatus()==1||TaskAllocation.PUBLICATION_MARKER.equals(a.getModule())||("comprehensive-case-training".equals(a.getModule())&&!comprehensiveParticipating))continue; TrainingTask t=trainingTaskMapper.selectByTaskKey(a.getModule()); if(t==null||!index.containsKey(t.getProjectName()))continue; StudentTrainingAnswer ans=studentTrainingAnswerMapper.selectByStudentClassAndTask(user.getUserId(),classId,t.getId()); StudentExperimentReportModuleDTO m=index.get(t.getProjectName());m.setTotalTaskCount(m.getTotalTaskCount()+1);int score=ans==null||ans.getAiAssessmentScore()==null?0:ans.getAiAssessmentScore();m.setScore(m.getScore().add(BigDecimal.valueOf(score)));if(ans!=null&&(Boolean.TRUE.equals(ans.getSubmitted())||"COMPLETED".equals(ans.getProgressStatus())))m.setCompletedTaskCount(m.getCompletedTaskCount()+1);StudentExperimentReportTaskDTO row=new StudentExperimentReportTaskDTO();row.setTaskName(t.getTaskName());row.setModuleName(t.getProjectName());if(ans!=null){row.setProgressStatus(ans.getProgressStatus());row.setSubmitted(ans.getSubmitted());row.setAiAssessmentScore(ans.getAiAssessmentScore());}tasks.add(row);} BigDecimal total=BigDecimal.ZERO;BigDecimal participatingWeight=BigDecimal.ZERO;for(StudentExperimentReportModuleDTO m:modules){BigDecimal score=m.getTotalTaskCount()==0?BigDecimal.ZERO:m.getScore().divide(BigDecimal.valueOf(m.getTotalTaskCount()),2,BigDecimal.ROUND_HALF_UP);m.setScore(score);if(Boolean.TRUE.equals(m.getParticipating())){BigDecimal weight=m.getWeight()==null?BigDecimal.ZERO:m.getWeight();total=total.add(score.multiply(weight));participatingWeight=participatingWeight.add(weight);}}report.setTotalScore(participatingWeight.signum()==0?BigDecimal.ZERO:total.divide(participatingWeight,2,BigDecimal.ROUND_HALF_UP));report.setModules(modules);report.setTasks(tasks);return report; }
private boolean hasPublishedComprehensiveTask(String classId){if(taskAllocationMapper==null)return false;TaskAllocationExample example=new TaskAllocationExample();example.createCriteria().andClassIdEqualTo(classId);List<TaskAllocation> allocations=taskAllocationMapper.selectByExample(example);boolean published=false;boolean enabled=false;for(TaskAllocation allocation:allocations==null?Collections.<TaskAllocation>emptyList():allocations){if(allocation==null)continue;if(TaskAllocation.PUBLICATION_MARKER.equals(allocation.getModule()))published=true;else if("comprehensive-case-training".equals(allocation.getModule())&&(allocation.getDisabledStatus()==null||allocation.getDisabledStatus()==0))enabled=true;}return published&&enabled;}
private BigDecimal[] weights(String id){TeachingClassScoreWeight w=teachingClassScoreWeightMapper==null?null:teachingClassScoreWeightMapper.selectByTeachingClassId(id);if(w==null)return DEFAULTS;return new BigDecimal[]{w.getFoundationWeight(),w.getMarketInsightWeight(),w.getPlanningDesignWeight(),w.getDevelopmentValidationWeight(),w.getLaunchOperationWeight(),w.getComprehensiveTrainingWeight()};} private BigDecimal[] weights(String id){TeachingClassScoreWeight w=teachingClassScoreWeightMapper==null?null:teachingClassScoreWeightMapper.selectByTeachingClassId(id);if(w==null)return DEFAULTS;return new BigDecimal[]{w.getFoundationWeight(),w.getMarketInsightWeight(),w.getPlanningDesignWeight(),w.getDevelopmentValidationWeight(),w.getLaunchOperationWeight(),w.getComprehensiveTrainingWeight()};}
} }

@ -42,6 +42,7 @@ import java.util.stream.Collectors;
@Service @Service
public class TrainingTaskServiceImpl implements TrainingTaskService { public class TrainingTaskServiceImpl implements TrainingTaskService {
private static final Pattern SPLIT_PATTERN = Pattern.compile("[;|]"); private static final Pattern SPLIT_PATTERN = Pattern.compile("[;|]");
private static final String COMPREHENSIVE_CASE_TRAINING_TASK_KEY = "comprehensive-case-training";
@Autowired @Autowired
public TrainingTaskMapper trainingTaskMapper; public TrainingTaskMapper trainingTaskMapper;
@ -291,9 +292,13 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
ensureDefaultTasks(null); ensureDefaultTasks(null);
String normalizedTaskKey = StringUtils.trimToEmpty(taskKey); String normalizedTaskKey = StringUtils.trimToEmpty(taskKey);
TrainingTask defaultTask = trainingTaskMapper.selectByTaskKey(normalizedTaskKey); TrainingTask defaultTask = trainingTaskMapper.selectByTaskKey(normalizedTaskKey);
if (StringUtils.isBlank(teachingClassId) && requiresExplicitPublication(normalizedTaskKey)) {
return null;
}
if (StringUtils.isNotBlank(teachingClassId)) { if (StringUtils.isNotBlank(teachingClassId)) {
Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId); Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId);
if (publishedTaskKeys != null && !publishedTaskKeys.contains(normalizedTaskKey)) { if ((publishedTaskKeys != null && !publishedTaskKeys.contains(normalizedTaskKey))
|| (requiresExplicitPublication(normalizedTaskKey) && publishedTaskKeys == null)) {
return null; return null;
} }
ensureClassTasksInitialized(teachingClassId, trainingTaskMapper.selectList(null, null, null), null); ensureClassTasksInitialized(teachingClassId, trainingTaskMapper.selectList(null, null, null), null);
@ -301,6 +306,9 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
if (classTask != null) { if (classTask != null) {
return Boolean.TRUE.equals(classTask.getEnabled()) ? toTask(classTask) : null; return Boolean.TRUE.equals(classTask.getEnabled()) ? toTask(classTask) : null;
} }
if (requiresExplicitPublication(normalizedTaskKey)) {
return null;
}
} }
return defaultTask; return defaultTask;
} }
@ -319,19 +327,28 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
ensureDefaultTasks(null); ensureDefaultTasks(null);
List<TrainingTask> defaults = trainingTaskMapper.selectList(null, null, null); List<TrainingTask> defaults = trainingTaskMapper.selectList(null, null, null);
if (StringUtils.isBlank(teachingClassId)) { if (StringUtils.isBlank(teachingClassId)) {
return filterEnabled(sortTasks(defaults), enabledOnly); return filterEnabled(sortTasks(defaults).stream()
.filter(task -> !requiresExplicitPublication(task.getTaskKey()))
.collect(Collectors.toList()), enabledOnly);
} }
List<TrainingTaskClassConfig> classTasks = ensureClassTasksInitialized(teachingClassId, defaults, null); List<TrainingTaskClassConfig> classTasks = ensureClassTasksInitialized(teachingClassId, defaults, null);
List<TrainingTask> tasks = filterEnabled(toTasks(classTasks), enabledOnly); List<TrainingTask> tasks = filterEnabled(toTasks(classTasks), enabledOnly);
Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId); Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId);
if (publishedTaskKeys == null) { if (publishedTaskKeys == null) {
return tasks; return tasks.stream()
.filter(task -> !requiresExplicitPublication(task.getTaskKey()))
.collect(Collectors.toList());
} }
return tasks.stream() return tasks.stream()
.filter(task -> publishedTaskKeys.contains(task.getTaskKey())) .filter(task -> publishedTaskKeys.contains(task.getTaskKey()))
.filter(task -> !requiresExplicitPublication(task.getTaskKey()) || Boolean.TRUE.equals(task.getEnabled()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private boolean requiresExplicitPublication(String taskKey) {
return COMPREHENSIVE_CASE_TRAINING_TASK_KEY.equals(StringUtils.trimToEmpty(taskKey));
}
/** /**
* @return null when this teaching class has never been configured (default: all tasks), * @return null when this teaching class has never been configured (default: all tasks),
* otherwise the explicitly published task keys, which may be empty. * otherwise the explicitly published task keys, which may be empty.
@ -844,6 +861,7 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
private List<TrainingTask> defaultTasks() { private List<TrainingTask> defaultTasks() {
List<TrainingTask> tasks = new ArrayList<>(); List<TrainingTask> tasks = new ArrayList<>();
addDefault(tasks, "综合实训", COMPREHENSIVE_CASE_TRAINING_TASK_KEY, "综合案例实训");
addDefault(tasks, "互联网产品开发基础认知", "new-product-survey", "新产品调查与分析"); addDefault(tasks, "互联网产品开发基础认知", "new-product-survey", "新产品调查与分析");
addDefault(tasks, "互联网产品开发基础认知", "product-development-factors", "产品开发关键因素"); addDefault(tasks, "互联网产品开发基础认知", "product-development-factors", "产品开发关键因素");
addDefault(tasks, "互联网产品开发基础认知", "product-development-process", "产品开发主要流程"); addDefault(tasks, "互联网产品开发基础认知", "product-development-process", "产品开发主要流程");

@ -65,7 +65,7 @@ class TaskAllocationControllerTest {
schoolClass.setClassType("TEACHING"); schoolClass.setClassType("TEACHING");
when(controller.schoolClassMapper.selectByPrimaryKey("teaching-1")).thenReturn(schoolClass); when(controller.schoolClassMapper.selectByPrimaryKey("teaching-1")).thenReturn(schoolClass);
TaskAllocation allocation = new TaskAllocation(); TaskAllocation allocation = new TaskAllocation();
allocation.setModule("任务A"); allocation.setModule("comprehensive-case-training");
allocation.setSort(1); allocation.setSort(1);
ResultEntity result = controller.updateTaskAllocationByClassId(Collections.singletonList(allocation), "teaching-1", "school-1", "teacher-1"); ResultEntity result = controller.updateTaskAllocationByClassId(Collections.singletonList(allocation), "teaching-1", "school-1", "teacher-1");
@ -78,7 +78,7 @@ class TaskAllocationControllerTest {
assertNotNull(inserted.get(0).getId()); assertNotNull(inserted.get(0).getId());
assertEquals(TaskAllocation.PUBLICATION_MARKER, inserted.get(0).getModule()); assertEquals(TaskAllocation.PUBLICATION_MARKER, inserted.get(0).getModule());
assertEquals((byte) 1, inserted.get(0).getDisabledStatus()); assertEquals((byte) 1, inserted.get(0).getDisabledStatus());
assertEquals("任务A", inserted.get(1).getModule()); assertEquals("comprehensive-case-training", inserted.get(1).getModule());
assertEquals((byte) 0, inserted.get(1).getDisabledStatus()); assertEquals((byte) 0, inserted.get(1).getDisabledStatus());
assertEquals("teaching-1", inserted.get(1).getClassId()); assertEquals("teaching-1", inserted.get(1).getClassId());
assertEquals("school-1", inserted.get(1).getSchoolId()); assertEquals("school-1", inserted.get(1).getSchoolId());

@ -4,8 +4,17 @@ import com.sztzjy.linkCommerce.entity.SchoolClass;
import com.sztzjy.linkCommerce.entity.StuRank; import com.sztzjy.linkCommerce.entity.StuRank;
import com.sztzjy.linkCommerce.entity.StuRankExample; import com.sztzjy.linkCommerce.entity.StuRankExample;
import com.sztzjy.linkCommerce.entity.TeachingClassStudent; import com.sztzjy.linkCommerce.entity.TeachingClassStudent;
import com.sztzjy.linkCommerce.entity.TaskAllocation;
import com.sztzjy.linkCommerce.entity.StudentTrainingAnswer;
import com.sztzjy.linkCommerce.entity.TeachingClassScoreWeight;
import com.sztzjy.linkCommerce.entity.TrainingTask;
import com.sztzjy.linkCommerce.entity.Userinfo; import com.sztzjy.linkCommerce.entity.Userinfo;
import com.sztzjy.linkCommerce.entity.Weight; import com.sztzjy.linkCommerce.entity.Weight;
import com.sztzjy.linkCommerce.entity.dto.StudentExperimentReportModuleDTO;
import com.sztzjy.linkCommerce.mapper.StudentTrainingAnswerMapper;
import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper;
import com.sztzjy.linkCommerce.mapper.TeachingClassScoreWeightMapper;
import com.sztzjy.linkCommerce.mapper.TrainingTaskMapper;
import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper;
import com.sztzjy.linkCommerce.mapper.StuCountMapper; import com.sztzjy.linkCommerce.mapper.StuCountMapper;
import com.sztzjy.linkCommerce.mapper.StuGradeMapper; import com.sztzjy.linkCommerce.mapper.StuGradeMapper;
@ -14,6 +23,7 @@ import com.sztzjy.linkCommerce.mapper.StuStudyTimeMapper;
import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper;
import com.sztzjy.linkCommerce.mapper.UserinfoMapper; import com.sztzjy.linkCommerce.mapper.UserinfoMapper;
import com.sztzjy.linkCommerce.mapper.WeightMapper; import com.sztzjy.linkCommerce.mapper.WeightMapper;
import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@ -65,6 +75,36 @@ class ScoreRankServiceImplTeachingClassTest {
assertEquals("student-2", rankCaptor.getAllValues().get(1).getUserId()); assertEquals("student-2", rankCaptor.getAllValues().get(1).getUserId());
} }
@Test
void doRankTeachingClassNormalizesFiveModulesWhenComprehensiveIsNotPublishedByClass() {
ScoreRankServiceImpl service = serviceWithMocks();
SchoolClass teachingClass = new SchoolClass();
teachingClass.setSchoolClassId("teaching-1");
teachingClass.setClassName("teaching one");
teachingClass.setClassType("TEACHING");
when(service.schoolClassMapper.selectByPrimaryKey("teaching-1")).thenReturn(teachingClass);
when(service.teachingClassStudentMapper.selectByTeachingClassId("teaching-1")).thenReturn(Collections.singletonList(member("student-1")));
when(service.userinfoMapper.selectByPrimaryKey("student-1")).thenReturn(student("student-1", "s001"));
when(service.weightMapper.selectByPrimaryKey("school-1")).thenReturn(weight());
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(Collections.emptyList());
when(service.schoolDefaultTaskService.resolveForTeachingClass("teaching-1")).thenReturn(allocations(6));
String[] names = (String[]) org.springframework.test.util.ReflectionTestUtils.getField(StudentExperimentReportServiceImpl.class, "NAMES");
for (int i = 0; i < 6; i++) {
when(service.trainingTaskMapper.selectByTaskKey(taskKey(i))).thenReturn(trainingTask("id-" + i, names[i]));
if (i < 5) {
when(service.studentTrainingAnswerMapper.selectByStudentClassAndTask("student-1", "teaching-1", "id-" + i)).thenReturn(answer(100));
}
}
when(service.teachingClassScoreWeightMapper.selectByTeachingClassId("teaching-1")).thenReturn(sixWeights());
assertTrue(service.doRankTeachingClass("school-1", "teaching-1"));
ArgumentCaptor<StuRank> rankCaptor = ArgumentCaptor.forClass(StuRank.class);
verify(service.stuRankMapper).insert(rankCaptor.capture());
assertEquals(new BigDecimal("100.00"), rankCaptor.getValue().getScore());
}
private ScoreRankServiceImpl serviceWithMocks() { private ScoreRankServiceImpl serviceWithMocks() {
ScoreRankServiceImpl service = new ScoreRankServiceImpl(); ScoreRankServiceImpl service = new ScoreRankServiceImpl();
service.stuRankMapper = mock(StuRankMapper.class); service.stuRankMapper = mock(StuRankMapper.class);
@ -75,6 +115,11 @@ class ScoreRankServiceImplTeachingClassTest {
service.stuStudyTimeMapper = mock(StuStudyTimeMapper.class); service.stuStudyTimeMapper = mock(StuStudyTimeMapper.class);
service.schoolClassMapper = mock(SchoolClassMapper.class); service.schoolClassMapper = mock(SchoolClassMapper.class);
service.teachingClassStudentMapper = mock(TeachingClassStudentMapper.class); service.teachingClassStudentMapper = mock(TeachingClassStudentMapper.class);
service.taskAllocationMapper = mock(TaskAllocationMapper.class);
service.trainingTaskMapper = mock(TrainingTaskMapper.class);
service.studentTrainingAnswerMapper = mock(StudentTrainingAnswerMapper.class);
service.teachingClassScoreWeightMapper = mock(TeachingClassScoreWeightMapper.class);
service.schoolDefaultTaskService = mock(SchoolDefaultTaskService.class);
return service; return service;
} }
@ -106,6 +151,45 @@ class ScoreRankServiceImplTeachingClassTest {
return weight; return weight;
} }
private java.util.List<TaskAllocation> allocations(int count) {
TaskAllocation[] values = new TaskAllocation[count];
for (int i = 0; i < count; i++) {
TaskAllocation allocation = new TaskAllocation();
allocation.setModule(taskKey(i));
allocation.setDisabledStatus((byte) 0);
values[i] = allocation;
}
return Arrays.asList(values);
}
private TrainingTask trainingTask(String id, String project) {
TrainingTask task = new TrainingTask();
task.setId(id);
task.setProjectName(project);
return task;
}
private StudentTrainingAnswer answer(int score) {
StudentTrainingAnswer answer = new StudentTrainingAnswer();
answer.setAiAssessmentScore(score);
return answer;
}
private String taskKey(int index) {
return index == 5 ? "comprehensive-case-training" : "task-" + index;
}
private TeachingClassScoreWeight sixWeights() {
TeachingClassScoreWeight weight = new TeachingClassScoreWeight();
weight.setFoundationWeight(new BigDecimal("0.10"));
weight.setMarketInsightWeight(new BigDecimal("0.30"));
weight.setPlanningDesignWeight(new BigDecimal("0.10"));
weight.setDevelopmentValidationWeight(new BigDecimal("0.10"));
weight.setLaunchOperationWeight(new BigDecimal("0.20"));
weight.setComprehensiveTrainingWeight(new BigDecimal("0.20"));
return weight;
}
private void assertCriterion(StuRankExample example, String condition, Object value) { private void assertCriterion(StuRankExample example, String condition, Object value) {
assertTrue(example.getOredCriteria().get(0).getAllCriteria().stream() assertTrue(example.getOredCriteria().get(0).getAllCriteria().stream()
.anyMatch(criterion -> condition.equals(criterion.getCondition()) && value.equals(criterion.getValue()))); .anyMatch(criterion -> condition.equals(criterion.getCondition()) && value.equals(criterion.getValue())));

@ -6,6 +6,7 @@ import com.sztzjy.linkCommerce.entity.TaskAllocation;
import com.sztzjy.linkCommerce.entity.TrainingTask; import com.sztzjy.linkCommerce.entity.TrainingTask;
import com.sztzjy.linkCommerce.entity.dto.StudentExperimentReportDTO; import com.sztzjy.linkCommerce.entity.dto.StudentExperimentReportDTO;
import com.sztzjy.linkCommerce.mapper.StudentTrainingAnswerMapper; import com.sztzjy.linkCommerce.mapper.StudentTrainingAnswerMapper;
import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper;
import com.sztzjy.linkCommerce.mapper.TrainingTaskMapper; import com.sztzjy.linkCommerce.mapper.TrainingTaskMapper;
import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService; import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService;
import com.sztzjy.linkCommerce.service.StudentTeachingClassResolver; import com.sztzjy.linkCommerce.service.StudentTeachingClassResolver;
@ -14,6 +15,8 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@ -40,12 +43,81 @@ class StudentExperimentReportServiceImplTest {
assertEquals(6, report.getModules().size()); assertEquals(6, report.getModules().size());
assertEquals(new BigDecimal("80.00"), report.getModules().get(1).getScore()); assertEquals(new BigDecimal("80.00"), report.getModules().get(1).getScore());
assertEquals(new BigDecimal("0.30"), report.getModules().get(1).getWeight()); assertEquals(new BigDecimal("0.30"), report.getModules().get(1).getWeight());
assertEquals(new BigDecimal("24.00"), report.getTotalScore()); assertEquals(new BigDecimal("30.00"), report.getTotalScore());
assertEquals(1, report.getTasks().size()); assertEquals(1, report.getTasks().size());
} }
@Test
void normalizesFiveModulesWhenComprehensiveIsOnlyInTheSchoolDefault() {
StudentExperimentReportServiceImpl service = new StudentExperimentReportServiceImpl();
StudentTeachingClassResolver resolver = mock(StudentTeachingClassResolver.class);
SchoolDefaultTaskService taskService = mock(SchoolDefaultTaskService.class);
TrainingTaskMapper taskMapper = mock(TrainingTaskMapper.class);
StudentTrainingAnswerMapper answerMapper = mock(StudentTrainingAnswerMapper.class);
TaskAllocationMapper allocationMapper = mock(TaskAllocationMapper.class);
ReflectionTestUtils.setField(service, "studentTeachingClassResolver", resolver);
ReflectionTestUtils.setField(service, "schoolDefaultTaskService", taskService);
ReflectionTestUtils.setField(service, "trainingTaskMapper", taskMapper);
ReflectionTestUtils.setField(service, "studentTrainingAnswerMapper", answerMapper);
ReflectionTestUtils.setField(service, "taskAllocationMapper", allocationMapper);
when(resolver.resolveRequired(any())).thenReturn("class-1");
when(allocationMapper.selectByExample(any())).thenReturn(Collections.emptyList());
List<String> names = moduleNames();
when(taskService.resolveForTeachingClass("class-1")).thenReturn(allocations(6));
for (int i = 0; i < 6; i++) {
when(taskMapper.selectByTaskKey(taskKey(i))).thenReturn(task("id-" + i, names.get(i), taskKey(i)));
}
when(answerMapper.selectByStudentClassAndTask(eq("student-1"), eq("class-1"), anyString()))
.thenReturn(answer(100, true));
StudentExperimentReportDTO report = service.getCurrentReport(student());
assertEquals(new BigDecimal("100.00"), report.getTotalScore());
assertEquals(Boolean.FALSE, report.getModules().get(5).getParticipating());
assertEquals(0, report.getModules().get(5).getTotalTaskCount());
}
@Test
void publishedComprehensiveParticipatesAtZeroWhenStudentHasNotAnswered() {
StudentExperimentReportServiceImpl service = new StudentExperimentReportServiceImpl();
StudentTeachingClassResolver resolver = mock(StudentTeachingClassResolver.class);
SchoolDefaultTaskService taskService = mock(SchoolDefaultTaskService.class);
TrainingTaskMapper taskMapper = mock(TrainingTaskMapper.class);
StudentTrainingAnswerMapper answerMapper = mock(StudentTrainingAnswerMapper.class);
TaskAllocationMapper allocationMapper = mock(TaskAllocationMapper.class);
ReflectionTestUtils.setField(service, "studentTeachingClassResolver", resolver);
ReflectionTestUtils.setField(service, "schoolDefaultTaskService", taskService);
ReflectionTestUtils.setField(service, "trainingTaskMapper", taskMapper);
ReflectionTestUtils.setField(service, "studentTrainingAnswerMapper", answerMapper);
ReflectionTestUtils.setField(service, "taskAllocationMapper", allocationMapper);
when(resolver.resolveRequired(any())).thenReturn("class-1");
when(allocationMapper.selectByExample(any())).thenReturn(Arrays.asList(marker(), allocation(taskKey(5))));
List<String> names = moduleNames();
when(taskService.resolveForTeachingClass("class-1")).thenReturn(allocations(6));
for (int i = 0; i < 6; i++) {
when(taskMapper.selectByTaskKey(taskKey(i))).thenReturn(task("id-" + i, names.get(i), taskKey(i)));
}
for (int i = 0; i < 5; i++) {
when(answerMapper.selectByStudentClassAndTask("student-1", "class-1", "id-" + i)).thenReturn(answer(100, true));
}
StudentExperimentReportDTO report = service.getCurrentReport(student());
assertEquals(new BigDecimal("80.00"), report.getTotalScore());
assertEquals(Boolean.TRUE, report.getModules().get(5).getParticipating());
assertEquals(1, report.getModules().get(5).getTotalTaskCount());
assertEquals(BigDecimal.ZERO.setScale(2), report.getModules().get(5).getScore());
}
private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("student-1"); user.setRoleId(4); return user; } private JwtUser student() { JwtUser user = new JwtUser(); user.setUserId("student-1"); user.setRoleId(4); return user; }
private TaskAllocation allocation(String key) { return allocation(key, (byte) 0); } private TaskAllocation allocation(String key) { return allocation(key, (byte) 0); }
private TaskAllocation allocation(String key, byte disabled) { TaskAllocation value = new TaskAllocation(); value.setModule(key); value.setDisabledStatus(disabled); return value; } private TaskAllocation allocation(String key, byte disabled) { TaskAllocation value = new TaskAllocation(); value.setModule(key); value.setDisabledStatus(disabled); return value; }
private TrainingTask task(String id, String project, String name) { TrainingTask value = new TrainingTask(); value.setId(id); value.setProjectName(project); value.setTaskName(name); return value; } private TrainingTask task(String id, String project, String name) { TrainingTask value = new TrainingTask(); value.setId(id); value.setProjectName(project); value.setTaskName(name); return value; }
private StudentTrainingAnswer answer(int score, boolean submitted) { StudentTrainingAnswer value = new StudentTrainingAnswer(); value.setAiAssessmentScore(score); value.setSubmitted(submitted); value.setProgressStatus("COMPLETED"); return value; } private StudentTrainingAnswer answer(int score, boolean submitted) { StudentTrainingAnswer value = new StudentTrainingAnswer(); value.setAiAssessmentScore(score); value.setSubmitted(submitted); value.setProgressStatus("COMPLETED"); return value; }
private TaskAllocation marker() { return allocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1); }
private List<TaskAllocation> allocations(int count) { TaskAllocation[] values = new TaskAllocation[count]; for (int i = 0; i < count; i++) values[i] = allocation(taskKey(i)); return Arrays.asList(values); }
private String taskKey(int index) { return index == 5 ? "comprehensive-case-training" : "task-" + index; }
private List<String> moduleNames() { return Arrays.asList((String[]) ReflectionTestUtils.getField(StudentExperimentReportServiceImpl.class, "NAMES")); }
} }

@ -2,11 +2,13 @@ package com.sztzjy.linkCommerce.service.impl;
import com.sztzjy.linkCommerce.config.security.JwtUser; import com.sztzjy.linkCommerce.config.security.JwtUser;
import com.sztzjy.linkCommerce.entity.SchoolClass; import com.sztzjy.linkCommerce.entity.SchoolClass;
import com.sztzjy.linkCommerce.entity.TaskAllocation;
import com.sztzjy.linkCommerce.entity.TeachingClassStudent; import com.sztzjy.linkCommerce.entity.TeachingClassStudent;
import com.sztzjy.linkCommerce.entity.TrainingTask; import com.sztzjy.linkCommerce.entity.TrainingTask;
import com.sztzjy.linkCommerce.entity.TrainingTaskClassConfig; import com.sztzjy.linkCommerce.entity.TrainingTaskClassConfig;
import com.sztzjy.linkCommerce.entity.importDto.TrainingTaskImportDTO; import com.sztzjy.linkCommerce.entity.importDto.TrainingTaskImportDTO;
import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper;
import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper;
import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper;
import com.sztzjy.linkCommerce.mapper.TrainingTaskClassConfigMapper; import com.sztzjy.linkCommerce.mapper.TrainingTaskClassConfigMapper;
import com.sztzjy.linkCommerce.mapper.TrainingTaskMapper; import com.sztzjy.linkCommerce.mapper.TrainingTaskMapper;
@ -220,9 +222,11 @@ class TrainingTaskServiceImplTest {
service.ensureDefaultTasks("system"); service.ensureDefaultTasks("system");
ArgumentCaptor<TrainingTask> captor = ArgumentCaptor.forClass(TrainingTask.class); ArgumentCaptor<TrainingTask> captor = ArgumentCaptor.forClass(TrainingTask.class);
verify(service.trainingTaskMapper, times(22)).insertSelective(captor.capture()); verify(service.trainingTaskMapper, times(23)).insertSelective(captor.capture());
assertFalse(captor.getAllValues().stream().anyMatch(task -> "new-product-survey".equals(task.getTaskKey()))); assertFalse(captor.getAllValues().stream().anyMatch(task -> "new-product-survey".equals(task.getTaskKey())));
assertEquals("product-development-factors", captor.getAllValues().get(0).getTaskKey()); assertEquals("comprehensive-case-training", captor.getAllValues().get(0).getTaskKey());
assertEquals("综合实训", captor.getAllValues().get(0).getProjectName());
assertEquals("综合案例实训", captor.getAllValues().get(0).getTaskName());
} }
@Test @Test
@ -510,7 +514,7 @@ class TrainingTaskServiceImplTest {
service.saveClassTask("class-1", "new-product-survey", payload, "teacher-1"); service.saveClassTask("class-1", "new-product-survey", payload, "teacher-1");
ArgumentCaptor<TrainingTaskClassConfig> captor = ArgumentCaptor.forClass(TrainingTaskClassConfig.class); ArgumentCaptor<TrainingTaskClassConfig> captor = ArgumentCaptor.forClass(TrainingTaskClassConfig.class);
verify(service.trainingTaskClassConfigMapper, times(24)).insertSelective(captor.capture()); verify(service.trainingTaskClassConfigMapper, times(25)).insertSelective(captor.capture());
TrainingTaskClassConfig savedOverride = captor.getAllValues().stream() TrainingTaskClassConfig savedOverride = captor.getAllValues().stream()
.filter(config -> "new-product-survey".equals(config.getTaskKey())) .filter(config -> "new-product-survey".equals(config.getTaskKey()))
.filter(config -> "Class Name".equals(config.getTaskName())) .filter(config -> "Class Name".equals(config.getTaskName()))
@ -601,6 +605,204 @@ class TrainingTaskServiceImplTest {
assertEquals(0, result.size()); assertEquals(0, result.size());
} }
@Test
void studentListHidesComprehensiveTrainingUntilTheClassHasPublishedIt() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask legacy = storedTask("task-1", "new-product-survey");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(legacy, comprehensive));
when(service.trainingTaskClassConfigMapper.selectListByTeachingClass("class-1", null))
.thenReturn(List.of(overrideTask("config-1", "class-1", "new-product-survey"),
overrideTask("config-2", "class-1", "comprehensive-case-training")));
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(Collections.emptyList());
List<TrainingTask> result = service.listForStudent("stu-1", true);
assertEquals(List.of("new-product-survey"), result.stream()
.map(TrainingTask::getTaskKey)
.collect(java.util.stream.Collectors.toList()));
}
@Test
void studentTaskLookupHidesComprehensiveTrainingUntilTheClassHasPublishedIt() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectByTaskKey("comprehensive-case-training")).thenReturn(comprehensive);
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(Collections.emptyList());
TrainingTask result = service.getStudentTaskByTaskKey("comprehensive-case-training", "stu-1");
assertNull(result);
}
@Test
void studentTaskLookupReturnsComprehensiveTrainingWhenPublishedAndEnabledForTheClass() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectByTaskKey("comprehensive-case-training")).thenReturn(comprehensive);
when(service.trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey("class-1", "comprehensive-case-training"))
.thenReturn(overrideTask("config-1", "class-1", "comprehensive-case-training"));
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(List.of(
taskAllocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1),
taskAllocation("comprehensive-case-training", (byte) 0)));
TrainingTask result = service.getStudentTaskByTaskKey("comprehensive-case-training", "stu-1");
assertEquals("comprehensive-case-training", result.getTaskKey());
}
@Test
void studentTaskLookupHidesPublishedComprehensiveTrainingWhenItsClassTaskIsDisabled() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectByTaskKey("comprehensive-case-training")).thenReturn(comprehensive);
TrainingTaskClassConfig disabled = overrideTask("config-1", "class-1", "comprehensive-case-training");
disabled.setEnabled(Boolean.FALSE);
when(service.trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey("class-1", "comprehensive-case-training"))
.thenReturn(disabled);
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(List.of(
taskAllocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1),
taskAllocation("comprehensive-case-training", (byte) 0)));
TrainingTask result = service.getStudentTaskByTaskKey("comprehensive-case-training", "stu-1");
assertNull(result);
}
@Test
void studentListReturnsComprehensiveTrainingWhenPublishedAndEnabledForTheClass() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask legacy = storedTask("task-1", "new-product-survey");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(legacy, comprehensive));
when(service.trainingTaskClassConfigMapper.selectListByTeachingClass("class-1", null))
.thenReturn(List.of(overrideTask("config-1", "class-1", "new-product-survey"),
overrideTask("config-2", "class-1", "comprehensive-case-training")));
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(List.of(
taskAllocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1),
taskAllocation("new-product-survey", (byte) 0),
taskAllocation("comprehensive-case-training", (byte) 0)));
List<TrainingTask> result = service.listForStudent("stu-1", true);
assertEquals(List.of("new-product-survey", "comprehensive-case-training"), result.stream()
.map(TrainingTask::getTaskKey)
.collect(java.util.stream.Collectors.toList()));
}
@Test
void studentListHidesComprehensiveTrainingWhenThePublishedKeyIsRemoved() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask legacy = storedTask("task-1", "new-product-survey");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(legacy, comprehensive));
when(service.trainingTaskClassConfigMapper.selectListByTeachingClass("class-1", null))
.thenReturn(List.of(overrideTask("config-1", "class-1", "new-product-survey"),
overrideTask("config-2", "class-1", "comprehensive-case-training")));
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(List.of(
taskAllocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1),
taskAllocation("new-product-survey", (byte) 0)));
List<TrainingTask> result = service.listForStudent("stu-1", true);
assertEquals(List.of("new-product-survey"), result.stream()
.map(TrainingTask::getTaskKey)
.collect(java.util.stream.Collectors.toList()));
}
@Test
void studentListHidesComprehensiveTrainingWhenItsPublishedAllocationIsDisabled() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask legacy = storedTask("task-1", "new-product-survey");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(legacy, comprehensive));
when(service.trainingTaskClassConfigMapper.selectListByTeachingClass("class-1", null))
.thenReturn(List.of(overrideTask("config-1", "class-1", "new-product-survey"),
overrideTask("config-2", "class-1", "comprehensive-case-training")));
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(List.of(
taskAllocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1),
taskAllocation("new-product-survey", (byte) 0),
taskAllocation("comprehensive-case-training", (byte) 1)));
List<TrainingTask> result = service.listForStudent("stu-1", true);
assertEquals(List.of("new-product-survey"), result.stream()
.map(TrainingTask::getTaskKey)
.collect(java.util.stream.Collectors.toList()));
}
@Test
void studentListHidesDisabledComprehensiveTrainingWhenDisabledTasksAreRequested() {
TrainingTaskServiceImpl service = studentTaskService("class-1");
TrainingTask legacy = storedTask("task-1", "new-product-survey");
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(legacy, comprehensive));
TrainingTaskClassConfig disabled = overrideTask("config-2", "class-1", "comprehensive-case-training");
disabled.setEnabled(Boolean.FALSE);
when(service.trainingTaskClassConfigMapper.selectListByTeachingClass("class-1", null))
.thenReturn(List.of(overrideTask("config-1", "class-1", "new-product-survey"), disabled));
when(service.taskAllocationMapper.selectByExample(any())).thenReturn(List.of(
taskAllocation(TaskAllocation.PUBLICATION_MARKER, (byte) 1),
taskAllocation("new-product-survey", (byte) 0),
taskAllocation("comprehensive-case-training", (byte) 0)));
List<TrainingTask> result = service.listForStudent("stu-1", false);
assertEquals(List.of("new-product-survey"), result.stream()
.map(TrainingTask::getTaskKey)
.collect(java.util.stream.Collectors.toList()));
}
@Test
void teacherClassTaskListIncludesComprehensiveTrainingWithoutPublication() {
TrainingTaskServiceImpl service = new TrainingTaskServiceImpl();
service.trainingTaskMapper = mock(TrainingTaskMapper.class);
service.trainingTaskClassConfigMapper = mock(TrainingTaskClassConfigMapper.class);
service.schoolClassMapper = mock(SchoolClassMapper.class);
TrainingTask comprehensive = comprehensiveTrainingTask();
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(comprehensive));
when(service.trainingTaskClassConfigMapper.selectListByTeachingClass("class-1", null)).thenReturn(Collections.emptyList());
SchoolClass schoolClass = teachingClass("class-1", "teacher-1");
schoolClass.setSchoolId("school-1");
when(service.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(schoolClass);
JwtUser teacher = new JwtUser();
teacher.setUserId("teacher-1");
teacher.setSchoolId("school-1");
List<TrainingTask> result = service.listForTeachingClass("class-1", true, teacher);
assertEquals(List.of("comprehensive-case-training"), result.stream()
.map(TrainingTask::getTaskKey)
.collect(java.util.stream.Collectors.toList()));
}
private TrainingTaskServiceImpl studentTaskService(String teachingClassId) {
TrainingTaskServiceImpl service = new TrainingTaskServiceImpl();
service.trainingTaskMapper = mock(TrainingTaskMapper.class);
service.trainingTaskClassConfigMapper = mock(TrainingTaskClassConfigMapper.class);
service.teachingClassStudentMapper = mock(TeachingClassStudentMapper.class);
service.taskAllocationMapper = mock(TaskAllocationMapper.class);
TeachingClassStudent membership = new TeachingClassStudent();
membership.setTeachingClassId(teachingClassId);
when(service.teachingClassStudentMapper.selectActiveByStudentUserId("stu-1")).thenReturn(membership);
return service;
}
private TrainingTask comprehensiveTrainingTask() {
TrainingTask task = storedTask("task-comprehensive", "comprehensive-case-training");
task.setProjectName("综合实训");
task.setTaskName("综合案例实训");
task.setSort(1);
return task;
}
private TaskAllocation taskAllocation(String module, byte disabledStatus) {
TaskAllocation allocation = new TaskAllocation();
allocation.setModule(module);
allocation.setDisabledStatus(disabledStatus);
return allocation;
}
private TrainingTask storedTask(String id, String taskKey) { private TrainingTask storedTask(String id, String taskKey) {
TrainingTask task = new TrainingTask(); TrainingTask task = new TrainingTask();
task.setId(id); task.setId(id);

Loading…
Cancel
Save