| | |
| | | </if> |
| | | <if test="type != null and type != ''">and type = #{type}</if> |
| | | <if test="startTime != null"> |
| | | and visit_time >= #{startTime} |
| | | and IFNULL(visit_time, IFNULL(finishtime, create_time)) >= #{startTime} |
| | | </if> |
| | | <if test="endTime != null"> |
| | | and visit_time < date_add(#{endTime}, interval 1 day) |
| | | and IFNULL(visit_time, IFNULL(finishtime, create_time)) < date_add(#{endTime}, interval 1 day) |
| | | </if> |
| | | <if test="libTemplateIds != null and libTemplateIds.size() > 0"> |
| | | and libtemplateid IN |
| | |
| | | OR |
| | | </if> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | deptcode IN |
| | | leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <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="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"> |
| | | leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | |
| | | from service_subtask |
| | | where del_flag = 0 |
| | | <if test="questionType != null">and type = #{questionType}</if> |
| | | <!-- |
| | | 2026-10-21 修正(南华 /statistics 查不到数据): |
| | | 原来是「leavehospitaldistrictcode IN(...) AND deptcode IN(...)」两条独立条件, |
| | | 而满意度子任务(service_subtask.type=2 + service_type 6/14/15/16) |
| | | 通常只写 deptcode、leavehospitaldistrictcode 为 NULL(南华 3803 条全部为 NULL), |
| | | 两个条件永远不可能同时满足 → 该方法返回空 → 后面 hasVoice/hasQuestionnaire 都为 false |
| | | → 整个统计接口返回空。 |
| | | |
| | | 这里改成与 selectSatisfactionSendCount / selectSatisfactionFillPersonCountByQuestion |
| | | 完全一致的「科室 OR 病区」口径(同一个页面,四处 SQL 必须同口径,否则会出现 |
| | | "有类型没数据"或"有数据没类型"的割裂)。 |
| | | --> |
| | | <if test="(hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0) or (deptcodes != null and deptcodes.size() > 0)"> |
| | | AND ( |
| | | <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0"> |
| | | AND leavehospitaldistrictcode IN |
| | | <foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" separator="," |
| | | close=")"> |
| | | leavehospitaldistrictcode IN |
| | | <foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" |
| | | separator="," close=")"> |
| | | #{hospitaldistrictcode} |
| | | </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"> |
| | | AND deptcode IN |
| | | leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <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="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"> |
| | | leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <if test="serviceTypes != null and serviceTypes.size() > 0"> |
| | | AND service_type IN |
| | |
| | | #{serviceType} |
| | | </foreach> |
| | | </if> |
| | | <!-- |
| | | 时间口径:满意度子任务(type=2)的 visit_time 经常为空(南华 3803 条全为 NULL), |
| | | 只按 visit_time 过滤会把这些数据整批排除。这里按 |
| | | visit_time -> finishtime -> create_time 依次兜底,与其余三条统计 SQL 保持一致。 |
| | | --> |
| | | <if test="startTime != null and endTime != null"> |
| | | AND visit_time >= #{startTime} |
| | | AND visit_time < date_add(#{endTime}, interval 1 day) |
| | | AND IFNULL(visit_time, IFNULL(finishtime, create_time)) >= #{startTime} |
| | | AND IFNULL(visit_time, IFNULL(finishtime, create_time)) < date_add(#{endTime}, interval 1 day) |
| | | </if> |
| | | </select> |
| | | |
| | | <!-- ================================================ |
| | | 本次条件下「真正下发过任务」的模板 id(去重) |
| | | |
| | | 用途:把题库题目(svy_lib_template_script / ivr_liba_template_script) |
| | | 裁剪成本期真正在用的模板,避免「题库里挂着一堆从来没下发过的历史模板」 |
| | | 导致 /statistics 多出一整批 0 分区间的行(实测 69 行 → 应只有 25 行)。 |
| | | |
| | | ⚠️ 条件必须与 selectSatisfactionSubtaskTypes 逐条一致(只是多了 type 与 libtemplateid 两列), |
| | | 否则会出现「有类型的模板被裁掉 / 裁剪后没有数据」的割裂。 |
| | | ================================================ --> |
| | | <select id="selectSatisfactionActiveTemplateIds" resultType="java.lang.Long"> |
| | | select distinct libtemplateid |
| | | from service_subtask |
| | | where del_flag = 0 |
| | | and libtemplateid is not null |
| | | <if test="type != null and type != ''">and type = #{type}</if> |
| | | <if test="(q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0) or (q.deptcodes != null and q.deptcodes.size() > 0)"> |
| | | AND ( |
| | | <if test="q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0"> |
| | | leavehospitaldistrictcode IN |
| | | <foreach collection="q.hospitaldistrictcodes" item="hospitaldistrictcode" open="(" |
| | | separator="," close=")"> |
| | | #{hospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0 and q.deptcodes != null and q.deptcodes.size() > 0"> |
| | | OR |
| | | </if> |
| | | <if test="q.deptcodes != null and q.deptcodes.size() > 0"> |
| | | leaveldeptcode IN |
| | | <foreach collection="q.deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <if test="(q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0) or (q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0)"> |
| | | AND ( |
| | | <if test="q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0"> |
| | | leavehospitaldistrictcode IN |
| | | <foreach collection="q.leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator="," close=")"> |
| | | #{leavehospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="(q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0) and (q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0)"> |
| | | OR |
| | | </if> |
| | | <if test="q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0"> |
| | | leaveldeptcode IN |
| | | <foreach collection="q.leaveldeptcodes" item="leaveldeptcode" open="(" separator="," close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <if test="q.serviceTypes != null and q.serviceTypes.size() > 0"> |
| | | AND service_type IN |
| | | <foreach collection="q.serviceTypes" item="serviceType" open="(" separator="," close=")"> |
| | | #{serviceType} |
| | | </foreach> |
| | | </if> |
| | | <!-- 时间口径:visit_time -> finishtime -> create_time 依次兜底,与其余四条统计 SQL 保持一致 --> |
| | | <if test="q.startTime != null and q.endTime != null"> |
| | | AND IFNULL(visit_time, IFNULL(finishtime, create_time)) >= #{q.startTime} |
| | | AND IFNULL(visit_time, IFNULL(finishtime, create_time)) < date_add(#{q.endTime}, interval 1 day) |
| | | </if> |
| | | </select> |
| | | |
| | |
| | | and d.del_flag=0 |
| | | <!-- 分母必须和明细用同一套时间条件,否则选了时间范围后比例会按全量历史被稀释 --> |
| | | <if test="startOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="startFinishTime != null"> |
| | | AND date_format(s.finishtime,'%y%m%d') >= date_format(#{startFinishTime},'%y%m%d') |
| | |
| | | AND s.sendstate = 6 |
| | | and d.del_flag=0 |
| | | <if test="startOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="startFinishTime != null"> |
| | | AND date_format(s.finishtime,'%y%m%d') >= date_format(#{startFinishTime},'%y%m%d') |
| | |
| | | MAX(t.task_name) AS taskName, |
| | | d.asrtext AS optionresult, |
| | | d.score AS score, |
| | | MAX(s.deptcode) AS deptcode, |
| | | MAX(s.deptname) AS deptname, |
| | | MAX(s.leaveldeptcode) AS deptcode, |
| | | MAX(s.leaveldeptname) AS deptname, |
| | | MAX(s.leavehospitaldistrictcode) AS leavehospitaldistrictcode, |
| | | MAX(s.leavehospitaldistrictname) AS leavehospitaldistrictname, |
| | | d.targetvalue AS targetvalue, |
| | |
| | | AND d.del_flag=0 |
| | | <!-- 分母与明细用同一套时间条件,否则选了日期区间后各选项比例合计不到 100% --> |
| | | <if test="startOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="startFinishTime != null"> |
| | | AND date_format(s.finishtime,'%y%m%d') >= date_format(#{startFinishTime},'%y%m%d') |
| | |
| | | '%') |
| | | </if> |
| | | <if test="startOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') >= date_format(#{startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endOutHospTime != null"> |
| | | AND date_format(s.endtime,'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)),'%y%m%d') <= date_format(#{endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="startFinishTime != null"> |
| | | AND date_format(s.finishtime,'%y%m%d') >= date_format(#{startFinishTime},'%y%m%d') |
| | |
| | | <select id="statQuestionOptionByKsOrBq" resultType="com.ruoyi.satisfaction.domain.dto.QuestionCountKsOrBqDTO" |
| | | parameterType="com.ruoyi.satisfaction.domain.vo.QuestionCountKsOrBqVO"> |
| | | SELECT |
| | | s.deptname AS deptname, |
| | | s.leavehospitaldistrictname AS leavehospitaldistrictname, |
| | | IFNULL(s.leaveldeptname, s.deptname) AS deptname, |
| | | IFNULL(s.leavehospitaldistrictname, s.hospitaldistrictname) AS leavehospitaldistrictname, |
| | | d.questiontext AS questionText, |
| | | d.targetvalue AS targetvalue, -- 所有选项拼接 |
| | | d.asrtext AS asrtext, -- 用户实际选中的选项 |
| | |
| | | </foreach> |
| | | </if> |
| | | <if test=" leaveldeptcodes != null and leaveldeptcodes.size()>0"> |
| | | AND deptcode IN |
| | | AND leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," |
| | | close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | <!-- 在院满意度:按在院病区/在院科室列过滤(只在传了这组参数时生效) --> |
| | | <if test="hospitaldistrictcodes != null and hospitaldistrictcodes.size() > 0"> |
| | | AND hospitaldistrictcode IN |
| | | <foreach collection="hospitaldistrictcodes" item="hospitaldistrictcode" open="(" |
| | | separator="," |
| | | close=")"> |
| | | #{hospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | AND deptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," |
| | | close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </if> |
| | | <!-- |
| | | 2026-10-21 修正:原来 deptOrDistrict==2 时写的是 |
| | | 「AND leavehospitaldistrictcode IN (...) OR deptcode IN (...)」, |
| | | 没有括号 —— SQL 里 AND 优先级高于 OR,实际等价于 |
| | | (全部 AND 条件 AND 病区 IN ...) OR 科室 IN ... |
| | | 于是「科室命中」那一支完全绕过了 service_type / 日期 / del_flag 等所有条件, |
| | | 南华(病区为空、按科室查)会捞回全库历史数据 → 数据明显不对。 |
| | | 这里补齐括号,让 2 = 科室 OR 病区。 |
| | | --> |
| | | <if test="deptOrDistrict ==2"> |
| | | AND ( |
| | | <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size() > 0"> |
| | | AND leavehospitaldistrictcode IN |
| | | 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"> |
| | | OR deptcode IN |
| | | leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," |
| | | close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | </select> |
| | | |
| | |
| | | s.leavehospitaldistrictname AS name, |
| | | </when> |
| | | <otherwise> |
| | | s.deptcode AS code, |
| | | s.deptname AS name, |
| | | s.leaveldeptcode AS code, |
| | | s.leaveldeptname AS name, |
| | | </otherwise> |
| | | </choose> |
| | | CAST(d.score AS DECIMAL(10,4)) AS w |
| | |
| | | </if> |
| | | </when> |
| | | <otherwise> |
| | | AND s.deptcode IS NOT NULL AND s.deptcode <> '' |
| | | AND s.deptname IS NOT NULL AND s.deptname <> '' |
| | | AND s.leaveldeptcode IS NOT NULL AND s.leaveldeptcode <> '' |
| | | AND s.leaveldeptname IS NOT NULL AND s.leaveldeptname <> '' |
| | | <if test="deptCodes != null and deptCodes.size() > 0"> |
| | | AND s.deptcode IN |
| | | AND s.leaveldeptcode IN |
| | | <foreach collection="deptCodes" item="deptCode" open="(" separator="," close=")"> |
| | | #{deptCode} |
| | | </foreach> |
| | |
| | | </if> |
| | | <if test="type != null and type != ''">and ss.type = #{type}</if> |
| | | <if test="startTime != null"> |
| | | and ss.visit_time >= #{startTime} |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) >= #{startTime} |
| | | </if> |
| | | <if test="endTime != null"> |
| | | and ss.visit_time < date_add(#{endTime}, interval 1 day) |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) < date_add(#{endTime}, interval 1 day) |
| | | </if> |
| | | <if test="libTemplateIds != null and libTemplateIds.size() > 0"> |
| | | and ss.libtemplateid IN |
| | |
| | | OR |
| | | </if> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | ss.deptcode IN |
| | | ss.leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <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> |
| | | <if test="type != null and type != ''">and ss.type = #{type}</if> |
| | | <if test="startTime != null"> |
| | | and ss.visit_time >= #{startTime} |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) >= #{startTime} |
| | | </if> |
| | | <if test="endTime != null"> |
| | | and ss.visit_time < date_add(#{endTime}, interval 1 day) |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) < date_add(#{endTime}, interval 1 day) |
| | | </if> |
| | | <if test="libTemplateIds != null and libTemplateIds.size() > 0"> |
| | | and ss.libtemplateid IN |
| | |
| | | OR |
| | | </if> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | ss.deptcode IN |
| | | ss.leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <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> |
| | | <if test="type != null and type != ''">and ss.type = #{type}</if> |
| | | <if test="startTime != null"> |
| | | and ss.visit_time >= #{startTime} |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) >= #{startTime} |
| | | </if> |
| | | <if test="endTime != null"> |
| | | and ss.visit_time < date_add(#{endTime}, interval 1 day) |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) < date_add(#{endTime}, interval 1 day) |
| | | </if> |
| | | <if test="libTemplateIds != null and libTemplateIds.size() > 0"> |
| | | and ss.libtemplateid IN |
| | |
| | | OR |
| | | </if> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | ss.deptcode IN |
| | | ss.leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <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> |
| | | <if test="type != null and type != ''">and ss.type = #{type}</if> |
| | | <if test="startTime != null"> |
| | | and ss.visit_time >= #{startTime} |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) >= #{startTime} |
| | | </if> |
| | | <if test="endTime != null"> |
| | | and ss.visit_time < date_add(#{endTime}, interval 1 day) |
| | | and IFNULL(ss.visit_time, IFNULL(ss.finishtime, ss.create_time)) < date_add(#{endTime}, interval 1 day) |
| | | </if> |
| | | <if test="libTemplateIds != null and libTemplateIds.size() > 0"> |
| | | and ss.libtemplateid IN |
| | |
| | | OR |
| | | </if> |
| | | <if test="deptcodes != null and deptcodes.size() > 0"> |
| | | ss.deptcode IN |
| | | ss.leaveldeptcode IN |
| | | <foreach collection="deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | ) |
| | | </if> |
| | | <!-- 离院满意度:按离院科室/病区过滤(科室 OR 病区,与页面口径一致) --> |
| | | <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> |
| | | ) |
| | |
| | | AND service_type = #{q.serviceType} |
| | | </if> |
| | | <if test="q.startOutHospTime != null"> |
| | | AND date_format(endtime,'%y%m%d') >= date_format(#{q.startOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(endtime, IFNULL(finishtime, create_time)),'%y%m%d') >= date_format(#{q.startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="q.endOutHospTime != null"> |
| | | AND date_format(endtime,'%y%m%d') <= date_format(#{q.endOutHospTime},'%y%m%d') |
| | | AND date_format(IFNULL(endtime, IFNULL(finishtime, create_time)),'%y%m%d') <= date_format(#{q.endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <!-- |
| | | 2026-10-21 新增:按「完成时间」过滤(页面提交的 startFinishTime / endFinishTime)。 |
| | | 口径与 statQuestionOptionBySubtaskIds 里的 |
| | | date_format(s.finishtime,'%y%m%d') 区间完全等价(参数都是 yyyy-MM-dd 零点), |
| | | 但这里刻意写成 finishtime 的裸区间而不用 date_format(): |
| | | 列上套函数会让索引失效,裸区间才能走 (…, finishtime) 索引。 |
| | | 上线前这里完全没有时间条件,service_subtask 会被整表扫描, |
| | | 下游再把所有历史满意度子任务 id 灌进 IN 列表 —— 这是该接口慢的主因。 |
| | | --> |
| | | <if test="q.startFinishTime != null"> |
| | | AND finishtime >= #{q.startFinishTime} |
| | | </if> |
| | | <if test="q.endFinishTime != null"> |
| | | AND finishtime < DATE_ADD(#{q.endFinishTime}, INTERVAL 1 DAY) |
| | | </if> |
| | | <!-- |
| | | 科室 / 病区口径(2026-10-21 重构:过滤哪一列由入参决定) |
| | | ================================================================== |
| | | 四个参数各自对应一列,谁传进来就过滤谁,不再一律按「离院病区」过滤: |
| | | hospitaldistrictcodes → hospitaldistrictcode 在院/当前病区 |
| | | leavehospitaldistrictcodes → leavehospitaldistrictcode 离院病区 |
| | | deptcodes → deptcode 在院/当前科室 |
| | | leaveldeptcodes → leaveldeptcode 离院科室 |
| | | 同一维度里两个参数都传(少见)时按 OR —— 它们是同一件事的两个列写法; |
| | | 病区维度与科室维度之间由 deptOrDistrict 决定:1/3 = AND,2/4 = OR。 |
| | | 背景:南华这批数据的病区写在 hospitaldistrictcode(实测 40003514 有 409 条), |
| | | leavehospitaldistrictcode 基本为空;只认离院病区会让统计只剩 5 条。 |
| | | --> |
| | | <!-- 1/3:病区 AND 科室 --> |
| | | <if test="q.deptOrDistrict==1"> |
| | | <if test="(q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0) or (q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0)"> |
| | | AND ( |
| | | <trim prefixOverrides="OR"> |
| | | <if test="q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0"> |
| | | hospitaldistrictcode IN |
| | | <foreach collection="q.hospitaldistrictcodes" item="districtcode" open="(" separator="," close=")"> |
| | | #{districtcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0"> |
| | | AND leavehospitaldistrictcode IN |
| | | OR leavehospitaldistrictcode IN |
| | | <foreach collection="q.leavehospitaldistrictcodes" item="districtcode" open="(" separator="," close=")"> |
| | | #{districtcode} |
| | | </foreach> |
| | | </if> |
| | | </trim> |
| | | ) |
| | | </if> |
| | | <if test="(q.deptcodes != null and q.deptcodes.size() > 0) or (q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0)"> |
| | | AND ( |
| | | <trim prefixOverrides="OR"> |
| | | <if test="q.deptcodes != null and q.deptcodes.size() > 0"> |
| | | deptcode IN |
| | | <foreach collection="q.deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0"> |
| | | AND deptcode IN |
| | | OR leaveldeptcode IN |
| | | <foreach collection="q.leaveldeptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </trim> |
| | | ) |
| | | </if> |
| | | </if> |
| | | <!-- 2/4:病区 OR 科室 --> |
| | | <if test="q.deptOrDistrict==2"> |
| | | <if test="(q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0) or (q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0) or (q.deptcodes != null and q.deptcodes.size() > 0) or (q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0)"> |
| | | AND ( |
| | | <trim prefixOverrides="OR"> |
| | | <if test="q.hospitaldistrictcodes != null and q.hospitaldistrictcodes.size() > 0"> |
| | | hospitaldistrictcode IN |
| | | <foreach collection="q.hospitaldistrictcodes" item="districtcode" open="(" separator="," close=")"> |
| | | #{districtcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.leavehospitaldistrictcodes != null and q.leavehospitaldistrictcodes.size() > 0"> |
| | | OR leavehospitaldistrictcode IN |
| | | <foreach collection="q.leavehospitaldistrictcodes" item="districtcode" open="(" separator="," close=")"> |
| | | #{districtcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.deptcodes != null and q.deptcodes.size() > 0"> |
| | | OR deptcode IN |
| | | <foreach collection="q.deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0"> |
| | | OR leaveldeptcode IN |
| | | <foreach collection="q.leaveldeptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </trim> |
| | | ) |
| | | </if> |
| | | </if> |
| | | <!-- 其它取值:保持旧行为,只看科室(列同样按入参区分) --> |
| | | <if test="q.deptOrDistrict != null and q.deptOrDistrict != '1' and q.deptOrDistrict != '2'"> |
| | | <if test="q.deptcodes != null and q.deptcodes.size() > 0"> |
| | | AND deptcode IN |
| | | <foreach collection="q.deptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="q.leaveldeptcodes != null and q.leaveldeptcodes.size() > 0"> |
| | | AND leaveldeptcode IN |
| | | <foreach collection="q.leaveldeptcodes" item="deptcode" open="(" separator="," close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | </if> |
| | | </select> |
| | | |
| | | <!-- ================================================================ |