liusheng
4 天以前 0bbbd746e8c39d91ad7b47a4e36e29ab972dc98c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package com.ruoyi.inhospvisit.api;
 
import com.ruoyi.common.core.service.dto.VisitAgainSubtaskDto;
import com.ruoyi.inhospvisit.service.InhospVisitTaskService;
import com.ruoyi.inhospvisit.service.TaskGroupCycleRoller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
/**
 * {@link InhospVisitApi} 的唯一内部实现(<b>常驻 Bean</b>)。
 *
 * <p>⚠️ <b>调用方不要直接注入本类</b>,应注入常驻门面 {@link InhospVisitFacade}
 * —— 门面负责开关判断与降级,本类只做转发。
 *
 * <p>⚠️ <b>刻意不加 {@code @ConditionalOnProperty}</b>:该注解只在启动时求值一次,
 * 无法支持"改完 {@code sys_config} 参数即时生效";开关判断统一由门面在运行时做。
 *
 * <h3>当前接入状态(第 10 步)</h3>
 * <table border="1">
 *   <tr><th>方法</th><th>状态</th></tr>
 *   <tr><td>{@link #dealOutHospInfo(String)}</td>
 *       <td>✅ 已接入 {@link InhospVisitTaskService}(第 10 步切换)</td></tr>
 *   <tr><td>{@link #rollTaskGroupCycle()}</td>
 *       <td>✅ 已接入 {@link TaskGroupCycleRoller}(第 9 步搬迁)</td></tr>
 *   <tr><td>{@link #dealOutHospInfoBySchedule(String)}</td>
 *       <td>⏸ 未接入:该方法本次不搬(含手术分支与任务组 builder,属第二批
 *           {@code ruoyi-othervisit} 范围),仍由 smartor 的实现承接。
 *           {@code RyTask} 在本步<b>不改这一处</b>。</td></tr>
 *   <tr><td>{@link #buildAgainVisitDraft}</td>
 *       <td>⏸ 未接入:「随访超时→再次随访」链路;原实现调
 *           {@code boxedServiceSubtask},需把 {@code pat_med_operation_item} 维度也考虑进来。
 *           本次保持现状(返回空结果 = 不生成),并在 {@code RyTask} 侧暂不改这一处。</td></tr>
 *   <tr><td>{@link #generatePublicitySubtask}</td>
 *       <td>✅ 已接入(宣教模块回调本模块建子任务)</td></tr>
 * </table>
 */
@Slf4j
@Component
public class DefaultInhospVisitApi implements InhospVisitApi {
 
    @Autowired
    private InhospVisitTaskService inhospVisitTaskService;
 
    @Autowired
    private TaskGroupCycleRoller taskGroupCycleRoller;
 
    @Autowired
    private com.ruoyi.inhospvisit.service.InhospSubtaskWriter inhospSubtaskWriter;
 
    @Autowired
    private com.ruoyi.inhospvisit.mapper.VisitInhospMapper inhospMapper;
 
    @Autowired
    private com.ruoyi.inhospvisit.mapper.VisitArchiveMapper archiveMapper;
 
    @Autowired
    private org.springframework.beans.factory.ObjectProvider<com.ruoyi.common.core.service.OtherVisitApi> otherVisitApiProvider;
 
    @Autowired
    private org.springframework.beans.factory.ObjectProvider<com.ruoyi.common.core.service.OuthospVisitApi> outhospVisitApiProvider;
 
    private com.ruoyi.common.core.service.OtherVisitApi otherVisitApi() {
        if (otherVisitApiProvider == null) {
            return null;
        }
        try {
            return otherVisitApiProvider.stream().findFirst().orElse(null);
        } catch (Exception e) {
            log.warn("【出入院随访】获取 OtherVisitApi 失败:{}", e.toString());
            return null;
        }
    }
 
    private com.ruoyi.common.core.service.OuthospVisitApi outhospVisitApi() {
        if (outhospVisitApiProvider == null) {
            return null;
        }
        try {
            return outhospVisitApiProvider.stream().findFirst().orElse(null);
        } catch (Exception e) {
            log.warn("【出入院随访】获取 OuthospVisitApi 失败:{}", e.toString());
            return null;
        }
    }
 
    @Override
    public boolean isEnabled() {
        // 门面已经判过开关;这里表示"实现存在"
        return true;
    }
 
    @Override
    public int dealOutHospInfo(String config) {
        return inhospVisitTaskService.dealOutHospInfo(config);
    }
 
