<?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.task.mapper.ServiceSubtaskMapper">
|
|
<resultMap type="com.ruoyi.task.domain.ServiceSubtask" id="ServiceSubtaskResult">
|
<result property="id" column="id"/>
|
<result property="sendname" column="sendname"/>
|
<result property="phone" column="phone"/>
|
<result property="sex" column="sex"/>
|
<result property="nurseName" column="nurse_name"/>
|
<result property="nurseId" column="nurse_id"/>
|
<result property="age" column="age"/>
|
<result property="sfzh" column="sfzh"/>
|
<result property="addr" column="addr"/>
|
<result property="senderdetail" column="senderdetail"/>
|
<result property="type" column="type"/>
|
<result property="taskid" column="taskid"/>
|
<result property="templateid" column="templateid"/>
|
<result property="templatename" column="templatename"/>
|
<result property="senddate" column="senddate"/>
|
<result property="senduuid" column="senduuid"/>
|
<result property="result" column="result"/>
|
<result property="finishtime" column="finishtime"/>
|
<result property="finishState" column="finish_state"/>
|
<result property="recordid" column="recordid"/>
|
<result property="exrecallcount" column="exrecallcount"/>
|
<result property="pulltime" column="pulltime"/>
|
<result property="leaveldeptcode" column="leaveldeptcode"/>
|
<result property="labelstatus" column="labelstatus"/>
|
<result property="delFlag" column="del_flag"/>
|
<result property="updateBy" column="update_by"/>
|
<result property="updateTime" column="update_time"/>
|
<result property="createBy" column="create_by"/>
|
<result property="createTime" column="create_time"/>
|
<result property="isupload" column="isupload"/>
|
<result property="uploadTime" column="upload_time"/>
|
<result property="orgid" column="orgid"/>
|
<result property="pid" column="pid"/>
|
<result property="guid" column="guid"/>
|
<result property="taskGuid" column="task_guid"/>
|
<result property="textParam" column="text_param"/>
|
<result property="preachform" column="preachform"/>
|
<result property="bedNo" column="bed_no"/>
|
<result property="sendType" column="send_type"/>
|
<result property="taskName" column="task_name"/>
|
<result property="taskDesc" column="task_desc"/>
|
<result property="operator" column="operator"/>
|
<result property="operatorNo" column="operator_no"/>
|
<result property="hospno" column="hospno"/>
|
<result property="hospType" column="hosp_type"/>
|
<result property="wechat" column="wechat"/>
|
<result property="leaveicd10code" column="leaveicd10code"/>
|
<result property="leavediagname" column="leavediagname"/>
|
<result property="diagname" column="diagname"/>
|
<result property="leaveldeptname" column="leaveldeptname"/>
|
<!-- 2026-11:原 sendlimit* 四个空闲列复用为「在院维度」(hospitaldistrict* = 在院病区,deptcode/name = 在院科室) -->
|
<result property="hospitaldistrictcode" column="hospitaldistrictcode"/>
|
<result property="hospitaldistrictname" column="hospitaldistrictname"/>
|
<result property="deptcode" column="deptcode"/>
|
<result property="deptname" column="deptname"/>
|
<result property="admindate" column="admindate"/>
|
<result property="roomno" column="roomno"/>
|
<result property="patid" column="patid"/>
|
<result property="libtemplatename" column="libtemplatename"/>
|
<result property="libtemplateid" column="libtemplateid"/>
|
<result property="openid" column="openid"/>
|
<result property="longSendTime" column="long_send_time"/>
|
<result property="serviceType" column="service_type"/>
|
<result property="score" column="score"/>
|
<result property="submit" column="submit"/>
|
<result property="drname" column="drname"/>
|
<result property="drcode" column="drcode"/>
|
<result property="starttime" column="starttime"/>
|
<result property="endtime" column="endtime"/>
|
<result property="leavehospitaldistrictcode" column="leavehospitaldistrictcode"/>
|
<result property="leavehospitaldistrictname" column="leavehospitaldistrictname"/>
|
<result property="excep" column="excep"/>
|
<result property="remark" column="remark"/>
|
<result property="doctorOpinion" column="doctor_opinion"/>
|
<result property="suggest" column="suggest"/>
|
<result property="sendstate" column="sendstate"/>
|
<result property="inhospid" column="inhospid"/>
|
<result property="patfrom" column="patfrom"/>
|
<result property="patguid" column="patguid"/>
|
<result property="visitCount" column="visit_count"/>
|
<result property="isVisitAgain" column="is_visit_again"/>
|
<result property="upid" column="upid"/>
|
<result property="visitType" column="visit_type"/>
|
<result property="visitTime" column="visit_time"/>
|
<result property="visitDeptName" column="visit_dept_name"/>
|
<result property="visitDeptCode" column="visit_dept_code"/>
|
<result property="managementDoctor" column="management_doctor"/>
|
<result property="managementDoctorCode" column="management_doctor_code"/>
|
<result property="currentPreachform" column="current_preachform"/>
|
<result property="taskSituation" column="task_situation"/>
|
<result property="isabnormal" column="isabnormal"/>
|
<result property="continueFlag" column="continue_flag"/>
|
<result property="continueTimeNow" column="continue_time_now"/>
|
<result property="continueContent" column="continue_content"/>
|
<result property="continueCount" column="continue_count"/>
|
<result property="continueTimeNext" column="continue_time_next"/>
|
<result property="operationItemId" column="operation_item_id"/>
|
<result property="scheduleId" column="schedule_id"/>
|
<result property="scheduleDetailId" column="schedule_detail_id"/>
|
<result property="scheduleSeq" column="schedule_seq"/>
|
<result property="loopCount" column="loop_count"/>
|
<result property="isManuallyCalled" column="is_manually_called"/>
|
<result property="campusid" column="campusid"/>
|
<result property="diagType" column="diag_type"/>
|
<!-- 2026-11:重要性标记编码(日间手术/日间诊疗/无…),建任务时取自 pat_med_inhosp -->
|
<result property="importanceFlagCode" column="importance_flag_code"/>
|
</resultMap>
|
|
<resultMap type="com.ruoyi.task.domain.ServiceSubtaskCount" id="ServiceSubtaskResult2">
|
<result property="month" column="month"/>
|
<result property="serviceType" column="service_type"/>
|
<result property="subTaskId" column="subTaskId"/>
|
<result property="joyCount" column="joyCount"/>
|
<result property="joyAllCount" column="joyAllCount"/>
|
<result property="joyTotal" column="joyTotal"/>
|
<result property="joyName" column="joyName"/>
|
|
</resultMap>
|
|
<resultMap type="com.ruoyi.task.domain.ServiceSubtaskScriptCount" id="ServiceSubtaskScriptCountResult">
|
<result property="scriptid" column="scriptid"/>
|
<result property="templateid" column="templateid"/>
|
<result property="scriptType" column="script_type"/>
|
<result property="scriptContent" column="script_content"/>
|
<result property="subtaskType" column="subtask_type"/>
|
<result property="completedQuantity" column="completed_quantity"/>
|
<result property="allQuantity" column="all_quantity"/>
|
<result property="completedPercentage" column="completed_percentage"/>
|
<result property="optionText" column="option_text"/>
|
<result property="chosenQuantity" column="chosen_quantity"/>
|
<result property="chosenPercentage" column="chosen_percentage"/>
|
<result property="options" column="options"/>
|
</resultMap>
|
|
<resultMap type="com.ruoyi.task.domain.ServiceSubtaskStatistic" id="ServiceSubtaskStatisticResult">
|
<result property="taskName" column="task_name"/>
|
<result property="drcode" column="drcode"/>
|
<result property="drname" column="drname"/>
|
<result property="dischargeCount" column="discharge_count"/>
|
<result property="nonFollowUp" column="non_follow_up"/>
|
<result property="filterCount" column="filter_count"/>
|
<result property="followUpNeeded" column="follow_up_needed"/>
|
<result property="needFollowUp" column="need_follow_up"/>
|
<result property="pendingFollowUp" column="pending_follow_up"/>
|
<result property="followUpFail" column="follow_up_fail"/>
|
<result property="manual" column="manual"/>
|
<result property="voice" column="voice"/>
|
<result property="sms" column="sms"/>
|
<result property="weChat" column="we_chat"/>
|
<result property="taskSituation1" column="task_situation1"/>
|
<result property="taskSituation2" column="task_situation2"/>
|
<result property="taskSituation3" column="task_situation3"/>
|
<result property="taskSituation4" column="task_situation4"/>
|
<result property="taskSituation5" column="task_situation5"/>
|
<result property="taskSituation6" column="task_situation6"/>
|
</resultMap>
|
<sql id="selectServiceSubtaskVo">
|
select id,
|
hosp_type,
|
campusid,
|
task_guid,
|
diagname,
|
patfrom,
|
management_doctor,
|
management_doctor_code,
|
current_preachform,
|
upid,
|
isabnormal,
|
visit_dept_name,
|
visit_dept_code,
|
visit_time,
|
inhospid,
|
visit_count,
|
is_visit_again,
|
patguid,
|
suggest,
|
sendstate,
|
endtime,
|
nurse_id,
|
nurse_name,
|
starttime,
|
submit,
|
drname,
|
excep,
|
drcode,
|
long_send_time,
|
openid,
|
remark,
|
doctor_opinion,
|
service_type,
|
libtemplateid,
|
libtemplatename,
|
hospno,
|
score,
|
phone,
|
sex,
|
age,
|
patid,
|
sfzh,
|
addr,
|
senderdetail,
|
type,
|
taskid,
|
templateid,
|
templatename,
|
senddate,
|
senduuid,
|
result,
|
finishtime,
|
finish_state,
|
recordid,
|
exrecallcount,
|
pulltime,
|
leaveldeptcode,
|
labelstatus,
|
del_flag,
|
update_by,
|
update_time,
|
create_by,
|
create_time,
|
isupload,
|
upload_time,
|
pid,
|
guid,
|
text_param,
|
preachform,
|
bed_no,
|
send_type,
|
task_name,
|
task_desc,
|
operator_no,
|
operator,
|
wechat,
|
sendname,
|
roomno,
|
admindate,
|
leaveldeptname,
|
hospitaldistrictcode,
|
hospitaldistrictname,
|
deptcode,
|
deptname,
|
importance_flag_code,
|
stop_state,
|
leavehospitaldistrictcode,
|
leavehospitaldistrictname,
|
leavediagname,
|
leaveicd10code,
|
orgid,
|
visit_type,
|
continue_flag,
|
continue_time_now,
|
continue_content,
|
continue_count,
|
continue_time_next,
|
operation_item_id,
|
schedule_id,
|
schedule_detail_id,
|
schedule_seq,
|
loop_count,
|
task_situation,
|
is_manually_called
|
from service_subtask
|
</sql>
|
|
<!-- 超时完成、延期完成逻辑 完成时状态(finish_state)计算:仅当本次更新把 sendstate 置为 6(随访完成)时使用。
|
基准截止时间 base:
|
非任务组(appltype != 5):endtime + send_day(缺省1) + (Σ service_subtask_preachform.compensate_time + 1) 天;
|
任务组(appltype = 5):按 schedule_benchmark 解析基准时间
|
(1-入院 2-出院 3-就诊 4-入组 0/其它-自定义时间)
|
+ day_offset + (Σ compensate_time + 1) 天(不叠加 send_day);
|
与 RyTask/RedisMqReceiver 的 isSubtaskDeadline、selectTimelyRateBatch 口径保持一致;
|
delay = COALESCE(service_task.delay_finish_days, 0);
|
finish_time = COALESCE(入参 finishtime, 库中 finishtime, NOW()):
|
finish_time <= base -> 1 正常完成
|
delay > 0 且 finish_time <= base + delay -> 2 延期完成
|
其余(含 delay 为 0 或 NULL、或已超出延期窗口) -> 3 超时完成
|
finishtime 为空时用 NOW() 兜底,保证完成时一定写入状态;
|
base 为空(endtime / schedule / day_offset 缺失)时保持原值不覆盖。 -->
|
<sql id="finishDeadlineExpr">
|
DATE_ADD(
|
CASE
|
WHEN COALESCE(st.appltype, '') = '5' THEN
|
DATE_ADD(
|
CASE sts.schedule_benchmark
|
WHEN 1 THEN service_subtask.starttime
|
WHEN 2 THEN service_subtask.endtime
|
WHEN 3 THEN service_subtask.admindate
|
WHEN 4 THEN service_subtask.create_time
|
ELSE sts.schedule_benchmark_custom_time
|
END,
|
INTERVAL std.day_offset DAY)
|
ELSE
|
DATE_ADD(service_subtask.endtime, INTERVAL COALESCE(st.send_day, 1) DAY)
|
END,
|
INTERVAL (COALESCE((SELECT SUM(CAST(COALESCE(NULLIF(TRIM(pf.compensate_time), ''), '0') AS SIGNED))
|
FROM service_subtask_preachform pf
|
WHERE pf.subid = service_subtask.id AND pf.del_flag = 0), 0) + 1) DAY)
|
</sql>
|
|
<sql id="finishStateExpr">
|
COALESCE((
|
SELECT
|
CASE
|
WHEN <include refid="finishDeadlineExpr"/> IS NULL THEN NULL
|
WHEN COALESCE(#{finishtime,jdbcType=TIMESTAMP}, service_subtask.finishtime, NOW())
|
<= <include refid="finishDeadlineExpr"/>
|
THEN 1
|
WHEN COALESCE(st.delay_finish_days, 0) > 0
|
AND COALESCE(#{finishtime,jdbcType=TIMESTAMP}, service_subtask.finishtime, NOW())
|
<= DATE_ADD(<include refid="finishDeadlineExpr"/>,
|
INTERVAL COALESCE(st.delay_finish_days, 0) DAY)
|
THEN 2
|
ELSE 3
|
END
|
FROM (SELECT 1) dummy
|
LEFT JOIN service_task st ON st.taskid = service_subtask.taskid
|
LEFT JOIN service_task_schedule sts ON sts.id = service_subtask.schedule_id
|
LEFT JOIN service_task_schedule_detail std ON std.id = service_subtask.schedule_detail_id
|
LIMIT 1
|
), finish_state)
|
</sql>
|
|
<!-- 当前执行方式:首次随访 current_preachform 为空时,取 preachform 的第一个执行方式兜底 -->
|
<sql id="effectiveCurrentPreachformExpr">
|
COALESCE(NULLIF(TRIM(current_preachform), ''), TRIM(SUBSTRING_INDEX(preachform, ',', 1)))
|
</sql>
|
|
<select id="selectServiceSubtaskBySendstate" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="taskid != null ">and taskid = #{taskid}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
<if test="serviceType != null ">and service_type = #{serviceType}</if>
|
<if test="patid != null ">and patid = #{patid}</if>
|
<if test="sendstates!=null">
|
AND sendstate IN
|
<foreach collection="sendstates" item="sendstate" open="(" separator=","
|
close=")">
|
#{sendstate}
|
</foreach>
|
</if>
|
</select>
|
|
<select id="queryServiceSubtaskList" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="subId != null">and id = #{subId}</if>
|
<if test="taskid != null ">and taskid = #{taskid}</if>
|
<if test="visitTime != null">and date_format(visit_time,'%y%m%d') <= date_format(#{visitTime},'%y%m%d')</if>
|
<if test="sendstate != null ">and sendstate = #{sendstate}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
</select>
|
|
<!-- ======================================================================
|
科室 / 病区筛选(2026-11 修订版)
|
两组条件【各自独立】,互不牵连(在院病区与离院病区不会同时存在):
|
离院组:leavehospitaldistrictcodes → leavehospitaldistrictcode
|
leaveldeptcodes → leaveldeptcode
|
在院组:hospitaldistrictcodes → hospitaldistrictcode(在院病区)
|
deptcodes → deptcode(在院科室)
|
组内组合方式由 deptOrDistrict 决定:'1' = AND,'2' = OR。
|
('3'/'4' 是「离院病区 + 随访科室 visit_dept_code」那套,单独分支,不走这里)
|
两组之间是 AND:只传一组时另一组自动不拼。
|
空数组 [] 一律视为"没传",不会拼出 IN ()。
|
====================================================================== -->
|
<sql id="filterLeaveDimAnd">
|
/* f-v3 */
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (
|
leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="lvWardCodeItem" open="(" separator="," close=")">
|
#{lvWardCodeItem}
|
</foreach>
|
<!-- 延续护理任务(service_type='99')可以在患者还没出院时生成:
|
这类记录只有「在院维度」(hospitaldistrictcode / deptcode),出院维度是 NULL。
|
NULL 不匹配任何 IN,任务会「提示生成成功、列表里却查不到」,
|
所以出院维度为空时用同一套编码体系的在院维度兜底。 -->
|
OR (service_type = '99' AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode = '')
|
AND hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="lvWardCodeItem" open="(" separator="," close=")">
|
#{lvWardCodeItem}
|
</foreach>)
|
)
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
AND (
|
leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="lvDeptCodeItem" open="(" separator="," close=")">
|
#{lvDeptCodeItem}
|
</foreach>
|
OR (service_type = '99' AND (leaveldeptcode IS NULL OR leaveldeptcode = '')
|
AND deptcode IN
|
<foreach collection="leaveldeptcodes" item="lvDeptCodeItem" open="(" separator="," close=")">
|
#{lvDeptCodeItem}
|
</foreach>)
|
)
|
</if>
|
</sql>
|
|
<!-- 即将超时过滤:是否即将超时(soonTimeout=1) + 即将超时时间(soonTimeoutHours,单位小时)。
|
截止时间口径与 RyTask/RedisMqReceiver 的 isSubtaskDeadline 保持一致:
|
service_subtask.endtime + service_task.send_day(缺省1) + (Σ service_subtask_preachform.compensate_time + 1) 天;
|
仅当存在有效补偿记录时才计算截止时间(无补偿记录不参与即将超时);
|
仅统计“尚未超时、且在 N 小时内将要超时”的数据。 -->
|
<sql id="soonTimeoutDeadlineExpr">
|
(
|
SELECT DATE_ADD(
|
DATE_ADD(ss.endtime, INTERVAL COALESCE(st.send_day, 1) DAY),
|
INTERVAL (COALESCE(pf.compensate_days, 0) + 1) DAY
|
)
|
FROM service_subtask ss
|
LEFT JOIN service_task st ON st.taskid = ss.taskid AND st.del_flag = '0'
|
INNER JOIN (
|
SELECT subid,
|
SUM(CAST(COALESCE(NULLIF(TRIM(compensate_time), ''), '0') AS SIGNED)) AS compensate_days
|
FROM service_subtask_preachform
|
WHERE del_flag = 0
|
GROUP BY subid
|
) pf ON pf.subid = ss.id
|
WHERE ss.id = service_subtask.id
|
)
|
</sql>
|
|
<sql id="soonTimeoutFilter">
|
<if test="soonTimeout != null and soonTimeout == 1">
|
AND <include refid="soonTimeoutDeadlineExpr"/> > NOW()
|
AND <include refid="soonTimeoutDeadlineExpr"/> <= DATE_ADD(NOW(), INTERVAL COALESCE(#{soonTimeoutHours}, 0) HOUR)
|
</if>
|
</sql>
|
|
<sql id="filterLeaveDimOr">
|
/* f-v3 */
|
<if test="(leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0)
|
or (leaveldeptcodes != null and leaveldeptcodes.size() > 0)">
|
AND (
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
(
|
leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="lvWardCodeItem" open="(" separator="," close=")">
|
#{lvWardCodeItem}
|
</foreach>
|
<!-- 延续护理任务(service_type='99')可以在患者还没出院时生成:
|
这类记录只有「在院维度」(hospitaldistrictcode / deptcode),出院维度是 NULL。
|
NULL 不匹配任何 IN,任务会「提示生成成功、列表里却查不到」,
|
所以出院维度为空时用同一套编码体系的在院维度兜底。 -->
|
OR (service_type = '99' AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode = '')
|
AND hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="lvWardCodeItem" open="(" separator="," close=")">
|
#{lvWardCodeItem}
|
</foreach>)
|
)
|
</if>
|
<if test="(leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0)
|
and (leaveldeptcodes != null and leaveldeptcodes.size() > 0)">
|
OR
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
(
|
leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="lvDeptCodeItem" open="(" separator="," close=")">
|
#{lvDeptCodeItem}
|
</foreach>
|
OR (service_type = '99' AND (leaveldeptcode IS NULL OR leaveldeptcode = '')
|
AND deptcode IN
|
<foreach collection="leaveldeptcodes" item="lvDeptCodeItem" open="(" separator="," close=")">
|
#{lvDeptCodeItem}
|
</foreach>)
|
)
|
</if>
|
)
|
</if>
|
</sql>
|
|
<sql id="filterInhospDimAnd">
|
/* f-v3 */
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="inWardCodeItem" open="(" separator="," close=")">
|
#{inWardCodeItem}
|
</foreach>
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND deptcode IN
|
<foreach collection="deptcodes" item="inDeptCodeItem" open="(" separator="," close=")">
|
#{inDeptCodeItem}
|
</foreach>
|
</if>
|
</sql>
|
|
<sql id="filterInhospDimOr">
|
/* f-v3 */
|
<if test="(hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0)
|
or (deptcodes != null and deptcodes.size() > 0)">
|
AND (
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="inWardCodeItem" open="(" separator="," close=")">
|
#{inWardCodeItem}
|
</foreach>
|
</if>
|
<if test="(hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0)
|
and (deptcodes != null and deptcodes.size() > 0)">
|
OR
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
deptcode IN
|
<foreach collection="deptcodes" item="inDeptCodeItem" open="(" separator="," close=")">
|
#{inDeptCodeItem}
|
</foreach>
|
</if>
|
)
|
</if>
|
</sql>
|
|
<!-- ==================================================================
|
service_subtask 列表查询的公共 where 片段
|
==================================================================
|
patItem 走「两阶段分页」:
|
① selectServiceSubtaskIdsPage —— 只查 id,走覆盖索引,不为被 offset
|
跳过的每一行回表读 100 列;
|
② selectServiceSubtaskList + subIdList —— 按 id 回表,只读一页的量。
|
两条语句的 where 必须【逐字一致】,否则第②步会把第①步选出的行过滤掉,
|
导致一页返回不足 pageSize 条。所以收成公共片段,杜绝两份口径漂移。
|
================================================================== -->
|
<sql id="serviceSubtaskWhere">
|
where del_flag = 0
|
<if test="subId != null ">and id = #{subId}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
<if test="sendname != null and sendname != ''">and sendname like concat('%', #{sendname}, '%')</if>
|
<if test="phone != null and phone != ''">and phone = #{phone}</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">and
|
leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and
|
leavehospitaldistrictname = #{leavehospitaldistrictname}
|
</if>
|
<if test="leavediagname != null and leavediagname != ''">and leavediagname like concat('%',
|
#{leavediagname}, '%')
|
</if>
|
<if test="managementDoctor != null and managementDoctor != ''">and management_doctor like concat('%',
|
#{managementDoctor}, '%')
|
</if>
|
<if test="sex != null and sex != ''">and sex = #{sex}</if>
|
<if test="age != null ">and age = #{age}</if>
|
<if test="patguid != null ">and patguid = #{patguid}</if>
|
<if test="subId != null ">and id = #{subId}</if>
|
<if test="inhospid != null ">and inhospid = #{inhospid}</if>
|
<if test="managementDoctorCode != null ">and management_doctor_code = #{managementDoctorCode}</if>
|
<if test="submit != null ">and submit = #{submit}</if>
|
<if test="upid != null ">and upid = #{upid}</if>
|
<if test="patfrom != null ">and patfrom = #{patfrom}</if>
|
<if test="serviceType != null ">and service_type = #{serviceType}</if>
|
<if test="patid != null ">and patid = #{patid}</if>
|
<if test="sfzh != null and sfzh != ''">and sfzh = #{sfzh}</if>
|
<if test="addr != null and addr != ''">and addr = #{addr}</if>
|
<if test="senderdetail != null and senderdetail != ''">and senderdetail = #{senderdetail}</if>
|
<if test="type != null and type != ''">and type = #{type}</if>
|
<if test="taskid != null ">and taskid = #{taskid}</if>
|
<if test="sendstates != null and sendstates.size() > 0">
|
AND sendstate IN
|
<foreach collection="sendstates" item="state" open="(" separator="," close=")">
|
#{state}
|
</foreach>
|
</if>
|
<if test="subIdList != null and subIdList.size() > 0">
|
AND id IN
|
<foreach collection="subIdList" item="subId" open="(" separator="," close=")">
|
#{subId}
|
</foreach>
|
</if>
|
<!-- taskIds筛选 -->
|
<if test="taskIds != null and taskIds.size() > 0">
|
AND taskid IN
|
<foreach collection="taskIds" item="itemTaskId" open="(" separator=","
|
close=")">
|
#{itemTaskId}
|
</foreach>
|
</if>
|
<if test="operationItemIds != null and operationItemIds.size() > 0">
|
AND operation_item_id IN
|
<foreach collection="operationItemIds" item="operationItemIdItem" open="(" separator="," close=")">
|
#{operationItemIdItem}
|
</foreach>
|
</if>
|
<if test="inhospids != null and inhospids.size() > 0">
|
AND inhospid IN
|
<foreach collection="inhospids" item="inhospidItem" open="(" separator="," close=")">
|
#{inhospidItem}
|
</foreach>
|
</if>
|
<if test="templateid != null and templateid != ''">and templateid = #{templateid}</if>
|
<if test="templatename != null and templatename != ''">and templatename like concat('%', #{templatename},
|
'%')
|
</if>
|
<if test="startOutHospTime != null">
|
AND endtime >= DATE(#{startOutHospTime})
|
</if>
|
<if test="endOutHospTime != null">
|
AND endtime < DATE_ADD(DATE(#{endOutHospTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="startSendDateTime != null">
|
AND visit_time >= DATE(#{startSendDateTime})
|
</if>
|
<if test="endSendDateTime != null">
|
AND visit_time < DATE_ADD(DATE(#{endSendDateTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="finishtimeStart != null">
|
AND finishtime >= DATE(#{finishtimeStart})
|
</if>
|
<if test="finishtimeEnd != null">
|
AND finishtime < DATE_ADD(DATE(#{finishtimeEnd}), INTERVAL 1 DAY)
|
</if>
|
<if test="longSendTime != null">
|
AND long_send_time < DATE_ADD(DATE(#{longSendTime}), INTERVAL 1 DAY)
|
</if>
|
<!--
|
科室/病区筛选(2026-11 修订):
|
离院组(leaveldeptcodes / leavehospitaldistrictcodes)保持原逻辑;
|
在院组(deptcodes / hospitaldistrictcodes → deptcode / hospitaldistrictcode)是新增的一组;
|
组内按 deptOrDistrict 取 AND('1') / OR('2'),两组之间 AND(只传一组时另一组不拼)。
|
-->
|
<if test='deptOrDistrict == "1"'>
|
<include refid="filterLeaveDimAnd"/>
|
<include refid="filterInhospDimAnd"/>
|
</if>
|
<if test='deptOrDistrict == "2"'>
|
<include refid="filterLeaveDimOr"/>
|
<include refid="filterInhospDimOr"/>
|
</if>
|
<!-- ⚠️ deptOrDistrict 是 String:OGNL 里 '1'(单引号单字符)是 char,String != char 恒 false!
|
必须写成双引号字符串(XML 属性用单引号包住),或直接和数字比(OGNL 会做 String→Number 转换)。 -->
|
<if test='deptOrDistrict == "3"'>
|
AND (1=1
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="("
|
separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test=" visitDeptCodes != null and visitDeptCodes.size()>0">
|
AND visit_dept_code IN
|
<foreach collection="visitDeptCodes" item="visitDeptCode" open="(" separator=","
|
close=")">
|
#{visitDeptCode}
|
</foreach>
|
</if>
|
)
|
</if>
|
<if test='deptOrDistrict == "4"'>
|
AND (1=1
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="("
|
separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test=" visitDeptCodes != null and visitDeptCodes.size()>0">
|
OR visit_dept_code IN
|
<foreach collection="visitDeptCodes" item="visitDeptCode" open="(" separator=","
|
close=")">
|
#{visitDeptCode}
|
</foreach>
|
</if>
|
)
|
</if>
|
<if test="visitTime != null">
|
AND visit_time >= DATE(#{visitTime})
|
AND visit_time < DATE_ADD(DATE(#{visitTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="senddate != null ">and senddate = #{senddate}</if>
|
<if test="senduuid != null and senduuid != ''">and senduuid = #{senduuid}</if>
|
<if test="result != null and result != ''">and result = #{result}</if>
|
<if test="finishtime != null ">and finishtime = #{finishtime}</if>
|
<if test="recordid != null ">and recordid = #{recordid}</if>
|
<if test="exrecallcount != null ">and exrecallcount = #{exrecallcount}</if>
|
<if test="pulltime != null ">and pulltime = #{pulltime}</if>
|
<if test="leaveldeptcode != null and leaveldeptcode != ''">and leaveldeptcode = #{leaveldeptcode}</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">and leaveldeptname = #{leaveldeptname}</if>
|
<if test="labelstatus != null ">and labelstatus = #{labelstatus}</if>
|
<if test="isupload != null ">and isupload = #{isupload}</if>
|
<if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="pid != null ">and pid = #{pid}</if>
|
<if test="preachform != null ">and preachform = #{preachform}</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">and current_preachform = #{currentPreachform}</if>
|
<if test="currentPreachforms != null and currentPreachforms != ''">
|
and FIND_IN_SET(<include refid="effectiveCurrentPreachformExpr"/>, #{currentPreachforms})
|
</if>
|
<if test="guid != null and guid != ''">and guid = #{guid}</if>
|
<if test="textParam != null and textParam != ''">and text_param = #{textParam}</if>
|
<if test="bedNo != null">and bed_no = #{bedNo}</if>
|
<if test="sendType != null and sendType != ''">and send_type = #{sendType}</if>
|
<if test="operator != null and operator != ''">and operator = #{operator}</if>
|
<if test="operatorNo != null and operatorNo != ''">and operator_no = #{operatorNo}</if>
|
<if test="wechat != null and wechat != ''">and wechat = #{wechat}</if>
|
<if test="hospType != null and hospType != ''">and hosp_type = #{hospType}</if>
|
<!--
|
2026-11:重要性标记筛选(对应 service_subtask.importance_flag_code,建任务时取自
|
pat_med_inhosp.importance_flag_code)。两种写法:
|
① 精确单值 importanceFlagCode = 'FH0165.01'(或描述口径 '日间手术')
|
② 精确多值 importanceFlagCodes = ['FH0165.01','FH0165.02']
|
该列采集时就被拼成**描述串**(ImportFlagEnum 的 desc),多值用英文逗号拼接,
|
如 '无,日间手术'(见 ServiceSLTDHealthcareRecordServiceImpl#hospitalizedApply)——
|
等值/IN 只命中单值行;多值行(现场仅 7 条,都在出院记录上)要筛全需自行写
|
find_in_set。两种口径并存(有库存枚举编码、有库存中文描述),传什么按什么精确比,
|
不做值域归一。
|
-->
|
<if test="importanceFlagCode != null and importanceFlagCode != ''">
|
and importance_flag_code = #{importanceFlagCode}
|
</if>
|
<if test="importanceFlagCodes != null and importanceFlagCodes.size() > 0">
|
AND importance_flag_code IN
|
<foreach collection="importanceFlagCodes" item="impFlagItem" open="(" separator="," close=")">
|
#{impFlagItem}
|
</foreach>
|
</if>
|
<if test="libtemplateid != null ">and libtemplateid = #{libtemplateid}</if>
|
<if test="libtemplatename != null ">and libtemplatename = #{libtemplatename}</if>
|
<if test="openid != null ">and openid = #{openid}</if>
|
<if test="sendstate != null ">and sendstate = #{sendstate}</if>
|
<if test="operationItemId != null ">and operation_item_id = #{operationItemId}</if>
|
<if test="drname != null and drname != ''">and drname like concat('%', #{drname}, '%')</if>
|
<if test="taskName != null and taskName != ''">and task_name like concat('%', #{taskName}, '%')</if>
|
<if test="drcode != null and drcode != ''">and (drcode = #{drcode}</if>
|
<if test="nurseId != null and nurseId != ''">or nurse_id = #{nurseId})</if>
|
<if test="starttime != null ">and starttime = #{starttime}</if>
|
<if test="endtime != null ">and endtime = #{endtime}</if>
|
<if test="excep != null ">and excep = #{excep}</if>
|
<if test="nurseName != null ">and nurse_name = #{nurseName}</if>
|
<if test="score != null">and score = #{score}</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND visit_count > 1
|
</if>
|
<if test="remark != null">and remark = #{remark}</if>
|
<if test="doctorOpinion != null and doctorOpinion != ''">and doctor_opinion like concat('%', #{doctorOpinion}, '%')</if>
|
<if test="suggest != null">and suggest = #{suggest}</if>
|
<if test="createBy != null">and create_by = #{createBy}</if>
|
<if test="taskGuid != null">and task_guid = #{taskGuid}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="isManuallyCalled != null">and is_manually_called = #{isManuallyCalled}</if>
|
<if test="isVisitAgain != null">and is_visit_again = #{isVisitAgain}</if>
|
<if test="visitCount != null and visitCount > 1 and visitDeptCodes != null and visitDeptCodes.size() > 0">
|
AND visit_dept_code IN
|
<foreach collection="visitDeptCodes" item="visitDeptCode" open="("
|
separator=","
|
close=")">
|
#{visitDeptCode}
|
</foreach>
|
</if>
|
<include refid="soonTimeoutFilter"/>
|
</sql>
|
|
<!-- 排序片段:保持原语义,只在调用方显式传 sort 时才拼 order by
|
(导出等不分页的调用方行为完全不变) -->
|
<sql id="serviceSubtaskOrderBy">
|
<if test="sort != null and sort==0">order by endtime asc</if>
|
<if test="sort != null and sort==1">order by endtime desc</if>
|
<if test="sort != null and sort==2">order by visit_time asc</if>
|
<if test="sort != null and sort==3">order by visit_time desc</if>
|
<if test="sort != null and sort==5">order by admindate asc</if>
|
<if test="sort != null and sort==6">order by admindate desc</if>
|
<if test="sort != null and sort==7">order by visit_time asc</if>
|
<if test="sort != null and sort==8">order by visit_time desc</if>
|
<if test="sort != null and sort==9">order by sendname asc</if>
|
</sql>
|
|
<!-- 分页场景专用排序:sort 为空时兜底 order by id desc。
|
原来 sort 为空时整条 SQL 没有 order by,limit/offset 取到的是「不确定顺序」,
|
翻页会重复或漏行;这里给一个稳定顺序(想改成 id asc 只改这一行)。 -->
|
<sql id="serviceSubtaskOrderByPaged">
|
<include refid="serviceSubtaskOrderBy"/>
|
<if test="sort == null">order by id desc</if>
|
</sql>
|
|
<select id="selectServiceSubtaskList" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
<include refid="serviceSubtaskWhere"/>
|
<include refid="serviceSubtaskOrderBy"/>
|
<if test="pageSize != null and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
|
</select>
|
|
<!--
|
两阶段分页第 1 步:只取 id。
|
select 列表只有 id,where/order 涉及的列都在 idx_ss_org_cam_del_* 上,
|
因此能走「覆盖索引 + 提前截断」;被 offset 跳过的那几千行不再回表读 100 列。
|
第 2 步由调用方用 subIdList 回表取整行(见 ServiceSubtaskServiceImpl#selectServiceSubtaskPage)。
|
-->
|
<select id="selectServiceSubtaskIdsPage" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultType="java.lang.Long">
|
select id
|
from service_subtask
|
<include refid="serviceSubtaskWhere"/>
|
<include refid="serviceSubtaskOrderByPaged"/>
|
limit ${pageSize} OFFSET ${pageNum}
|
</select>
|
|
<select id="getCompensateServiceSubtaskList" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where del_flag = 0
|
and sendstate != 5
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="visitTime != null">and date_format(visit_time,'%y%m%d') <= date_format(#{visitTime},'%y%m%d') </if>
|
<if test="subId != null">and id = #{subId} </if>
|
<if test="sendstate != null ">and sendstate = #{sendstate}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
UNION ALL
|
<include refid="selectServiceSubtaskVo"/>
|
where del_flag = 0
|
and sendstate = 5
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="visitTime != null">
|
AND date_format(visit_time,'%y%m%d') <= date_format(DATE_ADD(#{visitTime}, INTERVAL 1 DAY),'%y%m%d')
|
</if>
|
<if test="subId != null">
|
AND id = #{subId}
|
</if>
|
<if test="sendstate != null ">and sendstate = #{sendstate}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
</select>
|
|
<select id="selectServiceSubtaskListByCreateTime" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where del_flag = 0
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="createStartTime != null and createEndTime != null">and create_time BETWEEN #{createStartTime} AND
|
#{createEndTime}
|
</if>
|
<if test="createBy != null ">and create_by = #{createBy}</if>
|
<if test="sendname != null ">and sendname = #{sendname}</if>
|
<if test="sfzh != null ">and sfzh = #{sfzh}</if>
|
<if test="patguid != null ">and patguid = #{patguid}</if>
|
<if test="upid != null ">and upid = #{upid}</if>
|
<if test="visitCount != null ">and visit_count = #{visitCount}</if>
|
<if test="isVisitAgain != null ">and is_visit_again = #{isVisitAgain}</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="managementDoctorCode != null">and management_doctor_code = #{managementDoctorCode}</if>
|
<if test="managementDoctor != null">and management_doctor = #{managementDoctor}</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">and current_preachform = #{currentPreachform}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
|
</select>
|
|
<select id="selectServiceSubtaskListAgain" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where 1=1
|
and del_flag = 0
|
and upid is not null
|
and visit_count > 1
|
<if test="createStartTime != null and createEndTime != null">and create_time BETWEEN #{createStartTime} AND
|
#{createEndTime}
|
</if>
|
<if test="senddate != null ">and senddate = #{senddate}</if>
|
<if test="senduuid != null and senduuid != ''">and senduuid = #{senduuid}</if>
|
<if test="result != null and result != ''">and result = #{result}</if>
|
<if test="finishtime != null ">and finishtime = #{finishtime}</if>
|
<if test="recordid != null ">and recordid = #{recordid}</if>
|
<if test="exrecallcount != null ">and exrecallcount = #{exrecallcount}</if>
|
<if test="pulltime != null ">and pulltime = #{pulltime}</if>
|
<if test="leaveldeptcode != null and leaveldeptcode != ''">and leaveldeptcode = #{leaveldeptcode}</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">and leaveldeptname = #{leaveldeptname}</if>
|
<if test="labelstatus != null ">and labelstatus = #{labelstatus}</if>
|
<if test="isupload != null ">and isupload = #{isupload}</if>
|
<if test="uploadTime != null ">and upload_time = #{uploadTime}</if>
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="pid != null ">and pid = #{pid}</if>
|
<if test="preachform != null ">and preachform = #{preachform}</if>
|
<if test="guid != null and guid != ''">and guid = #{guid}</if>
|
<if test="textParam != null and textParam != ''">and text_param = #{textParam}</if>
|
<if test="bedNo != null">and bed_no = #{bedNo}</if>
|
<if test="sendType != null and sendType != ''">and send_type = #{sendType}</if>
|
<if test="operator != null and operator != ''">and operator = #{operator}</if>
|
<if test="operatorNo != null and operatorNo != ''">and operator_no = #{operatorNo}</if>
|
<if test="wechat != null and wechat != ''">and wechat = #{wechat}</if>
|
<if test="hospType != null and hospType != ''">and hosp_type = #{hospType}</if>
|
<if test="libtemplateid != null ">and libtemplateid = #{libtemplateid}</if>
|
<if test="libtemplatename != null ">and libtemplatename = #{libtemplatename}</if>
|
<if test="openid != null ">and openid = #{openid}</if>
|
<if test="longSendTime != null ">and long_send_time = #{longSendTime}</if>
|
<if test="sendstate != null ">and sendstate = #{sendstate}</if>
|
<if test="drname != null and drname != ''">and drname like concat('%', #{drname}, '%')</if>
|
<if test="taskName != null and taskName != ''">and task_name like concat('%', #{taskName}, '%')</if>
|
<if test="drcode != null and drcode != ''">and (drcode = #{drcode}</if>
|
<if test="nurseId != null and nurseId != ''">or nurse_id = #{nurseId})</if>
|
<if test="starttime != null ">and starttime = #{starttime}</if>
|
<if test="endtime != null ">and endtime = #{endtime}</if>
|
<if test="excep != null ">and excep = #{excep}</if>
|
<if test="nurseName != null ">and nurse_name = #{nurseName}</if>
|
<if test="visitTime != null ">and visit_time = #{visitTime}</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">and current_preachform = #{currentPreachform}</if>
|
<if test="managementDoctorCode != null">and management_doctor_code = #{managementDoctorCode}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="managementDoctor != null">and management_doctor like concat('%',#{managementDoctor}, '%')</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
<include refid="soonTimeoutFilter"/>
|
</select>
|
|
<select id="selectSendstateByCondition" parameterType="com.ruoyi.task.domain.ServiceSubtask" resultType="Integer">
|
SELECT b.sendstate
|
from service_task a
|
JOIN service_subtask b on a.taskid = b.taskid and a.pat_cycle = 0 and b.del_flag = 0
|
where 1=1
|
and b.taskid = #{taskid}
|
and b.patid = #{patid}
|
<if test="createTime != null and createTime != ''">
|
DATE_FORMAT(b.create_time, '%Y-%m-%d') LIKE CONCAT(#{createTimeNew}, '%')
|
</if>
|
<if test="sendstate != null ">and b.sendstate = #{sendstate}</if>
|
<if test="orgid != null and orgid != ''">and b.orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and b.campusid = #{campusid}</if>
|
</select>
|
|
<select id="selectTimelyRate" parameterType="com.ruoyi.task.domain.ServiceSubtask" resultType="double">
|
SELECT sum( a.finished )/ sum( 1 ) FROM
|
(SELECT id, visit_time, finishtime,
|
(CASE WHEN ( DATE_FORMAT( visit_time, '%y%m%d' )< DATE_FORMAT( IF ( ISNULL( finishtime ), NOW(), finishtime
|
), '%y%m%d' ) )
|
THEN 1 ELSE 0 END ) finished,1 AS tasknumber FROM service_subtask
|
WHERE del_flag=0
|
<if test="starttime == null and endtime==null">
|
AND visit_time < NOW()
|
</if>
|
<if test="starttime != null and endtime!=null">
|
AND date_format(visit_time,'%y%m%d') >= date_format(#{starttime},'%y%m%d')
|
AND date_format(visit_time,'%y%m%d') <= date_format(#{endtime},'%y%m%d')
|
</if>
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="serviceType != null and serviceType != ''">and service_type = #{serviceType}</if>
|
<if test="serviceTypes != null and serviceTypes != ''">and service_type IN (#{serviceTypes})</if>
|
<if test="leaveldeptcode != null and leaveldeptcode != ''">and leaveldeptcode = #{leaveldeptcode}</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">and leaveldeptname = #{leaveldeptname}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">and
|
leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and
|
leavehospitaldistrictname = #{leavehospitaldistrictname}
|
</if>
|
<if test="managementDoctorCode != null">and management_doctor_code = #{managementDoctorCode}</if>
|
<if test="managementDoctor != null">and management_doctor like concat('%',#{managementDoctor}, '%')</if>
|
<if test="startOutHospTime != null">
|
AND endtime >= DATE(#{startOutHospTime})
|
</if>
|
<if test="endOutHospTime != null">
|
AND endtime < DATE_ADD(DATE(#{endOutHospTime}), INTERVAL 1 DAY)
|
</if>
|
) a
|
</select>
|
|
<select id="selectTimelyRateBatch" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity" resultType="map">
|
SELECT
|
<if test="groupKey != null and groupKey != ''">
|
ss.${groupKey} as groupKey,
|
</if>
|
SUM(CASE WHEN ss.finishtime IS NOT NULL AND DATE(ss.visit_time) <= DATE(ss.finishtime) THEN 1 ELSE 0 END) /
|
COUNT(*) AS finishRate,
|
<!-- 及时率基准:
|
1) 非任务组(appltype != 5):endtime + send_day(缺省1) + Σ补偿天数 + 1 天;
|
2) 任务组(appltype = 5):按 schedule_benchmark 解析基准时间
|
(1-入院时间 2-出院时间 3-就诊时间 4-入组时间 0/其它-自定义时间)
|
+ day_offset + Σ补偿天数 + 1 天(不再叠加 send_day);
|
完成时间 finishtime <= 基准时间计为及时,分母仍为应随访数。
|
补偿天数只取 service_subtask_preachform.compensate_time 的汇总值一次,
|
避免与补偿明细相加造成重复补偿或一对多放大分母。 -->
|
SUM(CASE
|
WHEN ss.finishtime IS NOT NULL
|
AND COALESCE(st.appltype, '') != '5'
|
AND ss.endtime IS NOT NULL
|
AND ss.finishtime <= DATE_ADD(
|
DATE_ADD(ss.endtime, INTERVAL COALESCE(st.send_day, 1) DAY),
|
INTERVAL (COALESCE(cp.compensate_days, 0) + 1) DAY)
|
THEN 1
|
WHEN ss.finishtime IS NOT NULL
|
AND st.appltype = '5'
|
AND std.day_offset IS NOT NULL
|
AND ss.finishtime <= DATE_ADD(
|
DATE_ADD(
|
CASE sts.schedule_benchmark
|
WHEN 1 THEN ss.starttime
|
WHEN 2 THEN ss.endtime
|
WHEN 3 THEN ss.admindate
|
WHEN 4 THEN ss.create_time
|
ELSE sts.schedule_benchmark_custom_time
|
END, INTERVAL std.day_offset DAY),
|
INTERVAL (COALESCE(cp.compensate_days, 0) + 1) DAY)
|
THEN 1
|
ELSE 0
|
END) / COUNT(*) AS rate
|
FROM service_subtask ss
|
<!-- 这里按 taskid / 历史 schedule 快照关联,不按 del_flag 过滤:
|
任务或计划被编辑后旧 schedule/detail 会置为 del_flag=1,
|
但历史 subtask 仍引用旧 ID,过滤会丢失历史及时率基准。 -->
|
LEFT JOIN service_task st
|
ON st.taskid = ss.taskid
|
LEFT JOIN service_task_schedule sts
|
ON sts.id = ss.schedule_id
|
LEFT JOIN service_task_schedule_detail std
|
ON std.id = ss.schedule_detail_id
|
<!-- 补偿时间:先按子任务聚合成一行再关联,避免一对多放大 COUNT(*) 分母。
|
compensate_time 是 varchar 且可能存成空串,需先置空再转数字 -->
|
LEFT JOIN (
|
SELECT subid,
|
SUM(CAST(COALESCE(NULLIF(TRIM(compensate_time), ''), '0') AS SIGNED)) AS compensate_days
|
FROM service_subtask_preachform
|
WHERE del_flag = 0
|
GROUP BY subid
|
) cp ON cp.subid = ss.id
|
WHERE ss.del_flag = 0
|
AND ss.visit_time IS NOT NULL
|
AND ss.sendstate != 4
|
<if test="starttime == null and endtime==null">
|
AND DATE(ss.visit_time) < DATE(NOW())
|
</if>
|
<if test="starttime != null and endtime!=null">
|
AND ss.visit_time >= #{starttime}
|
AND ss.visit_time < DATE_ADD(#{endtime}, INTERVAL 1 DAY)
|
</if>
|
<if test="orgid != null and orgid != ''">AND ss.orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and ss.campusid = #{campusid}</if>
|
<if test="leaveldeptcode != null and leaveldeptcode != ''">and ss.leaveldeptcode = #{leaveldeptcode}</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">and ss.leaveldeptname = #{leaveldeptname}</if>
|
<if test="isabnormal != null">and ss.isabnormal = #{isabnormal}</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">and
|
ss.leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and
|
ss.leavehospitaldistrictname = #{leavehospitaldistrictname}
|
</if>
|
<if test="managementDoctorCode != null">and ss.management_doctor_code = #{managementDoctorCode}</if>
|
<if test="managementDoctor != null">and ss.management_doctor like concat('%',#{managementDoctor}, '%')</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND ss.visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND ss.visit_count > 1
|
</if>
|
<if test="serviceTypeList != null">
|
AND ss.service_type IN
|
<foreach collection="serviceTypeList" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startOutHospTime != null">
|
AND date_format(ss.endtime,'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d')
|
</if>
|
<if test="endOutHospTime != null">
|
AND date_format(ss.endtime,'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d')
|
</if>
|
<if test="groupKey != null and groupKey != ''">
|
AND IFNULL(ss.${groupKey}, 'Unknown') IN
|
<foreach collection="groupKeyList" item="key" open="(" separator=","
|
close=")">
|
#{key}
|
</foreach>
|
GROUP BY ss.${groupKey}
|
</if>
|
</select>
|
|
<select id="selectTimelyRateDetail" parameterType="com.ruoyi.task.domain.ServiceSubtask"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where 1=1
|
and id in (
|
SELECT id FROM
|
(SELECT id, visit_time, finishtime,
|
(CASE WHEN ( DATE_FORMAT( visit_time, '%y%m%d' ) < DATE_FORMAT( IF ( ISNULL( finishtime ), NOW(),
|
finishtime
|
), '%y%m%d' ) )
|
THEN 1 ELSE 0 END ) finished,1 AS tasknumber FROM service_subtask
|
WHERE del_flag=0
|
-- AND visit_time < NOW()
|
<if test="starttime != null and endtime!=null">
|
AND date_format(visit_time,'%y%m%d') >= date_format(#{starttime},'%y%m%d')
|
AND date_format(visit_time,'%y%m%d') <= date_format(#{endtime},'%y%m%d')
|
</if>
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="serviceType != null and serviceType != ''">and service_type = #{serviceType}</if>
|
<if test="serviceTypes != null and serviceTypes != ''">and service_type IN (#{serviceTypes})</if>
|
<if test="isabnormal != null ">and isabnormal = #{isabnormal}</if>
|
<if test="leaveldeptcode != null and leaveldeptcode != ''">and leaveldeptcode = #{leaveldeptcode}</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">and leaveldeptname = #{leaveldeptname}</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">and
|
leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and
|
leavehospitaldistrictname = #{leavehospitaldistrictname}
|
</if>
|
<if test="managementDoctorCode != null">and management_doctor_code = #{managementDoctorCode}</if>
|
<if test="managementDoctor != null">and management_doctor like concat('%',#{managementDoctor}, '%')</if>
|
<if test="startOutHospTime != null">
|
AND date_format(endtime,'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d')
|
</if>
|
<if test="endOutHospTime != null">
|
AND date_format(endtime,'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d')
|
</if>
|
) a where a.finished =1)
|
</select>
|
|
<select id="selectServiceSubtaskById" parameterType="Long" resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where id = #{id}
|
</select>
|
|
<select id="selectCompletedInhospFollowups" resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where del_flag = '0'
|
and sendstate = 6
|
and hosp_type in ('2', '6')
|
and orgid = #{orgid}
|
and finishtime >= #{startTime}
|
<if test="serviceTypes != null and serviceTypes.size() > 0">
|
and service_type in
|
<foreach collection="serviceTypes" item="serviceType" open="(" separator="," close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
order by id asc
|
limit #{limit}
|
</select>
|
|
<select id="selectServiceSubtaskByDiagname" parameterType="com.ruoyi.task.domain.ServiceSubtask"
|
resultMap="ServiceSubtaskResult">
|
select sendstate,starttime,endtime,nurse_name,phone,sex,task_name,sendname,leavediagname,visit_time FROM
|
service_subtask WHERE del_flag=0
|
and service_type != 4
|
<if test="leavediagname != null">and leavediagname like concat('%',#{leavediagname}, '%')</if>
|
<if test="sendname != null">and sendname like concat('%',#{sendname}, '%')</if>
|
<if test="taskName != null">and task_name like concat('%',#{taskName}, '%')</if>
|
<if test="sendstate != null">and sendstate = #{sendstate}</if>
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid} </if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext}</if>
|
<if test="startOutHospTime != null">
|
AND endtime >= DATE(#{startOutHospTime})
|
</if>
|
<if test="endOutHospTime != null">
|
AND endtime < DATE_ADD(DATE(#{endOutHospTime}), INTERVAL 1 DAY)
|
</if>
|
GROUP BY sendname,sendstate,starttime,endtime,nurse_name,phone,sex,task_name,leavediagname,visit_time
|
ORDER BY sendname,visit_time
|
<if test="pageSize != null and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
|
</select>
|
|
<insert id="insertServiceSubtask" parameterType="com.ruoyi.task.domain.ServiceSubtask" useGeneratedKeys="true"
|
keyProperty="id">
|
insert into service_subtask
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
<if test="sendname != null">sendname,</if>
|
<if test="phone != null">phone,</if>
|
<if test="sex != null">sex,</if>
|
<if test="age != null">age,</if>
|
<if test="sfzh != null">sfzh,</if>
|
<if test="addr != null">addr,</if>
|
<if test="senderdetail != null">senderdetail,</if>
|
<if test="type != null">type,</if>
|
<if test="taskid != null">taskid,</if>
|
<if test="templateid != null">templateid,</if>
|
<if test="templatename != null">templatename,</if>
|
<if test="senddate != null">senddate,</if>
|
<if test="senduuid != null">senduuid,</if>
|
<if test="result != null">result,</if>
|
<if test="finishtime != null">finishtime,</if>
|
<if test="finishState != null">finish_state,</if>
|
<if test="recordid != null">recordid,</if>
|
<if test="exrecallcount != null">exrecallcount,</if>
|
<if test="pulltime != null">pulltime,</if>
|
<if test="leaveldeptcode != null">leaveldeptcode,</if>
|
<!-- 2026-11:原 sendlimit* 复用列(在院维度:在院病区/在院科室),仅出院随访会填值 -->
|
<if test="hospitaldistrictcode != null and hospitaldistrictcode != ''">hospitaldistrictcode,</if>
|
<if test="hospitaldistrictname != null and hospitaldistrictname != ''">hospitaldistrictname,</if>
|
<if test="deptcode != null and deptcode != ''">deptcode,</if>
|
<if test="deptname != null and deptname != ''">deptname,</if>
|
<!-- 2026-11:重要性标记编码(日间手术/日间诊疗…),建任务时从 pat_med_inhosp 同步 -->
|
<if test="importanceFlagCode != null and importanceFlagCode != ''">importance_flag_code,</if>
|
<if test="labelstatus != null">labelstatus,</if>
|
<if test="updateBy != null">update_by,</if>
|
<if test="updateTime != null">update_time,</if>
|
<if test="createBy != null">create_by,</if>
|
<if test="createTime != null">create_time,</if>
|
<if test="isupload != null">isupload,</if>
|
<if test="uploadTime != null">upload_time,</if>
|
<if test="orgid != null and orgid != ''">orgid,</if>
|
<if test="campusid != null and campusid != ''">campusid,</if>
|
<if test="pid != null">pid,</if>
|
<if test="guid != null">guid,</if>
|
<if test="textParam != null">text_param,</if>
|
<if test="preachform != null">preachform,</if>
|
<if test="bedNo != null">bed_no,</if>
|
<if test="sendType != null and sendType != ''">send_type,</if>
|
<if test="taskName != null and taskName != ''">task_name,</if>
|
<if test="taskDesc != null and taskDesc != ''">task_desc,</if>
|
<if test="operator != null and operator != ''">operator,</if>
|
<if test="operatorNo != null and operatorNo != ''">operator_no,</if>
|
<if test="hospType != null and hospType != ''">hosp_type,</if>
|
<if test="hospno != null and hospno != ''">hospno,</if>
|
<if test="wechat != null and wechat != ''">wechat,</if>
|
<if test="roomno != null and roomno != ''">roomno,</if>
|
<if test="admindate != null">admindate,</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">leaveldeptname,</if>
|
<if test="leaveicd10code != null and leaveicd10code != ''">leaveicd10code,</if>
|
<if test="leavediagname != null and leavediagname != ''">leavediagname,</if>
|
<!-- diagname:入院诊断名称。原 insert 漏了这一列,而出院链路的
|
boxedServiceSubtask 一直在 setDiagname(patMedInhosp.diagname),
|
于是 service_subtask.diagname 永远为 NULL(select 侧却一直在读它)。 -->
|
<if test="diagname != null and diagname != ''">diagname,</if>
|
<if test="libtemplateid != null ">libtemplateid,</if>
|
<if test="libtemplatename != null ">libtemplatename,</if>
|
<if test="patid != null ">patid,</if>
|
<if test="openid != null ">openid,</if>
|
<if test="longSendTime != null ">long_send_time,</if>
|
<if test="serviceType != null ">service_type,</if>
|
<if test="score != null ">score,</if>
|
<if test="submit != null ">submit,</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">
|
leavehospitaldistrictcode,
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">
|
leavehospitaldistrictname,
|
</if>
|
<if test="drname != null ">drname,</if>
|
<if test="drcode != null ">drcode,</if>
|
<if test="endtime != null ">endtime,</if>
|
<if test="starttime != null ">starttime,</if>
|
<if test="excep != null ">excep,</if>
|
<if test="nurseName != null ">nurse_name,</if>
|
<if test="nurseId != null ">nurse_id,</if>
|
<if test="remark != null ">remark,</if>
|
<if test="doctorOpinion != null ">doctor_opinion,</if>
|
<if test="suggest != null ">suggest,</if>
|
<if test="sendstate != null ">sendstate,</if>
|
<if test="inhospid != null ">inhospid,</if>
|
<if test="patfrom != null ">patfrom,</if>
|
<if test="taskGuid != null ">task_guid,</if>
|
<if test="patguid != null ">patguid,</if>
|
<if test="visitCount != null ">visit_count,</if>
|
<if test="isVisitAgain != null ">is_visit_again,</if>
|
<if test="upid != null ">upid,</if>
|
<if test="visitTime != null ">visit_Time,</if>
|
<if test="visitDeptCode != null">visit_dept_code,</if>
|
<if test="visitDeptName != null">visit_dept_name,</if>
|
<if test="managementDoctorCode != null">management_doctor_code,</if>
|
<if test="managementDoctor != null">management_doctor,</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">current_preachform,</if>
|
<if test="taskSituation != null">task_situation,</if>
|
<if test="isabnormal != null">isabnormal,</if>
|
<if test="continueFlag != null ">continue_flag,</if>
|
<if test="continueTimeNow != null ">continue_time_now,</if>
|
<if test="continueCount != null ">continue_count,</if>
|
<if test="continueTimeNext != null ">continue_time_next,</if>
|
<if test="continueContent != null ">continue_content,</if>
|
<if test="operationItemId != null ">operation_item_id,</if>
|
<if test="scheduleId != null ">schedule_id,</if>
|
<if test="scheduleDetailId != null ">schedule_detail_id,</if>
|
<if test="scheduleSeq != null ">schedule_seq,</if>
|
<if test="loopCount != null ">loop_count,</if>
|
<if test="isManuallyCalled != null ">is_manually_called,</if>
|
</trim>
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<if test="sendname != null">#{sendname},</if>
|
<if test="phone != null">#{phone},</if>
|
<if test="sex != null">#{sex},</if>
|
<if test="age != null">#{age},</if>
|
<if test="sfzh != null">#{sfzh},</if>
|
<if test="addr != null">#{addr},</if>
|
<if test="senderdetail != null">#{senderdetail},</if>
|
<if test="type != null">#{type},</if>
|
<if test="taskid != null">#{taskid},</if>
|
<if test="templateid != null">#{templateid},</if>
|
<if test="templatename != null">#{templatename},</if>
|
<if test="senddate != null">#{senddate},</if>
|
<if test="senduuid != null">#{senduuid},</if>
|
<if test="result != null">#{result},</if>
|
<if test="finishtime != null">#{finishtime},</if>
|
<if test="finishState != null">#{finishState},</if>
|
<if test="recordid != null">#{recordid},</if>
|
<if test="exrecallcount != null">#{exrecallcount},</if>
|
<if test="pulltime != null">#{pulltime},</if>
|
<if test="leaveldeptcode != null">#{leaveldeptcode},</if>
|
<!-- 2026-11:原 sendlimit* 复用列(入院/在院维度),仅出院随访会填值 -->
|
<if test="hospitaldistrictcode != null and hospitaldistrictcode != ''">#{hospitaldistrictcode},</if>
|
<if test="hospitaldistrictname != null and hospitaldistrictname != ''">#{hospitaldistrictname},</if>
|
<if test="deptcode != null and deptcode != ''">#{deptcode},</if>
|
<if test="deptname != null and deptname != ''">#{deptname},</if>
|
<if test="importanceFlagCode != null and importanceFlagCode != ''">#{importanceFlagCode},</if>
|
<if test="labelstatus != null">#{labelstatus},</if>
|
<if test="updateBy != null">#{updateBy},</if>
|
<if test="updateTime != null">#{updateTime},</if>
|
<if test="createBy != null">#{createBy},</if>
|
<if test="createTime != null">#{createTime},</if>
|
<if test="isupload != null">#{isupload},</if>
|
<if test="uploadTime != null">#{uploadTime},</if>
|
<if test="orgid != null and orgid != ''">#{orgid},</if>
|
<if test="campusid != null and campusid != ''">#{campusid},</if>
|
<if test="pid != null">#{pid},</if>
|
<if test="guid != null">#{guid},</if>
|
<if test="textParam != null">#{textParam},</if>
|
<if test="preachform != null">#{preachform},</if>
|
<if test="bedNo != null">#{bedNo},</if>
|
<if test="sendType != null and sendType != ''">#{sendType},</if>
|
<if test="taskName != null and taskName != ''">#{taskName},</if>
|
<if test="taskDesc != null and taskDesc != ''">#{taskDesc},</if>
|
<if test="operator != null and operator != ''">#{operator},</if>
|
<if test="operatorNo != null and operatorNo != ''">#{operatorNo},</if>
|
<if test="hospType != null and hospType != ''">#{hospType},</if>
|
<if test="hospno != null and hospno != ''">#{hospno},</if>
|
<if test="wechat != null and wechat != ''">#{wechat},</if>
|
<if test="roomno != null and roomno != ''">#{roomno},</if>
|
<if test="admindate != null ">#{admindate},</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">#{leaveldeptname},</if>
|
<if test="leaveicd10code != null and leaveicd10code != ''">#{leaveicd10code},</if>
|
<if test="leavediagname != null and leavediagname != ''">#{leavediagname},</if>
|
<if test="diagname != null and diagname != ''">#{diagname},</if>
|
<if test="libtemplateid != null ">#{libtemplateid},</if>
|
<if test="libtemplatename != null ">#{libtemplatename},</if>
|
<if test="patid != null ">#{patid},</if>
|
<if test="openid != null ">#{openid},</if>
|
<if test="longSendTime != null ">#{longSendTime},</if>
|
<if test="serviceType != null ">#{serviceType},</if>
|
<if test="score != null ">#{score},</if>
|
<if test="submit != null ">#{submit},</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">
|
#{leavehospitaldistrictcode},
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">
|
#{leavehospitaldistrictname},
|
</if>
|
<if test="drname != null ">#{drname},</if>
|
<if test="drcode != null ">#{drcode},</if>
|
<if test="endtime != null ">#{endtime},</if>
|
<if test="starttime != null ">#{starttime},</if>
|
<if test="excep != null ">#{excep},</if>
|
<if test="nurseName != null ">#{nurseName},</if>
|
<if test="nurseId != null ">#{nurseId},</if>
|
<if test="remark != null ">#{remark},</if>
|
<if test="doctorOpinion != null ">#{doctorOpinion},</if>
|
<if test="suggest != null ">#{suggest},</if>
|
<if test="sendstate != null ">#{sendstate},</if>
|
<if test="inhospid != null ">#{inhospid},</if>
|
<if test="patfrom != null ">#{patfrom},</if>
|
<if test="taskGuid != null ">#{taskGuid},</if>
|
<if test="patguid != null ">#{patguid},</if>
|
<if test="visitCount != null ">#{visitCount},</if>
|
<if test="isVisitAgain != null ">#{isVisitAgain},</if>
|
<if test="upid != null ">#{upid},</if>
|
<if test="visitTime != null ">#{visitTime},</if>
|
<if test="visitDeptCode != null">#{visitDeptCode},</if>
|
<if test="visitDeptName != null">#{visitDeptName},</if>
|
<if test="managementDoctorCode != null">#{managementDoctorCode},</if>
|
<if test="managementDoctor != null">#{managementDoctor},</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">#{currentPreachform},</if>
|
<if test="taskSituation != null">#{taskSituation},</if>
|
<if test="isabnormal != null">#{isabnormal},</if>
|
<if test="continueFlag != null ">#{continueFlag},</if>
|
<if test="continueTimeNow != null ">#{continueTimeNow,jdbcType=TIMESTAMP},</if>
|
<if test="continueCount != null ">#{continueCount},</if>
|
<if test="continueTimeNext != null ">#{continueTimeNext,jdbcType=TIMESTAMP},</if>
|
<if test="continueContent != null ">#{continueContent},</if>
|
<if test="operationItemId != null ">#{operationItemId},</if>
|
<if test="scheduleId != null ">#{scheduleId},</if>
|
<if test="scheduleDetailId != null ">#{scheduleDetailId},</if>
|
<if test="scheduleSeq != null ">#{scheduleSeq},</if>
|
<if test="loopCount != null ">#{loopCount},</if>
|
<if test="isManuallyCalled != null ">#{isManuallyCalled},</if>
|
</trim>
|
</insert>
|
|
<!-- 二次随访幂等:仅当 is_visit_again 不是目标值时更新,返回受影响行数 -->
|
<update id="updateIsVisitAgainById">
|
update service_subtask
|
set is_visit_again = #{isVisitAgain},
|
update_time = now()
|
where id = #{id}
|
and (is_visit_again is null or is_visit_again <> #{isVisitAgain})
|
</update>
|
|
<update id="updateServiceSubtask" parameterType="com.ruoyi.task.domain.ServiceSubtask">
|
update service_subtask
|
<trim prefix="SET" suffixOverrides=",">
|
<if test="sendname != null">sendname = #{sendname},</if>
|
<if test="phone != null">phone = #{phone},</if>
|
<if test="sex != null">sex = #{sex},</if>
|
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
<if test="age != null">age = #{age},</if>
|
<if test="sfzh != null">sfzh = #{sfzh},</if>
|
<if test="addr != null">addr = #{addr},</if>
|
<if test="senderdetail != null">senderdetail = #{senderdetail},</if>
|
<if test="type != null">type = #{type},</if>
|
<if test="taskid != null">taskid = #{taskid},</if>
|
<if test="templateid != null">templateid = #{templateid},</if>
|
<if test="templatename != null">templatename = #{templatename},</if>
|
<if test="senddate != null">senddate = #{senddate},</if>
|
<if test="senduuid != null">senduuid = #{senduuid},</if>
|
<if test="result != null">result = #{result},</if>
|
<if test="finishtime != null">finishtime = #{finishtime},</if>
|
<if test="recordid != null">recordid = #{recordid},</if>
|
<if test="exrecallcount != null">exrecallcount = #{exrecallcount},</if>
|
<if test="pulltime != null">pulltime = #{pulltime},</if>
|
<if test="leaveldeptcode != null">leaveldeptcode = #{leaveldeptcode},</if>
|
<if test="labelstatus != null">labelstatus = #{labelstatus},</if>
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
<if test="createBy != null">create_by = #{createBy},</if>
|
<if test="createTime != null">create_time = #{createTime},</if>
|
<if test="isupload != null">isupload = #{isupload},</if>
|
<if test="uploadTime != null">upload_time = #{uploadTime},</if>
|
<if test="orgid != null and orgid != ''">orgid = #{orgid},</if>
|
<if test="campusid != null and campusid != ''">campusid = #{campusid},</if>
|
<if test="pid != null">pid = #{pid},</if>
|
<if test="guid != null">guid = #{guid},</if>
|
<if test="textParam != null">text_param = #{textParam},</if>
|
<if test="preachform != null">preachform = #{preachform},</if>
|
<if test="bedNo != null">bed_no = #{bedNo},</if>
|
<if test="sendType != null and sendType != ''">send_type = #{sendType},</if>
|
<if test="taskName != null and taskName != ''">task_name = #{taskName},</if>
|
<if test="taskDesc != null and taskDesc != ''">task_desc = #{taskDesc},</if>
|
<if test="operatorNo != null and operatorNo != ''">operator_no = #{operatorNo},</if>
|
<if test="operator != null and operator != ''">operator = #{operator},</if>
|
<if test="hospType != null and hospType != ''">hosp_type = #{hospType},</if>
|
<if test="hospno != null and hospno != ''">hospno = #{hospno},</if>
|
<if test="wechat != null and wechat != ''">wechat = #{wechat},</if>
|
<if test="roomno != null and roomno != ''">roomno = #{roomno},</if>
|
<if test="admindate != null ">admindate = #{admindate},</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">leaveldeptname = #{leaveldeptname},</if>
|
<if test="leaveicd10code != null and leaveicd10code != ''">leaveicd10code = #{leaveicd10code},</if>
|
<if test="leavediagname != null and leavediagname != ''">leavediagname = #{leavediagname},</if>
|
<if test="libtemplateid != null ">libtemplateid = #{libtemplateid},</if>
|
<if test="libtemplatename != null ">libtemplatename = #{libtemplatename},</if>
|
<if test="patid != null ">patid = #{patid},</if>
|
<if test="openid != null ">openid = #{openid},</if>
|
<if test="longSendTime != null ">long_send_time = #{longSendTime},</if>
|
<if test="sendstate != null ">sendstate = #{sendstate},</if>
|
<if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
|
<if test="serviceType != null ">service_type = #{serviceType},</if>
|
<if test="score != null ">score = #{score},</if>
|
<if test="submit != null ">submit = #{submit},</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">leavehospitaldistrictcode
|
= #{leavehospitaldistrictcode},
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">leavehospitaldistrictname
|
= #{leavehospitaldistrictname},
|
</if>
|
<if test="drname != null ">drname = #{drname},</if>
|
<if test="drcode != null ">drcode = #{drcode},</if>
|
<if test="starttime != null ">starttime = #{starttime},</if>
|
<if test="endtime != null ">endtime = #{endtime},</if>
|
<if test="excep != null ">excep = #{excep},</if>
|
<if test="nurseName != null ">nurse_name=#{nurseName},</if>
|
<if test="nurseId != null ">nurse_id=#{nurseId},</if>
|
<if test="remark != null ">remark=#{remark},</if>
|
<if test="doctorOpinion != null ">doctor_opinion=#{doctorOpinion},</if>
|
<if test="suggest != null ">suggest=#{suggest},</if>
|
<if test="inhospid != null ">inhospid=#{inhospid},</if>
|
<if test="patfrom != null ">patfrom=#{patfrom},</if>
|
<if test="taskGuid != null ">task_guid=#{taskGuid},</if>
|
<if test="patguid != null ">patguid=#{patguid},</if>
|
<if test="visitCount != null ">visit_count=#{visitCount},</if>
|
<if test="isVisitAgain != null ">is_visit_again=#{isVisitAgain},</if>
|
<if test="upid != null ">upid=#{upid},</if>
|
<if test="visitTime != null ">visit_time=#{visitTime},</if>
|
<if test="visitDeptCode != null">visit_dept_code = #{visitDeptCode},</if>
|
<if test="visitDeptName != null">visit_dept_name = #{visitDeptName},</if>
|
<if test="managementDoctorCode != null">management_doctor_code = #{managementDoctorCode},</if>
|
<if test="managementDoctor != null">management_doctor=#{managementDoctor},</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">current_preachform=#{currentPreachform},</if>
|
<if test="taskSituation != null">task_situation=#{taskSituation},</if>
|
<if test="isabnormal != null">isabnormal=#{isabnormal},</if>
|
<if test="continueFlag != null ">continue_flag = #{continueFlag},</if>
|
<if test="continueTimeNow != null ">continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP},</if>
|
<if test="continueCount != null ">continue_count = #{continueCount},</if>
|
<if test="continueTimeNext != null ">continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP},</if>
|
<if test="continueContent != null ">continue_content = #{continueContent},</if>
|
<if test="operationItemId != null ">operation_item_id = #{operationItemId},</if>
|
<if test="scheduleId != null ">schedule_id = #{scheduleId},</if>
|
<if test="scheduleDetailId != null ">schedule_detail_id = #{scheduleDetailId},</if>
|
<if test="scheduleSeq != null ">schedule_seq = #{scheduleSeq},</if>
|
<if test="loopCount != null ">loop_count = #{loopCount},</if>
|
<if test="isManuallyCalled != null ">is_manually_called = #{isManuallyCalled},</if>
|
</trim>
|
where id = #{id}
|
</update>
|
|
<!-- 微信公众号已领取未填写按默认选项完成:只更新当前子任务。
|
条件 sendstate=1 + 未提交,保证只处理当前被领取且未填写的子任务,不波及其他任务。 -->
|
<update id="updateWechatDefaultComplete" parameterType="com.ruoyi.task.domain.ServiceSubtask">
|
update service_subtask
|
set sendstate = 6,
|
finishtime = #{finishtime},
|
result = #{result},
|
remark = case
|
when remark is null or remark = '' then #{remark}
|
else concat(remark, ',', #{remark})
|
end,
|
update_time = now(),
|
finish_state = <include refid="finishStateExpr"/>
|
where id = #{id}
|
and orgid = #{orgid}
|
and sendstate = 1
|
and (submit is null or submit != 1)
|
</update>
|
|
<update id="updateServiceSubtaskByPatId" parameterType="com.ruoyi.task.domain.ServiceSubtask">
|
update service_subtask
|
<trim prefix="SET" suffixOverrides=",">
|
<if test="sendname != null">sendname = #{sendname},</if>
|
<if test="phone != null">phone = #{phone},</if>
|
<if test="sex != null">sex = #{sex},</if>
|
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
<if test="age != null">age = #{age},</if>
|
<if test="sfzh != null">sfzh = #{sfzh},</if>
|
<if test="addr != null">addr = #{addr},</if>
|
<if test="senderdetail != null">senderdetail = #{senderdetail},</if>
|
<if test="type != null">type = #{type},</if>
|
<if test="taskid != null">taskid = #{taskid},</if>
|
<if test="templateid != null">templateid = #{templateid},</if>
|
<if test="templatename != null">templatename = #{templatename},</if>
|
<if test="senddate != null">senddate = #{senddate},</if>
|
<if test="senduuid != null">senduuid = #{senduuid},</if>
|
<if test="result != null">result = #{result},</if>
|
<if test="finishtime != null">finishtime = #{finishtime},</if>
|
<if test="recordid != null">recordid = #{recordid},</if>
|
<if test="exrecallcount != null">exrecallcount = #{exrecallcount},</if>
|
<if test="pulltime != null">pulltime = #{pulltime},</if>
|
<if test="leaveldeptcode != null">leaveldeptcode = #{leaveldeptcode},</if>
|
<if test="labelstatus != null">labelstatus = #{labelstatus},</if>
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
<if test="createBy != null">create_by = #{createBy},</if>
|
<if test="createTime != null">create_time = #{createTime},</if>
|
<if test="isupload != null">isupload = #{isupload},</if>
|
<if test="uploadTime != null">upload_time = #{uploadTime},</if>
|
<if test="orgid != null and orgid != ''">orgid = #{orgid},</if>
|
<if test="campusid != null and campusid != ''">campusid = #{campusid},</if>
|
<if test="pid != null">pid = #{pid},</if>
|
<if test="guid != null">guid = #{guid},</if>
|
<if test="textParam != null">text_param = #{textParam},</if>
|
<if test="preachform != null">preachform = #{preachform},</if>
|
<if test="bedNo != null">bed_no = #{bedNo},</if>
|
<if test="sendType != null and sendType != ''">send_type = #{sendType},</if>
|
<if test="taskName != null and taskName != ''">task_name = #{taskName},</if>
|
<if test="taskDesc != null and taskDesc != ''">task_desc = #{taskDesc},</if>
|
<if test="operatorNo != null and operatorNo != ''">operator_no = #{operatorNo},</if>
|
<if test="operator != null and operator != ''">operator = #{operator},</if>
|
<if test="hospType != null and hospType != ''">hosp_type = #{hospType},</if>
|
<if test="hospno != null and hospno != ''">hospno = #{hospno},</if>
|
<if test="wechat != null and wechat != ''">wechat = #{wechat},</if>
|
<if test="roomno != null and roomno != ''">roomno = #{roomno},</if>
|
<if test="admindate != null">admindate = #{admindate},</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">leaveldeptname = #{leaveldeptname},</if>
|
<if test="leaveicd10code != null and leaveicd10code != ''">leaveicd10code = #{leaveicd10code},</if>
|
<if test="leavediagname != null and leavediagname != ''">leavediagname = #{leavediagname},</if>
|
<if test="libtemplateid != null ">libtemplateid = #{libtemplateid},</if>
|
<if test="libtemplatename != null ">libtemplatename = #{libtemplatename},</if>
|
<if test="patid != null ">patid = #{patid},</if>
|
<if test="openid != null ">openid = #{openid},</if>
|
<if test="longSendTime != null ">long_send_time = #{longSendTime},</if>
|
<if test="sendstate != null ">sendstate = #{sendstate},</if>
|
<if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
|
<if test="serviceType != null ">service_type = #{serviceType},</if>
|
<if test="score != null ">score = #{score},</if>
|
<if test="visitCount != null ">visit_count = #{visitCount},</if>
|
<if test="submit != null ">submit = #{submit},</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">leavehospitaldistrictcode
|
= #{leavehospitaldistrictcode},
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">leavehospitaldistrictname
|
= #{leavehospitaldistrictname},
|
</if>
|
<if test="drname != null ">drname = #{drname},</if>
|
<if test="drcode != null ">drcode = #{drcode},</if>
|
<if test="starttime != null ">starttime = #{starttime},</if>
|
<if test="endtime != null ">endtime = #{endtime},</if>
|
<if test="excep != null ">excep = #{excep},</if>
|
<if test="nurseName != null ">nurse_name=#{nurseName},</if>
|
<if test="nurseId != null ">nurse_id=#{nurseId},</if>
|
<if test="remark != null ">remark=#{remark},</if>
|
<if test="doctorOpinion != null ">doctor_opinion=#{doctorOpinion},</if>
|
<if test="suggest != null ">suggest=#{suggest},</if>
|
<if test="inhospid != null ">inhospid=#{inhospid},</if>
|
<if test="patfrom != null ">patfrom=#{patfrom},</if>
|
<if test="taskGuid != null ">taskGuid=#{taskGuid},</if>
|
<if test="patguid != null ">patguid=#{patguid},</if>
|
<if test="isVisitAgain != null ">is_visit_again=#{isVisitAgain},</if>
|
<if test="upid != null ">upid=#{upid},</if>
|
<if test="visitTime != null ">visit_time=#{visitTime},</if>
|
<if test="visitDeptCode != null">visit_dept_code = #{visitDeptCode},</if>
|
<if test="visitDeptName != null">visit_dept_name = #{visitDeptName},</if>
|
<if test="managementDoctorCode != null">management_doctor_code = #{managementDoctorCode},</if>
|
<if test="managementDoctor != null">management_doctor=#{managementDoctor},</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">current_preachform=#{currentPreachform},</if>
|
<if test="taskSituation != null">task_situation=#{taskSituation},</if>
|
<if test="isabnormal != null">isabnormal=#{isabnormal},</if>
|
<if test="continueFlag != null ">continue_flag = #{continueFlag},</if>
|
<if test="continueTimeNow != null ">continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP},</if>
|
<if test="continueCount != null ">continue_count = #{continueCount},</if>
|
<if test="continueTimeNext != null ">continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP},</if>
|
<if test="continueContent != null ">continue_content = #{continueContent},</if>
|
<if test="isManuallyCalled != null ">is_manually_called = #{isManuallyCalled},</if>
|
</trim>
|
where 1=1
|
<if test="patid != null ">and patid = #{patid}</if>
|
<if test="id != null ">and id = #{id}</if>
|
<if test="taskid != null ">and taskid = #{taskid}</if>
|
<if test="orgid != null and orgid != ''">and orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and campusid = #{campusid}</if>
|
</update>
|
|
<update id="updateServiceSubtaskByCondition" parameterType="com.ruoyi.task.domain.ServiceSubtask">
|
update service_subtask
|
<trim prefix="SET" suffixOverrides=",">
|
<if test="sendname != null">sendname = #{sendname},</if>
|
<if test="phone != null">phone = #{phone},</if>
|
<if test="sex != null">sex = #{sex},</if>
|
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
<if test="sendstate != null ">sendstate = #{sendstate},</if>
|
<if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
|
<if test="age != null">age = #{age},</if>
|
<if test="sfzh != null">sfzh = #{sfzh},</if>
|
<if test="addr != null">addr = #{addr},</if>
|
<if test="senderdetail != null">senderdetail = #{senderdetail},</if>
|
<if test="type != null">type = #{type},</if>
|
<if test="taskid != null">taskid = #{taskid},</if>
|
<if test="templateid != null">templateid = #{templateid},</if>
|
<if test="templatename != null">templatename = #{templatename},</if>
|
<if test="senddate != null">senddate = #{senddate},</if>
|
<if test="senduuid != null">senduuid = #{senduuid},</if>
|
<if test="result != null">result = #{result},</if>
|
<if test="finishtime != null">finishtime = #{finishtime},</if>
|
<if test="recordid != null">recordid = #{recordid},</if>
|
<if test="exrecallcount != null">exrecallcount = #{exrecallcount},</if>
|
<if test="pulltime != null">pulltime = #{pulltime},</if>
|
<if test="leaveldeptcode != null">leaveldeptcode = #{leaveldeptcode},</if>
|
<if test="labelstatus != null">labelstatus = #{labelstatus},</if>
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
<if test="createBy != null">create_by = #{createBy},</if>
|
<if test="createTime != null">create_time = #{createTime},</if>
|
<if test="isupload != null">isupload = #{isupload},</if>
|
<if test="uploadTime != null">upload_time = #{uploadTime},</if>
|
<if test="orgid != null and orgid != ''">orgid = #{orgid},</if>
|
<if test="campusid != null and campusid != ''">campusid = #{campusid},</if>
|
<if test="pid != null">pid = #{pid},</if>
|
<if test="guid != null">guid = #{guid},</if>
|
<if test="visitCount != null">visit_count = #{visitCount},</if>
|
<if test="isVisitAgain != null">is_visit_again = #{isVisitAgain},</if>
|
<if test="textParam != null">text_param = #{textParam},</if>
|
<if test="preachform != null">preachform = #{preachform},</if>
|
<if test="bedNo != null">bed_no = #{bedNo},</if>
|
<if test="sendType != null and sendType != ''">send_type = #{sendType},</if>
|
<if test="taskName != null and taskName != ''">task_name = #{taskName},</if>
|
<if test="taskDesc != null and taskDesc != ''">task_desc = #{taskDesc},</if>
|
<if test="operatorNo != null and operatorNo != ''">operator_no = #{operatorNo},</if>
|
<if test="operator != null and operator != ''">operator = #{operator},</if>
|
<if test="hospType != null and hospType != ''">hosp_type = #{hospType},</if>
|
<if test="hospno != null and hospno != ''">hospno = #{hospno},</if>
|
<if test="wechat != null and wechat != ''">wechat = #{wechat},</if>
|
<if test="roomno != null and roomno != ''">roomno = #{roomno},</if>
|
<if test="admindate != null">admindate = #{admindate},</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">leaveldeptname = #{leaveldeptname},</if>
|
<if test="leaveicd10code != null and leaveicd10code != ''">leaveicd10code = #{leaveicd10code},</if>
|
<if test="leavediagname != null and leavediagname != ''">leavediagname = #{leavediagname},</if>
|
<if test="libtemplateid != null ">libtemplateid = #{libtemplateid},</if>
|
<if test="libtemplatename != null ">libtemplatename = #{libtemplatename},</if>
|
<if test="patid != null ">patid = #{patid},</if>
|
<if test="openid != null ">openid = #{openid},</if>
|
<if test="longSendTime != null ">long_send_time = #{longSendTime},</if>
|
<if test="serviceType != null ">service_type = #{serviceType},</if>
|
<if test="score != null ">score = #{score},</if>
|
<if test="submit != null ">submit = #{submit},</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">leavehospitaldistrictcode
|
= #{leavehospitaldistrictcode},
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">leavehospitaldistrictname
|
= #{leavehospitaldistrictname},
|
</if>
|
<if test="drname != null ">drname = #{drname},</if>
|
<if test="drcode != null ">drcode = #{drcode},</if>
|
<if test="endtime != null ">endtime = #{endtime},</if>
|
<if test="starttime != null ">starttime = #{starttime},</if>
|
<if test="excep != null ">excep = #{excep},</if>
|
<if test="nurseName != null ">nurse_name=#{nurseName},</if>
|
<if test="nurseId != null ">nurse_id=#{nurseId},</if>
|
<if test="remark != null ">remark=#{remark},</if>
|
<if test="doctorOpinion != null ">doctor_opinion=#{doctorOpinion},</if>
|
<if test="suggest != null ">suggest=#{suggest},</if>
|
<if test="inhospid != null ">inhospid=#{inhospid},</if>
|
<if test="patfrom != null ">patfrom=#{patfrom},</if>
|
<if test="taskGuid != null ">task_guid=#{taskGuid},</if>
|
<if test="patguid != null ">patguid=#{patguid},</if>
|
<if test="upid != null ">upid=#{upid},</if>
|
<if test="visitTime != null ">visit_time=#{visitTime},</if>
|
<if test="visitDeptCode != null">visit_dept_code = #{visitDeptCode},</if>
|
<if test="visitDeptName != null">visit_dept_name = #{visitDeptName},</if>
|
<if test="managementDoctorCode != null">management_doctor_code = #{managementDoctorCode},</if>
|
<if test="managementDoctor != null">management_doctor=#{managementDoctor},</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">current_preachform=#{currentPreachform},</if>
|
<if test="taskSituation != null">task_situation=#{taskSituation},</if>
|
<if test="isabnormal != null">isabnormal=#{isabnormal},</if>
|
<if test="continueFlag != null ">continue_flag = #{continueFlag},</if>
|
<if test="continueTimeNow != null ">continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP},</if>
|
<if test="continueCount != null ">continue_count = #{continueCount},</if>
|
<if test="continueTimeNext != null ">continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP},</if>
|
<if test="continueContent != null ">continue_content = #{continueContent},</if>
|
<if test="isManuallyCalled != null ">is_manually_called = #{isManuallyCalled},</if>
|
</trim>
|
<where>
|
<if test="patid != null ">
|
patid = #{patid}
|
</if>
|
<if test="taskid != null ">
|
and taskid = #{taskid}
|
</if>
|
<if test="id != null ">
|
and id = #{id}
|
</if>
|
<if test="inhospid != null ">
|
and inhospid = #{inhospid}
|
</if>
|
</where>
|
</update>
|
|
<update id="updateServiceSubtaskByTaskGuid" parameterType="com.ruoyi.task.domain.ServiceSubtask">
|
update service_subtask
|
<trim prefix="SET" suffixOverrides=",">
|
<if test="sendname != null">sendname = #{sendname},</if>
|
<if test="phone != null">phone = #{phone},</if>
|
<if test="sex != null">sex = #{sex},</if>
|
<if test="sendstate != null ">sendstate = #{sendstate},</if>
|
<if test="sendstate != null and sendstate == 6">finish_state = <include refid="finishStateExpr"/>,</if>
|
<if test="age != null">age = #{age},</if>
|
<if test="sfzh != null">sfzh = #{sfzh},</if>
|
<if test="addr != null">addr = #{addr},</if>
|
<if test="senderdetail != null">senderdetail = #{senderdetail},</if>
|
<if test="type != null">type = #{type},</if>
|
<if test="taskid != null">taskid = #{taskid},</if>
|
<if test="templateid != null">templateid = #{templateid},</if>
|
<if test="templatename != null">templatename = #{templatename},</if>
|
<if test="senddate != null">senddate = #{senddate},</if>
|
<if test="senduuid != null">senduuid = #{senduuid},</if>
|
<if test="result != null">result = #{result},</if>
|
<if test="finishtime != null">finishtime = #{finishtime},</if>
|
<if test="recordid != null">recordid = #{recordid},</if>
|
<if test="exrecallcount != null">exrecallcount = #{exrecallcount},</if>
|
<if test="pulltime != null">pulltime = #{pulltime},</if>
|
<if test="leaveldeptcode != null">leaveldeptcode = #{leaveldeptcode},</if>
|
<if test="labelstatus != null">labelstatus = #{labelstatus},</if>
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
<if test="createBy != null">create_by = #{createBy},</if>
|
<if test="createTime != null">create_time = #{createTime},</if>
|
<if test="isupload != null">isupload = #{isupload},</if>
|
<if test="uploadTime != null">upload_time = #{uploadTime},</if>
|
<if test="orgid != null and orgid != ''">orgid = #{orgid},</if>
|
<if test="campusid != null and campusid != ''">campusid = #{campusid},</if>
|
<if test="pid != null">pid = #{pid},</if>
|
<if test="guid != null">guid = #{guid},</if>
|
<if test="textParam != null">text_param = #{textParam},</if>
|
<if test="preachform != null">preachform = #{preachform},</if>
|
<if test="bedNo != null">bed_no = #{bedNo},</if>
|
<if test="sendType != null and sendType != ''">send_type = #{sendType},</if>
|
<if test="taskName != null and taskName != ''">task_name = #{taskName},</if>
|
<if test="taskDesc != null and taskDesc != ''">task_desc = #{taskDesc},</if>
|
<if test="operatorNo != null and operatorNo != ''">operator_no = #{operatorNo},</if>
|
<if test="operator != null and operator != ''">operator = #{operator},</if>
|
<if test="hospType != null and hospType != ''">hosp_type = #{hospType},</if>
|
<if test="hospno != null and hospno != ''">hospno = #{hospno},</if>
|
<if test="wechat != null and wechat != ''">wechat = #{wechat},</if>
|
<if test="roomno != null and roomno != ''">roomno = #{roomno},</if>
|
<if test="admindate != null ">admindate = #{admindate},</if>
|
<if test="visitCount != null ">visit_count = #{visitCount},</if>
|
<if test="isVisitAgain != null ">is_visit_again = #{isVisitAgain},</if>
|
<if test="leaveldeptname != null and leaveldeptname != ''">leaveldeptname = #{leaveldeptname},</if>
|
<if test="leaveicd10code != null and leaveicd10code != ''">leaveicd10code = #{leaveicd10code},</if>
|
<if test="leavediagname != null and leavediagname != ''">leavediagname = #{leavediagname},</if>
|
<if test="libtemplateid != null ">libtemplateid = #{libtemplateid},</if>
|
<if test="libtemplatename != null ">libtemplatename = #{libtemplatename},</if>
|
<if test="patid != null ">patid = #{patid},</if>
|
<if test="openid != null ">openid = #{openid},</if>
|
<if test="longSendTime != null ">long_send_time = #{longSendTime},</if>
|
<if test="serviceType != null ">service_type = #{serviceType},</if>
|
<if test="score != null ">score = #{score},</if>
|
<if test="submit != null ">submit = #{submit},</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">leavehospitaldistrictcode
|
= #{leavehospitaldistrictcode},
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">leavehospitaldistrictname
|
= #{leavehospitaldistrictname},
|
</if>
|
<if test="drname != null ">drname = #{drname},</if>
|
<if test="drcode != null ">drcode = #{drcode},</if>
|
<if test="endtime != null ">endtime = #{endtime},</if>
|
<if test="starttime != null ">starttime = #{starttime},</if>
|
<if test="excep != null ">excep = #{excep},</if>
|
<if test="nurseName != null ">nurse_name=#{nurseName},</if>
|
<if test="nurseId != null ">nurse_id=#{nurseId},</if>
|
<if test="remark != null ">remark=#{remark},</if>
|
<if test="doctorOpinion != null ">doctor_opinion=#{doctorOpinion},</if>
|
<if test="suggest != null ">suggest=#{suggest},</if>
|
<if test="inhospid != null ">inhospid=#{inhospid},</if>
|
<if test="patfrom != null ">patfrom=#{patfrom},</if>
|
<if test="taskGuid != null ">task_guid=#{taskGuid},</if>
|
<if test="patguid != null ">patguid=#{patguid},</if>
|
<if test="upid != null ">upid=#{upid},</if>
|
<if test="visitTime != null ">visit_time=#{visitTime},</if>
|
<if test="visitDeptCode != null">visit_dept_code = #{visitDeptCode},</if>
|
<if test="visitDeptName != null">visit_dept_name = #{visitDeptName},</if>
|
<if test="managementDoctorCode != null">management_doctor_code = #{managementDoctorCode},</if>
|
<if test="managementDoctor != null">management_doctor=#{managementDoctor},</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">current_preachform=#{currentPreachform},</if>
|
<if test="taskSituation != null">task_situation=#{taskSituation},</if>
|
<if test="isabnormal != null">isabnormal=#{isabnormal},</if>
|
<if test="continueFlag != null ">continue_flag = #{continueFlag},</if>
|
<if test="continueTimeNow != null ">continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP},</if>
|
<if test="continueCount != null ">continue_count = #{continueCount},</if>
|
<if test="continueTimeNext != null ">continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP},</if>
|
<if test="continueContent != null ">continue_content = #{continueContent},</if>
|
<if test="isManuallyCalled != null ">is_manually_called = #{isManuallyCalled},</if>
|
</trim>
|
where task_guid = #{taskGuid} and task_name = #{taskName}
|
</update>
|
|
<update id="deleteServiceSubtaskById" parameterType="Long">
|
update service_subtask
|
<trim prefix="SET" suffixOverrides=",">
|
del_flag =1
|
</trim>
|
where id = #{id}
|
</update>
|
|
<update id="deleteServiceSubtaskByCondition">
|
update service_subtask
|
<trim prefix="SET" suffixOverrides=",">
|
del_flag =1
|
</trim>
|
where patid = #{patid} and taskid = #{taskid}
|
</update>
|
|
<!-- 人工随访:软删除患者出院记录对应的未完成随访任务 -->
|
<update id="deleteUnfinishedServiceSubtaskByInhospids">
|
update service_subtask
|
set del_flag = 1
|
where del_flag = 0
|
and patid = #{patid}
|
and sendstate in
|
<foreach collection="sendstates" item="sendstate" open="(" separator="," close=")">
|
#{sendstate}
|
</foreach>
|
and inhospid in
|
<foreach collection="inhospids" item="inhospid" open="(" separator="," close=")">
|
#{inhospid}
|
</foreach>
|
</update>
|
|
<!-- 人工随访重复校验:同一患者同一任务下是否已有未完成随访任务 -->
|
<select id="countUnfinishedServiceSubtaskByPatidAndTaskid" resultType="int">
|
select count(1)
|
from service_subtask
|
where del_flag = 0
|
and patid = #{patid}
|
and taskid = #{taskid}
|
and sendstate in
|
<foreach collection="sendstates" item="sendstate" open="(" separator="," close=")">
|
#{sendstate}
|
</foreach>
|
</select>
|
|
<select id="getSfStatistics" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult">
|
select id,
|
visit_count,
|
is_visit_again,
|
type,
|
orgid,
|
drcode,
|
drname,
|
management_doctor_code,
|
management_doctor,
|
leavehospitaldistrictcode,
|
leavehospitaldistrictname,
|
leaveldeptcode,
|
leaveldeptname,
|
sendstate,
|
preachform,
|
<include refid="effectiveCurrentPreachformExpr"/> AS current_preachform,
|
excep,
|
nurse_id,
|
nurse_name,
|
taskid,
|
task_name,
|
<if test="groupKey != null and groupKey == 'taskid'">
|
(SELECT st.diag_type FROM service_task st WHERE st.taskid = service_subtask.taskid LIMIT 1) AS diag_type,
|
</if>
|
visit_time,
|
visit_dept_code,
|
finishtime,
|
endtime,
|
senddate,
|
suggest,
|
result,
|
templateid,
|
templatename,
|
patid,
|
sendname,
|
send_type,
|
recordid,
|
exrecallcount,
|
continue_flag,
|
continue_time_now,
|
continue_content,
|
continue_count,
|
continue_time_next,
|
task_situation,
|
finish_state,
|
is_manually_called
|
from service_subtask
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<!-- 2026-10-21:病区为空时视为"不限"
|
南华满意度子任务的 leavehospitaldistrictcode 有 83%(3236/3811)为 NULL,
|
原来「科室 AND 病区」两个条件永远不可能同时成立 → 整张统计表空。
|
判空放行只影响病区为空的记录,有病区的数据行为不变。 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="taskIds != null and taskIds.size() > 0">
|
AND taskid IN
|
<foreach collection="taskIds" item="taskId" open="(" separator=","
|
close=")">
|
#{taskId}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<!-- 2026-10-21:visit_time 为空(南华满意度 3811/3811 全为 NULL)时按完成/创建时间兜底 -->
|
<if test="startTime != null and endTime!=null">
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) >= DATE(#{startTime})
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="hospitalStartTime != null and hospitalEndTime!=null">
|
AND endtime >= DATE(#{hospitalStartTime})
|
AND endtime < DATE_ADD(DATE(#{hospitalEndTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP}</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and type = #{type}
|
</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND visit_count > 1
|
</if>
|
<if test="groupKey != null and groupKey != '' and groupKeyList != null and groupKeyList.size>0">
|
AND IFNULL(${groupKey}, 'Unknown') IN
|
<foreach collection="groupKeyList" item="key" open="(" separator=","
|
close=")">
|
#{key}
|
</foreach>
|
</if>
|
</select>
|
|
<select id="getSpecialSfStatistics" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskStatisticResult">
|
select
|
<if test="groupKey != null and groupKey == 'task_name'">
|
a.task_name,
|
</if>
|
<if test="groupKey != null and groupKey == 'drcode'">
|
b.drcode,
|
b.drname,
|
</if>
|
COUNT(1) AS discharge_count,
|
SUM(CASE WHEN b.sendstate = 4 THEN 1 ELSE 0 END) AS non_follow_up,
|
SUM(CASE WHEN b.sendstate = 4 and b.task_situation = 6 THEN 1 ELSE 0 END) AS filter_count,
|
SUM(CASE WHEN b.sendstate != 4 THEN 1 ELSE 0 END) AS follow_up_needed,
|
SUM(CASE WHEN b.sendstate != 4 THEN 1 ELSE 0 END) AS need_follow_up,
|
SUM(CASE WHEN b.sendstate = 2 THEN 1 ELSE 0 END) AS pending_follow_up,
|
SUM(CASE WHEN b.sendstate = 5 or b.sendstate = 7 THEN 1 ELSE 0 END) AS follow_up_fail,
|
SUM(CASE WHEN b.current_preachform = '1' THEN 1 ELSE 0 END) AS manual,
|
SUM(CASE WHEN b.current_preachform = '3' THEN 1 ELSE 0 END) AS voice,
|
SUM(CASE WHEN b.current_preachform = '4' THEN 1 ELSE 0 END) AS sms,
|
SUM(CASE WHEN b.current_preachform = '5' THEN 1 ELSE 0 END) AS we_chat,
|
SUM(CASE WHEN b.task_situation = 1 THEN 1 ELSE 0 END) AS task_situation1,
|
SUM(CASE WHEN b.task_situation = 2 THEN 1 ELSE 0 END) AS task_situation2,
|
SUM(CASE WHEN b.task_situation = 3 THEN 1 ELSE 0 END) AS task_situation3,
|
SUM(CASE WHEN b.task_situation = 4 THEN 1 ELSE 0 END) AS task_situation4,
|
SUM(CASE WHEN b.task_situation = 5 THEN 1 ELSE 0 END) AS task_situation5,
|
SUM(CASE WHEN b.task_situation = 7 THEN 1 ELSE 0 END) AS task_situation7
|
from service_task a
|
JOIN service_subtask b on a.taskid = b.taskid
|
where 1=1
|
and a.del_flag = '0'
|
and b.del_flag = '0'
|
and a.appltype = '3'
|
<if test="orgid != null and orgid != ''">and a.orgid = #{orgid}</if>
|
<if test="campusid != null and campusid != ''">and b.campusid = #{campusid}</if>
|
<if test="taskId != null">and a.task_id = #{taskId}</if>
|
<if test="taskName != null and taskName != ''">
|
and a.task_name like concat('%', #{taskName}, '%')
|
</if>
|
<if test="diagType != null and diagType != ''">
|
and a.diag_type = #{diagType}
|
</if>
|
<if test="taskIds != null and taskIds.size() > 0">
|
AND a.task_id IN
|
<foreach collection="taskIds" item="taskIdItem" open="(" separator=","
|
close=")">
|
#{taskIdItem}
|
</foreach>
|
</if>
|
<if test="taskNames != null and taskNames.size() > 0">
|
AND a.task_name IN
|
<foreach collection="taskNames" item="taskNameItem" open="(" separator=","
|
close=")">
|
#{taskNameItem}
|
</foreach>
|
</if>
|
<if test="diagTypes != null and diagTypes.size() > 0">
|
AND a.diag_type IN
|
<foreach collection="diagTypes" item="diagTypeItem" open="(" separator=","
|
close=")">
|
#{diagTypeItem}
|
</foreach>
|
</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="deptcodes != null and deptcodes.size() > 0">
|
AND b.leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND b.service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime!=null">
|
AND b.visit_time >= DATE(#{startTime})
|
AND b.visit_time < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="visitDeptCode != null">and b.visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and b.visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and b.isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and b.continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and b.continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and b.continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and b.continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP}</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and b.type = #{type}
|
</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND b.visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND b.visit_count > 1
|
</if>
|
<if test="groupKey != null and groupKey == 'task_name'">
|
GROUP BY a.task_name
|
</if>
|
<if test="groupKey != null and groupKey == 'drcode'">
|
GROUP BY b.drcode, b.drname
|
</if>
|
</select>
|
|
<select id="getSfStatisticsGroupKey" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultType="String">
|
select
|
<choose>
|
<when test="groupColumn != null and groupColumn != ''">
|
${groupColumn} as groupKey
|
</when>
|
<when test="groupKey != null and groupKey != ''">
|
${groupKey} as groupKey
|
</when>
|
<otherwise>
|
NULL as groupKey
|
</otherwise>
|
</choose>
|
from service_subtask
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<!-- 2026-10-21:病区为空时视为"不限"
|
南华满意度子任务的 leavehospitaldistrictcode 有 83%(3236/3811)为 NULL,
|
原来「科室 AND 病区」两个条件永远不可能同时成立 → 整张统计表空。
|
判空放行只影响病区为空的记录,有病区的数据行为不变。 -->
|
<choose>
|
<!-- 满意度统计(getSfStatisticsScript):改用“有效病区”列,
|
出院病区为空则回退到在院病区。筛选因此真正生效,
|
空病区的记录也会归到它真实的在院病区,而不是混进用户选中的病区。 -->
|
<when test="districtColumn != null and districtColumn != ''">
|
<!-- 出院病区为空回退到在院病区。这里刻意写成 OR 展开而不是 IFNULL(a,b) IN (...):
|
列被函数包住就用不了索引,56 万行明细表上是全表扫(实测 5.1s → 0.7s)。
|
两个分支分别命中 idx_ss_district_pair 的 (leave..., hospital...) 前缀。 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
OR (leavehospitaldistrictcode IS NULL AND hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
))
|
</if>
|
</when>
|
<otherwise>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
</otherwise>
|
</choose>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
|
close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND (hospitaldistrictcode IS NULL OR hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="hospitaldeptcodes != null and hospitaldeptcodes.size() > 0">
|
AND deptcode IN
|
<foreach collection="hospitaldeptcodes" item="hospitaldeptcode" open="(" separator=","
|
close=")">
|
#{hospitaldeptcode}
|
</foreach>
|
</if>
|
<if test="taskIds != null and taskIds.size() > 0">
|
AND taskid IN
|
<foreach collection="taskIds" item="taskId" open="(" separator=","
|
close=")">
|
#{taskId}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<!-- 2026-10-21:visit_time 为空(南华满意度 3811/3811 全为 NULL)时按完成/创建时间兜底 -->
|
<if test="startTime != null and endTime!=null">
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) >= DATE(#{startTime})
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="hospitalStartTime != null and hospitalEndTime!=null">
|
AND endtime >= DATE(#{hospitalStartTime})
|
AND endtime < DATE_ADD(DATE(#{hospitalEndTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP}</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and type = #{type}
|
</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND visit_count > 1
|
</if>
|
<choose>
|
<when test="groupColumn != null and groupColumn != ''">
|
group by ${groupColumn}
|
order by ${groupColumn}
|
</when>
|
<when test="groupKey != null and groupKey != ''">
|
group by ${groupKey}
|
order by ${groupKey}
|
</when>
|
</choose>
|
<!-- pageNum 是 1 起始的,OFFSET 必须用 (pageNum-1)*pageSize;
|
以前直接写 OFFSET ${pageNum},第一页会跳掉第一条分组。 -->
|
<if test="pageSize != null and pageNum != null">
|
limit ${pageSize} OFFSET ${pageOffset}
|
</if>
|
</select>
|
|
<!--
|
==================================================================
|
随访分类统计(/smartor/serviceSubtask/getSfStatisticsCount)性能优化
|
==================================================================
|
改造前:getSfStatisticsScript 先把 service_subtask 命中的**全部明细行**
|
(getSfStatistics 共 select 39 个字段,含 continue_content / result / suggest 等大字段)
|
捞回 JVM,再在内存里按 drcode/科室/病区 逐行 if 累加;此外还要把这次命中的
|
**全部子任务 id** 灌进 getSfStatisticsCategory 的 IN 列表再查一遍。
|
命中几千行时,网络传输(远端的库尤其明显)+ 内存遍历 + 超大 IN 列表就是接口慢的主因。
|
|
改造后:累加下推到数据库,一次 GROUP BY 只返回“分组数”(通常几十行)的统计结果;
|
满意度题目量也同样按分组在库里聚合。统计口径与原来的 getStatisticCategory 逐条对齐。
|
这两个语句的 where 条件与 getSfStatistics 保持一致,保证结果集不变。
|
|
分组列(2026-10 起):
|
离院维度 —— groupKey = leaveldeptcode / leavehospitaldistrictcode;
|
在院维度 —— groupKey = deptcode / hospitaldistrictcode;
|
过滤与分组使用同一列(groupColumn = groupKey),避免分组键与聚合行口径不一致。
|
==================================================================
|
-->
|
<resultMap type="com.ruoyi.task.domain.ServiceSubtaskStatistic" id="ServiceSubtaskScriptStatisticResult">
|
<result property="groupCode" column="group_code"/>
|
<result property="groupName" column="group_name"/>
|
<result property="taskId" column="taskid"/>
|
<result property="taskName" column="task_name"/>
|
<result property="dischargeCount" column="discharge_count"/>
|
<result property="firstVisitCount" column="first_visit_count"/>
|
<result property="againVisitCount" column="again_visit_count"/>
|
<result property="drcode" column="drcode"/>
|
<result property="drname" column="drname"/>
|
<result property="deptcode" column="deptcode"/>
|
<result property="deptname" column="deptname"/>
|
<result property="leavehospitaldistrictcode" column="leavehospitaldistrictcode"/>
|
<result property="leavehospitaldistrictname" column="leavehospitaldistrictname"/>
|
<result property="hospitaldistrictcode" column="hospitaldistrictcode"/>
|
<result property="hospitaldistrictname" column="hospitaldistrictname"/>
|
<result property="hospitaldeptcode" column="hospitaldeptcode"/>
|
<result property="hospitaldeptname" column="hospitaldeptname"/>
|
<result property="nonFollowUp" column="non_follow_up"/>
|
<result property="followUpNeeded" column="follow_up_needed"/>
|
<result property="needFollowUp" column="need_follow_up"/>
|
<result property="pendingFollowUp" column="pending_follow_up"/>
|
<result property="followUpSuccess" column="follow_up_success"/>
|
<result property="followUpFail" column="follow_up_fail"/>
|
<result property="manual" column="manual"/>
|
<result property="voice" column="voice"/>
|
<result property="sms" column="sms"/>
|
<result property="weChat" column="we_chat"/>
|
<result property="abnormal" column="abnormal"/>
|
<result property="needFollowUpAgain" column="need_follow_up_again"/>
|
<result property="pendingFollowUpAgain" column="pending_follow_up_again"/>
|
<result property="followUpSuccessAgain" column="follow_up_success_again"/>
|
<result property="followUpFailAgain" column="follow_up_fail_again"/>
|
<result property="manualAgain" column="manual_again"/>
|
<result property="voiceAgain" column="voice_again"/>
|
<result property="smsAgain" column="sms_again"/>
|
<result property="weChatAgain" column="we_chat_again"/>
|
<result property="abnormalAgain" column="abnormal_again"/>
|
</resultMap>
|
|
<!--
|
按分组聚合随访统计(替代“全量明细回内存再累加”)。
|
口径说明(与原 ServiceSubtaskServiceImpl.getStatisticCategory 完全一致):
|
* 无需随访:sendstate = 4
|
* 应随访:sendstate 非空且 != 4
|
* 首次(visit_count = 1) / 再次(visit_count > 1) 两个分支互斥,与原来的 if / else if 一致
|
* 人工/语音/短信/微信:首次分支**不**排除 sendstate = 4(原代码如此),再次分支同样
|
* 异常:excep = '1' 且 sendstate 非空
|
* 首次随访率 / 再次随访率在 Java 里按原公式(含原来的分母判断)计算
|
-->
|
<select id="getSfStatisticsScriptSum" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskScriptStatisticResult">
|
select
|
IFNULL(${groupColumn}, 'Unknown') as group_code,
|
<!-- 分组键对应的显示名:病区统计时就是这一组的病区名。
|
以前这一列是 MAX(hospitaldistrictname),一个组混了多个病区时会随机显示其中一个,
|
于是出现“选血液内科病区却显示骨科中心三病区”。 -->
|
<choose>
|
<when test="groupKey != null and groupKey == 'taskid'">
|
MAX(task_name) as group_name,
|
</when>
|
<otherwise>
|
MAX(IFNULL(leavehospitaldistrictname, hospitaldistrictname)) as group_name,
|
</otherwise>
|
</choose>
|
MAX(taskid) as taskid,
|
MAX(task_name) as task_name,
|
MAX(drcode) as drcode,
|
MAX(drname) as drname,
|
MAX(leaveldeptcode) as deptcode,
|
MAX(leaveldeptname) as deptname,
|
MAX(leavehospitaldistrictcode) as leavehospitaldistrictcode,
|
MAX(leavehospitaldistrictname) as leavehospitaldistrictname,
|
MAX(hospitaldistrictcode) as hospitaldistrictcode,
|
MAX(hospitaldistrictname) as hospitaldistrictname,
|
MAX(deptcode) as hospitaldeptcode,
|
MAX(deptname) as hospitaldeptname,
|
SUM(CASE WHEN visit_count = 1 THEN 1 ELSE 0 END) as first_visit_count,
|
SUM(CASE WHEN visit_count > 1 THEN 1 ELSE 0 END) as again_visit_count,
|
SUM(CASE WHEN sendstate = 4 THEN 1 ELSE 0 END) as non_follow_up,
|
SUM(CASE WHEN sendstate is not null and sendstate != 4 THEN 1 ELSE 0 END) as follow_up_needed,
|
SUM(CASE WHEN visit_count = 1 and sendstate is not null and sendstate != 4 THEN 1 ELSE 0 END) as need_follow_up,
|
SUM(CASE WHEN visit_count = 1 and sendstate = 2 THEN 1 ELSE 0 END) as pending_follow_up,
|
SUM(CASE WHEN visit_count = 1 and sendstate = 6 THEN 1 ELSE 0 END) as follow_up_success,
|
SUM(CASE WHEN visit_count = 1 and (sendstate = 5 or sendstate = 7) THEN 1 ELSE 0 END) as follow_up_fail,
|
SUM(CASE WHEN visit_count = 1 and sendstate is not null and current_preachform = '1' THEN 1 ELSE 0 END) as manual,
|
SUM(CASE WHEN visit_count = 1 and sendstate is not null and current_preachform = '3' THEN 1 ELSE 0 END) as voice,
|
SUM(CASE WHEN visit_count = 1 and sendstate is not null and current_preachform = '4' THEN 1 ELSE 0 END) as sms,
|
SUM(CASE WHEN visit_count = 1 and sendstate is not null and current_preachform = '5' THEN 1 ELSE 0 END) as we_chat,
|
SUM(CASE WHEN visit_count = 1 and sendstate is not null and excep = '1' THEN 1 ELSE 0 END) as abnormal,
|
SUM(CASE WHEN visit_count > 1 and sendstate is not null and sendstate != 4 THEN 1 ELSE 0 END) as need_follow_up_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate = 2 THEN 1 ELSE 0 END) as pending_follow_up_again,
|
SUM(CASE WHEN visit_count > 1 and (sendstate = 1 or sendstate = 3 or sendstate = 6) THEN 1 ELSE 0 END) as follow_up_success_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate = 5 THEN 1 ELSE 0 END) as follow_up_fail_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate is not null and current_preachform = '1' THEN 1 ELSE 0 END) as manual_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate is not null and current_preachform = '3' THEN 1 ELSE 0 END) as voice_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate is not null and current_preachform = '4' THEN 1 ELSE 0 END) as sms_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate is not null and current_preachform = '5' THEN 1 ELSE 0 END) as we_chat_again,
|
SUM(CASE WHEN visit_count > 1 and sendstate is not null and excep = '1' THEN 1 ELSE 0 END) as abnormal_again,
|
<!-- 出院人次:原来的内存实现是 serviceSubtaskList.size(),即分组内命中的子任务条数。
|
改成本语句后一直没有聚合这一列,页面上“出院人次”恒为 0,与应随访人次自相矛盾。 -->
|
COUNT(*) as discharge_count
|
from service_subtask
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<choose>
|
<!-- 满意度统计:改用“有效病区”列(出院病区为空回退在院病区),筛选才真正生效 -->
|
<when test="districtColumn != null and districtColumn != ''">
|
<!-- 出院病区为空回退到在院病区。这里刻意写成 OR 展开而不是 IFNULL(a,b) IN (...):
|
列被函数包住就用不了索引,56 万行明细表上是全表扫(实测 5.1s → 0.7s)。
|
两个分支分别命中 idx_ss_district_pair 的 (leave..., hospital...) 前缀。 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
OR (leavehospitaldistrictcode IS NULL AND hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
))
|
</if>
|
</when>
|
<otherwise>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
</otherwise>
|
</choose>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
|
close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND (hospitaldistrictcode IS NULL OR hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="hospitaldeptcodes != null and hospitaldeptcodes.size() > 0">
|
AND deptcode IN
|
<foreach collection="hospitaldeptcodes" item="hospitaldeptcode" open="(" separator=","
|
close=")">
|
#{hospitaldeptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime!=null">
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) >= DATE(#{startTime})
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="hospitalStartTime != null and hospitalEndTime!=null">
|
AND endtime >= DATE(#{hospitalStartTime})
|
AND endtime < DATE_ADD(DATE(#{hospitalEndTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP}</if>
|
<if test="type != null">
|
and type = #{type}
|
</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND visit_count > 1
|
</if>
|
<!-- 过滤列必须与 GROUP BY 的列一致:都用 groupColumn(满意度病区统计时它是
|
IFNULL(出院病区, 在院病区) 这样的表达式),否则聚合出来的分组键过滤不上,题目量会全变 0。 -->
|
<if test="groupColumn != null and groupColumn != '' and groupKeyList != null and groupKeyList.size>0">
|
AND IFNULL(${groupColumn}, 'Unknown') IN
|
<foreach collection="groupKeyList" item="key" open="(" separator=","
|
close=")">
|
#{key}
|
</foreach>
|
</if>
|
group by IFNULL(${groupColumn}, 'Unknown')
|
</select>
|
|
<!--
|
按分组聚合满意度题目量(替代 getSfStatisticsCategory 的“逐子任务 IN 查询 + 内存 N*M 过滤”)。
|
where 条件 = 上面聚合查询的条件 + 原 getSfStatisticsCategory 的明细条件,
|
因此命中的明细集合与改造前(getSfStatisticsCategory 结果再按子任务与分组求交)完全一致。
|
configValue 为空时不调用本语句(原实现在这种场景下题目量一律为 0)。
|
-->
|
<select id="getSfStatisticsScriptJoySum" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultType="map">
|
select
|
<choose>
|
<when test="districtColumn != null and districtColumn != ''">
|
IFNULL(${districtColumn}, 'Unknown') as groupCode,
|
</when>
|
<otherwise>
|
IFNULL(t.${groupColumn}, 'Unknown') as groupCode,
|
</otherwise>
|
</choose>
|
SUM(CASE WHEN a.categoryid IN(${configValue})
|
THEN 1 ELSE 0 END) as joyAllCount,
|
SUM(CASE WHEN a.categoryid IN(${configValue})
|
AND IFNULL(a.matchedtext,a.asrtext) is not null
|
AND IFNULL(a.matchedtext,a.asrtext) != ''
|
THEN 1 ELSE 0 END) as joyCount
|
from service_subtask_detail a
|
INNER JOIN service_subtask t on a.sub_id = t.id
|
where 1=1
|
and a.del_flag = 0
|
and t.del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and t.orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and t.campusid = #{campusid}
|
</if>
|
<choose>
|
<!-- 满意度统计:与聚合主查询一致,用“有效病区”列过滤,
|
否则题目量会和主查询的行对不上(分组键不一样,过滤不上就全变 0)。 -->
|
<when test="districtColumn != null and districtColumn != ''">
|
<!-- 出院病区为空回退到在院病区。这里刻意写成 OR 展开而不是 IFNULL(a,b) IN (...):
|
列被函数包住就用不了索引,56 万行明细表上是全表扫(实测 5.1s → 0.7s)。
|
两个分支分别命中 idx_ss_district_pair 的 (leave..., hospital...) 前缀。 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
OR (leavehospitaldistrictcode IS NULL AND hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
))
|
</if>
|
</when>
|
<otherwise>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (t.leavehospitaldistrictcode IS NULL OR t.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
</otherwise>
|
</choose>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND t.leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
AND t.leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
|
close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND (t.hospitaldistrictcode IS NULL OR t.hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="hospitaldeptcodes != null and hospitaldeptcodes.size() > 0">
|
AND t.deptcode IN
|
<foreach collection="hospitaldeptcodes" item="hospitaldeptcode" open="(" separator=","
|
close=")">
|
#{hospitaldeptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND t.service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime!=null">
|
AND IFNULL(t.visit_time, IFNULL(t.finishtime, t.create_time)) >= DATE(#{startTime})
|
AND IFNULL(t.visit_time, IFNULL(t.finishtime, t.create_time)) < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="hospitalStartTime != null and hospitalEndTime!=null">
|
AND t.endtime >= DATE(#{hospitalStartTime})
|
AND t.endtime < DATE_ADD(DATE(#{hospitalEndTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="visitDeptCode != null">and t.visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and t.visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and t.isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and t.continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and t.continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and t.continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and t.continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP}</if>
|
<if test="type != null">
|
and t.type = #{type}
|
</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND t.visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND t.visit_count > 1
|
</if>
|
<if test="districtColumn != null and districtColumn != '' and groupKeyList != null and groupKeyList.size>0">
|
AND IFNULL(${districtColumn}, 'Unknown') IN
|
<foreach collection="groupKeyList" item="key" open="(" separator=","
|
close=")">
|
#{key}
|
</foreach>
|
</if>
|
<if test="(districtColumn == null or districtColumn == '') and groupKey != null and groupKey != '' and groupKeyList != null and groupKeyList.size>0">
|
AND IFNULL(t.${groupKey}, 'Unknown') IN
|
<foreach collection="groupKeyList" item="key" open="(" separator=","
|
close=")">
|
#{key}
|
</foreach>
|
</if>
|
<choose>
|
<when test="districtColumn != null and districtColumn != ''">
|
group by IFNULL(${districtColumn}, 'Unknown')
|
</when>
|
<otherwise>
|
group by IFNULL(t.${groupColumn}, 'Unknown')
|
</otherwise>
|
</choose>
|
</select>
|
|
<select id="getSfStatisticsHyperlink" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult">
|
select id,
|
visit_count,
|
is_visit_again,
|
type,
|
orgid,
|
drcode,
|
drname,
|
leavehospitaldistrictcode,
|
leavehospitaldistrictname,
|
leaveldeptcode,
|
leaveldeptname,
|
sendstate,
|
preachform,
|
<include refid="effectiveCurrentPreachformExpr"/> AS current_preachform,
|
excep,
|
nurse_id,
|
nurse_name,
|
taskid,
|
task_name,
|
visit_time,
|
visit_dept_code,
|
visit_dept_name,
|
finishtime,
|
endtime,
|
senddate,
|
suggest,
|
result,
|
templateid,
|
templatename,
|
patid,
|
sendname,
|
send_type,
|
recordid,
|
exrecallcount,
|
continue_flag,
|
continue_time_now,
|
continue_content,
|
continue_count,
|
continue_time_next,
|
task_situation,
|
remark,
|
doctor_opinion,
|
finish_state,
|
is_manually_called
|
from service_subtask
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<!-- 2026-10-21:病区为空时视为"不限"(南华满意度 83% 子任务无病区),有病区的数据行为不变 -->
|
<!-- 与 getSfStatisticsScript 的汇总行保持一致:出院病区为空则回退到在院病区,
|
否则点“查看详情”查出来的条数会和汇总行的数字对不上。 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
OR (leavehospitaldistrictcode IS NULL AND hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
))
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<!-- 2026-10-21:visit_time 为空时按完成/创建时间兜底 -->
|
<if test="startTime != null and endTime!=null">
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) >= DATE(#{startTime})
|
AND IFNULL(visit_time, IFNULL(finishtime, create_time)) < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="hospitalStartTime != null and hospitalEndTime!=null">
|
AND endtime >= DATE(#{hospitalStartTime})
|
AND endtime < DATE_ADD(DATE(#{hospitalEndTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="continueTimeNow != null ">and continue_time_now = #{continueTimeNow,jdbcType=TIMESTAMP}</if>
|
<if test="continueCount != null ">and continue_count = #{continueCount}</if>
|
<if test="continueTimeNext != null ">and continue_time_next = #{continueTimeNext,jdbcType=TIMESTAMP}</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and type = #{type}
|
</if>
|
<!-- 首个再次随访:精确查 visit_count = 2,与统计口径一致 -->
|
<if test="hyperLinkInfoType == 'againFollowUpPushCountInfo'">
|
AND visit_count = 2
|
</if>
|
<!-- 其他类型保持原语义:1 首次,>1 再次 -->
|
<if test="hyperLinkInfoType != 'againFollowUpPushCountInfo' and visitCount != null and visitCount == 1">
|
AND visit_count = 1
|
</if>
|
<if test="hyperLinkInfoType != 'againFollowUpPushCountInfo' and visitCount != null and visitCount > 1">
|
AND visit_count > 1
|
</if>
|
<if test="groupKey != null and groupKey != '' and groupKeyList != null and groupKeyList.size>0">
|
AND IFNULL(${groupKey}, 'Unknown') IN
|
<foreach collection="groupKeyList" item="key" open="(" separator=","
|
close=")">
|
#{key}
|
</foreach>
|
</if>
|
AND sendstate IS NOT NULL
|
<if test="sendstates != null and sendstates.size() > 0">
|
AND sendstate IN
|
<foreach collection="sendstates" item="state" open="(" separator="," close=")">
|
#{state}
|
</foreach>
|
</if>
|
<if test="currentPreachform != null and currentPreachform != '' ">
|
AND <include refid="effectiveCurrentPreachformExpr"/> = #{currentPreachform}
|
<if test="followUpCountStyle != null and followUpCountStyle = '1'">
|
AND sendstate != 4
|
</if>
|
</if>
|
<if test="excep != null and excep != ''">
|
AND excep = #{excep}
|
</if>
|
<if test="taskSituation != null">
|
AND task_situation = #{taskSituation}
|
</if>
|
<if test="finishState != null">
|
AND finish_state = #{finishState}
|
</if>
|
<if test="drcode != null and drcode != ''">
|
AND drcode = #{drcode}
|
</if>
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">
|
AND leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</if>
|
<if test="deptcode != null and deptcode != ''">
|
AND leaveldeptcode = #{deptcode}
|
</if>
|
<if test="isManuallyCalled != null">
|
AND is_manually_called = #{isManuallyCalled}
|
</if>
|
<if test="suggest != null and suggest != ''">
|
AND TRIM(suggest) = #{suggest}
|
</if>
|
order by endtime desc
|
<if test="pageSize != null and pageNum != null">
|
limit ${pageSize} OFFSET ${pageNum}
|
</if>
|
</select>
|
|
<select id="getSfStatisticsJoy" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult2">
|
SELECT sub_id as subTaskId,COUNT(sub_id) joyCount,
|
(SELECT COUNT(1) FROM ivr_liba_target WHERE assortid IN (SELECT config_value FROM sys_config WHERE
|
config_key='joyCount')) joyAllCount
|
FROM service_subtask_detail a
|
WHERE sub_id IN(SELECT id FROM service_subtask t
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<!-- 2026-10-21:病区为空时视为"不限"(南华满意度 83% 子任务无病区),有病区的数据行为不变 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime!=null">
|
AND date_format(IFNULL(visit_time, IFNULL(finishtime, create_time)),'%y%m%d') >= date_format(#{startTime},'%y%m%d')
|
AND date_format(IFNULL(visit_time, IFNULL(finishtime, create_time)),'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
</if>
|
<if test="visitDeptCode != null">and visit_dept_code = #{visitDeptCode}</if>
|
<if test="visitDeptName != null">and visit_dept_name = #{visitDeptName}</if>
|
<if test="isabnormal != null">and isabnormal = #{isabnormal}</if>
|
)
|
AND targetid IN ( SELECT id FROM ivr_liba_target WHERE assortid IN (SELECT config_value FROM sys_config WHERE
|
config_key='joyCount'))
|
GROUP BY sub_id
|
</select>
|
|
<select id="getSfStatisticsJoydetails" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult2">
|
SELECT joyName,joyCount,joyAllCount,ROUND(joyCount/joyAllCount,2) joyTotal FROM (
|
SELECT targetname joyName,
|
(select COUNT(sub_id) FROM service_subtask_detail WHERE sub_id IN(SELECT id FROM service_subtask t
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<!-- 2026-10-21:病区为空时视为"不限"(南华满意度 83% 子任务无病区),有病区的数据行为不变 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime!=null">
|
AND date_format(IFNULL(visit_time, IFNULL(finishtime, create_time)),'%y%m%d') >= date_format(#{startTime},'%y%m%d')
|
AND date_format(IFNULL(visit_time, IFNULL(finishtime, create_time)),'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
</if>
|
) AND targetid=a.id) joyCount , (SELECT COUNT(*) from (select sub_id FROM service_subtask_detail
|
WHERE sub_id IN(SELECT id FROM service_subtask t
|
where 1=1
|
and del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">AND
|
leavehospitaldistrictcode IN
|
<foreach
|
collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime!=null">
|
AND date_format(IFNULL(visit_time, IFNULL(finishtime, create_time)),'%y%m%d') >= date_format(#{startTime},'%y%m%d')
|
AND date_format(IFNULL(visit_time, IFNULL(finishtime, create_time)),'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
</if>
|
GROUP BY sub_id ) ) ta ) joyAllCount
|
FROM ivr_liba_target a
|
WHERE assortid IN (SELECT config_value FROM sys_config WHERE config_key=
|
'joyCount')
|
)a1
|
</select>
|
|
<select id="getSfStatisticsCategory" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult2">
|
SELECT
|
<if test="configValue != null and configValue != ''">
|
SUM(CASE WHEN a.categoryid IN(${configValue})
|
THEN 1 ELSE 0 END) AS joyAllCount,
|
</if>
|
<if test="configValue != null and configValue != ''">
|
SUM(CASE WHEN a.categoryid IN(${configValue})
|
AND IFNULL(a.matchedtext,a.asrtext) is not null
|
AND IFNULL(a.matchedtext,a.asrtext) != ''
|
THEN 1 ELSE 0 END) AS joyCount,
|
</if>
|
a.sub_id as subTaskId
|
FROM service_subtask_detail a
|
INNER JOIN service_subtask t ON a.sub_id = t.id
|
where 1=1
|
and a.del_flag=0
|
AND t.del_flag=0
|
<if test="orgid != null and orgid != ''">
|
and t.orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and t.campusid = #{campusid}
|
</if>
|
<!-- 2026-10-21:病区为空时视为"不限"
|
南华满意度子任务的 leavehospitaldistrictcode 有 83%(3236/3811)为 NULL,
|
原来「科室 AND 病区」两个条件永远不可能同时成立 → 整张统计表空。
|
判空放行只影响病区为空的记录,有病区的数据行为不变。 -->
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (t.leavehospitaldistrictcode IS NULL OR t.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
)
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND t.leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="subTaskIds != null and subTaskIds.size() > 0">
|
AND t.id IN
|
<foreach collection="subTaskIds" item="subTaskId" open="(" separator=","
|
close=")">
|
#{subTaskId}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND t.service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<!-- 2026-10-21:visit_time 为空时按完成/创建时间兜底 -->
|
<if test="startTime != null and endTime!=null">
|
AND date_format(IFNULL(t.visit_time, IFNULL(t.finishtime, t.create_time)),'%y%m%d') >= date_format(#{startTime},'%y%m%d')
|
AND date_format(IFNULL(t.visit_time, IFNULL(t.finishtime, t.create_time)),'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
</if>
|
<if test="visitDeptCode != null">
|
and t.visit_dept_code = #{visitDeptCode}
|
</if>
|
<if test="visitDeptName != null">
|
and t.visit_dept_name = #{visitDeptName}
|
</if>
|
<if test="isabnormal != null">
|
and t.isabnormal = #{isabnormal}
|
</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and t.type = #{type}
|
</if>
|
GROUP BY a.sub_id
|
</select>
|
|
<select id="getSfStatisticsScriptDetails" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskScriptCountResult">
|
SELECT
|
MIN(a.id) as scriptid,
|
MIN(a.templateid) as templateid,
|
MIN(a.script_type) as script_type,
|
a.script_content,
|
b.subtask_type,
|
SUM(b.completed_quantity) as completed_quantity,
|
SUM(b.all_quantity) as all_quantity,
|
ROUND(SUM(b.completed_quantity)/SUM(b.all_quantity),2) as completed_percentage
|
FROM
|
<if test="type == 1">
|
ivr_task_template_script a
|
</if>
|
<if test="type == 2">
|
svy_task_template_script a
|
</if>
|
INNER JOIN(
|
SELECT
|
ssd.scriptid AS scriptid,
|
ss.type as subtask_type,
|
SUM(CASE WHEN IFNULL(ssd.matchedtext,ssd.asrtext) IS NOT NULL
|
AND IFNULL(ssd.matchedtext,ssd.asrtext) != '' THEN 1
|
ELSE 0 END) AS completed_quantity,
|
COUNT(*) AS all_quantity
|
FROM
|
service_subtask_detail ssd
|
INNER JOIN service_subtask ss ON ssd.sub_id = ss.id
|
WHERE 1=1
|
AND ss.del_flag=0
|
AND ssd.del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
AND ss.orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND ss.campusid = #{campusid}
|
</if>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (ss.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
OR (ss.leavehospitaldistrictcode IS NULL AND ss.hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
))
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND ss.leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
AND ss.leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
|
close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND ss.hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="hospitaldeptcodes != null and hospitaldeptcodes.size() > 0">
|
AND ss.deptcode IN
|
<foreach collection="hospitaldeptcodes" item="hospitaldeptcode" open="(" separator=","
|
close=")">
|
#{hospitaldeptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND ss.service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<!-- 2026-10-21:visit_time 为空(南华满意度 3811/3811 全为 NULL)时按完成/创建时间兜底 -->
|
<if test="startTime != null and endTime!=null">
|
AND date_format(IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)),'%y%m%d') >= date_format(#{startTime},'%y%m%d')
|
AND date_format(IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)),'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and ss.type = #{type}
|
</if>
|
<if test="configValue != null and configValue != ''">
|
AND ssd.categoryid IN (${configValue})
|
</if>
|
group by ssd.scriptid) b
|
ON a.id = b.scriptid
|
<!-- 适用单条查询 -->
|
<if test="scriptids != null and scriptids != ''">
|
AND a.scriptid in
|
(SELECT lib_script.scriptid FROM
|
svy_lib_template_script lib_script
|
WHERE lib_script.scriptid in (${scriptids}))
|
</if>
|
<!-- 同一道题会被复制到多个任务模板,按题目内容合并,保证一道题只返回一条 -->
|
GROUP BY a.script_content, b.subtask_type
|
ORDER BY MIN(a.id)
|
</select>
|
|
<select id="getSfStatisticsScriptItemDetails" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskScriptCountResult">
|
SELECT
|
a.script_content,
|
ss.type as subtask_type,
|
IFNULL(ssd.matchedtext,ssd.asrtext) AS option_text,
|
COUNT(*) AS chosen_quantity
|
FROM
|
service_subtask_detail ssd
|
INNER JOIN service_subtask ss ON ssd.sub_id = ss.id
|
INNER JOIN
|
<if test="type == 1">
|
ivr_task_template_script a ON a.id = ssd.scriptid
|
</if>
|
<if test="type == 2">
|
svy_task_template_script a ON a.id = ssd.scriptid
|
</if>
|
where 1=1
|
and ss.del_flag=0
|
and ssd.del_flag=0
|
<if test="orgid != null and orgid != ''">
|
and ss.orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and ss.campusid = #{campusid}
|
</if>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND (ss.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
OR (ss.leavehospitaldistrictcode IS NULL AND ss.hospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
))
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND ss.leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0">
|
AND ss.leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
|
close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND ss.hospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="hospitaldeptcodes != null and hospitaldeptcodes.size() > 0">
|
AND ss.deptcode IN
|
<foreach collection="hospitaldeptcodes" item="hospitaldeptcode" open="(" separator=","
|
close=")">
|
#{hospitaldeptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND ss.service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator=","
|
close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<!-- 2026-10-21:visit_time 为空(南华满意度 3811/3811 全为 NULL)时按完成/创建时间兜底 -->
|
<if test="startTime != null and endTime!=null">
|
AND date_format(IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)),'%y%m%d') >= date_format(#{startTime},'%y%m%d')
|
AND date_format(IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)),'%y%m%d') <= date_format(#{endTime},'%y%m%d')
|
</if>
|
<!-- 目前只统计语音和问卷 -->
|
<if test="type != null">
|
and ss.type = #{type}
|
</if>
|
<if test="configValue != null and configValue != ''">
|
AND ssd.categoryid IN (${configValue})
|
</if>
|
group by a.script_content, ss.type, IFNULL(ssd.matchedtext,ssd.asrtext)
|
</select>
|
|
<!--
|
问题选项数字下钻:返回选择了指定选项的 service_subtask 列表。
|
过滤口径与 getSfStatisticsScriptDetails / getSfStatisticsScriptItemDetails 保持一致,
|
额外支持 statisticaltype:1-病区、2-科室、3-病种。
|
-->
|
<select id="getSfStatisticsScriptDetailsHyperlink" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult">
|
SELECT ss.*
|
FROM service_subtask ss
|
WHERE ss.del_flag = 0
|
<if test="orgid != null and orgid != ''">
|
AND ss.orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND ss.campusid = #{campusid}
|
</if>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND ss.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND ss.deptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="serviceType != null and serviceType.size() > 0">
|
AND ss.service_type IN
|
<foreach collection="serviceType" item="serviceType" open="(" separator="," close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
<if test="startTime != null and endTime != null">
|
AND ss.visit_time >= DATE(#{startTime})
|
AND ss.visit_time < DATE_ADD(DATE(#{endTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="type != null and type != ''">
|
AND ss.type = #{type}
|
</if>
|
|
<!-- 统计维度:1-按病区 2-按科室 3-按taskid -->
|
<if test="statisticaltype != null and statisticaltype == 1">
|
<choose>
|
<when test="deptcode != null and deptcode != ''">
|
AND ss.leavehospitaldistrictcode = #{deptcode}
|
</when>
|
<when test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">
|
AND ss.leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</when>
|
</choose>
|
</if>
|
<if test="statisticaltype != null and statisticaltype == 2 and deptcode != null and deptcode != ''">
|
AND ss.deptcode = #{deptcode}
|
</if>
|
<if test="statisticaltype != null and statisticaltype == 3 and taskId != null">
|
AND ss.taskid = #{taskId}
|
</if>
|
<!-- 兼容不传 statisticaltype 时按单值条件过滤 -->
|
<if test="statisticaltype == null">
|
<if test="leavehospitaldistrictcode != null and leavehospitaldistrictcode != ''">
|
AND ss.leavehospitaldistrictcode = #{leavehospitaldistrictcode}
|
</if>
|
<if test="deptcode != null and deptcode != ''">
|
AND ss.deptcode = #{deptcode}
|
</if>
|
<if test="taskId != null">
|
AND ss.taskid = #{taskId}
|
</if>
|
</if>
|
|
<!-- 题目 + 选项匹配:只保留回答中选择了该选项的子任务 -->
|
AND EXISTS (
|
SELECT 1
|
FROM service_subtask_detail ssd
|
WHERE ssd.sub_id = ss.id
|
AND ssd.del_flag = 0
|
<if test="configValue != null and configValue != ''">
|
AND ssd.categoryid IN (${configValue})
|
</if>
|
<choose>
|
<when test="optionText != null">
|
AND IFNULL(ssd.matchedtext, ssd.asrtext) = #{optionText}
|
</when>
|
<otherwise>
|
AND 1 = 0
|
</otherwise>
|
</choose>
|
<choose>
|
<!-- 优先按题目内容匹配:同一道题复制到多个任务模板时 scriptid 不同,但 script_content 相同 -->
|
<when test="scriptContent != null and scriptContent != ''">
|
AND ssd.scriptid IN (
|
<choose>
|
<when test="type == '1'">
|
SELECT its.id FROM ivr_task_template_script its
|
WHERE its.script_content = #{scriptContent}
|
</when>
|
<when test="type == '2'">
|
SELECT sts.id FROM svy_task_template_script sts
|
WHERE sts.script_content = #{scriptContent}
|
</when>
|
<otherwise>
|
SELECT its.id FROM ivr_task_template_script its
|
WHERE its.script_content = #{scriptContent}
|
UNION
|
SELECT sts.id FROM svy_task_template_script sts
|
WHERE sts.script_content = #{scriptContent}
|
</otherwise>
|
</choose>
|
)
|
</when>
|
<when test="scriptid != null">
|
AND ssd.scriptid = #{scriptid}
|
</when>
|
<otherwise>
|
AND 1 = 0
|
</otherwise>
|
</choose>
|
)
|
ORDER BY ss.endtime DESC, ss.id DESC
|
<if test="pageSize != null and pageSize > 0">
|
LIMIT #{pageSize}
|
<if test="pageNum != null and pageNum >= 0">
|
OFFSET #{pageNum}
|
</if>
|
</if>
|
</select>
|
|
<select id="getDataByTime" resultMap="ServiceSubtaskResult">
|
|
select id,
|
sendname,
|
long_send_time,
|
phone,
|
suggest,
|
sex,
|
age,
|
openid,
|
sfzh,
|
addr,
|
current_preachform,
|
senderdetail,
|
type,
|
taskid,
|
visit_time,
|
templateid,
|
templatename,
|
senddate,
|
senduuid,
|
result,
|
finishtime,
|
recordid,
|
exrecallcount,
|
pulltime,
|
leaveldeptcode,
|
labelstatus,
|
del_flag,
|
upid,
|
update_by,
|
update_time,
|
create_by,
|
create_time,
|
isupload,
|
upload_time,
|
orgid,
|
pid,
|
visit_count,
|
is_visit_again,
|
guid,
|
text_param,
|
preachform,
|
bed_no,
|
send_type,
|
task_name,
|
task_desc,
|
operator_no,
|
operator,
|
hospno,
|
hosp_type,
|
wechat,
|
roomno,
|
admindate,
|
patid,
|
service_type,
|
leaveldeptname,
|
score,
|
drname,
|
drcode,
|
starttime,
|
endtime,
|
leavehospitaldistrictcode,
|
leavehospitaldistrictname,
|
excep,
|
nurse_id,
|
nurse_name,
|
remark,
|
doctor_opinion,
|
inhospid,
|
patfrom,
|
task_guid,
|
leavediagname,
|
patguid,
|
visitDeptCode,
|
visitDeptName,
|
management_doctor_code,
|
management_doctor,
|
isabnormal,
|
leaveicd10code
|
FROM service_subtask,
|
JSON_TABLE(send_time_slot, '$[*]' COLUMNS (
|
begantime DATETIME PATH '$.begantime',
|
endtime DATETIME PATH '$.endtime'
|
)) AS jt
|
WHERE jt.begantime > #{beganTime}
|
AND jt.begantime <= #{endTime}
|
AND del_flag = 0
|
</select>
|
|
<!-- 获取随访门诊每月的数量-->
|
<select id="getSfFzInfoEveryMonth" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq"
|
resultMap="ServiceSubtaskResult2">
|
SELECT DATE_FORMAT(st.finishtime, '%Y-%m') AS month,
|
st.service_type as service_type,
|
st.id as subTaskId,
|
COUNT(*) AS count
|
FROM
|
service_subtask st
|
JOIN
|
sys_user_dept dd
|
ON dep.dept_id = dd.dept_id
|
WHERE
|
dd.user_id =#{userId}
|
AND st.finishtime IS NOT NULL
|
and DATE_FORMAT(st.finishtime
|
, '%Y-%m') >= #{startTime}
|
and DATE_FORMAT(st.finishtime
|
, '%Y-%m') <= #{endTime}
|
GROUP BY
|
month, st.service_type, st.id
|
ORDER BY
|
month, st.service_type, st.id;
|
</select>
|
|
<select id="getDeptRanking" parameterType="com.ruoyi.common.core.service.dto.PatMedReq" resultType="com.ruoyi.common.core.service.dto.PatMedRes">
|
SELECT leaveldeptname AS deptname,
|
count(1) AS rc
|
FROM service_subtask
|
WHERE DATE_FORMAT(visit_time, '%Y-%m-%d') >= #{startDate}
|
AND DATE_FORMAT(visit_time, '%Y-%m-%d') <= #{endDate}
|
AND service_type IN (2, 13)
|
AND del_flag = '0'
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
GROUP BY leaveldeptname
|
</select>
|
|
<!-- 服务统计查询 - 按时间维度统计出院/门诊随访数据 -->
|
<select id="getServiceStatistics" parameterType="com.ruoyi.task.domain.ServiceStatisticsRequest"
|
resultType="com.ruoyi.task.domain.ServiceStatisticsResponse">
|
SELECT
|
timePeriod,
|
SUM(dischargeFollowCount) AS dischargeFollowCount,
|
SUM(outpatientFollowCount) AS outpatientFollowCount,
|
SUM(pmiCount) AS pmiCount,
|
SUM(pmoCount) AS pmoCount
|
FROM (
|
SELECT
|
<choose>
|
<when test="timeType == 'day'">
|
DATE_FORMAT(visit_time, '%Y-%m-%d') AS timePeriod,
|
</when>
|
<when test="timeType == 'month'">
|
DATE_FORMAT(visit_time, '%Y-%m') AS timePeriod,
|
</when>
|
<when test="timeType == 'year'">
|
DATE_FORMAT(visit_time, '%Y') AS timePeriod,
|
</when>
|
<when test="timeType == 'week'">
|
CONCAT(YEAR(visit_time), '-W', LPAD(WEEK(visit_time, 1), 2, '0')) AS timePeriod,
|
</when>
|
<otherwise>
|
DATE_FORMAT(visit_time, '%Y-%m-%d') AS timePeriod,
|
</otherwise>
|
</choose>
|
CASE WHEN service_type = '2' THEN 1 END AS dischargeFollowCount,
|
CASE WHEN service_type = '3' THEN 1 END AS outpatientFollowCount,
|
0 AS pmiCount,
|
0 AS pmoCount
|
FROM service_subtask
|
WHERE
|
del_flag = '0'
|
AND service_type IN (2, 13)
|
<if test="startDate != null and endDate != null">
|
AND visit_time >= #{startDate}
|
AND visit_time <= DATE_ADD(#{endDate}, INTERVAL 1 DAY)
|
</if>
|
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="districtcode" open="(" separator="," close=")">
|
#{districtcode}
|
</foreach>
|
</if>
|
|
<if test="serviceTypes != null and serviceTypes.size() > 0">
|
AND service_type IN
|
<foreach collection="serviceTypes" item="serviceType" open="(" separator="," close=")">
|
#{serviceType}
|
</foreach>
|
</if>
|
|
UNION ALL
|
|
-- 出院人次数据
|
SELECT
|
<choose>
|
<when test="timeType == 'day'">
|
DATE_FORMAT(endtime, '%Y-%m-%d') AS timePeriod,
|
</when>
|
<when test="timeType == 'month'">
|
DATE_FORMAT(endtime, '%Y-%m') AS timePeriod,
|
</when>
|
<when test="timeType == 'year'">
|
DATE_FORMAT(endtime, '%Y') AS timePeriod,
|
</when>
|
<when test="timeType == 'week'">
|
CONCAT(YEAR(endtime), '-W', LPAD(WEEK(endtime, 1), 2, '0')) AS timePeriod,
|
</when>
|
<otherwise>
|
DATE_FORMAT(endtime, '%Y-%m-%d') AS timePeriod,
|
</otherwise>
|
</choose>
|
0 AS dischargeFollowCount,
|
0 AS outpatientFollowCount,
|
1 AS pmiCount,
|
0 AS pmoCount
|
FROM pat_med_inhosp
|
WHERE del_flag = '0'
|
<if test="startDate != null and endDate != null">
|
AND endtime >= #{startDate}
|
AND endtime <= DATE_ADD(#{endDate}, INTERVAL 1 DAY)
|
</if>
|
AND inhospstate=1
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="districtcode" open="(" separator="," close=")">
|
#{districtcode}
|
</foreach>
|
</if>
|
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
|
<!-- UNION ALL-->
|
|
<!-- -- 门诊人次数据-->
|
<!-- SELECT-->
|
<!-- <choose>-->
|
<!-- <when test="timeType == 'day'">-->
|
<!-- DATE_FORMAT(admitdate, '%Y-%m-%d') AS timePeriod,-->
|
<!-- </when>-->
|
<!-- <when test="timeType == 'month'">-->
|
<!-- DATE_FORMAT(admitdate, '%Y-%m') AS timePeriod,-->
|
<!-- </when>-->
|
<!-- <when test="timeType == 'year'">-->
|
<!-- DATE_FORMAT(admitdate, '%Y') AS timePeriod,-->
|
<!-- </when>-->
|
<!-- <when test="timeType == 'week'">-->
|
<!-- CONCAT(YEAR(admitdate), '-W', LPAD(WEEK(admitdate, 1), 2, '0')) AS timePeriod,-->
|
<!-- </when>-->
|
<!-- <otherwise>-->
|
<!-- DATE_FORMAT(admitdate, '%Y-%m-%d') AS timePeriod,-->
|
<!-- </otherwise>-->
|
<!-- </choose>-->
|
<!-- 0 AS dischargeFollowCount,-->
|
<!-- 0 AS outpatientFollowCount,-->
|
<!-- 0 AS pmiCount,-->
|
<!-- 1 AS pmoCount-->
|
<!-- FROM pat_med_outhosp-->
|
<!-- WHERE del_flag = '0'-->
|
<!-- <if test="startDate != null and endDate != null">-->
|
<!-- AND admitdate >= #{startDate}-->
|
<!-- AND admitdate <= DATE_ADD(#{endDate}, INTERVAL 1 DAY)-->
|
<!-- </if>-->
|
<!-- <if test="orgid != null">-->
|
<!-- AND orgid = #{orgid}-->
|
<!-- </if>-->
|
<!-- <if test="campusid != null">-->
|
<!-- AND campusid = #{campusid}-->
|
<!-- </if>-->
|
<!-- <if test="deptcodes != null and deptcodes.size() > 0">-->
|
<!-- AND deptcode IN-->
|
<!-- <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")">-->
|
<!-- #{deptcode}-->
|
<!-- </foreach>-->
|
<!-- </if>-->
|
|
) AS combined_data
|
GROUP BY timePeriod
|
ORDER BY timePeriod DESC
|
</select>
|
|
<!-- 优化的统计查询:直接在数据库层完成聚合计算 -->
|
<select id="countByCondition" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity" resultType="map">
|
SELECT
|
SUM(CASE WHEN sendstate = 4 THEN 1 ELSE 0 END) AS wzx,
|
SUM(CASE WHEN sendstate != 4 AND sendstate != 2 THEN 1 ELSE 0 END) AS ysf,
|
SUM(CASE WHEN sendstate = 5 THEN 1 ELSE 0 END) AS fssb,
|
SUM(CASE WHEN sendstate >= 3 OR sendstate = 1 THEN 1 ELSE 0 END) AS yfs,
|
SUM(CASE WHEN sendstate = 1 THEN 1 ELSE 0 END) AS blq,
|
SUM(CASE WHEN sendstate = 4 THEN 1 ELSE 0 END) AS wxsf,
|
SUM(CASE WHEN sendstate != 4 THEN 1 ELSE 0 END) AS xsf,
|
SUM(CASE WHEN (sendstate = 1 OR sendstate = 2 OR sendstate = 3 OR sendstate = 7 ) THEN 1 ELSE 0
|
END) AS dsf,
|
SUM(CASE WHEN sendstate != 2 THEN 1 ELSE 0 END) AS yfs,
|
SUM(CASE WHEN sendstate = 2 THEN 1 ELSE 0 END) AS wfs,
|
SUM(CASE WHEN sendstate = 6 THEN 1 ELSE 0 END) AS ywc,
|
SUM(CASE WHEN sendstate = 7 THEN 1 ELSE 0 END) AS cs,
|
SUM(CASE WHEN excep IS NOT NULL AND excep = '1' THEN 1 ELSE 0 END) AS yc,
|
SUM(CASE WHEN excep IS NOT NULL AND excep = '2' THEN 1 ELSE 0 END) AS jg,
|
COUNT(1) as total
|
FROM service_subtask
|
where del_flag = 0
|
<if test="continueFlag != null ">and continue_flag = #{continueFlag}</if>
|
<if test="sendname != null and sendname != ''">
|
AND sendname LIKE CONCAT('%', #{sendname}, '%')
|
</if>
|
<if test="phone != null and phone != ''">
|
AND phone = #{phone}
|
</if>
|
<if test="finishtimeStart != null">
|
AND finishtime >= DATE(#{finishtimeStart})
|
</if>
|
<if test="finishtimeEnd != null">
|
AND finishtime < DATE_ADD(DATE(#{finishtimeEnd}), INTERVAL 1 DAY)
|
</if>
|
<!--
|
科室/病区筛选(2026-11 修订):
|
离院组(leaveldeptcodes / leavehospitaldistrictcodes)保持原逻辑;
|
在院组(deptcodes / hospitaldistrictcodes → deptcode / hospitaldistrictcode)是新增的一组;
|
组内按 deptOrDistrict 取 AND('1') / OR('2'),两组之间 AND(只传一组时另一组不拼)。
|
-->
|
<if test='deptOrDistrict == "1"'>
|
<include refid="filterLeaveDimAnd"/>
|
<include refid="filterInhospDimAnd"/>
|
</if>
|
<if test='deptOrDistrict == "2"'>
|
<include refid="filterLeaveDimOr"/>
|
<include refid="filterInhospDimOr"/>
|
</if>
|
<if test="visitCount != null and visitCount > 1 and visitDeptCodes != null and visitDeptCodes.size() > 0">
|
AND visit_dept_code IN
|
<foreach collection="visitDeptCodes" item="visitDeptCode" open="("
|
separator=","
|
close=")">
|
#{visitDeptCode}
|
</foreach>
|
</if>
|
<if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">
|
AND leavehospitaldistrictname = #{leavehospitaldistrictname}
|
</if>
|
<if test="leavediagname != null and leavediagname != ''">
|
AND leavediagname LIKE CONCAT('%', #{leavediagname}, '%')
|
</if>
|
<if test="managementDoctor != null and managementDoctor != ''">
|
AND management_doctor LIKE CONCAT('%', #{managementDoctor}, '%')
|
</if>
|
<if test="sex != null and sex != ''">
|
AND sex = #{sex}
|
</if>
|
<if test="age != null">
|
AND age = #{age}
|
</if>
|
<if test="patguid != null">
|
AND patguid = #{patguid}
|
</if>
|
<if test="subId != null">
|
AND id = #{subId}
|
</if>
|
<if test="inhospid != null">
|
AND inhospid = #{inhospid}
|
</if>
|
<if test="managementDoctorCode != null">
|
AND management_doctor_code = #{managementDoctorCode}
|
</if>
|
<if test="submit != null">
|
AND submit = #{submit}
|
</if>
|
<if test="upid != null">
|
AND upid = #{upid}
|
</if>
|
<if test="patfrom != null">
|
AND patfrom = #{patfrom}
|
</if>
|
<if test="serviceType != null">
|
AND service_type = #{serviceType}
|
</if>
|
<if test="patid != null">
|
AND patid = #{patid}
|
</if>
|
<if test="sfzh != null and sfzh != ''">
|
AND sfzh = #{sfzh}
|
</if>
|
<if test="addr != null and addr != ''">
|
AND addr = #{addr}
|
</if>
|
<if test="senderdetail != null and senderdetail != ''">
|
AND senderdetail = #{senderdetail}
|
</if>
|
<if test="type != null and type != ''">
|
AND type = #{type}
|
</if>
|
<if test="taskid != null">
|
AND taskid = #{taskid}
|
</if>
|
<if test="templateid != null and templateid != ''">
|
AND templateid = #{templateid}
|
</if>
|
<if test="templatename != null and templatename != ''">
|
AND templatename LIKE CONCAT('%', #{templatename}, '%')
|
</if>
|
<if test="startOutHospTime != null">
|
AND endtime >= DATE(#{startOutHospTime})
|
</if>
|
<if test="endOutHospTime != null">
|
AND endtime < DATE_ADD(DATE(#{endOutHospTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="startSendDateTime != null">
|
AND visit_time >= DATE(#{startSendDateTime})
|
</if>
|
<if test="endSendDateTime != null">
|
AND visit_time < DATE_ADD(DATE(#{endSendDateTime}), INTERVAL 1 DAY)
|
</if>
|
<if test="longSendTime != null">
|
AND long_send_time < DATE_ADD(DATE(#{longSendTime}), INTERVAL 1 DAY)
|
</if>
|
<!-- 2026-11:这里原本还有一份与上方 deptOrDistrict==1 完全重复的病区/科室条件,
|
已删除(条件改用 filterSubtaskWardDim / filterSubtaskDeptDim 片段,避免两份口径不一致) -->
|
<if test="leaveldeptcode != null and leaveldeptcode != ''">
|
AND leaveldeptcode = #{leaveldeptcode}
|
</if>
|
<if test="sendstate != null">
|
AND sendstate = #{sendstate}
|
</if>
|
<if test="sendstates != null and sendstates.size() > 0">
|
AND sendstate IN
|
<foreach collection="sendstates" item="state" open="(" separator="," close=")">
|
#{state}
|
</foreach>
|
</if>
|
<if test="currentPreachforms != null and currentPreachforms != ''">
|
AND FIND_IN_SET(<include refid="effectiveCurrentPreachformExpr"/>, #{currentPreachforms})
|
</if>
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<if test="guid != null and guid != ''">
|
AND guid = #{guid}
|
</if>
|
<if test="excep != null ">
|
AND excep = #{excep}
|
</if>
|
<if test="taskName != null and taskName != ''">
|
AND task_name like concat('%', #{taskName}, '%')
|
</if>
|
<if test="visitCount != null and visitCount == 1">
|
AND visit_count = 1
|
</if>
|
<if test="visitCount != null and visitCount > 1">
|
AND visit_count > 1
|
</if>
|
<if test="drname != null and drname != ''">
|
AND drname like concat('%', #{drname}, '%')
|
</if>
|
</select>
|
|
<select id="selectVisitCount" parameterType="com.ruoyi.common.core.service.dto.PatMedReq"
|
resultType="com.ruoyi.common.core.service.dto.PatMedRes">
|
select
|
0 AS rc,
|
count(1) AS rs
|
FROM
|
service_subtask
|
where 1=1
|
and del_flag = 0
|
and service_type=3
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<if test="startDate != null">
|
AND date_format( visit_time, '%y%m%d' ) >= date_format( #{startDate}, '%y%m%d' )
|
</if>
|
<if test="endDate != null">
|
AND date_format( visit_time, '%y%m%d' ) <= date_format(#{endDate},'%y%m%d')
|
</if>
|
<if test="deptcodeList != null and deptcodeList.size()>0">
|
and leaveldeptcode in
|
<foreach collection="deptcodeList" item="deptcode" open="(" separator="," close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
</select>
|
|
<!--
|
当前登录人「待处理」随访任务,按出院年月(endtime)分组统计,出院随访 / 门诊随访分开计数。
|
口径(与随访列表「待随访」页签一致):
|
1) 出院随访 service_type = '2',门诊随访 service_type = '3'
|
2) 统计状态 → sendstate IN (1,2,3,7):1 被领取 / 2 待发送 / 3 已发送 / 7 超时
|
(不含 4 不执行、5 发送失败、6 已完成)
|
3) 出院满 7 天 → endtime < (今天 - 7 天) + 1 天,
|
即「7 天前那一天」出院的也计入(用 <= DATE_SUB(...) 只会截到当天 0 点,会漏掉 9 条)
|
4) 只看最近 4 个出院月份(含当月)→ endtime >= 当月往前推 3 个月的 1 号
|
5) 科室/病区权限用 OR(与列表 deptOrDistrict=2 一致):
|
只有病区权限的用户,任务 leaveldeptcode 与本人科室对不上时也能量到,
|
否则会把整月数据过滤成 0。
|
说明:GROUP BY 只产出有数据的月份,前端按「当月 + 前 3 个月」补齐,没数据就显示 0 个。
|
不再限制 current_preachform(人工):该字段只是执行方式,
|
待随访任务里还有短信等方式,限定 '1' 会漏数。
|
-->
|
<select id="countPendingManualTaskByMonth"
|
parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultType="java.util.Map">
|
SELECT DATE_FORMAT(endtime, '%Y-%m') AS month,
|
SUM(CASE WHEN service_type = '2' THEN 1 ELSE 0 END) AS dischargeCnt,
|
SUM(CASE WHEN service_type = '3' THEN 1 ELSE 0 END) AS outpatientCnt
|
FROM service_subtask
|
WHERE del_flag = '0'
|
AND service_type IN ('2', '3')
|
<!-- 浮窗「待处理随访任务」口径:1 被领取 / 2 待发送 / 3 已发送 / 7 超时 -->
|
AND sendstate IN (1, 2, 3, 7)
|
AND endtime IS NOT NULL
|
AND endtime < DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 7 DAY), INTERVAL 1 DAY)
|
AND endtime >= DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 3 MONTH), '%Y-%m-01')
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<!-- 离院科室/病区:有科室按科室、有病区按病区,两者都有时取 OR -->
|
<include refid="filterLeaveDimOr"/>
|
GROUP BY DATE_FORMAT(endtime, '%Y-%m')
|
ORDER BY month
|
</select>
|
|
<select id="getCurrentUserServiceSubtaskCount" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultType="map">
|
SELECT
|
COUNT(CASE WHEN sendstate = 2 AND date_format(visit_time,'%y%m%d') <= date_format(CURDATE(),'%y%m%d') THEN 1
|
END) AS pendingVisitCount,
|
COUNT(CASE WHEN sendstate = 5 THEN 1 END) AS failedVisitCount,
|
SUM(CASE WHEN excep IS NOT NULL AND excep = '1' THEN 1 ELSE 0 END) AS abnormalVisitCount,
|
SUM(CASE WHEN excep IS NOT NULL AND excep = '2' THEN 1 ELSE 0 END) AS warnningVisitCount,
|
COUNT(*) AS allVisitCount,
|
<choose>
|
<when test="soonTimeoutHours != null and soonTimeoutHours > 0">
|
COUNT(CASE WHEN t.soon_deadline > NOW()
|
AND t.soon_deadline <= DATE_ADD(NOW(), INTERVAL #{soonTimeoutHours} HOUR)
|
THEN 1 END) AS soonTimeoutCount
|
</when>
|
<otherwise>
|
0 AS soonTimeoutCount
|
</otherwise>
|
</choose>
|
FROM (
|
SELECT ss.*,
|
<!-- 即将超时截止时间 = 出院时间(endtime) + 发送日(send_day, 缺省1) + 补偿天数(compensate_time 求和后再 +1 天),
|
与 RyTask/RedisMqReceiver 的 isSubtaskDeadline 口径保持一致;
|
无有效补偿记录(cp.subid 为空)时截止时间为 NULL,不参与即将超时统计 -->
|
CASE
|
WHEN cp.subid IS NULL THEN NULL
|
ELSE DATE_ADD(
|
DATE_ADD(ss.endtime, INTERVAL COALESCE(st.send_day, 1) DAY),
|
INTERVAL (COALESCE(cp.compensate_days, 0) + 1) DAY
|
)
|
END AS soon_deadline
|
FROM service_subtask ss
|
LEFT JOIN service_task st ON st.taskid = ss.taskid AND st.del_flag = '0'
|
<!-- 补偿时间:先按子任务聚合成一行再关联,避免一对多放大计数;
|
compensate_time 是 varchar 且可能存成空串,需先置空再转数字 -->
|
LEFT JOIN (
|
SELECT subid,
|
SUM(CAST(COALESCE(NULLIF(TRIM(compensate_time), ''), '0') AS SIGNED)) AS compensate_days
|
FROM service_subtask_preachform
|
WHERE del_flag = 0
|
GROUP BY subid
|
) cp ON cp.subid = ss.id
|
WHERE ss.del_flag = '0'
|
AND ss.service_type = '2'
|
AND ss.visit_count = 1
|
<if test="orgid != null and orgid != ''">
|
AND ss.orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and ss.campusid = #{campusid}
|
</if>
|
<!-- 离院科室/病区:有科室按科室、有病区按病区,两者都有时取 OR(原写法 1=1 会让筛选失效) -->
|
<if test="(leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0)
|
or (leaveldeptcodes != null and leaveldeptcodes.size() > 0)">
|
AND (
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
ss.leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="("
|
separator=","
|
close=")">
|
#{leavehospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="(leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0)
|
and (leaveldeptcodes != null and leaveldeptcodes.size() > 0)">
|
OR
|
</if>
|
<if test=" leaveldeptcodes != null and leaveldeptcodes.size()>0">
|
ss.leaveldeptcode IN
|
<foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator=","
|
close=")">
|
#{leaveldeptcode}
|
</foreach>
|
</if>)
|
</if>
|
) t
|
</select>
|
|
<!--
|
按病区或科室分组统计 continue_flag 数量
|
传了 leavehospitaldistrictcodes → 按病区维度
|
传了 deptcodes → 按科室维度
|
都不传 → 按病区维度统计全量
|
-->
|
<!-- 按病区分组统计延续护理数量 -->
|
<select id="getContinueNurseCount"
|
parameterType="com.ruoyi.task.domain.VO.ServiceSubtaskCotinueCountVO"
|
resultType="java.util.Map">
|
SELECT
|
leavehospitaldistrictcode AS groupCode,
|
leavehospitaldistrictname AS groupName,
|
SUM(CASE WHEN continue_flag = 1 THEN 1 ELSE 0 END) AS noContinueCnt,
|
SUM(CASE WHEN continue_flag = 2 THEN 1 ELSE 0 END) AS continueCnt
|
FROM service_subtask
|
WHERE del_flag = 0
|
AND continue_flag IN (1, 2)
|
AND leavehospitaldistrictcode IS NOT NULL AND leavehospitaldistrictcode != ''
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="leavehospitaldistrictcodes" item="code" open="(" separator="," close=")">
|
#{code}
|
</foreach>
|
</if>
|
GROUP BY leavehospitaldistrictcode, leavehospitaldistrictname
|
ORDER BY groupCode
|
</select>
|
|
<!-- 按科室分组统计延续护理数量 -->
|
<select id="getContinueNurseCountByDept"
|
parameterType="com.ruoyi.task.domain.VO.ServiceSubtaskCotinueCountVO"
|
resultType="java.util.Map">
|
SELECT
|
leaveldeptcode AS groupCode,
|
leaveldeptname AS groupName,
|
SUM(CASE WHEN continue_flag = 1 THEN 1 ELSE 0 END) AS noContinueCnt,
|
SUM(CASE WHEN continue_flag = 2 THEN 1 ELSE 0 END) AS continueCnt
|
FROM service_subtask
|
WHERE del_flag = 0
|
AND continue_flag IN (1, 2)
|
AND leaveldeptcode IS NOT NULL AND leaveldeptcode != ''
|
<if test="orgid != null and orgid != ''">
|
AND orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
AND campusid = #{campusid}
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="code" open="(" separator="," close=")">
|
#{code}
|
</foreach>
|
</if>
|
GROUP BY leaveldeptcode, leaveldeptname
|
ORDER BY groupCode
|
</select>
|
|
<!-- 宣教统计:按病区或科室分组,统计发送总量、发送成功量(sendstate=6)、已读量(finishtime不为空) -->
|
<select id="getHeLibraryCount" parameterType="com.ruoyi.template.domain.VO.HeLibraryCountVO" resultType="map">
|
SELECT
|
<choose>
|
<when test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
leavehospitaldistrictcode AS groupCode,
|
leavehospitaldistrictname AS groupName,
|
</when>
|
<otherwise>
|
leaveldeptcode AS groupCode,
|
leaveldeptname AS groupName,
|
</otherwise>
|
</choose>
|
COUNT(*) AS totalCount,
|
SUM(CASE WHEN sendstate = 6 THEN 1 ELSE 0 END) AS sendSuccessCount,
|
SUM(CASE WHEN finishtime IS NOT NULL THEN 1 ELSE 0 END) AS readCount
|
FROM service_subtask
|
WHERE del_flag = 0
|
AND service_type = 4
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<if test="sendstate != null">
|
AND sendstate = #{sendstate}
|
</if>
|
<if test="isFinished != null and isFinished != ''">
|
and finishtime is not null
|
</if>
|
<if test="starttime != null">AND starttime >= #{starttime}</if>
|
<if test="endtime != null">AND endtime <= #{endtime}</if>
|
<if test="visittime != null">AND DATE(visit_time) = DATE(#{visittime})</if>
|
<if test="finishtime != null">AND DATE(finishtime) = DATE(#{finishtime})</if>
|
<if test="hospType != null and hospType != ''">AND hosp_type = #{hospType}</if>
|
<choose>
|
<when test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="code" open="(" separator="," close=")">
|
#{code}
|
</foreach>
|
GROUP BY leavehospitaldistrictcode, leavehospitaldistrictname
|
ORDER BY groupCode
|
</when>
|
<otherwise>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="code" open="(" separator="," close=")">
|
#{code}
|
</foreach>
|
</if>
|
GROUP BY leaveldeptcode, leaveldeptname
|
ORDER BY groupCode
|
</otherwise>
|
</choose>
|
</select>
|
|
<!-- 任务组(appltype=5)滚动调度用:本轮仍在跑的数量 -->
|
<select id="countActiveByScheduleIdAndLoop" resultType="int">
|
select count(1)
|
from service_subtask
|
where schedule_id = #{scheduleId}
|
and loop_count = #{loopCount}
|
and (del_flag is null or del_flag = '0')
|
and sendstate in (1, 2, 3)
|
</select>
|
|
<!-- 任务组(appltype=5)滚动调度用:拉本轮全量 subtask,作为下一轮的克隆模板 -->
|
<select id="selectByScheduleIdAndLoop" resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where schedule_id = #{scheduleId}
|
and loop_count = #{loopCount}
|
and (del_flag is null or del_flag = '0')
|
order by schedule_seq asc, id asc
|
</select>
|
|
<select id="gethelibraryCountHyperlink" parameterType="com.ruoyi.template.domain.VO.HeLibraryCountVO"
|
resultMap="ServiceSubtaskResult">
|
select id,
|
visit_count,
|
is_visit_again,
|
type,
|
orgid,
|
drcode,
|
drname,
|
leavehospitaldistrictcode,
|
leavehospitaldistrictname,
|
leaveldeptcode,
|
leaveldeptname,
|
sendstate,
|
preachform,
|
current_preachform,
|
excep,
|
nurse_id,
|
nurse_name,
|
taskid,
|
task_name,
|
visit_time,
|
finishtime,
|
endtime,
|
senddate,
|
suggest,
|
result,
|
templateid,
|
templatename,
|
patid,
|
sendname,
|
send_type,
|
recordid,
|
exrecallcount,
|
continue_flag,
|
continue_time_now,
|
continue_content,
|
continue_count,
|
continue_time_next,
|
task_situation,
|
remark,
|
doctor_opinion
|
from service_subtask
|
where 1=1
|
and del_flag = 0
|
AND service_type = 4
|
<if test="orgid != null and orgid != ''">
|
and orgid = #{orgid}
|
</if>
|
<if test="campusid != null and campusid != ''">
|
and campusid = #{campusid}
|
</if>
|
<if test="sendstate != null">
|
AND sendstate = #{sendstate}
|
</if>
|
<if test="isFinished != null and isFinished != ''">
|
and finishtime is not null
|
</if>
|
<if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0">
|
AND leavehospitaldistrictcode IN
|
<foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator=","
|
close=")">
|
#{hospitaldistrictcode}
|
</foreach>
|
</if>
|
<if test="deptcodes != null and deptcodes.size() > 0">
|
AND leaveldeptcode IN
|
<foreach collection="deptcodes" item="deptcode" open="(" separator=","
|
close=")">
|
#{deptcode}
|
</foreach>
|
</if>
|
<if test="starttime != null">AND starttime >= #{starttime}</if>
|
<if test="endtime != null">AND endtime <= #{endtime}</if>
|
<if test="visittime != null">AND DATE(visit_time) = DATE(#{visittime})</if>
|
<if test="finishtime != null">AND DATE(finishtime) = DATE(#{finishtime})</if>
|
<if test="hospType != null and hospType != ''">AND hosp_type = #{hospType}</if>
|
order by endtime desc
|
<if test="pageSize != null and pageNum != null">
|
limit ${pageSize} OFFSET ${pageNum}
|
</if>
|
</select>
|
|
<select id="selectServiceSubtaskListDeadLine" parameterType="com.ruoyi.task.domain.entity.ServiceSubtaskEntity"
|
resultMap="ServiceSubtaskResult">
|
<include refid="selectServiceSubtaskVo"/>
|
where 1=1
|
and del_flag = 0
|
and visit_count = 1
|
and endtime
|
</select>
|
|
<!-- 门诊满意度综合得分排名(按科室或病区) -->
|
</mapper>
|