<?xml version="1.0" encoding="UTF-8" ?>
|
<!DOCTYPE mapper
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<mapper namespace="com.ruoyi.inhospvisit.mapper.VisitInhospMapper">
|
|
<!--
|
============================================================================
|
出入院随访模块自带的 pat_med_inhosp 查询。
|
============================================================================
|
与 smartor 的 mapper/smartor/PatMedInhospMapper.xml 是【两套等价的 SQL】:
|
· 本模块只依赖 ruoyi-common(不依赖 smartor,否则循环依赖),所以自己查;
|
· 纪律:改任一边必须同步改另一边,并重跑
|
sql/_probe/verify_inhospvisit_mapper.py (接口 ↔ XML 一一对应)
|
sql/_probe/verify_inhospvisit_sql_expansion.py (展开后逐条比对 WHERE/GROUP BY/ORDER BY)
|
|
与原 XML 的【三处有意差异】(都已在探针里登记):
|
1) 不引入原文件的 <sql id="selectPatMedInhospVo"> 共享片段 —— 本文件自带列清单,
|
自包含、便于逐条比对(满意度那次踩过"片段两处维护"的坑,这里选择相反做法);
|
2) selectForScan 的 SELECT 列做了删减:只保留随访侧真正用到的列
|
(原 XML 有 70+ 列,本模块只需要 40 列)。删列不影响 WHERE/GROUP BY/ORDER BY 语义;
|
3) 结果列用 AS 别名统一成行对象属性名,因此只需要一个 resultMap。
|
|
必须【逐字保留】的原语义(写错就直接改变线上随访结果):
|
1) JOIN pat_archive 且 a.del_flag=0 / b.del_flag=0 / a.idcardno IS NOT NULL
|
—— 决定"谁会被扫到";
|
2) GROUP BY b.inhospid, a.age, a.age_unit, a.telcode, a.id, a.sex
|
—— 去重语义;
|
3) 三种排序(cry=1/2/3 按出院时间倒序;cry=0 按床位自然序三选一)
|
—— 决定【处理次序】,而次序会影响"再入院停机"的最终结果。
|
============================================================================
|
-->
|
|
<resultMap type="com.ruoyi.inhospvisit.domain.row.VisitInhospRow" id="VisitInhospRowResult">
|
<result property="inhospid" column="inhospid"/>
|
<result property="patid" column="patid"/>
|
<result property="orgid" column="orgid"/>
|
<result property="campusid" column="campusid"/>
|
<result property="patno" column="patno"/>
|
<result property="inhospno" column="inhospno"/>
|
<result property="serialnum" column="serialnum"/>
|
<result property="patname" column="patname"/>
|
<result property="age" column="age"/>
|
<result property="sex" column="sex"/>
|
<result property="telcode" column="telcode"/>
|
<result property="starttime" column="starttime"/>
|
<result property="endtime" column="endtime"/>
|
<result property="fudate" column="fudate"/>
|
<result property="deptcode" column="deptcode"/>
|
<result property="deptname" column="deptname"/>
|
<result property="hospitaldistrictcode" column="hospitaldistrictcode"/>
|
<result property="hospitaldistrictname" column="hospitaldistrictname"/>
|
<result property="leaveldeptcode" column="leaveldeptcode"/>
|
<result property="leaveldeptname" column="leaveldeptname"/>
|
<result property="leavehospitaldistrictcode" column="leavehospitaldistrictcode"/>
|
<result property="leavehospitaldistrictname" column="leavehospitaldistrictname"/>
|
<result property="leaveicd10code" column="leaveicd10code"/>
|
<result property="leavediagname" column="leavediagname"/>
|
<result property="diagname" column="diagname"/>
|
<result property="nurseId" column="nurse_id"/>
|
<result property="nurseName" column="nurse_name"/>
|
<result property="drcode" column="drcode"/>
|
<result property="drname" column="drname"/>
|
<result property="managementDoctor" column="management_doctor"/>
|
<result property="managementDoctorCode" column="management_doctor_code"/>
|
<result property="deptcheckFlag" column="deptcheck_flag"/>
|
<result property="wardcheckFlag" column="wardcheck_flag"/>
|
<result property="diagcheckFlag" column="diagcheck_flag"/>
|
<result property="scheduleCheckFlag" column="schedulecheck_flag"/>
|
<result property="inDeptcheckFlag" column="in_deptcheck_flag"/>
|
<result property="inWardcheckFlag" column="in_wardcheck_flag"/>
|
<result property="inhospstate" column="inhospstate"/>
|
<result property="fuflag" column="fuflag"/>
|
<result property="longTaskReason" column="long_task_reason"/>
|
<result property="remark" column="remark"/>
|
<result property="medicalCode" column="medical_code"/>
|
</resultMap>
|
|
<!--
|
随访扫描 / 按标志位过滤(对应原 PatMedInhospMapper.xml 的 selectPatMedInhospList,L166-406)。
|
条件块的顺序与内容逐条对齐原 XML;只保留随访侧会用到的条件,删掉纯展示类条件
|
(hospitalname / bedNo / outWayId / importanceFlagCode 等),已登记为有意差异。
|
-->
|
<select id="selectForScan" parameterType="com.ruoyi.inhospvisit.domain.row.VisitInhospRow"
|
resultMap="VisitInhospRowResult">
|
select
|
a.age AS age,
|
a.telcode as telcode,
|
a.sex,
|
b.inhospid,
|
b.nurse_id,
|
b.nurse_name,
|
b.patname,
|
b.management_doctor,
|
b.management_doctor_code,
|
b.deptcheck_flag,
|
b.wardcheck_flag,
|
b.in_deptcheck_flag,
|
b.in_wardcheck_flag,
|
b.diagcheck_flag,
|
b.schedulecheck_flag,
|
b.inhospstate,
|
b.patno,
|
b.inhospno,
|
b.serialnum,
|
b.hospitaldistrictcode,
|
b.hospitaldistrictname,
|
b.diagname,
|
b.starttime,
|
b.endtime,
|
b.deptcode,
|
b.campusid,
|
b.deptname,
|
b.orgid,
|
b.patid,
|
b.leavediagname,
|
b.leaveicd10code,
|
b.drcode,
|
b.drname,
|
b.leaveldeptcode,
|
b.leaveldeptname,
|
b.leavehospitaldistrictcode,
|
b.leavehospitaldistrictname,
|
b.long_task_reason,
|
b.fuflag,
|
b.fudate,
|
b.remark,
|
b.medical_code
|
FROM
|
pat_med_inhosp b
|
JOIN
|
pat_archive a ON a.id = b.patid
|
where 1=1
|
AND a.del_flag = 0
|
AND b.del_flag = 0
|
AND a.idcardno IS NOT NULL
|
<if test="inhospid != null">and b.inhospid = #{inhospid}</if>
|
<if test="startOutHospTime != null ">and date_format(b.endtime,'%y%m%d') >=
|
date_format(#{startOutHospTime},'%y%m%d')
|
</if>
|
<if test="endOutHospTime != null ">and date_format(b.endtime,'%y%m%d') <=
|
date_format(#{endOutHospTime},'%y%m%d')
|
</if>
|
<if test="startInHospTime != null ">and date_format(b.starttime,'%y%m%d') >=
|
date_format(#{startInHospTime},'%y%m%d')
|
</if>
|
<if test="endInHospTime != null ">and date_format(b.starttime,'%y%m%d') <=
|
date_format(#{endInHospTime},'%y%m%d')
|
</if>
|
<if test="patname != null and patname != ''">and patname like concat('%', #{patname}, '%')</if>
|
<if test="endtime != null ">and b.endtime = #{endtime}</if>
|
<if test="fuflag != null ">and b.fuflag = #{fuflag}</if>
|
<if test="orgid != null ">and b.orgid = #{orgid}</if>
|
<if test="campusid != null ">and b.campusid = #{campusid}</if>
|
<if test="serialnum != null ">and b.serialnum = #{serialnum}</if>
|
<if test="patno != null ">and b.patno = #{patno}</if>
|
<if test="nurseId != null ">and b.nurse_id = #{nurseId}</if>
|
<if test="nurseName != null and nurseName != ''">and b.nurse_name = #{nurseName}</if>
|
<if test="deptcheckFlag != null ">and b.deptcheck_flag = #{deptcheckFlag}</if>
|
<if test="scheduleCheckFlag != null ">and b.schedulecheck_flag = #{scheduleCheckFlag}</if>
|
<if test="wardcheckFlag != null ">and b.wardcheck_flag = #{wardcheckFlag}</if>
|
<if test="inDeptcheckFlag != null ">and b.in_deptcheck_flag = #{inDeptcheckFlag}</if>
|
<if test="inWardcheckFlag != null ">and b.in_wardcheck_flag = #{inWardcheckFlag}</if>
|
<if test="diagcheckFlag != null ">and b.diagcheck_flag = #{diagcheckFlag}</if>
|
<!--
|
⚠️ 以下这些条件在【随访生成链】上确实不可达(13 个调用点里没有一个设它们,
|
见 sql/_probe/verify_inhospvisit_sql_expansion.py 的 REACHABILITY_EVIDENCE)。
|
但仍然【照抄保留】:保留后"与原 XML 的 WHERE 等价"就是可机械验证的事实,
|
而不是靠文档论证。代价只是几个永不进入的分支。
|
-->
|
<if test="inhospMydFlag != null ">and b.inhosp_myd_flag = #{inhospMydFlag}</if>
|
<if test="managementDoctor != null ">and b.management_doctor = #{managementDoctor}</if>
|
<if test="managementDoctorCode != null ">and b.management_doctor_code = #{managementDoctorCode}</if>
|
<if test="inhospno != null ">and b.inhospno = #{inhospno}</if>
|
<if test="bedNo != null ">and b.bed_no = #{bedNo}</if>
|
<if test="outWayId != null ">and b.out_way_id = #{outWayId}</if>
|
<if test="outWayName != null ">and b.out_way_name = #{outWayName}</if>
|
<if test="encounterSourceId != null ">and b.encounter_source_id = #{encounterSourceId}</if>
|
<if test="importanceFlagCode != null ">and b.importance_flag_code = #{importanceFlagCode}</if>
|
<if test="emergencyLevelCode != null ">and b.emergency_level_code = #{emergencyLevelCode}</if>
|
<if test="hospitalname != null and hospitalname != ''">and hospitalname like concat('%', #{hospitalname},
|
'%')
|
</if>
|
<if test="hospitaldistrictname != null and hospitaldistrictname != ''">and hospitaldistrictname like
|
concat('%', #{hospitaldistrictname}, '%')
|
</if>
|
<if test="cry != null and cry == 0 ">and b.endtime is null</if>
|
<if test="cry != null and cry == 1 ">and b.inhospstate=1</if>
|
<if test="cry != null and cry == 2 ">and b.inhospstate=2</if>
|
<if test="cry != null and cry == 3 ">and b.inhospstate=3</if>
|
<if test="inhospstate != null ">and b.inhospstate = #{inhospstate}</if>
|
<if test="schemestatus != null ">and b.schemestatus = #{schemestatus}</if>
|
<if test="leaveldeptcode != null ">and b.leaveldeptcode = #{leaveldeptcode}</if>
|
<if test="leavediagname != null and leavediagname != ''">and b.leavediagname like concat('%',
|
#{leavediagname}, '%')
|
</if>
|
<if test="drname != null and drname != ''">and b.drname like concat('%', #{drname}, '%')</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">and b.leaveldeptname like concat('%',
|
#{leaveldeptname}, '%')
|
</if>
|
<if test="deptname != null and deptname != ''">and b.deptname like concat('%', #{deptname}, '%')</if>
|
<if test="patid != null ">and a.id = #{patid}</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and
|
b.leavehospitaldistrictname like concat('%', #{leavehospitaldistrictname}, '%')
|
</if>
|
<if test="medicalCode != null and medicalCode != ''">and b.medical_code = #{medicalCode}</if>
|
<if test="medicalName != null and medicalName != ''">and b.medical_name = #{medicalName}</if>
|
<if test="medicalCompany != null and medicalCompany != ''">and b.medical_company = #{medicalCompany}</if>
|
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0">
|
AND b.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="hospitaldistrictcodeList != null and hospitaldistrictcodeList.size()>0">
|
AND b.hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodeList" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size()>0">
|
AND b.leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>
|
<if test="deptcodeList != null and deptcodeList.size()>0">
|
AND b.deptcode IN
|
<foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="icd10codeList != null and icd10codeList.size()>0">
|
AND b.leaveicd10code IN
|
<foreach collection="icd10codeList" item="icd10code" open="(" separator="," close=")">
|
#{icd10code}
|
</foreach>
|
</if>
|
GROUP BY
|
b.inhospid,
|
a.age,
|
a.age_unit,
|
a.telcode,
|
a.id,
|
a.sex
|
<if test="cry != null and cry==1">
|
order by b.endtime desc
|
</if>
|
<if test="cry != null and cry==2">
|
order by b.endtime desc
|
</if>
|
<if test="cry != null and cry==3">
|
order by b.endtime desc
|
</if>
|
<if test="cry != null and cry==0">
|
<!--
|
在院患者:可按入院床位正/倒序(bedSort=asc 或 desc),不传时保持默认排序(入院时间倒序 + 床位正序)。
|
床位按自然序排(只用 5.7 也支持的 REGEXP/CAST/TRIM/LENGTH,不依赖 8.0 的 REGEXP_REPLACE):
|
1) 床位为空/空串的排最后
|
2) 纯数字床位排前面,按数值大小(2 在 10 前)
|
3) 带字母/汉字的床位按长度 + 字符串(A2 在 A12 前)
|
4) inhospid 兜底,保证翻页顺序稳定
|
倒序只反转 2)、3) 两组内部顺序:空床位仍排最后,纯数字仍在前。
|
这段【逐字照抄】原 XML,不改。
|
-->
|
<choose>
|
<when test='"asc".equals(bedSort)'>
|
order by
|
coalesce(trim(b.bed_no), '') = '' ,
|
(trim(b.bed_no) regexp '^[0-9]+$') = 0 ,
|
cast(trim(b.bed_no) as unsigned) asc ,
|
length(trim(b.bed_no)) asc ,
|
trim(b.bed_no) asc ,
|
b.inhospid asc
|
</when>
|
<when test='"desc".equals(bedSort)'>
|
order by
|
coalesce(trim(b.bed_no), '') = '' ,
|
(trim(b.bed_no) regexp '^[0-9]+$') = 0 ,
|
cast(trim(b.bed_no) as unsigned) desc ,
|
length(trim(b.bed_no)) desc ,
|
trim(b.bed_no) desc ,
|
b.inhospid asc
|
</when>
|
<otherwise>
|
order by b.starttime desc , b.bed_no asc
|
</otherwise>
|
</choose>
|
</if>
|
</select>
|
|
<!--
|
按主键查(对应原 PatMedInhospMapper.xml 的 selectPatMedInhospByInhospid,L678-681)。
|
⚠️ 原实现走 <sql id="selectPatMedInhospVo"/> 共享片段;这里显式列出同一批列,不复制片段。
|
⚠️ 单表查询,不带 age / telcode / sex(原实现同样不带),所以按主键查出来的行这几个字段为 null。
|
这与原实现一致:boxedServiceSubtask 用到的患者字段一律来自 patArchive 查询,不来自这里。
|
-->
|
<select id="selectByInhospid" parameterType="Long" resultMap="VisitInhospRowResult">
|
select inhospid,
|
medical_code,
|
patname,
|
fuflag,
|
management_doctor,
|
management_doctor_code,
|
fudate,
|
remark,
|
nurse_id,
|
nurse_name,
|
deptcheck_flag,
|
wardcheck_flag,
|
in_deptcheck_flag,
|
in_wardcheck_flag,
|
diagcheck_flag,
|
schedulecheck_flag,
|
inhospstate,
|
patno,
|
long_task_reason,
|
inhospno,
|
serialnum,
|
hospitaldistrictcode,
|
hospitaldistrictname,
|
diagname,
|
starttime,
|
endtime,
|
deptcode,
|
deptname,
|
orgid,
|
patid,
|
leavediagname,
|
leaveicd10code,
|
drcode,
|
drname,
|
leaveldeptcode,
|
leaveldeptname,
|
leavehospitaldistrictcode,
|
leavehospitaldistrictname,
|
campusid
|
from pat_med_inhosp
|
where inhospid = #{inhospid}
|
</select>
|
|
<!--
|
只回写随访标志位与 long_task_reason。
|
⚠️ 原实现是 updatePatMedInhosp 的"近百个 <if>:传什么更新什么"。随访侧只写这几列,
|
所以这里显式列出 —— 避免"传了个半满实体导致某列被意外写空/漏写"这类静默问题。
|
⚠️ 标志位列名走【白名单 <choose> 展开成常量列名】,不做 ${} 字符串拼接:既防注入,
|
又让"哪些列可写"在代码里可枚举。
|
⚠️ reason 为 null 时【不改动】long_task_reason(与原 <if test="longTaskReason != null"> 一致)。
|
-->
|
<update id="updateFlags">
|
update pat_med_inhosp
|
<trim prefix="SET" suffixOverrides=",">
|
<choose>
|
<when test='flagColumn == "deptcheck_flag"'>deptcheck_flag = #{flagValue},</when>
|
<when test='flagColumn == "wardcheck_flag"'>wardcheck_flag = #{flagValue},</when>
|
<when test='flagColumn == "diagcheck_flag"'>diagcheck_flag = #{flagValue},</when>
|
<when test='flagColumn == "medcheck_flag"'>medcheck_flag = #{flagValue},</when>
|
<when test='flagColumn == "in_deptcheck_flag"'>in_deptcheck_flag = #{flagValue},</when>
|
<when test='flagColumn == "in_wardcheck_flag"'>in_wardcheck_flag = #{flagValue},</when>
|
<when test='flagColumn == "schedulecheck_flag"'>schedulecheck_flag = #{flagValue},</when>
|
<otherwise>
|
<!-- 非法列名:自赋值,保证 SET 不为空且不改数据(Service 层会先拦掉) -->
|
inhospid = inhospid,
|
</otherwise>
|
</choose>
|
<if test="reason != null">long_task_reason = #{reason},</if>
|
</trim>
|
where inhospid = #{inhospid}
|
</update>
|
|
<!--
|
只回写 remark(原 updateCheckFlag 的附带动作,PatMedInhospServiceImpl L1680-1683)。
|
与原实现"一次整实体更新"在结果上等价:原 updatePatMedInhosp 每个字段各自 <if>,
|
updateCheckFlag 那次调用只有 flag 与 remark 两个字段非 null。
|
-->
|
<update id="updateRemark">
|
update pat_med_inhosp
|
set remark = #{remark}
|
where inhospid = #{inhospid}
|
</update>
|
|
</mapper>
|