package com.smartor.service.impl.bridge; import com.ruoyi.common.core.service.PublicityDataPort; import com.ruoyi.common.core.service.dto.InHospPublicityRowDto; import com.ruoyi.common.core.service.dto.PublicityTaskMatchDto; import com.ruoyi.common.core.service.dto.VisitTaskRuleDto; import com.ruoyi.inhospvisit.domain.PatMedInhosp; import com.ruoyi.task.domain.ServiceTaskRule; import com.ruoyi.patarchive.mapper.PatArchiveMapper; import com.ruoyi.inhospvisit.api.InhospVisitFacade; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import com.ruoyi.common.core.domain.entity.PatArchive; import com.ruoyi.task.domain.ServiceTaskdept; import com.ruoyi.task.domain.ServiceTaskmedical; import com.ruoyi.task.mapper.ServiceTaskdeptMapper; import com.ruoyi.task.mapper.ServiceTaskmedicalMapper; /** * 【过渡实现】{@link PublicityDataPort} 在 smartor 侧的桥接(宣教模块的数据来源)。 * *
| 本类方法 | 原实现位置 |
|---|---|
| {@link #findInHospForPublicity} | L325-329(科室)、L376-379(病区) |
| {@link #findDeptPublicityTaskIds} | L347-353(deptType=1)、L390-396(deptType=2) |
| {@link #findMedicalPublicityTaskIds} | L424-434 |
| {@link #existsPatArchive} | L338-344、L382-388 |
| {@link #updatePublicityFlag} | L340-342 / L357-359 / L367-370(科室)、L384-386 / L400-402(病区) |
* 虽然本端口名义上服务宣教,但 {@link PublicityDataPort#findTaskRule} 服务的是 * 出院随访的规则编排 —— 见接口上的说明。 */ @Autowired private com.ruoyi.task.mapper.ServiceTaskRuleMapper serviceTaskRuleMapper; /** * 扫在院患者。 *
* 原实现两段查询的入参: *
* // 科室维度(L325-329)
* PatMedInhosp pmks = new PatMedInhosp();
* pmks.setDeptcheckFlag("0"); pmks.setInhospstate("1"); pmks.setFuflag("1");
*
* // 病区维度(L376-379)
* pmks.setInDeptcheckFlag(null); pmks.setInWardcheckFlag("0"); pmks.setDeptcheckFlag(null);
*
* ⚠️ 注意病区维度那段是复用同一个 pmks 对象并改字段,所以
* {@code inhospstate="1"} 与 {@code fuflag="1"} 是一直留着的。
* 这里用白名单参数区分两个维度,并保持"两段独立查询"。
*/
@Override
public List
* ⚠️ 三个字段都照原样透传,绝不做 null/空串归一:
* {@code ServiceTaskmedicalMapper.xml} 的条件是
* {@code
* ⚠️ 原实现取的是完整对象然后判 null(L338-344 / L382-388),
* 这里只判存在性 —— 宣教层确实只用到 null 判断
* (真正的患者信息填充发生在 inhospvisit 组装子任务时)。
* 这是有意的等价简化:把"取完整对象"降级为"取 existence",
* 不影响任何分支走向,但省掉一次大字段查询。
*
* 若将来发现 {@code selectPatArchiveByPatid} 内部还有别的副作用(例如缓存写入),
* 需要在 {@code verify_inhospvisit_semantics.py} 里补一条断言。
*/
@Override
public boolean existsPatArchive(Long patid) {
if (patid == null) {
return false;
}
PatArchive archive;
try {
archive = patArchiveMapper.selectPatArchiveByPatid(patid);
} catch (Exception e) {
log.warn("【宣教·过渡桥】查患者档案失败,按「不存在」处理。patid={},原因={}", patid, e.toString());
return false;
}
return Objects.nonNull(archive);
}
/**
* 回写宣教标志位 + 按需写 long_task_reason。
*
* ⚠️ 语义要点(照抄原实现,别"顺手修"):
*
* 语义与原实现完全一致:原代码是"在对象上 set 几个字段,然后
* {@code inhospVisitFacade.updatePatMedInhosp(obj)}",
* 而 {@code updatePatMedInhosp} 的 XML 对每个字段各自 {@code
* ⚠️ 该查询最多返回一条 —— 原实现直接取单个对象,这里也取第一条。
*/
@Override
public VisitTaskRuleDto findTaskRule(String leaveldeptcode, String leavehospitaldistrictcode) {
ServiceTaskRule ruleQuery = new ServiceTaskRule();
ruleQuery.setDeptcode(leaveldeptcode);
ruleQuery.setWardcode(leavehospitaldistrictcode);
ServiceTaskRule rule = serviceTaskRuleMapper.selectServiceTaskRuleByDeptOrWard(ruleQuery);
if (rule == null) {
return null;
}
VisitTaskRuleDto dto = new VisitTaskRuleDto();
dto.setId(rule.getId());
dto.setDeptRule(rule.getDeptRule());
dto.setWradRule(rule.getWradRule());
dto.setDiagRule(rule.getDiagRule());
dto.setDeptcode(rule.getDeptcode());
dto.setWardcode(rule.getWardcode());
dto.setOrgid(rule.getOrgid());
return dto;
}
private InHospPublicityRowDto toRow(PatMedInhosp r) {
InHospPublicityRowDto dto = new InHospPublicityRowDto();
dto.setInhospid(r.getInhospid());
dto.setPatid(r.getPatid());
dto.setOrgid(r.getOrgid());
dto.setDeptcode(r.getDeptcode());
dto.setHospitaldistrictcode(r.getHospitaldistrictcode());
dto.setLongTaskReason(r.getLongTaskReason());
dto.setMedicalCode(r.getMedicalCode());
dto.setMedicalName(r.getMedicalName());
dto.setMedicalCompany(r.getMedicalCompany());
return dto;
}
}
*
*/
@Override
public boolean updatePublicityFlag(Long inhospid, String flagColumn, String flagValue, String reason, boolean appendMode) {
if (!ALLOWED_CHECK_FLAG_COLUMNS.contains(flagColumn)) {
log.warn("【宣教·过渡桥】updatePublicityFlag 收到非法列名「{}」,只允许 {},放弃更新。inhospid={}", flagColumn, ALLOWED_CHECK_FLAG_COLUMNS, inhospid);
return false;
}
if (inhospid == null) {
log.warn("【宣教·过渡桥】updatePublicityFlag 缺少 inhospid,放弃更新。column={}", flagColumn);
return false;
}
PatMedInhosp update = new PatMedInhosp();
update.setInhospid(inhospid);
if ("in_deptcheck_flag".equals(flagColumn)) {
update.setInDeptcheckFlag(flagValue);
} else {
update.setInWardcheckFlag(flagValue);
}
if (reason != null) {
if (appendMode) {
// 原实现:先重查一次拿 long_task_reason,再拼接后写回(不判 null)
PatMedInhosp existing = inhospVisitFacade.selectPatMedInhospByInhospid(inhospid);
String oldReason = existing == null ? null : existing.getLongTaskReason();
update.setLongTaskReason(oldReason + reason);
} else {
update.setLongTaskReason(reason);
}
}
return inhospVisitFacade.updatePatMedInhosp(update) > 0;
}
/**
* 按字段更新(可一次写多个 flag)—— 供出院随访编排层的 3 个 {@code *ForPatient} 使用。
*