wlzboy
2026-03-31 61c4c3f45e4257e2e7662f033e2719e62366c632
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
@@ -78,6 +78,56 @@
        left join sys_task_vehicle tv on t.task_id = tv.task_id
        left join tb_vehicle_info v on tv.vehicle_id = v.vehicle_id
    </sql>
    <sql id="selectSysTaskVoWithEmergency">
        select t.task_id, t.task_code, t.task_type, t.task_status, t.task_description,
               t.departure_address, t.destination_address, t.departure_longitude, t.departure_latitude,
               t.destination_longitude, t.destination_latitude, t.estimated_distance,
               t.planned_start_time, t.planned_end_time,
               t.actual_start_time, t.actual_end_time, t.creator_id, t.assignee_id, t.dept_id,
               t.create_time, t.update_time, t.create_by, t.update_by, t.remark, t.del_flag, t.legacy_synced,
               u1.nick_name as creator_name, u2.nick_name as assignee_name, d.dept_name,
               (
                   select v2.vehicle_no
                   from sys_task_vehicle tv2
                   left join tb_vehicle_info v2 on tv2.vehicle_id = v2.vehicle_id
                   where tv2.task_id = t.task_id
                   order by tv2.assign_time asc
                   limit 1
               ) as vehicle_no,
               tv.id as tv_id, tv.task_id as tv_task_id, tv.vehicle_id as tv_vehicle_id,
               v.vehicle_no as tv_vehicle_no, v.vehicle_type as tv_vehicle_type,
               v.vehicle_brand as tv_vehicle_brand, v.vehicle_model as tv_vehicle_model,
               tv.assign_time as tv_assign_time, tv.assign_by as tv_assign_by,
               tv.status as tv_status, tv.remark as tv_remark,
               CASE
                   WHEN e.legacy_dispatch_ord_class IS NOT NULL
                        AND e.legacy_dispatch_ns_time IS NOT NULL
                        AND e.legacy_dispatch_ord_no IS NOT NULL
                   THEN CONCAT(e.legacy_dispatch_ord_class,
                               DATE_FORMAT(e.legacy_dispatch_ns_time, '%Y%m%d'),
                               '-',
                               LPAD(CAST(e.legacy_dispatch_ord_no AS CHAR), 3, '0'))
                   ELSE NULL
               END AS dispatch_code,
               CASE
                   WHEN e.legacy_service_ord_class IS NOT NULL
                        AND e.legacy_service_ns_time IS NOT NULL
                        AND e.legacy_service_ord_no IS NOT NULL
                   THEN CONCAT(e.legacy_service_ord_class,
                               DATE_FORMAT(e.legacy_service_ns_time, '%Y%m%d'),
                               '-',
                               LPAD(CAST(e.legacy_service_ord_no AS CHAR), 3, '0'))
                   ELSE NULL
               END AS service_code
        from sys_task t
        left join sys_user u1 on t.creator_id = u1.user_id
        left join sys_user u2 on t.assignee_id = u2.user_id
        left join sys_dept d on t.dept_id = d.dept_id
        left join sys_task_vehicle tv on t.task_id = tv.task_id
        left join tb_vehicle_info v on tv.vehicle_id = v.vehicle_id
        left join sys_task_emergency e on t.task_id = e.task_id
    </sql>
    <select id="selectSysTaskList" parameterType="TaskQueryVO" resultMap="SysTaskResult">
        <include refid="selectSysTaskVo"/>
