package com.sztzjy.linkCommerce.service.impl; import com.sztzjy.linkCommerce.entity.SchoolClass; import com.sztzjy.linkCommerce.entity.SchoolDefaultTaskInitialization; import com.sztzjy.linkCommerce.entity.TaskAllocation; import com.sztzjy.linkCommerce.entity.TaskAllocationExample; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.SchoolDefaultTaskInitializationMapper; import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper; import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.UUID; @Service public class SchoolDefaultTaskServiceImpl implements SchoolDefaultTaskService { private static final String SCHOOL_DEFAULT_PREFIX = "SCHOOL_DEFAULT:"; @Autowired TaskAllocationMapper taskAllocationMapper; @Autowired SchoolClassMapper schoolClassMapper; @Autowired(required = false) SchoolDefaultTaskInitializationMapper initializationMapper; @Autowired(required = false) @Qualifier("asyncTaskExecutor") AsyncTaskExecutor taskExecutor; public static String schoolDefaultClassId(String schoolId) { return SCHOOL_DEFAULT_PREFIX + schoolId; } @Override public List resolveForTeachingClass(String teachingClassId) { List teachingClassTasks = listByClassId(teachingClassId); if (!teachingClassTasks.isEmpty()) { return teachingClassTasks; } SchoolClass schoolClass = schoolClassMapper == null ? null : schoolClassMapper.selectByPrimaryKey(teachingClassId); if (schoolClass != null && StringUtils.isNotBlank(schoolClass.getSchoolId())) { List schoolTasks = getSchoolDefault(schoolClass.getSchoolId()); if (!schoolTasks.isEmpty()) { return schoolTasks; } } return listByClassId(PLATFORM_DEFAULT_CLASS_ID); } @Override public List getSchoolDefault(String schoolId) { if (StringUtils.isBlank(schoolId)) { return Collections.emptyList(); } return listByClassId(schoolDefaultClassId(schoolId)); } @Override public List getPlatformDefault() { return listByClassId(PLATFORM_DEFAULT_CLASS_ID); } @Override public SchoolDefaultTaskInitialization getInitialization(String schoolId) { return initializationMapper == null || StringUtils.isBlank(schoolId) ? null : initializationMapper.selectByPrimaryKey(schoolId); } @Override public void enqueueInitialization(String schoolId) { if (StringUtils.isBlank(schoolId)) { throw new IllegalArgumentException("学校不能为空"); } markPending(schoolId); if (taskExecutor == null) { initializeInBackground(schoolId); return; } try { taskExecutor.execute(() -> initializeInBackground(schoolId)); } catch (RuntimeException ex) { markFailed(schoolId, ex); throw ex; } } @Override public void replaceSchoolDefault(String schoolId, List tasks) { if (StringUtils.isBlank(schoolId)) { throw new IllegalArgumentException("学校不能为空"); } String classId = schoolDefaultClassId(schoolId); TaskAllocationExample example = new TaskAllocationExample(); example.createCriteria().andClassIdEqualTo(classId); taskAllocationMapper.deleteByExample(example); for (TaskAllocation task : tasks == null ? Collections.emptyList() : tasks) { task.setId(UUID.randomUUID().toString()); task.setClassId(classId); task.setSchoolId(schoolId); taskAllocationMapper.insert(task); } } @Override public void initializeSchoolDefault(String schoolId) { if (StringUtils.isBlank(schoolId) || hasSchoolDefault(schoolId)) { markReady(schoolId); return; } List platformTasks = listByClassId(PLATFORM_DEFAULT_CLASS_ID); if (platformTasks.isEmpty()) { throw new IllegalStateException("平台基线实训任务为空"); } for (TaskAllocation source : platformTasks) { TaskAllocation copy = new TaskAllocation(); copy.setId(UUID.randomUUID().toString()); copy.setClassId(schoolDefaultClassId(schoolId)); copy.setSchoolId(schoolId); copy.setModule(source.getModule()); copy.setDisabledStatus(source.getDisabledStatus()); copy.setSort(source.getSort()); taskAllocationMapper.insert(copy); } markReady(schoolId); } private void initializeInBackground(String schoolId) { markRunning(schoolId); try { initializeSchoolDefault(schoolId); } catch (RuntimeException ex) { markFailed(schoolId, ex); } } private boolean hasSchoolDefault(String schoolId) { TaskAllocationExample example = new TaskAllocationExample(); example.createCriteria().andClassIdEqualTo(schoolDefaultClassId(schoolId)); return taskAllocationMapper.countByExample(example) > 0; } private List listByClassId(String classId) { if (taskAllocationMapper == null || StringUtils.isBlank(classId)) { return Collections.emptyList(); } TaskAllocationExample example = new TaskAllocationExample(); example.createCriteria().andClassIdEqualTo(classId); example.setOrderByClause("sort asc"); List tasks = taskAllocationMapper.selectByExample(example); return tasks == null ? Collections.emptyList() : tasks; } private void markReady(String schoolId) { updateInitialization(schoolId, "READY", null); } private void markPending(String schoolId) { if (initializationMapper == null) { return; } SchoolDefaultTaskInitialization existing = initializationMapper.selectByPrimaryKey(schoolId); Date now = new Date(); if (existing == null) { SchoolDefaultTaskInitialization record = new SchoolDefaultTaskInitialization(); record.setSchoolId(schoolId); record.setStatus("PENDING"); record.setAttemptCount(1); record.setCreateTime(now); record.setUpdateTime(now); initializationMapper.insert(record); return; } SchoolDefaultTaskInitialization record = new SchoolDefaultTaskInitialization(); record.setSchoolId(schoolId); record.setStatus("PENDING"); record.setAttemptCount((existing.getAttemptCount() == null ? 0 : existing.getAttemptCount()) + 1); record.setUpdateTime(now); initializationMapper.updateByPrimaryKeySelective(record); } private void markRunning(String schoolId) { updateInitialization(schoolId, "RUNNING", null); } private void markFailed(String schoolId, RuntimeException ex) { updateInitialization(schoolId, "FAILED", StringUtils.abbreviate(ex.getMessage(), 1000)); } private void updateInitialization(String schoolId, String status, String error) { if (initializationMapper == null || StringUtils.isBlank(schoolId)) { return; } SchoolDefaultTaskInitialization record = new SchoolDefaultTaskInitialization(); record.setSchoolId(schoolId); record.setStatus(status); record.setLastError(error); record.setUpdateTime(new Date()); initializationMapper.updateByPrimaryKeySelective(record); } }