    /**
     * ✅ 已接入:转发到 {@code com.ruoyi.common.core.service.OtherVisitApi}(smartor 过渡实现)。
     * <p>
     * 该方法<b>本身未搬迁</b>(含手术分支与任务组 builder,属第二批 {@code ruoyi-othervisit}),
     * 但端点已迁进本模块,所以这里只做转发 —— 行为与原 Controller 直接调
     * {@code iPatMedInhospService.dealOutHospInfoBySchedule(config)} 完全一致。
     */
    @Override
    public int dealOutHospInfoBySchedule(String config) {
        com.ruoyi.common.core.service.OtherVisitApi api = otherVisitApi();
        if (api == null) {
            log.warn("【出入院随访】OtherVisitApi 不可用,dealOutHospInfoBySchedule 跳过。config={}", config);
            return 0;
        }
        return api.dealOutHospInfoBySchedule(config);
    }
 
    /**
     * ✅ 已接入:转发到 {@code com.ruoyi.common.core.service.OtherVisitApi}(smartor 过渡实现)。
     * <p>
     * 手术随访本次未搬(属第二批 {@code ruoyi-othervisit}),端点已迁进本模块,故此处只转发。
     */
    @Override
    public int addOperationSubTask(String config) {
        com.ruoyi.common.core.service.OtherVisitApi api = otherVisitApi();
        if (api == null) {
            log.warn("【出入院随访】OtherVisitApi 不可用,addOperationSubTask 跳过。config={}", config);
            return 0;
        }
        return api.addOperationSubTask(config);
    }
 
    /**
     * ✅ 已接入:转发到 {@code com.ruoyi.common.core.service.OuthospVisitApi}(smartor 过渡实现)。
     * <p>
     * 门诊随访属第二批 {@code ruoyi-outpatientvisit},本次只接转发。
     * 站点判断({@code active != "xh"})在 Controller 里,与原实现位置一致。
     */
    @Override
    public int dealOutpatientInfo() {
        com.ruoyi.common.core.service.OuthospVisitApi api = outhospVisitApi();
        if (api == null) {
            log.warn("【出入院随访】OuthospVisitApi 不可用(门诊随访模块未装配),dealOutpatientInfo 跳过。");
            return 0;
        }
        return api.dealOutpatientInfo();
    }
 
    @Override
    public int rollTaskGroupCycle() {
        return taskGroupCycleRoller.rollCycleTasks();
    }
 
    /**
     * ⏸ 未接入(见类注释):返回"未找到出入院记录",调用方会跳过该条(与原实现的 continue 语义一致,
     * 但不会因为"模块未接入"而误生成子任务)。
     */
    @Override
    public VisitAgainSubtaskDto buildAgainVisitDraft(String orgid, Long inhospid, Long newTaskId, Long sendstate) {
        log.warn("【出入院随访】buildAgainVisitDraft 本次未接入(随访超时→再次随访链路属后续范围),"
                + "返回空结果。orgid={}, inhospid={}", orgid, inhospid);
        return InhospVisitFacade.emptyAgainDraft("本次未接入(后续范围)");
    }
 
    /**
     * 宣教模块回调:为某患者生成一条宣教类子任务(type=0/4/5)。
     * <p>
     * 逐行对应原 {@code dealOutHospInfo} 里那两段宣教的最终动作
     * —— 即 {@code writeInSubTask(taskId, true, patMedInhosp, patArchive, type, config)}。
     * 这里按 inhospid 重新加载出入院记录与患者档案,然后委托给
     * {@link com.ruoyi.inhospvisit.service.InhospSubtaskWriter}(<b>boxed 的 type=0/4/5 分支全仓只有一份</b>)。
     */
    @Override
    public boolean generatePublicitySubtask(Long taskid, Long patid, Long inhospid, int type, String config) {
        if (inhospid == null) {
            log.warn("【出入院随访】generatePublicitySubtask 缺少 inhospid,跳过。taskid={}, patid={}, type={}",
                    taskid, patid, type);
            return false;
        }
        com.ruoyi.inhospvisit.domain.row.VisitInhospRow inhosp = inhospMapper.selectByInhospid(inhospid);
        if (inhosp == null) {
            log.warn("【出入院随访】generatePublicitySubtask 查不到出入院记录,跳过。inhospid={}", inhospid);
            return false;
        }
        // 患者档案:原实现传 patMedInhosp.patid(不是宣教模块传来的 patid),这里保持一致
        com.ruoyi.common.core.service.dto.VisitArchiveRow archive = archiveMapper.selectByPatid(inhosp.getPatid());
        if (archive == null) {
            log.warn("【出入院随访】generatePublicitySubtask 查不到患者档案,跳过。patid={}", inhosp.getPatid());
            return false;
        }
        // check=true:让 writeInSubTask 内部做去重/再入院校验(原实现两段宣教都是 true)
        inhospSubtaskWriter.writeInSubTask(taskid, true, inhosp, archive, type, config);
        return true;
    }
}