package com.ruoyi.inhospvisit.support;
|
|
import com.ruoyi.inhospvisit.domain.row.VisitInhospRow;
|
import com.ruoyi.inhospvisit.mapper.VisitInhospMapper;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.HashSet;
|
import java.util.Set;
|
|
/**
|
* 随访标志位回写器 —— 统一封装"改 {@code pat_med_inhosp} 的哪个 check_flag"这件事。
|
*
|
* <h3>来源对照(@ b25c3b51)</h3>
|
* <table border="1">
|
* <tr><th>本类方法</th><th>原实现</th><th>行数</th></tr>
|
* <tr><td>{@link #updateCheckFlag(VisitInhospRow, Integer, String, String)}</td>
|
* <td>{@code updateCheckFlag}(L1660-1684)</td><td>25</td></tr>
|
* <tr><td>{@link #setFlag}</td><td>{@code writeInSubTask} 里逐处
|
* {@code patMedInhosp2.setXxxcheckFlag(...)} + {@code updatePatMedInhosp}</td><td>—</td></tr>
|
* </table>
|
*
|
* <h3>⚠️ type → 列的映射必须原样保留(含历史交叉写)</h3>
|
* 原 {@code updateCheckFlag} 的 switch(L1663-1679):
|
* <pre>
|
* 1 -> deptcheck_flag 2 -> wardcheck_flag 3 -> diagcheck_flag
|
* 4 -> in_deptcheck_flag 5 -> in_wardcheck_flag
|
* </pre>
|
* 而 {@code writeInSubTask} 里回写时会根据 type 单独 set,且存在<b>历史交叉写</b>:
|
* <ul>
|
* <li>type=5 的"任务不存在"分支(L721-722)写的是 {@code inWardcheckFlag};</li>
|
* <li>type=5 的"成功/失败回写"(L885/L896)写的也是 {@code inWardcheckFlag};</li>
|
* <li>但 {@code dealOutHospInfo} 的病区宣教分支写的是 {@code in_deptcheck_flag}(见 ruoyi-publicity)。</li>
|
* </ul>
|
* 所以这里<b>不统一</b>:{@link #updateCheckFlag} 照抄原 switch;
|
* 各调用点要写哪一列由它自己用 {@link #setFlag} 显式指定。任何"顺手统一"都是行为变更。
|
*
|
* <h3>为什么单独成类而不是塞进 VisitSubtaskFactory</h3>
|
* 工厂是"纯组装"(可被 A 档逐行比对);本类是"写库"。
|
* 混在一起会让"组装器一个副作用都没有"这个前提失效,探针也就失去意义。
|
*/
|
@Slf4j
|
@Component
|
public class InhospFlagWriter {
|
|
/** 允许回写的标志位列白名单(与 {@code VisitInhospMapper.updateFlags} 的 {@code <choose>} 一致) */
|
private static final Set<String> ALLOWED_FLAG_COLUMNS = Collections.unmodifiableSet(
|
new HashSet<>(Arrays.asList(
|
"deptcheck_flag", "wardcheck_flag", "diagcheck_flag", "medcheck_flag",
|
"in_deptcheck_flag", "in_wardcheck_flag", "schedulecheck_flag")));
|
|
@Autowired
|
private VisitInhospMapper inhospMapper;
|
|
/**
|
* 统一回写标志位 —— 照抄原 {@code updateCheckFlag(PatMedInhosp, Integer type, String flagValue, String remark)}。
|
* <p>
|
* 原实现(L1660-1684):
|
* <pre>
|
* PatMedInhosp updateObj = new PatMedInhosp();
|
* updateObj.setInhospid(patMedInhosp.getInhospid());
|
* switch (type) { case 1: updateObj.setDeptcheckFlag(flagValue); break; ... }
|
* if (StringUtils.isNotEmpty(remark)) {
|
* updateObj.setRemark(remark + " (type=" + type + ")");
|
* }
|
* patMedInhospMapper.updatePatMedInhosp(updateObj);
|
* </pre>
|
* ⚠️ 注意两点:
|
* <ol>
|
* <li>它写的是 {@code remark}(不是 {@code long_task_reason})——原样保留;</li>
|
* <li>remark 非空时会拼上 {@code " (type=N)"} 后缀 —— 原样保留这个格式。</li>
|
* </ol>
|
*
|
* @param row 出入院记录(只用 inhospid)
|
* @param type 1=离院科室 2=离院病区 3=疾病 4=入院科室 5=入院病区
|
* @param flagValue 要写入的标志位值
|
* @param remark 备注;非空时会拼 {@code " (type=N)"} 后缀后写入 remark 列
|
*/
|
public void updateCheckFlag(VisitInhospRow row, Integer type, String flagValue, String remark) {
|
String column = columnOfType(type);
|
if (column == null) {
|
log.warn("【出入院随访】updateCheckFlag 收到未知 type={},忽略。inhospid={}",
|
type, row == null ? null : row.getInhospid());
|
return;
|
}
|
String finalRemark = remark;
|
if (com.ruoyi.common.utils.StringUtils.isNotEmpty(remark)) {
|
finalRemark = remark + " (type=" + type + ")";
|
}
|
// 原实现走的是"整实体动态更新"(会顺带把 remark 写进去)。
|
// 这里 updateFlags 只覆盖 flag + long_task_reason,所以 remark 需要单独写。
|
setFlagWithRemark(row, column, flagValue, finalRemark);
|
}
|
|
/**
|
* 只回写一个标志位(对应 {@code writeInSubTask} 里逐处 set 单个 flag 的写法)。
|
* <p>
|
* 原实现的写法是:新建一个"只有 inhospid + 要改的 flag"的 {@code PatMedInhosp},
|
* 再调 {@code updatePatMedInhosp}(XML 里每个字段各自 {@code <if test="xxx != null">},
|
* 所以只有非 null 字段生效)。
|
*
|
* @param inhospid 出入院记录ID
|
* @param column 标志位列名(白名单校验)
|
* @param value 标志位值
|
* @return true = 影响行数 > 0
|
*/
|
public boolean setFlag(Long inhospid, String column, String value) {
|
if (!ALLOWED_FLAG_COLUMNS.contains(column)) {
|
log.warn("【出入院随访】setFlag 收到非法列名「{}」,忽略。inhospid={}", column, inhospid);
|
return false;
|
}
|
return inhospMapper.updateFlags(inhospid, column, value, null) > 0;
|
}
|
|
/**
|
* 回写标志位 + 覆盖式写 {@code long_task_reason}。
|
* <p>
|
* 对应 {@code writeInSubTask} 里"任务不存在"/"异常"分支的写法:
|
* 先 {@code setLongTaskReason(旧值 + 文案)} 再 update。
|
* 注意:那些分支在 Java 侧是 {@code longTaskReason + "..."} 的字符串拼接
|
* (多数不判 null),所以这里由调用方传入拼好的完整值。
|
*
|
* @param inhospid 出入院记录ID
|
* @param column 标志位列名
|
* @param value 标志位值
|
* @param reason {@code long_task_reason} 的新值;null = 不改动
|
*/
|
public boolean setFlagWithReason(Long inhospid, String column, String value, String reason) {
|
if (!ALLOWED_FLAG_COLUMNS.contains(column)) {
|
log.warn("【出入院随访】setFlagWithReason 收到非法列名「{}」,忽略。inhospid={}", column, inhospid);
|
return false;
|
}
|
return inhospMapper.updateFlags(inhospid, column, value, reason) > 0;
|
}
|
|
/**
|
* 标志位列 + remark 一起写(原 {@code updateCheckFlag} 的实际效果)。
|
* <p>
|
* {@code VisitInhospMapper.updateFlags} 不覆盖 remark,所以这里复用它写 flag,
|
* 另外单独更新 remark —— 两个 update 与原实现的"一次整实体 update"在结果上等价
|
* (原实现也只会有 flag 与 remark 两个字段非 null)。
|
*/
|
/**
|
* 回写标志位 + 覆盖式写 {@code remark}(原 {@code updateCheckFlag} 的实际效果)。
|
* <p>
|
* {@code VisitInhospMapper.updateFlags} 不覆盖 remark,所以这里复用它写 flag,
|
* 另外单独更新 remark —— 两个 update 与原实现的"一次整实体 update"在结果上等价
|
* (原实现那次调用也只有 flag 与 remark 两个字段非 null)。
|
*
|
* @param inhospid 出入院记录ID
|
* @param column 标志位列名(白名单校验)
|
* @param flagValue 标志位值
|
* @param remark 新的 remark;null 表示只写 flag
|
*/
|
public void setFlagWithRemark(Long inhospid, String column, String flagValue, String remark) {
|
if (!ALLOWED_FLAG_COLUMNS.contains(column)) {
|
log.warn("【出入院随访】setFlagWithRemark 收到非法列名「{}」,忽略。inhospid={}", column, inhospid);
|
return;
|
}
|
if (inhospid == null) {
|
log.warn("【出入院随访】setFlagWithRemark 缺少 inhospid,忽略。column={}", column);
|
return;
|
}
|
inhospMapper.updateFlags(inhospid, column, flagValue, null);
|
if (remark != null) {
|
inhospMapper.updateRemark(inhospid, remark);
|
}
|
}
|
|
/**
|
* 标志位列 + remark 一起写({@link #updateCheckFlag} 用,入参是行对象)。
|
*/
|
private void setFlagWithRemark(VisitInhospRow row, String column, String flagValue, String remark) {
|
if (row == null || row.getInhospid() == null) {
|
log.warn("【出入院随访】setFlagWithRemark 缺少 inhospid,忽略。column={}", column);
|
return;
|
}
|
setFlagWithRemark(row.getInhospid(), column, flagValue, remark);
|
}
|
|
/**
|
* type → 标志位列。照抄原 {@code updateCheckFlag} 的 switch。
|
*
|
* @return 列名;未知 type 返回 {@code null}
|
*/
|
private String columnOfType(Integer type) {
|
if (type == null) {
|
return null;
|
}
|
switch (type) {
|
case 1:
|
return "deptcheck_flag";
|
case 2:
|
return "wardcheck_flag";
|
case 3:
|
return "diagcheck_flag";
|
case 4:
|
return "in_deptcheck_flag";
|
case 5:
|
return "in_wardcheck_flag";
|
default:
|
return null;
|
}
|
}
|
}
|