Merge remote-tracking branch 'origin/main'

bugfix/ai-assessment-evidence-rescore
陈沅 1 month ago
commit f8547d2bae

@ -169,6 +169,14 @@ public class TrainingTaskController {
} }
} }
@PostMapping("/knowledge/reindex-case-materials")
@ApiOperation("Reindex existing case materials for AI training knowledge")
public ResultEntity<Integer> reindexCaseMaterials(HttpServletRequest request) {
requireAdmin(request);
int count = trainingTaskService.reindexCaseMaterials();
return new ResultEntity<>(HttpStatus.OK, "Case material indexing submitted", count);
}
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@ApiOperation("Delete training task") @ApiOperation("Delete training task")
public ResultEntity delete(@PathVariable String id, HttpServletRequest request) { public ResultEntity delete(@PathVariable String id, HttpServletRequest request) {

@ -20,6 +20,8 @@ public interface TrainingTaskClassConfigMapper {
List<TrainingTaskClassConfig> selectListByTeachingClass(@Param("teachingClassId") String teachingClassId, List<TrainingTaskClassConfig> selectListByTeachingClass(@Param("teachingClassId") String teachingClassId,
@Param("enabled") Boolean enabled); @Param("enabled") Boolean enabled);
List<TrainingTaskClassConfig> selectAll();
int deleteByTeachingClassAndTaskKey(@Param("teachingClassId") String teachingClassId, int deleteByTeachingClassAndTaskKey(@Param("teachingClassId") String teachingClassId,
@Param("taskKey") String taskKey); @Param("taskKey") String taskKey);

@ -37,6 +37,14 @@ public interface TrainingTaskService {
void restoreClassTasksDefaults(String teachingClassId, String operatorId); void restoreClassTasksDefaults(String teachingClassId, String operatorId);
/**
* Rebuilds AI knowledge entries for all saved administrator and teaching-class case materials.
* Existing entries with an unchanged file hash are reused.
*
* @return number of effective case-material configurations submitted for indexing
*/
int reindexCaseMaterials();
TrainingTask getStudentTaskByTaskKey(String taskKey, String studentUserId); TrainingTask getStudentTaskByTaskKey(String taskKey, String studentUserId);
TrainingTask getStudentTaskByTaskKey(String taskKey, JwtUser student); TrainingTask getStudentTaskByTaskKey(String taskKey, JwtUser student);

@ -304,6 +304,40 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
} }
} }
@Override
public int reindexCaseMaterials() {
if (trainingKnowledgeService == null) return 0;
List<TrainingTask> tasks = trainingTaskMapper.selectList(null, null, null);
Map<String, TrainingTask> taskByKey = new LinkedHashMap<>();
int indexed = 0;
for (TrainingTask task : tasks) {
if (task == null || StringUtils.isBlank(task.getTaskKey())) continue;
taskByKey.put(task.getTaskKey(), task);
EffectiveTrainingTaskContent content = EffectiveTrainingTaskContent.resolve(task, null);
if (StringUtils.isNotBlank(content.getMaterialUrl())) {
indexCaseMaterial(task, content, null);
indexed++;
}
}
List<TrainingTaskClassConfig> classConfigs = trainingTaskClassConfigMapper.selectAll();
if (classConfigs == null) return indexed;
for (TrainingTaskClassConfig config : classConfigs) {
if (config == null || !Boolean.TRUE.equals(config.getEnabled())
|| StringUtils.isBlank(config.getTeachingClassId()) || StringUtils.isBlank(config.getTaskKey())) {
continue;
}
TrainingTask task = taskByKey.get(config.getTaskKey());
if (task == null) continue;
EffectiveTrainingTaskContent content = EffectiveTrainingTaskContent.resolve(task, config);
if (StringUtils.isBlank(content.getMaterialUrl())) continue;
indexCaseMaterial(task, content, config.getTeachingClassId());
indexed++;
}
return indexed;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void restoreClassTaskDefault(String teachingClassId, String taskKey, String operatorId) { public void restoreClassTaskDefault(String teachingClassId, String taskKey, String operatorId) {

@ -50,6 +50,12 @@
order by sort asc, create_time asc order by sort asc, create_time asc
</select> </select>
<select id="selectAll" resultMap="BaseResultMap">
select <include refid="Base_Column_List" />
from training_task_class_config
order by teaching_class_id asc, sort asc, create_time asc
</select>
<delete id="deleteByTeachingClassAndTaskKey"> <delete id="deleteByTeachingClassAndTaskKey">
delete from training_task_class_config delete from training_task_class_config
where teaching_class_id = #{teachingClassId,jdbcType=VARCHAR} where teaching_class_id = #{teachingClassId,jdbcType=VARCHAR}

@ -12,6 +12,8 @@ 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;
import com.sztzjy.linkCommerce.service.TrainingKnowledgeService;
import com.sztzjy.linkCommerce.training.knowledge.EffectiveTrainingTaskContent;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@ -52,6 +54,37 @@ class TrainingTaskServiceImplTest {
verify(service.jdbcTemplate, never()).execute(contains("task_allocation")); verify(service.jdbcTemplate, never()).execute(contains("task_allocation"));
} }
@Test
void reindexCaseMaterialsKeepsDefaultAndTeachingClassCasesSeparated() {
TrainingTaskServiceImpl service = new TrainingTaskServiceImpl();
service.trainingTaskMapper = mock(TrainingTaskMapper.class);
service.trainingTaskClassConfigMapper = mock(TrainingTaskClassConfigMapper.class);
service.trainingKnowledgeService = mock(TrainingKnowledgeService.class);
TrainingTask task = storedTask("task-1", "new-product-survey");
task.setMaterialName("管理员案例.docx");
task.setMaterialUrl("/file/admin-case.docx");
TrainingTaskClassConfig teacherConfig = overrideTask("config-1", "class-1", "new-product-survey");
teacherConfig.setMaterialName("教师案例.docx");
teacherConfig.setMaterialUrl("/file/teacher-case.docx");
when(service.trainingTaskMapper.selectList(null, null, null)).thenReturn(List.of(task));
when(service.trainingTaskClassConfigMapper.selectAll()).thenReturn(List.of(teacherConfig));
int indexed = service.reindexCaseMaterials();
assertEquals(2, indexed);
ArgumentCaptor<EffectiveTrainingTaskContent> contentCaptor = ArgumentCaptor.forClass(EffectiveTrainingTaskContent.class);
ArgumentCaptor<String> classCaptor = ArgumentCaptor.forClass(String.class);
verify(service.trainingKnowledgeService, times(2)).indexCaseMaterial(org.mockito.ArgumentMatchers.eq(task),
contentCaptor.capture(), classCaptor.capture());
assertEquals("ADMIN", contentCaptor.getAllValues().get(0).getScope());
assertEquals("task-1", contentCaptor.getAllValues().get(0).getEffectiveConfigId());
assertEquals("TEACHER", contentCaptor.getAllValues().get(1).getScope());
assertEquals("config-1", contentCaptor.getAllValues().get(1).getEffectiveConfigId());
assertNull(classCaptor.getAllValues().get(0));
assertEquals("class-1", classCaptor.getAllValues().get(1));
}
@Test @Test
void splitListSupportsCommonSeparators() { void splitListSupportsCommonSeparators() {
TrainingTaskServiceImpl service = new TrainingTaskServiceImpl(); TrainingTaskServiceImpl service = new TrainingTaskServiceImpl();

Loading…
Cancel
Save