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} 接口。
*
*
行为逐条对照
*
* - 按 taskid 查任务;查不到 → 打 ERROR 并 return 0(不抛异常);
* - 取 {@code serviceTask.preachformDesc};为空则整块跳过(返回 0);
* - 用 Jackson 把 JSON 反序列化成 {@code List};
* 解析失败只打 ERROR,不中断(随后 list 为 null → 走"解析后为空"分支);
* - 解析结果为空 → 打 ERROR 并 return 0;
* - 逐条:设 {@code taskid} → {@code subid};
* 先查重(已存在则 continue,不新增);
* {@code sendstate} 默认 "1",调用方传了非空值则覆写;
* 设 {@code orgid};insert。
*
*
* ⚠️ 原实现的 3 个要点,原样保留
*
* - 返回值【永远是 0】(原 L1102 {@code return 0;}),调用方也没有用它的返回值
* —— 所以本类也返回 0,不做"顺手改成成功条数";
* - 查重用的条件是 {@code ServiceSubtaskPreachform(subid, taskid, preachform)}
* —— 注意没有设 orgid(虽然 XML 支持该条件)。原样保留;
* - 解析失败时 {@code serviceSubtaskPreachformList} 保持 null,
* 由 {@code CollectionUtils.isEmpty(null) == true} 走进"解析后为空"分支 —— 原样保留这个控制流。
*
*
* ⚠️ 与调用方的事务关系(一处已登记的差异)
* 原实现里 {@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);
}
}