package com.ruoyi.inhospvisit.service; import com.ruoyi.common.core.service.OtherVisitApi; import com.ruoyi.common.core.service.PublicityApi; import com.ruoyi.common.core.service.PublicityDataPort; import com.ruoyi.common.core.service.dto.InHospPublicityRowDto; import com.ruoyi.common.core.service.dto.VisitTaskRuleDto; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.core.service.dto.VisitArchiveRow; import com.ruoyi.inhospvisit.domain.row.VisitInhospRow; import com.ruoyi.inhospvisit.mapper.VisitArchiveMapper; import com.ruoyi.inhospvisit.mapper.VisitInhospMapper; 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.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; /** * 出入院随访的两个入口 —— 逐行搬自 {@code PatMedInhospServiceImpl} 的 * {@code dealOutHospInfo}(L324-463,140 行)与 {@code dealOutHospInfoBySchedule}(L471-614,144 行)。 * *
* 顺序与原实现一致:先入院宣教,再药品宣教。 * 取不到宣教模块时按"没有宣教要做"处理并打 WARN(fail-open)。 */ private void dealInHospPublicityAndMedical(String config) { PublicityApi api = publicityApi(); if (api == null) { log.warn("【出入院随访】PublicityApi 不可用(宣教模块未装配),跳过入院宣教与药品宣教。"); return; } try { // 原 L331-409 api.dealInHospPublicity(config); } catch (Exception e) { // 宣教失败不能拖垮随访主流程 log.warn("【出入院随访】入院宣教回调失败,已忽略:{}", e.toString()); } try { // 原 L411-444 api.dealMedicalPublicity(config); } catch (Exception e) { log.warn("【出入院随访】药品宣教回调失败,已忽略:{}", e.toString()); } } /** * 手术随访回调(原 L449-451 与 L559-608 的 {@code addOperationSubTask})。 */ private void callOperationVisit(String config) { OtherVisitApi api = otherVisitApi(); if (api == null) { log.warn("【出入院随访】OtherVisitApi 不可用(手术随访模块未装配),跳过手术随访。"); return; } try { api.addOperationSubTask(config); } catch (Exception e) { log.warn("【出入院随访】手术随访回调失败,已忽略:{}", e.toString()); } } /** * 逐患者做规则编排(原 L448 的 {@code addSubTaskByRule(config, patMedInhosps)})。 *
* 原 {@code addSubTaskByRule}(L1691) 是个"遍历患者"的外层方法,
* 本次把"遍历"放在这里,把"单患者规则判定"放进
* {@link InhospTaskOrchestrator#addSubTaskByRule}。
* 这样切分之后,两边的方法名相同但职责不同,已在各自注释里写明。
*/
private void addSubTaskByRule(String config, List
* 所以本次把整个方法留在 smartor(行为一行不变),
* 等第二批做 {@code ruoyi-othervisit} 时连同任务组链路一起收走。
*
* 这样做的好处:本轮不需要为 {@code ScheduleSubtaskBuilder} 再造一个端口,
* 也不会因为"搬一半留一半"而在两处生成任务组的子任务。
*
* @param config {@code sys_config: visit.early.day}
* @return 原实现固定返回 1
*/
public int dealOutHospInfoBySchedule(String config) {
log.warn("【出入院随访】dealOutHospInfoBySchedule 本次未搬迁(含手术分支与任务组 builder,"
+ "属第二批 ruoyi-othervisit 范围),仍由 smartor 的实现承接。config={}", config);
return 1;
}
// ==========================================================================
// 辅助
// ==========================================================================
/** 原 L1703-1707:按离院科室/病区查规则(取不到端口时返回 null = 未配置规则 → 全部生成) */
private VisitTaskRuleDto findTaskRule(VisitInhospRow row) {
PublicityDataPort port = dataPort();
if (port == null) {
log.warn("【出入院随访】PublicityDataPort 不可用,规则按「未配置」处理(全部生成)。inhospid={}",
row.getInhospid());
return null;
}
try {
return port.findTaskRule(row.getLeaveldeptcode(), row.getLeavehospitaldistrictcode());
} catch (Exception e) {
log.warn("【出入院随访】查任务规则失败,按「未配置」处理:{}", e.toString());
return null;
}
}
/** 把端口的规则 DTO 适配成编排器内嵌的规则视图(字段一一对应,含拼错的 {@code wradRule}) */
private InhospTaskOrchestrator.VisitTaskRule toOrchestratorRule(VisitTaskRuleDto dto) {
if (dto == null) {
return null;
}
InhospTaskOrchestrator.VisitTaskRule r = new InhospTaskOrchestrator.VisitTaskRule();
r.setDeptRule(dto.getDeptRule());
r.setWradRule(dto.getWradRule());
r.setDiagRule(dto.getDiagRule());
return r;
}
private void updateInhosp(com.ruoyi.common.core.service.dto.VisitInhospUpdateDto u) {
PublicityDataPort port = dataPort();
if (port == null) {
log.warn("【出入院随访】PublicityDataPort 不可用,无法写回标志位。inhospid={}", u.getInhospid());
return;
}
port.updateVisitInhosp(u);
}
private PublicityDataPort dataPort() {
if (dataPortProvider == null) {
return null;
}
try {
return dataPortProvider.stream().findFirst().orElse(null);
} catch (Exception e) {
log.warn("【出入院随访】获取 PublicityDataPort 失败:{}", e.toString());
return null;
}
}
private PublicityApi publicityApi() {
if (publicityApiProvider == null) {
return null;
}
try {
return publicityApiProvider.stream().findFirst().orElse(null);
} catch (Exception e) {
log.warn("【出入院随访】获取 PublicityApi 失败:{}", e.toString());
return null;
}
}
private OtherVisitApi otherVisitApi() {
if (otherVisitApiProvider == null) {
return null;
}
try {
return otherVisitApiProvider.stream().findFirst().orElse(null);
} catch (Exception e) {
log.warn("【出入院随访】获取 OtherVisitApi 失败:{}", e.toString());
return null;
}
}
}
为什么不搬(一个必须说明的范围决定)
* 原 {@code dealOutHospInfoBySchedule}(L471-614) 由两段构成:
*
*
* 两段都依赖 {@code ScheduleSubtaskBuilder} —— 它同时服务"HIS 自动纳入"与
* "前端手动勾选患者"两条路径(见其类注释),**不属于本次范围**。
* 而手术分支按版图属第二批的 {@code ruoyi-othervisit}。
*