-- ============================================================================
|
-- 南华附一(nhfy):满意度统计 4 个接口"数据不对" —— 定位与修复
|
-- · POST /smartor/serviceSubtaskDetail/sltdMydTotalByScore
|
-- · POST /smartor/serviceSubtaskDetail/statQuestionOptionByKsOrBq (页面调了 3 次)
|
-- 2026-10-21
|
--
|
-- 【根因(3 个,均已在库上量化)】
|
--
|
-- ① 出院时间过滤用的是 endtime,而南华满意度子任务的 endtime 大量为空
|
-- service_subtask.endtime:3803 条满意度子任务中 3151 条为 NULL(83%)。
|
-- 而 selectMydSubtaskRefs / statQuestionOption / statQuestionOptionBySubtaskIds
|
-- 四个 statement 的"出院时间区间"都直接 date_format(s.endtime,...) 过滤
|
-- → 页面一选出院日期,数据就被筛掉大半(实测:加 2026-07-23~2026-10-21 后 refs = 0)。
|
-- 修复:统一改为 IFNULL(s.endtime, IFNULL(s.finishtime, s.create_time)) 兜底。
|
-- 修复后同一条件 refs = 387(= 满意度 sendstate=6 的 380 + 未完成 7)。
|
--
|
-- ② statQuestionOptionByKsOrBq 的「科室 OR 病区」少了括号(真 Bug,同德也错)
|
-- 原 SQL(deptOrDistrict==2 分支):
|
-- AND leavehospitaldistrictcode IN (...) OR deptcode IN (...)
|
-- AND 优先级高于 OR,实际等价于
|
-- (所有 AND 条件 AND 病区 IN ...) OR 科室 IN ...
|
-- → "科室命中"那一支完全绕过了 service_type / 日期 / del_flag 条件。
|
-- 实测(南华、科室 40003511、2026-07-23~2026-10-21):
|
-- 修正前 17604 行 修正后 7220 行 (多算了 2.4 倍,全是历史/其它任务类型)
|
-- 修复:改成 AND (病区 IN (...) OR 科室 IN (...))。
|
--
|
-- ③ 综合得分口径写死成省立同德(SLTD)五档文案
|
-- SltdSatisfactionController#calcMydScore 里 resolve(SatisfactionSites.SLTD) 是硬编码。
|
-- 同德口径靠选项文案 "很满意/满意/一般/不满意/很不满意" 判档,
|
-- 而南华问卷(模板 514 / libtemplateid 200)的选项是「是(有)/(总是)很安静/很熟练/主动讲过…」
|
-- → 一条都匹配不上 → 得分恒为 "0.00"。
|
-- 修复:站点改由 sys_config: satisfaction.site 决定(默认 sltd,保持同德不变);
|
-- 南华可配 common(= 按明细 score 求平均)。
|
--
|
-- ⚠️ 但要注意:南华这个问卷**根本没配分值**
|
-- svy_task_template_script.score(模板514,19题) = '00000000000'
|
-- svy_task_template_targetoption.score(58个选项) = 0
|
-- service_subtask_detail.score(63108 行) = 0 / '00000000000'
|
-- 所以即便切到 common 口径,综合得分仍然是 0.00。
|
-- 要出得分,必须先给选项/题目配分值(业务配置),否则这个列对南华没有意义。
|
--
|
-- 【已改的代码】ruoyi-satisfaction
|
-- · SatisfactionMapper.xml
|
-- - selectMydSubtaskRefs / statQuestionOption / statQuestionOptionBySubtaskIds:
|
-- 出院时间 endtime → IFNULL(endtime, finishtime, create_time)
|
-- - selectMydSubtaskRefs:deptOrDistrict 补上 2(OR)分支(原来只在 1 时拼病区,科室却无条件拼)
|
-- - statQuestionOptionByKsOrBq:deptOrDistrict==2 的 OR 补括号
|
-- · SatisfactionSwitch:新增 site(),读 sys_config: satisfaction.site(10 秒进程内缓存)
|
-- · SltdSatisfactionController#calcMydScore:改为 resolve(satisfactionSwitch.site())
|
--
|
-- 【修复后实测(条件:科室 40003511 / 病区 40003514 / 2026-07-23~2026-10-21)】
|
-- refs = 387;按科室分组选项分布正常,例如「肿瘤科一病房」每题 379 人
|
-- ============================================================================
|
|
|
-- ----------------------------------------------------------------------------
|
-- 【0】证据 SQL(随时可重跑)
|
-- ----------------------------------------------------------------------------
|
-- ① 出院时间为空的比例
|
SELECT COUNT(*) AS rows_total,
|
SUM(endtime IS NULL) AS endtime_null,
|
SUM(leavehospitaldistrictname IS NULL OR leavehospitaldistrictname = '') AS district_name_empty
|
FROM service_subtask
|
WHERE del_flag = 0 AND type = '2' AND service_type IN ('6', '14', '15', '16');
|
|
-- ② OR 漏括号的影响面(修正前 vs 修正后)
|
SELECT '修正前(无括号)' AS version, COUNT(*) AS rows_cnt
|
FROM service_subtask_detail d
|
JOIN service_subtask s ON d.sub_id = s.id
|
WHERE s.del_flag = 0 AND d.del_flag = 0 AND s.service_type IN ('6', '14')
|
AND d.create_time >= '2026-07-23 00:00:00'
|
AND d.create_time < date_add('2026-10-21', interval 1 day)
|
AND s.leavehospitaldistrictcode IN ('40003514') OR s.deptcode IN ('40003511');
|
|
SELECT '修正后(括号包住 OR)' AS version, COUNT(*) AS rows_cnt
|
FROM service_subtask_detail d
|
JOIN service_subtask s ON d.sub_id = s.id
|
WHERE s.del_flag = 0 AND d.del_flag = 0 AND s.service_type IN ('6', '14')
|
AND d.create_time >= '2026-07-23 00:00:00'
|
AND d.create_time < date_add('2026-10-21', interval 1 day)
|
AND (s.leavehospitaldistrictcode IN ('40003514') OR s.deptcode IN ('40003511'));
|
|
-- ③ 分值到底有没有配(三个层面都看一眼)
|
SELECT '题目分值' AS layer, score, COUNT(*) AS cnt
|
FROM svy_task_template_script WHERE templateID = 514 AND del_flag = 0 GROUP BY score
|
UNION ALL
|
SELECT '选项分值', o.score, COUNT(*)
|
FROM svy_task_template_targetoption o
|
JOIN svy_task_template_script s ON s.id = o.scriptid
|
WHERE s.templateID = 514 AND s.del_flag = 0 GROUP BY o.score
|
UNION ALL
|
SELECT '明细分值', d.score, COUNT(*)
|
FROM service_subtask_detail d
|
JOIN service_subtask ss ON ss.id = d.sub_id
|
WHERE ss.type = '2' AND ss.service_type IN ('6', '14') AND d.del_flag = 0
|
GROUP BY d.score;
|
|
|
-- ----------------------------------------------------------------------------
|
-- 【1】可选配置:综合得分口径站点(不改也能跑,只是得分口径按同德)
|
-- 同德:保持默认 sltd(或显式配置 sltd)
|
-- 南华:配 common —— ⚠️ 前提是问卷选项/题目配了分值,否则得分仍是 0.00
|
-- ----------------------------------------------------------------------------
|
-- INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
-- VALUES ('满意度综合得分口径', 'satisfaction.site', 'common', 'Y', 'admin', sysdate(),
|
-- 'sltd=省立同德五档文案加权(默认);common/nanhua=按明细 score 求平均');
|
|
-- 校验
|
-- SELECT config_key, config_value FROM sys_config WHERE config_key = 'satisfaction.site';
|
|
|
-- ----------------------------------------------------------------------------
|
-- 【2】可选数据/配置:让「综合得分」对南华有意义
|
-- 当前模板 514 的 19 道题、58 个选项分值全是 0,任何口径都算不出分。
|
-- 若医院接受"五档之外按 满足/部分满足/不满足 打分",请业务在
|
-- 「问卷模板 → 题目选项」里给每个选项配置分值,之后:
|
-- · 站点口径建议配 common(按明细 score 求平均,百分制)
|
-- · 历史明细的 score 不会自动回填,需另行评估要不要按选项补历史分值
|
-- ----------------------------------------------------------------------------
|
|
|
-- ----------------------------------------------------------------------------
|
-- 【3】验证:修正后的 refs 与按科室的选项分布
|
-- ----------------------------------------------------------------------------
|
SELECT COUNT(*) AS refs
|
FROM service_subtask
|
WHERE del_flag = 0
|
AND orgid = '20001001' AND campusid = '30001002'
|
AND service_type = '6'
|
AND date_format(IFNULL(endtime, IFNULL(finishtime, create_time)), '%y%m%d') >= date_format('2026-07-23', '%y%m%d')
|
AND date_format(IFNULL(endtime, IFNULL(finishtime, create_time)), '%y%m%d') <= date_format('2026-10-21', '%y%m%d')
|
AND (leavehospitaldistrictcode IN ('40003514') OR deptcode IN ('40003511'));
|
|
SELECT s.deptname, d.questiontext, d.asrtext, COUNT(*) AS cnt
|
FROM service_subtask_detail d
|
JOIN service_subtask s ON d.sub_id = s.id
|
WHERE s.del_flag = 0 AND d.del_flag = 0 AND s.service_type IN ('6', '14')
|
AND d.create_time >= '2026-07-23 00:00:00'
|
AND d.create_time < date_add('2026-10-21', interval 1 day)
|
AND (s.leavehospitaldistrictcode IN ('40003514') OR s.deptcode IN ('40003511'))
|
GROUP BY s.deptname, d.questiontext, d.asrtext
|
ORDER BY cnt DESC
|
LIMIT 5;
|
|
|
-- ============================================================================
|
-- 【另需注意(未改,属产品口径)】
|
-- 1) statQuestionOptionByKsOrBq 的 Java 侧按 deptname / leavehospitaldistrictname 分组,
|
-- 分组名为空直接跳过。南华满意度子的 leavehospitaldistrictname 有 3228/3803 为空,
|
-- 所以页面上「按病区」这个维度对南华基本是空的——不是取数错,是数据里没有病区。
|
-- 2) 同一页面的 mydTrend / sltdMydTotalByDimension / mzMydScoreRank 也都是同德口径
|
-- (出院时间、病区维度),南华要用需按同样思路逐个核对。
|
-- ============================================================================
|