liusheng
5 天以前 cc479e6a056785103996cc7ea67dbd5faa3e800e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?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.satisfaction.mapper.SatisfactionScriptMapper">
 
    <!--
      满意度统计取「满意度分类 / 模板问题 / 选项分值」的只读查询。
 
      与 smartor 原实现的差异(刻意为之,且不改口径):
      1) 原文用 resultMap + 共享 <sql> 片段(selectXxxVo),而片段被同文件里其它
         非满意度查询共用。这里【不复制片段】,改为显式列出满意度真正用到的列,
         避免同一份 SQL 两处维护。
      2) 完全不引用 smartor 的类型;一律用全限定类名或 java.util.Map。
      3) 全部是只读查询,不对 ivr_liba_* / svy_lib_* 做任何写操作。
 
      口径要点(必须与原文逐字一致):
      - queryIvrScriptByAssort / querySvyScriptByCategory:ids 为空时不拼 IN 条件;
      - selectIvrScriptByDimension:dimensionList 为空时拼 `dimension IS NOT NULL`;
      - selectSvyScriptByDimension:dimensionList 为空时【同样】拼该条件(原文写在 <where> 最后一行,极易看漏;早期迁移曾误判为不拼,已修正);
      - selectIvr/SvyTargetOptionScores:scriptIds 为 null 时不拼过滤,等于取全部分值。
    -->
 
    <!-- ================================================ 满意度分类(语音侧)
         原:IvrLibaScriptAssortMapper.selectIvrLibaScriptAssortList
         原文 where 里 del_flag=0 出现两次(片段后一次、末尾又一次),结果等价于一次,这里保留一次。
         注意:这里取的是【原始行】,而原服务方法 selectIvrLibaScriptAssortList 会把行拼成树、
         只返回顶层(pid is null or pid = -1)。需要顶层语义的调用方必须自己按 pid 过滤。 -->
    <select id="selectIvrCategoryList"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionCategoryRow">
        select id,
               index_assort_name as name,
               type,
               pid
        from ivr_liba_script_assort
        where del_flag = 0
        <if test="q.type != null and q.type != ''">
            and type like concat('%', #{q.type}, '%')
        </if>
        <if test="q.orgid != null and q.orgid != ''">
            and orgid = #{q.orgid}
        </if>
        order by seqno asc
    </select>
 
    <!-- ================================================ 满意度分类(问卷侧)
         原:SvyLibScriptCategoryMapper.selectSvyLibScriptCategoryList
             (该 statement 实际定义在 SvyLibTopicCategoryMapper.xml,namespace 与文件名不一致)
         注意:问卷侧原文就是直接取【全部行】(不拼树、不筛顶层),与语音侧不同。
         ⚠️ orgid 的条件与原文逐字一致:原文问卷侧是 `<if test="orgid != null">`(**没有** != ''),
            语音侧才是 `orgid != null and orgid != ''`。两侧不一致是原文行为,必须保留:
            若给问卷侧也加上 `!= ''`,当入参 orgid 为空串时,原实现按 `orgid = ''` 查(无数据),
            加了 != '' 则变成不带 orgid 条件(返回全部机构数据)—— 结果会变。 -->
    <select id="selectSvyCategoryList"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionCategoryRow">
        select id,
               name,
               type,
               pid
        from svy_lib_script_category
        where del_flag = 0
        <if test="q.type != null and q.type != ''">
            and type like concat('%', #{q.type}, '%')
        </if>
        <if test="q.orgid != null">
            and orgid = #{q.orgid}
        </if>
        order by seqno asc
    </select>
 
    <!-- ================================================ 按语音分类取问题
         原:IvrLibaTemplateScriptMapper.queryLibTemplateIds
         另外,「满意度异常配置题目」接口走的是 IvrLibaTemplateScriptMapper.selectIvrLibaTemplateScriptList
         (只 set scriptAssortid),其有效条件同样是 del_flag=0 + script_assortid 过滤,
         两条 statement 都【没有 order by】,因此本查询可一并服务两处;
         为了让该接口拿到 questionId / questionTopic / questionType / categoryId,
         这里额外多取 id、script_topic、script_type、script_assortid 四列(统计口径不使用它们)。 -->
    <select id="queryIvrScriptByAssort"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionIvrScriptRow">
        select id,
               templateid,
               scriptid,
               script_content as scriptContent,
               script_assortname as scriptAssortname,
               script_assortid as scriptAssortid,
               script_topic as scriptTopic,
               script_type as scriptType,
               dimension
        from ivr_liba_template_script
        where del_flag = 0
        <if test="q.scriptAssortids != null and q.scriptAssortids.size() > 0">
            and script_assortid in
            <foreach item="scriptAssortid" collection="q.scriptAssortids" open="(" separator="," close=")">
                #{scriptAssortid}
            </foreach>
        </if>
    </select>
 
    <!-- ================================================ 按问卷分类取问题
         原:SvyLibTemplateScriptMapper.querySvyLibTemplateIds
         注意:同时取 svyid 与 id —— 聚合统计用 svyid,选项分值关联用 id(与原文一致)
         另外,「满意度异常配置题目」接口走的是 SvyLibTemplateScriptMapper.selectSvyLibTemplateScriptList
         (只 set categoryid),其有效条件是 1=1 + del_flag=0 + categoryid 过滤,
         两条 statement 都【没有 order by】,因此本查询可一并服务两处;
         这里额外多取 script_topic、script_type、categoryid 三列(统计口径不使用它们)。 -->
    <select id="querySvyScriptByCategory"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionSvyScriptRow">
        select id,
               svyid,
               script_content as scriptContent,
               categoryName,
               categoryid,
               script_topic as scriptTopic,
               script_type as scriptType,
               dimension
        from svy_lib_template_script
        where del_flag = 0
        <if test="q.scriptCategoryids != null and q.scriptCategoryids.size() > 0">
            and categoryid in
            <foreach item="scriptCategoryid" collection="q.scriptCategoryids" open="(" separator="," close=")">
                #{scriptCategoryid}
            </foreach>
        </if>
    </select>
 
    <!-- ================================================ 按维度取问题(语音侧)
         原:IvrLibaTemplateScriptMapper.selectILTSBydimension
         口径要点:dimensionList 为空时拼 `dimension IS NOT NULL`(问卷侧原文也有,见 selectSvyScriptByDimension) -->
    <select id="selectIvrScriptByDimension"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionIvrScriptRow">
        select templateid,
               scriptid,
               script_content as scriptContent,
               script_assortname as scriptAssortname,
               dimension
        from ivr_liba_template_script
        <where>
            del_flag = 0
            <if test="q.dimensionList != null and q.dimensionList.size() > 0">
                and dimension in
                <foreach item="dimension" collection="q.dimensionList" open="(" separator="," close=")">
                    #{dimension}
                </foreach>
            </if>
            <if test="q.dimensionList == null or q.dimensionList.size() == 0">
                and dimension IS NOT NULL
            </if>
        </where>
    </select>
 
    <!-- ================================================ 按维度取问题(问卷侧)
         原:SvyLibTemplateScriptMapper.selectSLTScriptListBydimension
         ⚠️ 两侧其实【都要】拼 dimension IS NOT NULL:
            - 语音侧(selectIvrScriptByDimension)该条件紧跟在 dimensionList 分支之后;
            - 问卷侧原文把它写在 <where> 的**最后一行**(在 duty/report/circulation 那些
              满意度用不到的条件之后),容易看漏 —— 早期迁移时曾误判为"问卷侧不拼",已修正。
         ⚠️ 必须同时取 id 与 svyid 两个【不同】的列(原文的 <include> 片段就是这样):
            聚合统计(发送量/填报量)按 svyid 分组,而取「选项分值」时用的是 id(主键),
            对应 svy_lib_template_targetoption.scriptid。早期迁移时曾误写成 `svyid as id`,
            导致选项分值匹配不上 -> 最高分/最低分恒为 0.0。 -->
    <select id="selectSvyScriptByDimension"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionSvyScriptRow">
        select id,
               svyid,
               script_content as scriptContent,
               categoryName,
               dimension
        from svy_lib_template_script
        <where>
            del_flag = 0
            <if test="q.dimensionList != null and q.dimensionList.size() > 0">
                and dimension in
                <foreach item="dimension" collection="q.dimensionList" open="(" separator="," close=")">
                    #{dimension}
                </foreach>
            </if>
            <if test="q.dimensionList == null or q.dimensionList.size() == 0">
                and dimension IS NOT NULL
            </if>
        </where>
    </select>
 
    <!-- ================================================ 选项分值(语音侧)
         原:IvrLibaTemplateTargetoptionMapper.selectIvrLibaTargetoptionScores
         口径要点:scriptIds 为 null 时不拼过滤(等于取该表全部分值) -->
    <select id="selectIvrTargetOptionScores"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionOptionScoreRow">
        select scriptid as scriptid, score as score
        from ivr_liba_template_targetoption
        where del_flag = 0
        <if test="scriptIds != null and scriptIds.size() > 0">
            and scriptid IN
            <foreach collection="scriptIds" item="scriptId" open="(" separator="," close=")">
                #{scriptId}
            </foreach>
        </if>
    </select>
 
    <!-- ================================================ 选项分值(问卷侧)
         原:SvyLibTemplateTargetoptionMapper.selectSvyLibTargetoptionScores -->
    <select id="selectSvyTargetOptionScores"
            resultType="com.ruoyi.satisfaction.domain.row.SatisfactionOptionScoreRow">
        select scriptid as scriptid, score as score
        from svy_lib_template_targetoption
        where del_flag = 0
        <if test="scriptIds != null and scriptIds.size() > 0">
            and scriptid IN
            <foreach collection="scriptIds" item="scriptId" open="(" separator="," close=")">
                #{scriptId}
            </foreach>
        </if>
    </select>
 
</mapper>