@@ -86,6 +136,11 @@
            <if test="taskCode != null  and taskCode != ''"> and t.task_code like concat('%', #{taskCode}, '%')</if>
            <if test="taskType != null  and taskType != ''"> and t.task_type = #{taskType}</if>
            <if test="taskStatus != null  and taskStatus != ''"> and t.task_status = #{taskStatus}</if>
            <if test="taskStatusList != null and taskStatusList != ''"> and t.task_status in
                <foreach collection="taskStatusList.split(',')" item="status" open="(" separator="," close=")">
                    #{status}
                </foreach>
            </if>
            <if test="vehicleNo != null  and vehicleNo != ''"> and v.vehicle_no like concat('%', #{vehicleNo}, '%')</if>
            <!-- 综合查询:当前用户所在机构 OR 当前用户创建 OR 分配给当前用户 -->
            <if test="(creatorId != null and creatorId != 0) or (assigneeId != null and assigneeId != 0) or (deptId != null and deptId != 0) or (deptIds != null and deptIds.size() > 0)">
@@ -289,7 +344,6 @@
            <if test="actualEndTime != null">actual_end_time = #{actualEndTime},</if>
            <if test="creatorId != null">creator_id = #{creatorId},</if>
            <if test="assigneeId != null">assignee_id = #{assigneeId},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
@@ -340,4 +394,135 @@
            #{taskId}
        </foreach>
    </delete>
    <!-- 根据联系人电话和创建日期查询任务数量 -->
    <select id="countTaskByPhoneAndDate" resultType="int">
        select count(1)
        from sys_task t
        inner join sys_task_emergency e on t.task_id = e.task_id
        where t.del_flag = '0'
          and e.patient_phone = #{phone}
          and DATE(t.create_time) = #{createDate}
    </select>
    <!-- 查询车辆在指定时间范围内的任务列表 -->
    <select id="selectVehicleTasksInTimeRange" parameterType="map" resultMap="SysTaskResult">
        select t.task_id, t.task_code, t.task_type, t.task_status,
               t.departure_address, t.destination_address,
               t.actual_start_time, t.actual_end_time,
               t.planned_start_time, t.planned_end_time,
               t.estimated_distance,
               tv.vehicle_id
        from sys_task t
        inner join sys_task_vehicle tv on t.task_id = tv.task_id
        where tv.vehicle_id = #{vehicleId}
          and t.del_flag = '0'
          and t.task_status not in ('CANCELLED')
          and (
              <!-- 实际时间有值时,使用实际时间判断重叠 -->
              (t.actual_start_time is not null and t.actual_end_time is not null
               and t.actual_start_time &lt;= #{endTime} and t.actual_end_time &gt;= #{startTime})
              or
              <!-- 实际开始时间有值但未结束时,使用当前时间作为结束时间 -->
              (t.actual_start_time is not null and t.actual_end_time is null
               and t.actual_start_time &lt;= #{endTime})
              or
              <!-- 实际时间都为空时,使用计划时间判断重叠 -->
              (t.actual_start_time is null and t.actual_end_time is null
               and t.planned_start_time &lt;= #{endTime} and t.planned_end_time &gt;= #{startTime})
          )
        order by t.actual_start_time, t.planned_start_time
    </select>
    <!-- 优化的多码查询方法,关联sys_task_emergency表 -->
    <select id="selectSysTaskListByMultiCodeOptimized" parameterType="TaskQueryVO" resultMap="SysTaskResult">
        <include refid="selectSysTaskVoWithEmergency"/>
        <where>
            t.del_flag = '0'
            <if test="taskCode != null  and taskCode != ''">
                and (
                    t.task_code like concat('%', #{taskCode}, '%')
                    or CASE
                           WHEN e.legacy_dispatch_ord_class IS NOT NULL
                                AND e.legacy_dispatch_ns_time IS NOT NULL
                                AND e.legacy_dispatch_ord_no IS NOT NULL
                           THEN CONCAT(e.legacy_dispatch_ord_class,
                                       DATE_FORMAT(e.legacy_dispatch_ns_time, '%Y%m%d'),
                                       '-',
                                       LPAD(CAST(e.legacy_dispatch_ord_no AS CHAR), 3, '0'))
                           ELSE NULL
                       END like concat('%', #{taskCode}, '%')
                    or CASE
                           WHEN e.legacy_service_ord_class IS NOT NULL
                                AND e.legacy_service_ns_time IS NOT NULL
                                AND e.legacy_service_ord_no IS NOT NULL
                           THEN CONCAT(e.legacy_service_ord_class,
                                       DATE_FORMAT(e.legacy_service_ns_time, '%Y%m%d'),
                                       '-',
                                       LPAD(CAST(e.legacy_service_ord_no AS CHAR), 3, '0'))
                           ELSE NULL
                       END like concat('%', #{taskCode}, '%')
                )
            </if>
            <if test="taskType != null  and taskType != ''"> and t.task_type = #{taskType}</if>
            <if test="taskStatus != null  and taskStatus != ''"> and t.task_status = #{taskStatus}</if>
            <if test="taskStatusList != null and taskStatusList != ''"> and t.task_status in
                <foreach collection="taskStatusList.split(',')" item="status" open="(" separator="," close=")">
                    #{status}
                </foreach>
            </if>
            <if test="vehicleNo != null  and vehicleNo != ''"> and v.vehicle_no like concat('%', #{vehicleNo}, '%')</if>
            <!-- 综合查询:当前用户所在机构 OR 当前用户创建 OR 分配给当前用户 -->
            <if test="(creatorId != null and creatorId != 0) or (assigneeId != null and assigneeId != 0) or (deptId != null and deptId != 0) or (deptIds != null and deptIds.size() > 0)">
                and (
                    <!-- 查询指定分公司及其所有子部门的任务 -->
                    <if test="deptId != null and deptId != 0">
                        (t.dept_id = #{deptId} OR t.dept_id IN (
                            SELECT dept_id FROM sys_dept
                            WHERE del_flag = '0' AND find_in_set(#{deptId}, ancestors)
                        ))
                    </if>
                    <!-- 查询多个分公司及其所有子部门的任务 -->
                    <if test="deptIds != null and deptIds.size() > 0">
                        <if test="deptId != null and deptId != 0"> or </if>
                        (
                            <foreach collection="deptIds" item="branchDeptId" separator=" OR ">
                                (t.dept_id = #{branchDeptId} OR t.dept_id IN (
                                    SELECT dept_id FROM sys_dept
                                    WHERE del_flag = '0' AND find_in_set(#{branchDeptId}, ancestors)
                                ))
                            </foreach>
                        )
                    </if>
                    <if test="creatorId != null and creatorId != 0">
                        <if test="(deptId != null and deptId != 0) or (deptIds != null and deptIds.size() > 0)"> or </if>
                        t.creator_id = #{creatorId}
                    </if>
                    <if test="assigneeId != null and assigneeId != 0">
                        <if test="(deptId != null and deptId != 0) or (deptIds != null and deptIds.size() > 0) or (creatorId != null and creatorId != 0)"> or </if>
                        t.task_id IN (
                            SELECT task_id FROM sys_task_assignee WHERE user_id = #{assigneeId}
                        )
                    </if>
                )
            </if>
            <if test="plannedStartTimeBegin != null "> and t.planned_start_time &gt;= #{plannedStartTimeBegin}</if>
            <if test="plannedStartTimeEnd != null "> and t.planned_start_time &lt;= #{plannedStartTimeEnd}</if>
            <if test="plannedEndTimeBegin != null "> and t.planned_end_time &gt;= #{plannedEndTimeBegin}</if>
            <if test="plannedEndTimeEnd != null "> and t.planned_end_time &lt;= #{plannedEndTimeEnd}</if>
            <if test="overdue != null and overdue == true"> and t.planned_end_time &lt; now() and t.task_status != 'COMPLETED'</if>
        </where>
        order by
            CASE t.task_status
                WHEN 'PENDING' THEN 1
                WHEN 'DEPARTING' THEN 2
                WHEN 'ARRIVED' THEN 3
                WHEN 'RETURNING' THEN 4
                WHEN 'IN_PROGRESS' THEN 5
                WHEN 'COMPLETED' THEN 6
                WHEN 'CANCELLED' THEN 7
                ELSE 8
            END,
            t.create_time desc
    </select>
</mapper>