package com.ruoyi.inhospvisit.controller;
|
|
import com.ruoyi.common.core.service.IConfigService;
|
import com.ruoyi.inhospvisit.api.InhospVisitFacade;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RestController;
|
|
/**
|
* 出入院随访<b>触发端点</b> —— 从 {@code ruoyi-admin} 的 {@code PatMedInhospController} 迁入。
|
*
|
* <h3>⚠️ URL 一个都不能变</h3>
|
* 类级路径仍是 {@code /smartor/patinhosp},三个方法级路径逐字照抄:
|
* <ul>
|
* <li>{@code POST /smartor/patinhosp/dealOutHospInfo}</li>
|
* <li>{@code POST /smartor/patinhosp/dealOutHospInfoBySchedule}</li>
|
* <li>{@code POST /smartor/patinhosp/addOperationSubTask}</li>
|
* </ul>
|
* 真实前端在仓库外({@code D:\daima\smartor\smartor-web},代理 {@code localhost:8095}),
|
* 改了地址就无法回归。由 {@code sql/_probe/verify_inhospvisit_url_equivalence.py} 把关。
|
*
|
* <h3>迁入时同步删除</h3>
|
* {@code PatMedInhospController} 里对应这 3 个方法的
|
* {@code @PostMapping} 与 {@code @ApiOperation} 必须<b>同时删掉</b> ——
|
* 否则两个类都映射同一路径,Spring 会因 {@code Ambiguous mapping} <b>直接启动失败</b>。
|
*
|
* <h3>与原 Controller 的两处差异(等价改写,已登记)</h3>
|
* <ol>
|
* <li><b>不再注入 {@code ISysConfigService}</b>:{@code visit.early.day} 改由
|
* {@link InhospVisitTaskService} 内部读(它本来就要用这个值)。
|
* 原实现是在 Controller 里读好再传进去的,效果一致。</li>
|
* <li><b>{@code active} 只用于"是否做门诊随访"的站点判断</b>(原 L263 的
|
* {@code if (!active.equals("xh"))}),与原实现同一位置、同一写法。</li>
|
* </ol>
|
*
|
* <h3>开关如何生效</h3>
|
* 本模块的 {@code InhospVisitAvailabilityInterceptor} 通过
|
* {@code InhospVisitWebConfig} 挂在这两条精确路径上:
|
* <pre>
|
* /smartor/patinhosp/dealOutHospInfo
|
* /smartor/patinhosp/dealOutHospInfoBySchedule
|
* </pre>
|
* 迁入后"模块自己的端点 + 模块自己的拦截器"终于同处一个模块,
|
* 不再是跨模块注册(那是本次改造期间的一个临时状态)。
|
* <p>
|
* ⚠️ {@code /addOperationSubTask} <b>刻意不挂拦截器</b>:它的实现本次未搬
|
* (属第二批 {@code ruoyi-othervisit}),挂上会让"还没搬走的端点"也受本开关影响。
|
*/
|
@Slf4j
|
@Api(description = "出入院随访触发")
|
@RestController
|
@RequestMapping("/smartor/patinhosp")
|
public class InhospVisitController {
|
|
/** 站点:新华(暂时不做门诊随访) */
|
private static final String SITE_XH = "xh";
|
|
/** 出院随访「通知类任务」提前几天发(原 Controller 从 sys_config 读的就是这个键) */
|
private static final String VISIT_EARLY_DAY_KEY = "visit.early.day";
|
|
@Value("${spring.profiles.active}")
|
private String active;
|
|
@Autowired
|
private InhospVisitFacade inhospVisitFacade;
|
|
/**
|
* 参数配置服务(ruoyi-common 的接口,实现在 ruoyi-system)。
|
* <p>
|
* ⚠️ 用 {@code ObjectProvider} 惰性取:本模块只依赖 ruoyi-common,
|
* 在独立部署/测试等"容器里没有实现"的场景下不能因此启动失败。
|
* <p>
|
* ⚠️ <b>必须由 Controller 读、不能传给 Service 去读</b>:
|
* 原实现就是"Controller 读好再传进去"(原 L259/L274/L285),
|
* Service 层收的是<b>值</b>。保持这个形状,行为才一致。
|
*/
|
@Autowired
|
private ObjectProvider<IConfigService> configServiceProvider;
|
|
/**
|
* 出院随访主扫描 + 门诊随访(原 {@code PatMedInhospController#dealOutHospInfo} L256-266)。
|
* <p>
|
* 逐行对应:
|
* <pre>
|
* String config = configService.selectConfigByKey("visit.early.day");
|
* //出院表
|
* iPatMedInhospService.dealOutHospInfo(config);
|
* //门诊表(新华的暂时不做门诊随访)
|
* if (!active.equals("xh")) {
|
* iPatMedOuthospService.dealOutpatientInfo();
|
* }
|
* </pre>
|
* 搬迁后 {@code config} 由 {@link InhospVisitTaskService} 内部读取。
|
* 返回类型保持 {@code void}(与前端契约一致),<b>不改出参</b>。
|
*/
|
@ApiOperation("dealOutHospInfo")
|
@PostMapping("/dealOutHospInfo")
|
public void dealOutHospInfo() {
|
// 原 L259:String config = configService.selectConfigByKey("visit.early.day");
|
String config = readVisitEarlyDay();
|
//出院表(含入院宣教 / 药品宣教 / 规则编排 / 手术随访 / 再入院处理)
|
inhospVisitFacade.dealOutHospInfo(config);
|
//门诊表(新华的暂时不做门诊随访)
|
if (!SITE_XH.equals(active)) {
|
inhospVisitFacade.dealOutpatientInfo();
|
}
|
}
|
|
/**
|
* 任务组首轮纳入(原 {@code PatMedInhospController#dealOutHospInfoBySchedule} L271-277)。
|
* <p>
|
* ⚠️ 实现本次<b>未搬迁</b>(含手术分支与任务组 builder,属第二批范围),
|
* 由门面转发到 smartor 的实现 —— 行为与原 Controller 直接调用完全一致。
|
*/
|
@ApiOperation("dealOutHospInfoBySchedule")
|
@PostMapping("/dealOutHospInfoBySchedule")
|
public void dealOutHospInfoBySchedule() {
|
// 原 L274:String config = configService.selectConfigByKey("visit.early.day");
|
inhospVisitFacade.dealOutHospInfoBySchedule(readVisitEarlyDay());
|
}
|
|
/**
|
* 手术随访手动触发(原 {@code PatMedInhospController#addOperationSubTask} L282-287)。
|
* <p>
|
* ⚠️ 实现本次<b>未搬迁</b>(属第二批 {@code ruoyi-othervisit}),
|
* 由门面转发到 smartor 的实现。
|
*/
|
@ApiOperation("addOperationSubTask")
|
@PostMapping("/addOperationSubTask")
|
public void addOperationSubTask() {
|
// 原 L285:String config = configService.selectConfigByKey("visit.early.day");
|
inhospVisitFacade.addOperationSubTask(readVisitEarlyDay());
|
}
|
|
/**
|
* 读 {@code sys_config: visit.early.day}。
|
* <p>
|
* 对应原 Controller 三处 {@code configService.selectConfigByKey("visit.early.day")}。
|
* 取不到(没有实现 / 读库异常)时返回 {@code null} 并打 WARN ——
|
* 原实现在这种情况下拿到的也是 {@code null}({@code selectConfigByKey} 查不到即返回 null),
|
* 所以语义一致。
|
*/
|
private String readVisitEarlyDay() {
|
if (configServiceProvider == null) {
|
return null;
|
}
|
try {
|
IConfigService svc = configServiceProvider.stream().findFirst().orElse(null);
|
if (svc == null) {
|
log.warn("【出入院随访】容器里没有 IConfigService 实现,{} 按未配置(null)处理。",
|
VISIT_EARLY_DAY_KEY);
|
return null;
|
}
|
return svc.selectConfigByKey(VISIT_EARLY_DAY_KEY);
|
} catch (Exception e) {
|
log.warn("【出入院随访】读取 {} 失败,按未配置(null)处理:{}",
|
VISIT_EARLY_DAY_KEY, e.toString());
|
return null;
|
}
|
}
|
}
|