liusheng
2026-10-08 0bc3fc0304d163c9e54e4e36f45f72ce1b1d59fb
smartor/src/main/resources/mapper/smartor/ServiceSubtaskDetailTraceMapper.xml
@@ -59,14 +59,33 @@
        <result property="dutyDeptPersonCode" column="duty_dept_person_code"/>
        <result property="reportDeptPersonCode" column="report_dept_person_name"/>
        <result property="reportDeptPersonName" column="report_dept_person_code"/>
        <result property="circulationDeptPersonCode" column="circulation_dept_person_code"/>
        <result property="circulationDeptPersonName" column="circulation_dept_person_name"/>
        <result property="circulationDeptCode" column="circulation_dept_code"/>
        <result property="circulationDeptName" column="circulation_dept_name"/>
        <result property="circulationExplain" column="circulation_explain"/>
        <result property="circulationTime" column="circulation_time"/>
        <result property="circulationStatus" column="circulation_status"/>
        <result property="circulationPersonName" column="circulation_person_name"/>
        <result property="circulationPersonCode" column="circulation_person_code"/>
    </resultMap>
    <sql id="selectServiceSubtaskDetailTtraceVo">
        select id,
               circulation_status,
               circulation_person_name,
               circulation_person_code,
               duty_dept_person_name,
               duty_dept_person_code,
               report_dept_person_name,
               report_dept_person_code,
               circulation_dept_person_code,
               circulation_dept_person_name,
               circulation_dept_code,
               circulation_dept_name,
               circulation_explain,
               circulation_time,
               detail_id,
               is_myd_exception,
               dimension,
