| | |
| | | import com.ruoyi.common.utils.spring.SpringUtils; |
| | | import com.smartor.domain.ServiceSubtask; |
| | | import com.smartor.domain.ServiceSubtaskPreachform; |
| | | import com.smartor.domain.ServiceTask; |
| | | import com.smartor.domain.ServiceTaskSchedule; |
| | | import com.smartor.domain.ServiceTaskScheduleDetail; |
| | | import com.smartor.domain.ServiceTaskScheduleVO; |
| | | import com.smartor.domain.SvyTaskTemplateScript; |
| | | import com.smartor.mapper.ServiceSubtaskMapper; |
| | | import com.smartor.mapper.ServiceSubtaskPreachformMapper; |
| | | import com.smartor.mapper.ServiceTaskMapper; |
| | | import com.smartor.mapper.ServiceTaskScheduleDetailMapper; |
| | | import com.smartor.mapper.ServiceTaskScheduleMapper; |
| | | import com.smartor.mapper.SvyTaskTemplateScriptMapper; |
| | | import com.smartor.service.IServiceTaskScheduleService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | |
| | | @Autowired |
| | | private ServiceSubtaskPreachformMapper serviceSubtaskPreachformMapper; |
| | | |
| | | @Autowired |
| | | private ServiceTaskMapper serviceTaskMapper; |
| | | |
| | | @Autowired |
| | | private SvyTaskTemplateScriptMapper svyTaskTemplateScriptMapper; |
| | | |
| | | /** 单次扫描的最大计划数,避免长事务。 */ |
| | | private static final int ROLL_BATCH_LIMIT = 200; |
| | | |
| | |
| | | if (CollectionUtils.isEmpty(vo.getDetailList())) { |
| | | throw new BaseException("任务计划明细不能为空(至少一条 detail)"); |
| | | } |
| | | ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(vo.getTaskid()); |
| | | if (serviceTask == null) { |
| | | throw new BaseException("任务不存在或已删除,taskid=" + vo.getTaskid()); |
| | | } |
| | | |
| | | // 1. 旧计划软删 |
| | | serviceTaskScheduleMapper.deleteByTaskid(vo.getTaskid()); |
| | | serviceTaskScheduleDetailMapper.deleteByTaskid(vo.getTaskid()); |
| | | // 1. 旧计划删 |
| | | serviceTaskScheduleMapper.hardDeleteByTaskid(vo.getTaskid()); |
| | | serviceTaskScheduleDetailMapper.hardDeleteByTaskid(vo.getTaskid()); |
| | | |
| | | // 2. 主计划落库 |
| | | Date now = DateUtils.getNowDate(); |
| | |
| | | schedule.setNextExecuteTime(vo.getNextExecuteTime()); |
| | | schedule.setScheduleBenchmark(vo.getScheduleBenchmark() == null ? 0 : vo.getScheduleBenchmark()); |
| | | schedule.setScheduleBenchmarkCustomTime(vo.getScheduleBenchmarkCustomTime()); |
| | | |
| | | schedule.setDeptCodes(vo.getDeptCodes()); |
| | | schedule.setWardCodes(vo.getWardCodes()); |
| | | schedule.setIcd10Codes(vo.getIcd10Codes()); |
| | | schedule.setOplevelCodes(vo.getOplevelCodes()); |
| | | |
| | | schedule.setRemark(vo.getRemark()); |
| | | schedule.setDelFlag("0"); |
| | | schedule.setCreateBy(vo.getCreateBy()); |
| | |
| | | for (ServiceTaskScheduleDetail detail : detailList) { |
| | | detail.setTaskid(vo.getTaskid()); |
| | | detail.setScheduleid(schedule.getId()); |
| | | Long resolvedTemplateId = resolveTaskTemplateId(serviceTask, detail); |
| | | if (resolvedTemplateId != null) { |
| | | detail.setTemplateid(resolvedTemplateId); |
| | | } |
| | | if (detail.getSeq() == null) { |
| | | detail.setSeq(seq); |
| | | } |
| | |
| | | log.info("[任务组] taskid={} 计划保存完成, scheduleId={}, detail 条数={}", |
| | | vo.getTaskid(), schedule.getId(), detailList.size()); |
| | | return schedule; |
| | | } |
| | | |
| | | /** |
| | | * 计划明细的 templateid 应保存任务模板ID(svy_task_template.id), |
| | | * libtemplateid 才保存模板库ID(svy_lib_template_script.svyid)。 |
| | | * 兼容前端仍传模板库ID的情况:若明细模板在任务模板问题表中不存在, |
| | | * 且该ID就是任务的模板库ID,则回退到任务自己的模板ID。 |
| | | */ |
| | | private Long resolveTaskTemplateId(ServiceTask serviceTask, ServiceTaskScheduleDetail detail) { |
| | | Long detailTemplateId = detail.getTemplateid(); |
| | | if (detailTemplateId == null || serviceTask == null) { |
| | | return detailTemplateId; |
| | | } |
| | | if (hasTaskTemplateScripts(detailTemplateId)) { |
| | | return detailTemplateId; |
| | | } |
| | | // 只有问卷任务才依赖 svy_task_template_script,其它任务类型保持原逻辑 |
| | | if (!"2".equals(serviceTask.getType())) { |
| | | return detailTemplateId; |
| | | } |
| | | |
| | | Long taskTemplateId = serviceTask.getTemplateid(); |
| | | boolean detailUsesLibTemplate = detailTemplateId.equals(detail.getLibtemplateid()) |
| | | || String.valueOf(detailTemplateId).equals(serviceTask.getLibtemplateid()); |
| | | if (detailUsesLibTemplate && hasTaskTemplateScripts(taskTemplateId)) { |
| | | log.warn("计划明细模板ID [{}] 是模板库ID,已映射为任务模板ID [{}], taskid={}", |
| | | detailTemplateId, taskTemplateId, serviceTask.getTaskid()); |
| | | return taskTemplateId; |
| | | } |
| | | log.warn("计划明细模板ID [{}] 在任务模板问题表中不存在, taskid={}, taskTemplateId={}, taskLibTemplateId={}", |
| | | detailTemplateId, serviceTask.getTaskid(), taskTemplateId, serviceTask.getLibtemplateid()); |
| | | return detailTemplateId; |
| | | } |
| | | |
| | | private boolean hasTaskTemplateScripts(Long templateId) { |
| | | if (templateId == null) { |
| | | return false; |
| | | } |
| | | SvyTaskTemplateScript query = new SvyTaskTemplateScript(); |
| | | query.setTemplateID(templateId); |
| | | query.setDelFlag("0"); |
| | | return CollectionUtils.isNotEmpty(svyTaskTemplateScriptMapper.selectSvyTaskTemplateScriptList(query)); |
| | | } |
| | | |
| | | @Override |
| | |
| | | log.warn("[任务组-滚动] scheduleId={} 明细为空, 跳过", scheduleId); |
| | | return false; |
| | | } |
| | | ServiceTask serviceTask = serviceTaskMapper.selectServiceTaskByTaskid(schedule.getTaskid()); |
| | | |
| | | // 推进步长(轮间隔) |
| | | int stepNum = schedule.getScheduleTimeNum() == null ? 0 : schedule.getScheduleTimeNum(); |
| | |
| | | scheduleId, src.getScheduleSeq(), src.getId()); |
| | | continue; |
| | | } |
| | | ServiceSubtask copy = cloneForNextLoop(src, detail, nextLoop, stepNum, stepUnit, now); |
| | | ServiceSubtask copy = cloneForNextLoop(src, serviceTask, detail, nextLoop, stepNum, stepUnit, now); |
| | | serviceSubtaskMapper.insertServiceSubtask(copy); |
| | | // 复制 preachform |
| | | copyPreachform(src.getId(), copy); |
| | |
| | | /** |
| | | * 克隆 subtask 到下一轮:清主键、清回签字段、推进 visit_time、设置 loop_count。 |
| | | */ |
| | | private ServiceSubtask cloneForNextLoop(ServiceSubtask src, ServiceTaskScheduleDetail detail, |
| | | private ServiceSubtask cloneForNextLoop(ServiceSubtask src, ServiceTask serviceTask, |
| | | ServiceTaskScheduleDetail detail, |
| | | long nextLoop, int stepNum, int stepUnit, Date now) { |
| | | ServiceSubtask copy = JSON.parseObject(JSON.toJSONString(src), ServiceSubtask.class); |
| | | copy.setId(null); |
| | |
| | | copy.setSendstate(2L); |
| | | copy.setLoopCount(nextLoop); |
| | | copy.setScheduleDetailId(detail.getId()); |
| | | // 模板:detail 优先 |
| | | if (detail.getTemplateid() != null) { |
| | | copy.setTemplateid(detail.getTemplateid()); |
| | | // 模板:detail 优先,并把历史数据里的模板库ID映射为任务模板ID |
| | | Long resolvedTemplateId = resolveTaskTemplateId(serviceTask, detail); |
| | | if (resolvedTemplateId != null) { |
| | | copy.setTemplateid(resolvedTemplateId); |
| | | copy.setTemplatename(detail.getTemplatename()); |
| | | } |
| | | if (detail.getLibtemplateid() != null) { |