| | |
| | | <select id="getSfStatisticsGroupKey" parameterType="com.ruoyi.task.domain.ServiceSubtaskCountReq" |
| | | resultType="String"> |
| | | select |
| | | <if test="groupKey != null and groupKey != ''"> |
| | | <choose> |
| | | <when test="groupColumn != null and groupColumn != ''"> |
| | | ${groupColumn} as groupKey |
| | | </when> |
| | | <when test="groupKey != null and groupKey != ''"> |
| | | ${groupKey} as groupKey |
| | | </if> |
| | | </when> |
| | | <otherwise> |
| | | NULL as groupKey |
| | | </otherwise> |
| | | </choose> |
| | | from service_subtask |
| | | where 1=1 |
| | | and del_flag = 0 |
| | |
| | | 南华满意度子任务的 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="," |
| | |
| | | </foreach> |
| | | ) |
| | | </if> |
| | | </otherwise> |
| | | </choose> |
| | | <if test="leaveldeptcodes != null and leaveldeptcodes.size() > 0"> |
| | | AND leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," |
| | |
| | | <if test="visitCount != null and visitCount > 1"> |
| | | AND visit_count > 1 |
| | | </if> |
| | | <if test="groupKey != null and groupKey != ''"> |
| | | <choose> |
| | | <when test="groupColumn != null and groupColumn != ''"> |
| | | group by ${groupColumn} |
| | | order by ${groupColumn} |
| | | </when> |
| | | <when test="groupKey != null and groupKey != ''"> |
| | | group by ${groupKey} |
| | | </if> |
| | | order by ${groupKey} |
| | | </when> |
| | | </choose> |
| | | <!-- pageNum 是 1 起始的,OFFSET 必须用 (pageNum-1)*pageSize; |
| | | 以前直接写 OFFSET ${pageNum},第一页会跳掉第一条分组。 --> |
| | | <if test="pageSize != null and pageNum != null"> |
| | | limit ${pageSize} OFFSET ${pageNum} |
| | | limit ${pageSize} OFFSET ${pageOffset} |
| | | </if> |
| | | </select> |
| | | |
| | |
| | | --> |
| | | <resultMap type="com.ruoyi.task.domain.ServiceSubtaskStatistic" id="ServiceSubtaskScriptStatisticResult"> |
| | | <result property="groupCode" column="group_code"/> |
| | | <result property="groupName" column="group_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"/> |
| | |
| | | resultMap="ServiceSubtaskScriptStatisticResult"> |
| | | select |
| | | IFNULL(${groupColumn}, 'Unknown') as group_code, |
| | | <!-- 分组键对应的显示名:病区统计时就是这一组的病区名。 |
| | | 以前这一列是 MAX(hospitaldistrictname),一个组混了多个病区时会随机显示其中一个, |
| | | 于是出现“选血液内科病区却显示骨科中心三病区”。 --> |
| | | MAX(IFNULL(leavehospitaldistrictname, hospitaldistrictname)) as group_name, |
| | | MAX(drcode) as drcode, |
| | | MAX(drname) as drname, |
| | | MAX(leaveldeptcode) as deptcode, |
| | |
| | | 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 |
| | | 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="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="," |
| | |
| | | </foreach> |
| | | ) |
| | | </if> |
| | | </otherwise> |
| | | </choose> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | AND leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," |
| | |
| | | <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 |
| | | <!-- 过滤列必须与 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} |
| | |
| | | <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}) |
| | |
| | | <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="," |
| | |
| | | </foreach> |
| | | ) |
| | | </if> |
| | | </otherwise> |
| | | </choose> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | AND t.leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," |
| | |
| | | <if test="visitCount != null and visitCount > 1"> |
| | | AND t.visit_count > 1 |
| | | </if> |
| | | <if test="groupKey != null and groupKey != '' and groupKeyList != null and groupKeyList.size>0"> |
| | | <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" |
| | |
| | | and campusid = #{campusid} |
| | | </if> |
| | | <!-- 2026-10-21:病区为空时视为"不限"(南华满意度 83% 子任务无病区),有病区的数据行为不变 --> |
| | | <!-- 与 getSfStatisticsScript 的汇总行保持一致:出院病区为空则回退到在院病区, |
| | | 否则点“查看详情”查出来的条数会和汇总行的数字对不上。 --> |
| | | <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0"> |
| | | AND (leavehospitaldistrictcode IS NULL OR leavehospitaldistrictcode IN |
| | | 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 |
| | |
| | | AND ss.campusid = #{campusid} |
| | | </if> |
| | | <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0"> |
| | | AND ss.leavehospitaldistrictcode IN |
| | | 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 |
| | |
| | | and ss.campusid = #{campusid} |
| | | </if> |
| | | <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0"> |
| | | AND ss.leavehospitaldistrictcode IN |
| | | 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 |
| | |
| | | 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 = 5 OR sendstate = 7 ) THEN 1 ELSE 0 |
| | | 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, |
| | |
| | | 当前登录人「待处理」随访任务,按出院年月(endtime)分组统计,出院随访 / 门诊随访分开计数。 |
| | | 口径(与随访列表「待随访」页签一致): |
| | | 1) 出院随访 service_type = '2',门诊随访 service_type = '3' |
| | | 2) 待随访(未完成)→ sendstate IN (1,2,3,5,7),排除 4 不执行 / 6 完成 |
| | | 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 号 |
| | |
| | | FROM service_subtask |
| | | WHERE del_flag = '0' |
| | | AND service_type IN ('2', '3') |
| | | AND sendstate IN (1, 2, 3, 5, 7) |
| | | <!-- 浮窗「待处理随访任务」口径: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') |