From 7a8e5a6b26872007e0662a1b7180d8d3af73853f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B2=85?= <907037276@qq.com> Date: Mon, 24 Aug 2026 16:28:47 +0800 Subject: [PATCH] fix: sync admin task steps to student classes --- .../service/impl/TrainingTaskServiceImpl.java | 31 ++++++++++++++++ .../impl/TrainingTaskServiceImplTest.java | 37 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImpl.java index 063146b..a220c0a 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImpl.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImpl.java @@ -108,12 +108,14 @@ public class TrainingTaskServiceImpl implements TrainingTaskService { } @Override + @Transactional(rollbackFor = Exception.class) public TrainingTask update(String id, TrainingTask task) { ensureTrainingTaskTable(); TrainingTask existing = trainingTaskMapper.selectByPrimaryKey(id); if (existing == null) { throw new IllegalArgumentException("实训任务不存在"); } + String previousSteps = existing.getSteps(); normalizeTask(task); TrainingTask builtInTask = requireBuiltInTask(existing.getTaskKey()); task.setId(id); @@ -124,6 +126,7 @@ public class TrainingTaskServiceImpl implements TrainingTaskService { task.setSteps(normalizeSteps(task.getSteps(), builtInTask)); task.setUpdateTime(new Date()); trainingTaskMapper.updateByPrimaryKeySelective(task); + synchronizeClassTaskSteps(existing.getTaskKey(), previousSteps, task.getSteps()); return trainingTaskMapper.selectByPrimaryKey(id); } @@ -492,6 +495,34 @@ public class TrainingTaskServiceImpl implements TrainingTaskService { } } + private void synchronizeClassTaskSteps(String taskKey, String previousSteps, String updatedSteps) { + if (schoolClassMapper == null || trainingTaskClassConfigMapper == null + || StringUtils.equals(previousSteps, updatedSteps)) { + return; + } + SchoolClassExample example = new SchoolClassExample(); + example.createCriteria().andClassTypeEqualTo("TEACHING"); + List teachingClasses = schoolClassMapper.selectByExample(example); + if (teachingClasses == null || teachingClasses.isEmpty()) { + return; + } + for (SchoolClass teachingClass : teachingClasses) { + if (teachingClass == null || StringUtils.isBlank(teachingClass.getSchoolClassId())) { + continue; + } + TrainingTaskClassConfig classTask = trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey( + teachingClass.getSchoolClassId(), taskKey); + if (classTask == null || !StringUtils.equals(previousSteps, classTask.getSteps())) { + continue; + } + TrainingTaskClassConfig update = new TrainingTaskClassConfig(); + update.setId(classTask.getId()); + update.setSteps(updatedSteps); + update.setUpdateTime(new Date()); + trainingTaskClassConfigMapper.updateByPrimaryKeySelective(update); + } + } + private String resolveClassTaskCreator(String teachingClassId, String operatorId) { if (StringUtils.isNotBlank(operatorId)) { return operatorId; diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java index c65bfcd..d73d364 100644 --- a/src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/TrainingTaskServiceImplTest.java @@ -140,6 +140,43 @@ class TrainingTaskServiceImplTest { assertTrue(captor.getValue().getSteps().contains("Custom Step")); } + @Test + void updateTaskSynchronizesOnlyClassStepsStillMatchingThePreviousGlobalConfiguration() { + TrainingTaskServiceImpl service = new TrainingTaskServiceImpl(); + service.trainingTaskMapper = mock(TrainingTaskMapper.class); + service.trainingTaskClassConfigMapper = mock(TrainingTaskClassConfigMapper.class); + service.schoolClassMapper = mock(SchoolClassMapper.class); + + TrainingTask stored = storedTask("task-1", "new-product-survey"); + when(service.trainingTaskMapper.selectByPrimaryKey("task-1")).thenReturn(stored); + + SchoolClass defaultClass = teachingClass("class-default", "teacher-1"); + SchoolClass customizedClass = teachingClass("class-customized", "teacher-2"); + when(service.schoolClassMapper.selectByExample(any())).thenReturn(List.of(defaultClass, customizedClass)); + + TrainingTaskClassConfig defaultConfig = overrideTask("config-default", "class-default", "new-product-survey"); + defaultConfig.setSteps("[\"Step 1\",\"Step 2\",\"Step 3\",\"Step 4\"]"); + TrainingTaskClassConfig customizedConfig = overrideTask("config-customized", "class-customized", "new-product-survey"); + customizedConfig.setSteps("[\"Teacher Step\"]"); + when(service.trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey("class-default", "new-product-survey")) + .thenReturn(defaultConfig); + when(service.trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey("class-customized", "new-product-survey")) + .thenReturn(customizedConfig); + + TrainingTask payload = new TrainingTask(); + payload.setProjectName("Foundation"); + payload.setTaskKey("new-product-survey"); + payload.setTaskName("Admin Updated Name"); + payload.setSteps("[\"Admin Step 1\",\"Admin Step 2\"]"); + + service.update("task-1", payload); + + ArgumentCaptor captor = ArgumentCaptor.forClass(TrainingTaskClassConfig.class); + verify(service.trainingTaskClassConfigMapper).updateByPrimaryKeySelective(captor.capture()); + assertEquals("config-default", captor.getValue().getId()); + assertTrue(captor.getValue().getSteps().contains("Admin Step 1")); + } + @Test void createRejectsUnknownTaskKeyBecauseTaskCountIsFixed() { TrainingTaskServiceImpl service = new TrainingTaskServiceImpl();