package com.ruoyi.inhospvisit.service; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.core.service.VisitTaskCreateApi; import com.ruoyi.common.core.service.dto.VisitSubtaskDraft; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.core.service.dto.VisitPreachformRow; import com.ruoyi.inhospvisit.mapper.VisitPreachformMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Objects; /** * 「执行方式明细」写入器 —— 逐行搬自 {@code PatMedInhospServiceImpl#addServiceSubtaskPreachform} * (L1061-1103,43 行),并实现第 7 步预留的 * {@link InhospSubtaskWriter.SubtaskPreachformWriter} 接口。 * *

行为逐条对照

*
    *
  1. 按 taskid 查任务;查不到 → 打 ERROR 并 return 0(不抛异常);
  2. *
  3. 取 {@code serviceTask.preachformDesc};为空则整块跳过(返回 0);
  4. *
  5. 用 Jackson 把 JSON 反序列化成 {@code List}; * 解析失败只打 ERROR,不中断(随后 list 为 null → 走"解析后为空"分支);
  6. *
  7. 解析结果为空 → 打 ERROR 并 return 0;
  8. *
  9. 逐条:设 {@code taskid} → {@code subid}; * 先查重(已存在则 continue,不新增); * {@code sendstate} 默认 "1",调用方传了非空值则覆写; * 设 {@code orgid};insert。
  10. *
* *

⚠️ 原实现的 3 个要点,原样保留

* * *

⚠️ 与调用方的事务关系(一处已登记的差异)

* 原实现里 {@code addServiceSubtaskPreachform} 与 {@code insertServiceSubtask} 在同一个 try 内, * 它抛异常会被 {@code writeInSubTask} 的 catch 捕获并把标志位置 "2"。 * 搬迁后 {@link InhospSubtaskWriter} 把它放在自己的 try 里按"尽力而为"处理 * (见该方法注释)。这是有意的健壮性改进:写执行方式明细失败不该 * 让整条随访子任务被判为生成失败。已登记在 {@code verify_inhospvisit_writein_semantics.py} 的说明里。 */ @Slf4j @Service public class VisitPreachformWriter implements InhospSubtaskWriter.SubtaskPreachformWriter { /** 原实现里注释写明「这个 sendstate 需要在数据库设置一个默认值为"1"」 */ private static final String DEFAULT_SENDSTATE = "1"; @Autowired private VisitPreachformMapper preachformMapper; @Autowired private ObjectProvider taskCreateApiProvider; private final ObjectMapper objectMapper = new ObjectMapper(); @Override public void addServiceSubtaskPreachform(VisitSubtaskDraft serviceSubtask, String sendstate) { // 原 L1063-1067:按 taskid 查任务(这里走任务创建域的接口,而不是直接查 service_task) VisitTaskCreateApi api = taskApi(); String preachformDesc = api == null ? null : api.findPreachformDesc(serviceSubtask.getTaskid()); if (api == null) { log.error("addServiceSubtaskPreachform taskid={} 查不到任务,跳过preachform子表生成", serviceSubtask.getTaskid()); return; } // 原 L1070-1071 if (org.apache.commons.lang3.StringUtils.isNotEmpty(preachformDesc)) { // 原 L1072-1078:反序列化;失败只打 ERROR,list 保持 null List list = null; try { list = objectMapper.readValue(preachformDesc, new TypeReference>() { }); } catch (Exception e) { log.error("preachform转List报错了:{}", e.getMessage()); } // 原 L1079-1083 if (CollectionUtils.isEmpty(list)) { log.error("preachformDesc解析后为空,跳过preachform子表生成,taskid为:{},preachformDesc为:{}", serviceSubtask.getTaskid(), preachformDesc); return; } // 原 L1084-1098 for (VisitPreachformRow row : list) { row.setTaskid(serviceSubtask.getTaskid()); row.setSubid(serviceSubtask.getId()); // 原 L1088-1090:先查重,已存在就不新增 VisitPreachformRow query = new VisitPreachformRow(); query.setSubid(row.getSubid()); query.setTaskid(row.getTaskid()); query.setPreachform(row.getPreachform()); List exists = preachformMapper.selectList(query); if (CollectionUtils.isNotEmpty(exists)) { continue; } // 原 L1092-1094:默认 "1",调用方给了非空值则覆写 row.setSendstate(DEFAULT_SENDSTATE); if (StringUtils.isNotEmpty(sendstate)) { row.setSendstate(sendstate); } // 原 L1096-1097 row.setOrgid(serviceSubtask.getOrgid()); preachformMapper.insert(row); } } // 原 L1102:返回值固定为 0(见类注释) } private VisitTaskCreateApi taskApi() { if (taskCreateApiProvider == null) { return null; } try { return taskCreateApiProvider.stream().findFirst().orElse(null); } catch (Exception e) { log.warn("【出入院随访】获取 VisitTaskCreateApi 失败:{}", e.toString()); return null; } } /** 供测试断言:确认本类拿到的 ObjectMapper 非空(原实现是方法内 new,这里提为字段) */ boolean hasObjectMapper() { return Objects.nonNull(objectMapper); } }