From c5ac97682e3b4ca748541ace97cb37a2295bd81e Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 19 三月 2026 22:46:29 +0800
Subject: [PATCH] feat: 增加GPS清理后台任务

---
 ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml |  254 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 240 insertions(+), 14 deletions(-)

diff --git a/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
index ebc0e2d..fb24bf8 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
@@ -34,6 +34,7 @@
         <result property="creatorName"      column="creator_name"      />
         <result property="assigneeName"     column="assignee_name"     />
         <result property="deptName"         column="dept_name"         />
+        <result property="vehicleNo"        column="vehicle_no"        />
         <collection property="assignedVehicles" ofType="SysTaskVehicle">
             <result property="id"            column="tv_id"             />
             <result property="taskId"        column="tv_task_id"        />
@@ -57,6 +58,14 @@
                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,
@@ -69,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"/>
@@ -77,17 +136,43 @@
             <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)">
+            <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}</if>
-                    <if test="creatorId != null and creatorId != 0">
+                    <!-- 鏌ヨ鎸囧畾鍒嗗叕鍙稿強鍏舵墍鏈夊瓙閮ㄩ棬鐨勪换鍔� -->
+                    <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 (creatorId != null and creatorId != 0)"> or </if>
-                        t.assignee_id = #{assigneeId}
+                        <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>
@@ -135,7 +220,12 @@
 
     <select id="selectMyTasks" parameterType="Long" resultMap="SysTaskResult">
         <include refid="selectSysTaskVo"/>
-        where t.del_flag = '0' and (t.creator_id = #{userId} or t.assignee_id = #{userId})
+        where t.del_flag = '0' and (
+            t.creator_id = #{userId} 
+            OR t.task_id IN (
+                SELECT task_id FROM sys_task_assignee WHERE user_id = #{userId}
+            )
+        )
         order by 
             CASE t.task_status
                 WHEN 'PENDING' THEN 1
@@ -149,6 +239,19 @@
             END,
             t.update_time desc,
             t.create_time desc
+    </select>
+
+    <select id="selectTaskByVehicleIdAndDate" resultMap="SysTaskResult">
+        select tv.task_id, t.actual_start_time,
+        IFNULL(t.actual_end_time, NOW()) as actual_end_time
+        from sys_task_vehicle tv
+        inner join sys_task t on tv.task_id = t.task_id
+        where tv.vehicle_id = #{vehicleId}
+        and t.del_flag = '0'
+        and (
+        (t.actual_start_time &lt;= #{endTime} and (t.actual_end_time is null or t.actual_end_time &gt;= #{startTime}))
+        )
+        order by t.actual_start_time
     </select>
 
     <select id="selectTaskStatistics" resultType="TaskStatisticsVO">
@@ -186,10 +289,6 @@
             <if test="creatorId != null">creator_id,</if>
             <if test="assigneeId != null">assignee_id,</if>
             <if test="deptId != null">dept_id,</if>
-            <if test="plannedStartTime!=null">planned_start_time,</if>
-            <if test="plannedEndTime!=null">planned_end_time,</if>
-            <if test="plannedStartTime!=null">planned_start_time,</if>
-            <if test="plannedEndTime!=null">planned_end_time,</if>
             <if test="createTime != null">create_time,</if>
             update_time,
             <if test="createBy != null">create_by,</if>
@@ -216,10 +315,6 @@
             <if test="creatorId != null">#{creatorId},</if>
             <if test="assigneeId != null">#{assigneeId},</if>
             <if test="deptId != null">#{deptId},</if>
-            <if test="plannedStartTime!=null">#{plannedStartTime},</if>
-            <if test="plannedEndTime!=null">#{plannedEndTime},</if>
-            <if test="actualStartTime!=null">#{actualStartTime},</if>
-            <if test="actualEndTime!=null">#{actualEndTime},</if>
             <if test="createTime != null">#{createTime},</if>
             now(),
             <if test="createBy != null">#{createBy},</if>
@@ -299,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>

--
Gitblit v1.9.1