package com.ruoyi.task.api.contract;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.entity.PatArchive;
import com.ruoyi.common.core.service.dto.PatMedReq;
import com.ruoyi.common.core.service.dto.PatMedRes;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.inhospvisit.api.InhospVisitFacade;
import com.ruoyi.inhospvisit.domain.PatMedInhosp;
import com.ruoyi.inhospvisit.domain.PatMedInhospDTO;
import com.ruoyi.inhospvisit.domain.PatMedInhospVO;
import com.ruoyi.othervisit.api.OtherVisitFacade;
import com.ruoyi.othervisit.domain.PatMedOperationItem;
import com.ruoyi.task.api.spi.TaskArchivePort;
import com.ruoyi.task.common.ScheduleSubtaskBuilder;
import com.ruoyi.task.domain.ServiceSubtask;
import com.ruoyi.task.domain.ServiceSubtaskPreachform;
import com.ruoyi.task.domain.ServiceTask;
import com.ruoyi.task.domain.ServiceTaskRule;
import com.ruoyi.task.domain.ServiceTaskSchedule;
import com.ruoyi.task.domain.ServiceTaskScheduleDetail;
import com.ruoyi.task.domain.ServiceTaskdept;
import com.ruoyi.task.domain.ServiceTaskdiag;
import com.ruoyi.task.domain.ServiceTaskoper;
import com.ruoyi.task.domain.entity.ServiceSubtaskEntity;
import com.ruoyi.task.mapper.ServiceSubtaskMapper;
import com.ruoyi.task.mapper.ServiceSubtaskPreachformMapper;
import com.ruoyi.task.mapper.ServiceTaskMapper;
import com.ruoyi.task.mapper.ServiceTaskRuleMapper;
import com.ruoyi.task.mapper.ServiceTaskScheduleDetailMapper;
import com.ruoyi.task.mapper.ServiceTaskScheduleMapper;
import com.ruoyi.task.mapper.ServiceTaskdeptMapper;
import com.ruoyi.task.mapper.ServiceTaskdiagMapper;
import com.ruoyi.task.mapper.ServiceTaskoperMapper;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
/**
* 手术随访分支 + 任务组首轮纳入。
*
*
位置变更史(两次回退后才落在这里,别再随手挪)
*
* - 原本在 {@code PatMedInhospServiceImpl}(约 1600 行)里,2026-11 先整簇抽到
* {@code smartor/.../impl/op/OperationSubtaskWriter},原方法改成一行委托 ——
* 方法体逐字未变;
* - 尝试整类搬进 {@code ruoyi-othervisit} → Maven 环:
* {@code task -> othervisit -> patarchive -> task};
* - 改用 {@code ruoyi-task} + {@code TaskArchivePort} 断环,但当时用脚本摘方法
* 把 1600 行的类改坏,已回退;
* - 本轮(第 7 轮)落在 {@code ruoyi-task}:它本来就拥有
* {@code service_task*} / {@code service_subtask*} 的写能力,且已依赖
* {@code inhospvisit} / {@code othervisit},读档案走 {@link TaskArchivePort},
* 不依赖 ruoyi-patarchive,环彻底消失。
*
*
* ⚠️ 只搬位置,不改逻辑
* 方法体与在 smartor 时逐字一致;唯一的数据访问替换是
* {@code patArchiveMapper.selectPatArchiveByPatid(..)} → {@code taskArchivePort.findByPatid(..)}
* ({@code TaskArchivePortImpl} 里就是同一个 {@code PatArchiveMapper} 的纯转发)。
*
* 谁在调它
* 只经 {@link OtherVisitApiImpl}(本包内)对外,即 {@code ruoyi-common} 的
* {@code OtherVisitApi} 契约;smartor 侧的 {@code OtherVisitApiBridge} 已删除,
* {@code IPatMedInhospService} 上的 3 个过渡入口也已一并删除。
*/
@Slf4j
@Component
public class OperationSubtaskWriter {
@Value("${spring.profiles.active}")
private String active;
@Autowired
private InhospVisitFacade inhospVisitFacade;
@Autowired
private OtherVisitFacade otherVisitFacade;
@Autowired
private TaskArchivePort taskArchivePort;
@Autowired
private ScheduleSubtaskBuilder scheduleSubtaskBuilder;
@Autowired
private ServiceSubtaskMapper serviceSubtaskMapper;
@Autowired
private ServiceSubtaskPreachformMapper serviceSubtaskPreachformMapper;
@Autowired
private ServiceTaskMapper serviceTaskMapper;
@Autowired
private ServiceTaskScheduleDetailMapper serviceTaskScheduleDetailMapper;
@Autowired
private ServiceTaskScheduleMapper serviceTaskScheduleMapper;
@Autowired
private ServiceTaskoperMapper serviceTaskoperMapper;
public int dealOutHospInfoBySchedule(String config) {
ServiceTask serviceTaskVo = new ServiceTask();
serviceTaskVo.setLongTask(1);
serviceTaskVo.setAppltype("5");
List serviceTasks = serviceTaskMapper.selectServiceTaskList(serviceTaskVo);
if (CollectionUtils.isNotEmpty(serviceTasks)) {
for (ServiceTask serviceTask : serviceTasks) {
if (!ObjectUtils.isEmpty(serviceTask.getTaskid())) {
ServiceTaskSchedule serviceTaskSchedule = new ServiceTaskSchedule();
ServiceTaskSchedule taskSchedule = new ServiceTaskSchedule();
taskSchedule.setTaskid(serviceTask.getTaskid());
List serviceTaskSchedules = serviceTaskScheduleMapper.selectServiceTaskScheduleList(taskSchedule);
if (CollectionUtils.isNotEmpty(serviceTaskSchedules)) {
serviceTaskSchedule = serviceTaskSchedules.get(0);
String deptCodes = serviceTaskSchedule.getDeptCodes();
String wardCodes = serviceTaskSchedule.getWardCodes();
String icd10Codes = serviceTaskSchedule.getIcd10Codes();
String opLevelCodes = serviceTaskSchedule.getOplevelCodes();
List icd10CodeList = new ArrayList<>();
List opLevelCodeList = new ArrayList<>();
List deptCodeList = new ArrayList<>();
List wardCodeList = new ArrayList<>();
/**
* 随访类型(1-科室,2-病区,3-疾病 4-入院科室 5-入院病区 6-手术)
*/
Integer type = 1;
if (StringUtils.isNotEmpty(deptCodes)) {
type = 1;
deptCodeList = new ArrayList<>(Arrays.asList(deptCodes.split(",")));
}
if (StringUtils.isNotEmpty(wardCodes)) {
type = 2;
wardCodeList = new ArrayList<>(Arrays.asList(wardCodes.split(",")));
}
if (StringUtils.isNotEmpty(icd10Codes)) {
type = 3;
icd10CodeList = new ArrayList<>(Arrays.asList(icd10Codes.split(",")));
}
if (StringUtils.isNotEmpty(opLevelCodes)) {
type = 6;
opLevelCodeList = new ArrayList<>(Arrays.asList(opLevelCodes.split(",")));
}
//非手术处理方式
if (type != 6) {
PatMedInhosp patMedInhospVo = new PatMedInhosp();
patMedInhospVo.setScheduleCheckFlag("0");
patMedInhospVo.setInhospstate("1");
patMedInhospVo.setFuflag("1");
// patMedInhospVo.setDeptcodeList(deptCodeList);
patMedInhospVo.setLeaveldeptcodes(deptCodeList);
patMedInhospVo.setLeavehospitaldistrictcodes(wardCodeList);
patMedInhospVo.setIcd10codeList(icd10CodeList);
List patList = inhospVisitFacade.selectPatMedInhospList(patMedInhospVo);
log.info("dealOutHospInfoBySchedule 任务组随访, taskid = {}, 扫描患者人数 {}", serviceTask.getTaskid(), patList.size());
for (PatMedInhosp patMedInhosp : patList) {
ServiceTaskScheduleDetail scheduleDetailVo = new ServiceTaskScheduleDetail();
scheduleDetailVo.setTaskid(serviceTask.getTaskid());
scheduleDetailVo.setScheduleid(serviceTaskSchedule.getId());
List serviceTaskScheduleDetails = serviceTaskScheduleDetailMapper.selectServiceTaskScheduleDetailList(scheduleDetailVo);
PatArchive patArchive = taskArchivePort.findByPatid(patMedInhosp.getPatid());
if (Objects.isNull(patArchive)) {
continue;
}
//封装serviceSubtask
ServiceSubtask serviceSubtask = boxedServiceSubtask(serviceTask, patMedInhosp, patArchive, config, type);
List