From 09faa36132c8cbada5327649875534ef01c1a3b1 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 11 十二月 2025 20:44:31 +0800
Subject: [PATCH] feat: 优化任务里程统计

---
 ruoyi-ui/src/views/task/vehicle/index.vue |  205 ++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 179 insertions(+), 26 deletions(-)

diff --git a/ruoyi-ui/src/views/task/vehicle/index.vue b/ruoyi-ui/src/views/task/vehicle/index.vue
index bebb9f3..76c5ca6 100644
--- a/ruoyi-ui/src/views/task/vehicle/index.vue
+++ b/ruoyi-ui/src/views/task/vehicle/index.vue
@@ -1,25 +1,14 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="浠诲姟" prop="taskId">
-        <el-select v-model="queryParams.taskId" placeholder="璇烽�夋嫨浠诲姟" clearable filterable style="width: 200px">
-          <el-option
-            v-for="task in taskList"
-            :key="task.taskId"
-            :label="task.taskCode + ' - ' + getTaskTypeName(task.taskType)"
-            :value="task.taskId"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="杞﹁締" prop="vehicleId">
-        <el-select v-model="queryParams.vehicleId" placeholder="璇烽�夋嫨杞﹁締" clearable filterable style="width: 200px">
-          <el-option
-            v-for="vehicle in vehicleList"
-            :key="vehicle.vehicleId"
-            :label="vehicle.vehicleNo + ' - ' + vehicle.deptName"
-            :value="vehicle.vehicleId"
-          />
-        </el-select>
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
+      <el-form-item label="浠诲姟缂栧彿" prop="taskCode">
+        <el-input
+          v-model="queryParams.taskCode"
+          placeholder="璇疯緭鍏ヤ换鍔$紪鍙�"
+          clearable
+          @keyup.enter.native="handleQuery"
+          style="width: 200px"
+        />
       </el-form-item>
       <el-form-item label="杞︾墝鍙�" prop="vehicleNo">
         <el-input
@@ -27,6 +16,7 @@
           placeholder="璇疯緭鍏ヨ溅鐗屽彿"
           clearable
           @keyup.enter.native="handleQuery"
+          style="width: 200px"
         />
       </el-form-item>
       <el-form-item label="鍏宠仈鐘舵��" prop="status">
@@ -108,9 +98,20 @@
         </template>
       </el-table-column>
       <el-table-column label="杞︾墝鍙�" align="center" prop="vehicleNo" />
-      <el-table-column label="杞﹁締绫诲瀷" align="center" prop="vehicleType">
+      
+      <el-table-column label="褰撳墠浠诲姟鐘舵��" align="center" prop="currentTaskStatus" width="180">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.sys_vehicle_type" :value="scope.row.vehicleType"/>
+          <div v-if="scope.row.currentTaskCode">
+            <el-tag type="success" size="mini">
+              <i class="el-icon-loading"></i> 浠诲姟涓�
+            </el-tag>
+            <div style="font-size: 12px; color: #409EFF; margin-top: 5px;">
+              {{ scope.row.currentTaskCode }}
+            </div>
+          </div>
+          <el-tag v-else type="info" size="mini">
+            <i class="el-icon-circle-check"></i> 绌洪棽
+          </el-tag>
         </template>
       </el-table-column>
       
@@ -149,6 +150,12 @@
             @click="handleStatusChange(scope.row)"
             v-hasPermi="['task:vehicle:edit']"
           >鐘舵�佸彉鏇�</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-tickets"
+            @click="handleViewTaskList(scope.row)"
+          >浠诲姟娓呭崟</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -248,16 +255,68 @@
         <el-button @click="cancelStatusChange">鍙� 娑�</el-button>
       </div>
     </el-dialog>