@@ -277,55 +296,193 @@
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">
            and report_dept_person_code like concat('%', #{reportDeptPersonCode}, '%')
        </if>
        <if test="circulationDeptPersonCode != null  and circulationDeptPersonCode != ''">
            and circulation_dept_person_code like concat('%', #{circulationDeptPersonCode}, '%')
        </if>
        <if test="circulationDeptPersonName != null  and circulationDeptPersonName != ''">
            and circulation_dept_person_name like concat('%', #{circulationDeptPersonName}, '%')
        </if>
        <if test="circulationDeptCode != null  and circulationDeptCode != ''">
            and circulation_dept_code like concat('%', #{circulationDeptCode}, '%')
        </if>
        <if test="circulationDeptName != null  and circulationDeptName != ''">
            and circulation_dept_name like concat('%', #{circulationDeptName}, '%')
        </if>
        <if test="circulationExplain != null  and circulationExplain != ''">
            and circulation_explain like concat('%', #{circulationExplain}, '%')
        </if>
        <if test="circulationTime != null ">
            and circulation_time = #{circulationTime}
        </if>
        <if test="circulationStatus != null ">
            and circulation_status = #{circulationStatus}
        </if>
        <if test="circulationPersonName != null  and circulationPersonName != ''">
            and circulation_person_name like concat('%', #{circulationPersonName}, '%')
        </if>
        <if test="circulationPersonCode != null  and circulationPersonCode != ''">
            and circulation_person_code =#{circulationPersonCode}
        </if>
        <if test="pageSize != null  and pageNum != null">limit ${pageSize} OFFSET ${pageNum}</if>
    </select>
    <select id="tracedeallist" parameterType="com.smartor.domain.VO.DetailTraceDealVO"
            resultMap="ServiceSubtaskDetailTtraceResult">
        <include refid="selectServiceSubtaskDetailTtraceVo"/>
        where del_flag=0
    <!--
        异常问题处理情况查询(tracedeallist)的公共过滤条件。
        下面 5 条 SQL 共用本片段,保证「分页数据、问题总数、全量汇总」的口径完全一致。
        注意:questiontext 为空的行原实现里被 stream().filter(questiontext != null) 丢掉了,
        所以这里统一排除,汇总数才和原来一致。
    -->
    <sql id="traceDealWhere">
        and del_flag = 0
        and questiontext is not null
        <if test="vo.templateid != null  and vo.templateid != ''">
            and templateid = #{vo.templateid}
        </if>
        <if test="vo.todeptcode != null  and vo.todeptcode != ''">
            and FIND_IN_SET(#{vo.todeptcode}, todeptcode)
        </if>
        <if test="vo.todeptname != null  and vo.todeptname != ''">
            and todeptname like concat('%', #{vo.todeptname}, '%')
        </if>
        <if test="vo.handleStartTime != null and vo.handleEndTime != null">
            and handle_time between #{vo.handleStartTime} and #{vo.handleEndTime}
        </if>
        <if test="vo.orgid != null  and vo.orgid != ''">
            and orgid = #{vo.orgid}
        </if>
        <if test="vo.type != null  and vo.type != ''">
            and type = #{vo.type}
        </if>
        <if test="vo.templateType != null">
            and template_type = #{vo.templateType}
        </if>
        <if test="vo.isMydException != null ">
            and is_myd_exception = #{vo.isMydException}
        </if>
        <if test="vo.dimension != null  and vo.dimension != ''">
            and dimension = #{vo.dimension}
        </if>
        <if test="vo.dutyDeptPersonName != null  and vo.dutyDeptPersonName != ''">
            and duty_dept_person_name like concat('%', #{vo.dutyDeptPersonName}, '%')
        </if>
        <if test="vo.dutyDeptPersonCode != null  and vo.dutyDeptPersonCode != ''">
            and duty_dept_person_code like concat('%', #{vo.dutyDeptPersonCode}, '%')
        </if>
        <if test="vo.reportDeptPersonName != null  and vo.reportDeptPersonName != ''">
            and report_dept_person_name like concat('%', #{vo.reportDeptPersonName}, '%')
        </if>
        <if test="vo.reportDeptPersonCode != null  and vo.reportDeptPersonCode != ''">
            and report_dept_person_code like concat('%', #{vo.reportDeptPersonCode}, '%')
        </if>
        <if test="vo.circulationDeptPersonCode != null  and vo.circulationDeptPersonCode != ''">
            and circulation_dept_person_code like concat('%', #{vo.circulationDeptPersonCode}, '%')
        </if>
        <if test="vo.circulationDeptPersonName != null  and vo.circulationDeptPersonName != ''">
            and circulation_dept_person_name like concat('%', #{vo.circulationDeptPersonName}, '%')
        </if>
        <if test="vo.circulationDeptCode != null  and vo.circulationDeptCode != ''">
            and circulation_dept_code like concat('%', #{vo.circulationDeptCode}, '%')
        </if>
        <if test="vo.circulationDeptName != null  and vo.circulationDeptName != ''">
            and circulation_dept_name like concat('%', #{vo.circulationDeptName}, '%')
        </if>
        <if test="vo.circulationExplain != null  and vo.circulationExplain != ''">
            and circulation_explain like concat('%', #{vo.circulationExplain}, '%')
        </if>
        <if test="vo.circulationTime != null ">
            and circulation_time = #{vo.circulationTime}
        </if>
        <if test="vo.circulationStatus != null ">
            and circulation_status = #{vo.circulationStatus}
        </if>
        <if test="vo.circulationPersonName != null  and vo.circulationPersonName != ''">
            and circulation_person_name like concat('%', #{vo.circulationPersonName}, '%')
        </if>
        <if test="vo.circulationPersonCode != null  and vo.circulationPersonCode != ''">
            and circulation_person_code = #{vo.circulationPersonCode}
        </if>
    </sql>
        <if test="templateid != null  and templateid != ''">
            and templateid = #{templateid}
        </if>
        <if test="todeptcode != null  and todeptcode != ''">
            and FIND_IN_SET(#{todeptcode}, todeptcode)
        </if>
        <if test="todeptname != null  and todeptname != ''">
            and todeptname like concat('%', #{todeptname}, '%')
        </if>
        <if test="handleStartTime != null and handleEndTime != null">
            and handle_time between #{handleStartTime} and #{handleEndTime}
        </if>
    <!--
        当前页的问题分组聚合:分页按问题维度下推到 SQL。
        原来是把 service_subtask_detail_trace 全表(含 patdesc/recordurl 等大字段)拉回 Java 再分组,
        pageSize 完全没生效;现在 DB 只处理当前页的题目。
        <if test="orgid != null  and orgid != ''">
            and orgid = #{orgid}
        注意分组维度必须是 questiontext(接口文档约定「每个问题对应一条记录」):
        一个 questiontext 可能对应多个 scriptid,这时要把该问题所有 scriptid 的有效填写数加起来,
        所以这里用 group_concat(distinct scriptid) 把 scriptid 列表带回 Java(scriptid 取最小值用于展示)。
        如果改成 group by questiontext, scriptid,同一个问题会拆成多行,
        与 countTraceDealQuestions(按 questiontext 去重)、total、负责科室、最新处理人的口径都会不一致。
    -->
    <select id="selectTraceDealGroups" resultType="java.util.Map">
        select questiontext                                        as questiontext,
               min(scriptid)                                       as scriptid,
               group_concat(distinct scriptid)                      as scriptids,
               min(template_type)                                  as templateType,
               count(*)                                            as exceptionFillNum,
               sum(case when handle_flag = '1' then 1 else 0 end)   as yesDeal,
               sum(case when handle_flag = '1' then 0 else 1 end)   as noDeal
        from service_subtask_detail_trace
        where 1 = 1
        <include refid="traceDealWhere"/>
        group by questiontext
        order by questiontext
        <if test="vo.pageSize != null and vo.pageNum != null">
            limit ${vo.pageSize} offset ${vo.pageNum}
        </if>
    </select>
        <if test="type != null  and type != ''">
            and type = #{type}
        </if>
        <if test="templateType != null">
            and template_type = #{templateType}
        </if>
        <if test="isMydException != null ">
            and is_myd_exception = #{isMydException}
        </if>
        <if test="dimension != null  and dimension != ''">
            and dimension = #{dimension}
        </if>
        <if test="dutyDeptPersonName != null  and dutyDeptPersonName != ''">
            and duty_dept_person_name like concat('%', #{dutyDeptPersonName}, '%')
        </if>
        <if test="dutyDeptPersonCode != null  and dutyDeptPersonCode != ''">
            and duty_dept_person_code like concat('%', #{dutyDeptPersonCode}, '%')
        </if>
        <if test="reportDeptPersonName != null  and reportDeptPersonName != ''">
            and report_dept_person_name like concat('%', #{reportDeptPersonName}, '%')
        </if>
        <if test="reportDeptPersonCode != null  and reportDeptPersonCode != ''">
            and report_dept_person_code like concat('%', #{reportDeptPersonCode}, '%')
        </if>
    <!-- 问题总数(分页 total,按问题维度) -->
    <select id="countTraceDealQuestions" resultType="long">
        select count(distinct questiontext)
        from service_subtask_detail_trace
        where 1 = 1
        <include refid="traceDealWhere"/>
    </select>
    <!-- 全量汇总(不受分页影响):总数 + 已处理数,未处理数在 Java 里相减 -->
    <select id="sumTraceDeal" resultType="java.util.Map">
        select count(*)                                          as totalException,
               sum(case when handle_flag = '1' then 1 else 0 end) as yesDeal
        from service_subtask_detail_trace
        where 1 = 1
        <include refid="traceDealWhere"/>
    </select>
    <!-- 当前页问题的负责科室(按科室编号去重,名称取组内非空的一个) -->
    <select id="selectTraceDealDepts" resultType="java.util.Map">
        select questiontext      as questiontext,
               todeptcode        as deptCode,
               min(todeptname)   as deptName
        from service_subtask_detail_trace
        where 1 = 1
        <include refid="traceDealWhere"/>
        and todeptcode is not null and todeptcode != ''
        and questiontext in
        <foreach collection="questiontexts" item="qt" open="(" separator="," close=")">
            #{qt}
        </foreach>
        group by questiontext, todeptcode
    </select>
    <!-- 当前页问题的最新处理人和处理时间(handle_time 最大的一条) -->
    <select id="selectTraceDealLatestHandle" resultType="java.util.Map">
        select t.questiontext as questiontext,
               t.handle_by    as handleBy,
               t.handle_time  as handleTime
        from service_subtask_detail_trace t
                 inner join (select questiontext, max(handle_time) as maxHandleTime
                             from service_subtask_detail_trace
                             where 1 = 1
                             <include refid="traceDealWhere"/>
                             and handle_time is not null
                             and questiontext in
                             <foreach collection="questiontexts" item="qt" open="(" separator="," close=")">
                                 #{qt}
                             </foreach>
                             group by questiontext) m
                            on m.questiontext = t.questiontext and m.maxHandleTime = t.handle_time
        where t.del_flag = 0
    </select>
@@ -447,6 +604,31 @@
            </if>
            <if test="reportDeptPersonCode != null">report_dept_person_code,
            </if>
            <if test="circulationDeptPersonCode != null">circulation_dept_person_code,
            </if>
            <if test="circulationDeptPersonName != null">circulation_dept_person_name,
            </if>
            <if test="circulationDeptCode != null ">
                circulation_dept_code,
            </if>
            <if test="circulationDeptName != null">
                circulation_dept_name,
            </if>
            <if test="circulationExplain != null ">
                circulation_explain,
            </if>
            <if test="circulationTime != null ">
                circulation_time,
            </if>
            <if test="circulationStatus != null ">
                circulation_status,
            </if>
            <if test="circulationPersonName != null  and circulationPersonName != ''">
                circulation_person_name,
            </if>
            <if test="circulationPersonCode != null  and circulationPersonCode != ''">
                circulation_person_code,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="detailId != null">#{detailId},
@@ -556,6 +738,31 @@
            <if test="reportDeptPersonName != null">#{reportDeptPersonName},
            </if>
            <if test="reportDeptPersonCode != null">#{reportDeptPersonCode},
            </if>
            <if test="circulationDeptPersonCode != null">#{circulationDeptPersonCode},
            </if>
            <if test="circulationDeptPersonName != null">#{circulationDeptPersonName},
            </if>
            <if test="circulationDeptCode != null">
                #{circulationDeptCode},
            </if>
            <if test="circulationDeptName != null">
                #{circulationDeptName},
            </if>
            <if test="circulationExplain != null">
                #{circulationExplain},
            </if>
            <if test="circulationTime != null ">
                #{circulationTime},
            </if>
            <if test="circulationStatus != null ">
               #{circulationStatus},
            </if>
            <if test="circulationPersonName != null  and circulationPersonName != ''">
               #{circulationPersonName},
            </if>
            <if test="circulationPersonCode != null  and circulationPersonCode != ''">
              #{circulationPersonCode},
            </if>
        </trim>
    </insert>
@@ -725,6 +932,33 @@
            <if test="reportDeptPersonCode != null">report_dept_person_code =
                #{reportDeptPersonCode},
            </if>
            <if test="circulationDeptPersonCode != null">circulation_dept_person_code =
                #{circulationDeptPersonCode},
            </if>
            <if test="circulationDeptPersonName != null">circulation_dept_person_name =
                #{circulationDeptPersonName},
            </if>
            <if test="circulationDeptCode != null">circulation_dept_code =
                #{circulationDeptCode},
            </if>
            <if test="circulationDeptName != null">circulation_dept_name =
                #{circulationDeptName},
            </if>
            <if test="circulationExplain != null">circulation_explain =
                #{circulationExplain},
            </if>
            <if test="circulationTime != null">circulation_time =
                #{circulationTime},
            </if>
            <if test="circulationStatus != null ">
                circulation_status = #{circulationStatus},
            </if>
            <if test="circulationPersonName != null  and circulationPersonName != ''">
                circulation_person_name =#{circulationPersonName},
            </if>
            <if test="circulationPersonCode != null  and circulationPersonCode != ''">
                circulation_person_code =#{circulationPersonCode},
            </if>
        </trim>
        where id = #{id}
    </update>