+
+    <!-- 杞﹁締浠诲姟娓呭崟瀵硅瘽妗� -->
+    <el-dialog :title="'杞﹁締浠诲姟娓呭崟 - ' + currentVehicleNo" :visible.sync="taskListOpen" width="1200px" append-to-body>
+      <el-table v-loading="taskListLoading" :data="vehicleTaskList" max-height="500">
+        <el-table-column label="浠诲姟缂栧彿" align="center" prop="taskCode" width="180">
+          <template slot-scope="scope">
+            <el-button
+              type="text"
+              @click="handleViewTaskDetail(scope.row.taskId)"
+              style="font-family: 'Courier New', monospace; font-size: 13px;"
+            >{{ scope.row.taskCode }}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column label="浠诲姟绫诲瀷" align="center" prop="taskType" width="120">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.sys_task_type" :value="scope.row.taskType"/>
+          </template>
+        </el-table-column>
+        <el-table-column label="璁″垝寮�濮嬫椂闂�" align="center" prop="plannedStartTime" width="160">
+          <template slot-scope="scope">
+            <span v-if="scope.row.plannedStartTime">{{ parseTime(scope.row.plannedStartTime, '{y}-{m}-{d} {h}:{i}') }}</span>
+            <span v-else style="color: #C0C4CC;">--</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍑哄彂鍦板潃" align="center" prop="departureAddress" show-overflow-tooltip min-width="150" />
+        <el-table-column label="鐩爣鍦板潃" align="center" prop="destinationAddress" show-overflow-tooltip min-width="150" />
+        <el-table-column label="棰勮鍏噷鏁�" align="center" prop="estimatedDistance" width="110">
+          <template slot-scope="scope">
+            <span v-if="scope.row.estimatedDistance">{{ scope.row.estimatedDistance }} km</span>
+            <span v-else style="color: #C0C4CC;">--</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="浠诲姟鐘舵��" align="center" prop="taskStatus" width="100">
+          <template slot-scope="scope">
+            <dict-tag :options="dict.type.sys_task_status" :value="scope.row.taskStatus"/>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" width="100">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleViewTaskDetail(scope.row.taskId)"
+            >鏌ョ湅</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="taskListOpen = false">鍏� 闂�</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { listTaskVehicle, getTaskVehicle, delTaskVehicle, addTaskVehicle, updateTaskVehicle, updateTaskVehicleStatus, listTask } from "@/api/task";
+import { listTaskVehicle, getTaskVehicle, delTaskVehicle, addTaskVehicle, updateTaskVehicle, updateTaskVehicleStatus, listTask, getTask, batchGetVehicleCurrentTaskStatus } from "@/api/task";
 import { listVehicle } from "@/api/system/vehicle";
 
 export default {
   name: "TaskVehicle",
-  dicts: ['sys_task_vehicle_status', 'sys_vehicle_type', 'sys_task_type'],
+  dicts: ['sys_task_vehicle_status', 'sys_vehicle_type', 'sys_task_type', 'sys_task_status'],
   data() {
     return {
       // 閬僵灞�
@@ -288,12 +347,19 @@
       open: false,
       // 鏄惁鏄剧ず鐘舵�佸彉鏇村脊鍑哄眰
       statusOpen: false,
+      // 鏄惁鏄剧ず浠诲姟娓呭崟寮瑰嚭灞�
+      taskListOpen: false,
+      // 杞﹁締浠诲姟鍒楄〃
+      vehicleTaskList: [],
+      // 杞﹁締浠诲姟鍒楄〃鍔犺浇鐘舵��
+      taskListLoading: false,
+      // 褰撳墠鏌ョ湅鐨勮溅鐗屽彿
+      currentVehicleNo: '',
       // 鏌ヨ鍙傛暟
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        taskId: null,
-        vehicleId: null,
+        taskCode: null,
         vehicleNo: null,
         status: null,
         assignBy: null,
@@ -334,7 +400,39 @@
       listTaskVehicle(this.queryParams).then(response => {
         this.taskVehicleList = response.rows;
         this.total = response.total;
+        // 涓烘瘡涓溅杈嗗姞杞藉綋鍓嶄换鍔$姸鎬�
+        this.loadCurrentTaskStatus();
         this.loading = false;
+      });
+    },
+    /** 鍔犺浇杞﹁締褰撳墠浠诲姟鐘舵�侊紙浼樺寲锛氭壒閲忔煡璇級 */
+    loadCurrentTaskStatus() {
+      // 鎻愬彇鎵�鏈夎溅杈咺D
+      const vehicleIds = this.taskVehicleList
+        .map(item => item.vehicleId)
+        .filter(id => id != null);
+      
+      if (vehicleIds.length === 0) {
+        return;
+      }
+      
+      // 鎵归噺鏌ヨ杞﹁締褰撳墠浠诲姟鐘舵��
+      batchGetVehicleCurrentTaskStatus(vehicleIds).then(response => {
+        const statusMap = response.data || {};
+        
+        // 鏇存柊姣忎釜杞﹁締鐨勪换鍔$姸鎬�
+        this.taskVehicleList.forEach(item => {
+          if (item.vehicleId && statusMap[item.vehicleId]) {
+            const taskInfo = statusMap[item.vehicleId];
+            this.$set(item, 'currentTaskCode', taskInfo.taskCode);
+            this.$set(item, 'currentTaskStatus', taskInfo.taskStatus);
+          } else {
+            this.$set(item, 'currentTaskCode', null);
+            this.$set(item, 'currentTaskStatus', null);
+          }
+        });
+      }).catch(error => {
+        console.error('鍔犺浇杞﹁締浠诲姟鐘舵�佸け璐�:', error);
       });
     },
     /** 鑾峰彇浠诲姟鍒楄〃 */
@@ -484,6 +582,61 @@
       this.statusOpen = false;
       this.statusForm = {};
     },
+    /** 鏌ョ湅杞﹁締浠诲姟娓呭崟 */
+    handleViewTaskList(row) {
+      this.currentVehicleNo = row.vehicleNo;
+      this.taskListOpen = true;
+      this.taskListLoading = true;
+      
+      // 鏌ヨ璇ヨ溅杈嗙殑鎵�鏈変换鍔″叧鑱�
+      listTaskVehicle({ 
+        vehicleId: row.vehicleId,
+        pageNum: 1, 
+        pageSize: 1000 
+      }).then(response => {
+        const taskVehicles = response.rows || [];
+        
+        // 鑾峰彇鎵�鏈変换鍔D
+        const taskIds = [...new Set(taskVehicles.map(item => item.taskId).filter(id => id))];
+        
+        if (taskIds.length === 0) {
+          this.vehicleTaskList = [];
+          this.taskListLoading = false;
+          return;
+        }
+        
+        // 鎵归噺鏌ヨ浠诲姟璇︽儏
+        const taskPromises = taskIds.map(taskId => 
+          getTask(taskId).then(res => res.data).catch(() => null)
+        );
+        
+        Promise.all(taskPromises).then(tasks => {
+          // 杩囨护鎺夌┖鍊煎苟鎸夋椂闂存帓搴�
+          this.vehicleTaskList = tasks
+            .filter(task => task !== null)
+            .sort((a, b) => {
+              const timeA = new Date(a.plannedStartTime || a.createTime).getTime();
+              const timeB = new Date(b.plannedStartTime || b.createTime).getTime();
+              return timeB - timeA; // 闄嶅簭鎺掑垪
+            });
+          
+          this.taskListLoading = false;
+        }).catch(error => {
+          console.error('鏌ヨ浠诲姟璇︽儏澶辫触:', error);
+          this.$modal.msgError('鍔犺浇浠诲姟娓呭崟澶辫触');
+          this.taskListLoading = false;
+        });
+      }).catch(error => {
+        console.error('鏌ヨ杞﹁締浠诲姟鍏宠仈澶辫触:', error);
+        this.$modal.msgError('鍔犺浇浠诲姟娓呭崟澶辫触');
+        this.taskListLoading = false;
+      });
+    },
+    /** 鏌ョ湅浠诲姟璇︽儏 */
+    handleViewTaskDetail(taskId) {
+      // 璺宠浆鍒颁换鍔¤鎯呴〉闈�
+      this.$router.push('/task/general-detail/index/' + taskId);
+    },
     /** 浠诲姟閫夋嫨鍙樺寲 */
     handleTaskChange(taskId) {
       if (taskId) {

--
Gitblit v1.9.1