From ae478a3d5dab28dd598d39f27429e4a544b15ad2 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期四, 25 十二月 2025 22:48:06 +0800
Subject: [PATCH] feat:已完成时,检查附件是否上传

---
 app/pages/task/index.vue |  227 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 202 insertions(+), 25 deletions(-)

diff --git a/app/pages/task/index.vue b/app/pages/task/index.vue
index a0432b3..df49429 100644
--- a/app/pages/task/index.vue
+++ b/app/pages/task/index.vue
@@ -5,12 +5,12 @@
       <view class="task-header">
         <view class="header-title">浠诲姟鍒楄〃</view>
         <view class="header-actions">
-          <button class="search-toggle-btn" @click="toggleSearch">
+          <!-- <button class="search-toggle-btn" @click="toggleSearch">
             <uni-icons
               :type="showSearch ? 'close' : 'search'"
               size="20"
             ></uni-icons>
-          </button>
+          </button> -->
           <button class="refresh-btn" @click="refreshList">
             <uni-icons type="refresh" size="20"></uni-icons>
           </button>
@@ -270,12 +270,33 @@
         </view>
       </scroll-view>
     </view>
+    
+    <!-- 鍙栨秷鍘熷洜閫夋嫨瀵硅瘽妗� -->
+    <uni-popup ref="cancelPopup" type="center" :is-mask-click="false">
+      <view class="cancel-dialog">
+        <view class="dialog-title">璇烽�夋嫨鍙栨秷鍘熷洜</view>
+        <picker mode="selector" :range="cancelReasonList" range-key="label" @change="selectCancelReason">
+          <view class="reason-picker">
+            <view class="picker-label">鍙栨秷鍘熷洜</view>
+            <view class="picker-value">
+              {{ selectedCancelReasonLabel }}
+            </view>
+            <uni-icons type="arrowright" size="16"></uni-icons>
+          </view>
+        </picker>
+        <view class="dialog-buttons">
+          <button class="cancel-btn" @click="closeCancelDialog">鍙栨秷</button>
+          <button class="confirm-btn" @click="confirmCancelTask">纭畾</button>
+        </view>
+      </view>
+    </uni-popup>
   </view>
 </template>
 
 <script>
 import uniDatetimePicker from "@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue";
 import { listTask, changeTaskStatus, checkTaskConsentAttachment } from "@/api/task";
+import { getDicts } from "@/api/dict";
 import { mapState } from "vuex";
 import { formatDateTime } from "@/utils/common";
 import { checkTaskCanDepart } from "@/utils/taskValidator";
@@ -294,8 +315,8 @@
         vehicle: "",
         taskNo: "",
       },
-      statusOptions: ["鍏ㄩ儴鐘舵��", "寰呭鐞�", "澶勭悊涓�", "宸插畬鎴�"],
-      statusValues: ["", "pending", "processing", "completed"],
+      statusOptions: ["鍏ㄩ儴鐘舵��", "寰呭鐞�", "澶勭悊涓�", "宸插畬鎴�", "宸插彇娑�"],
+      statusValues: ["", "pending", "processing", "completed", "cancelled"],
       selectedStatus: "",
       selectedStatusText: "",
       startDate: "",
@@ -312,6 +333,12 @@
       pageSize: 10,
       total: 0,
       hasMore: true,
+      
+      // 鍙栨秷鍘熷洜鐩稿叧
+      cancelReasonList: [], // 鍙栨秷鍘熷洜鍒楄〃
+      showCancelDialog: false, // 鏄剧ず鍙栨秷鍘熷洜瀵硅瘽妗�
+      selectedCancelReason: '', // 閫変腑鐨勫彇娑堝師鍥�
+      currentCancelTask: null // 褰撳墠瑕佸彇娑堢殑浠诲姟
     };
   },
   computed: {
@@ -323,12 +350,24 @@
       // 瀹為檯鐨勭瓫閫夊皢鍦ㄨ姹傛湇鍔″櫒鏃跺畬鎴�
       return this.taskList;
     },
+    
+    // 鑾峰彇閫変腑鐨勫彇娑堝師鍥犳爣绛撅紙鐢ㄤ簬寮圭獥鏄剧ず锛�
+    selectedCancelReasonLabel() {
+      if (!this.selectedCancelReason || !this.cancelReasonList.length) {
+        return '璇烽�夋嫨'
+      }
+      const reason = this.cancelReasonList.find(r => r.value === this.selectedCancelReason)
+      return reason ? reason.label : '璇烽�夋嫨'
+    },
   },
   onLoad() {
     this.loadTaskList();
 
     // 鐩戝惉浠诲姟鍒楄〃鍒锋柊浜嬩欢
     uni.$on("refreshTaskList", this.handleRefreshEvent);
+    
+    // 鍔犺浇鍙栨秷鍘熷洜瀛楀吀
+    this.loadCancelReasonDict();
   },
   onShow() {
     // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛紙浠庡叾浠栭〉闈㈣繑鍥炴椂锛�
@@ -382,7 +421,8 @@
           "IN_PROGRESS",
         ].join(",");
       } else if (this.currentFilter === "completed") {
-        queryParams.taskStatus = "COMPLETED";
+        // 宸插畬鎴愬寘鍚細宸插畬鎴愬拰宸插彇娑�
+        queryParams.taskStatusList = "COMPLETED,CANCELLED";
       } else {
         // 濡傛灉娌℃湁浣跨敤椤堕儴tab绛涢�夛紝鍒欎娇鐢ㄦ煡璇㈡潯浠朵腑鐨勭姸鎬佺瓫閫�
         if (this.selectedStatus) {
@@ -395,11 +435,13 @@
               "IN_PROGRESS",
             ].join(","),
             completed: "COMPLETED",
+            cancelled: "CANCELLED",
           };
           if (statusMap[this.selectedStatus]) {
             if (
               this.selectedStatus === "pending" ||
-              this.selectedStatus === "completed"
+              this.selectedStatus === "completed" ||
+              this.selectedStatus === "cancelled"
             ) {
               queryParams.taskStatus = statusMap[this.selectedStatus];
             } else {
@@ -497,7 +539,8 @@
           "IN_PROGRESS",
         ].join(",");
       } else if (this.currentFilter === "completed") {
-        queryParams.taskStatus = "COMPLETED";
+        // 宸插畬鎴愬寘鍚細宸插畬鎴愬拰宸插彇娑�
+        queryParams.taskStatusList = "COMPLETED,CANCELLED";
       } else {
         // 濡傛灉娌℃湁浣跨敤椤堕儴tab绛涢�夛紝鍒欎娇鐢ㄦ煡璇㈡潯浠朵腑鐨勭姸鎬佺瓫閫�
         if (this.selectedStatus) {
@@ -510,11 +553,13 @@
               "IN_PROGRESS",
             ].join(","),
             completed: "COMPLETED",
+            cancelled: "CANCELLED",
           };
           if (statusMap[this.selectedStatus]) {
             if (
               this.selectedStatus === "pending" ||
-              this.selectedStatus === "completed"
+              this.selectedStatus === "completed" ||
+              this.selectedStatus === "cancelled"
             ) {
               queryParams.taskStatus = statusMap[this.selectedStatus];
             } else {
@@ -654,6 +699,8 @@
       this.endDate = "";
       this.searchForm.vehicle = "";
       this.searchForm.taskNo = "";
+      // 閲嶇疆鍚庨噸鏂板姞杞芥暟鎹�
+      this.loadTaskList();
     },
 
     // 鍒锋柊鍒楄〃
@@ -671,6 +718,9 @@
     // 绛涢��
     changeFilter(filter) {
       this.currentFilter = filter;
+      // 閲嶇疆鍒嗛〉
+      this.currentPage = 1;
+      this.hasMore = true;
       // 閲嶆柊鍔犺浇鏁版嵁
       this.loadTaskList();
     },
@@ -784,13 +834,9 @@
           break;
 
         case "cancel":
-          // 鍙栨秷 -> 浜屾纭鍚庣姸鎬佸彉涓哄凡鍙栨秷
-          this.$modal
-            .confirm("纭畾瑕佸彇娑堟浠诲姟鍚楋紵")
-            .then(() => {
-              this.updateTaskStatus(task.taskId, "CANCELLED", "浠诲姟宸插彇娑�");
-            })
-            .catch(() => {});
+          // 鍙栨秷 -> 鏄剧ず鍙栨秷鍘熷洜閫夋嫨瀵硅瘽妗�
+          this.currentCancelTask = task;
+          this.showCancelReasonDialog();
           break;
 
         case "arrive":
@@ -837,6 +883,56 @@
       this.getLocationAndUpdateStatus(taskId, status, remark);
     },
     
+    // 鍔犺浇鍙栨秷鍘熷洜瀛楀吀
+    loadCancelReasonDict() {
+      getDicts('task_cancel_reason').then(response => {
+        if (response.code === 200 && response.data) {
+          this.cancelReasonList = response.data.map(item => ({
+            value: item.dictValue,
+            label: item.dictLabel
+          }))
+        }
+      }).catch(error => {
+        console.error('鍔犺浇鍙栨秷鍘熷洜瀛楀吀澶辫触:', error)
+      })
+    },
+    
+    // 鏄剧ず鍙栨秷鍘熷洜瀵硅瘽妗�
+    showCancelReasonDialog() {
+      this.selectedCancelReason = ''
+      this.$refs.cancelPopup.open()
+    },
+    
+    // 纭鍙栨秷浠诲姟
+    confirmCancelTask() {
+      if (!this.selectedCancelReason) {
+        this.$modal.showToast('璇烽�夋嫨鍙栨秷鍘熷洜')
+        return
+      }
+      
+      this.$refs.cancelPopup.close()
+      
+      // 璋冪敤鏇存柊鐘舵�佹柟娉曪紝浼犻�掑彇娑堝師鍥�
+      this.updateTaskStatusWithCancelReason(this.currentCancelTask.taskId, 'CANCELLED', '浠诲姟宸插彇娑�', this.selectedCancelReason)
+    },
+    
+    // 鍙栨秷瀵硅瘽妗嗗叧闂�
+    closeCancelDialog() {
+      this.$refs.cancelPopup.close()
+      this.selectedCancelReason = ''
+      this.currentCancelTask = null
+    },
+    
+    // 閫夋嫨鍙栨秷鍘熷洜
+    selectCancelReason(e) {
+      this.selectedCancelReason = this.cancelReasonList[e.detail.value].value
+    },
+    
+    // 甯﹀彇娑堝師鍥犵殑鐘舵�佹洿鏂�
+    updateTaskStatusWithCancelReason(taskId, status, remark, cancelReason) {
+      this.getLocationAndUpdateStatus(taskId, status, remark, cancelReason)
+    },
+    
     // 妫�鏌ョ煡鎯呭悓鎰忎功闄勪欢骞舵洿鏂扮姸鎬�
     async checkConsentAttachmentAndThen(taskId, status, remark) {
       try {
@@ -844,12 +940,19 @@
           title: '妫�鏌ラ檮浠�...'
         });
         
-        const response = await checkTaskConsentAttachment(taskId);
+        // 娉ㄦ剰锛氳繖閲屼細琚姹傛嫤鎴櫒澶勭悊锛宑ode !== 200 鏃朵細 reject
+        const response = await checkTaskConsentAttachment(taskId).catch(err => {
+          // 鎷︽埅鍣� reject 鐨勬儏鍐碉紝杩斿洖涓�涓粯璁ゅ璞�
+          console.log('璇锋眰琚嫤鎴櫒 reject锛宔rr:', err);
+          return { code: -1, msg: '鏈笂浼犵煡鎯呭悓鎰忎功' };
+        });
         
         uni.hideLoading();
+        console.log('妫�鏌ラ檮浠剁粨鏋�:', response);
         
-        if (response.code === 200) {
+        if (response && response.code === 200) {
           // 宸蹭笂浼犵煡鎯呭悓鎰忎功锛岀户缁洿鏂扮姸鎬�
+          console.log('宸蹭笂浼犵煡鎯呭悓鎰忎功锛岀户缁畬鎴愪换鍔�');
           this.$modal
             .confirm("纭浠诲姟宸插畬鎴愶紵")
             .then(() => {
@@ -857,8 +960,11 @@
             })
             .catch(() => {});
         } else {
-          // 鏈笂浼犵煡鎯呭悓鎰忎功锛屾樉绀烘彁绀�
-          this.$modal.confirm('浠诲姟鏈笂浼犵煡鎯呭悓鎰忎功锛屾棤娉曞畬鎴愪换鍔°�傛槸鍚︾幇鍦ㄥ幓涓婁紶锛�').then(() => {
+          // 鏈笂浼犵煡鎯呭悓鎰忎功鎴栧叾浠栭敊璇紝闃绘瀹屾垚
+          const message = (response && response.msg) || '浠诲姟鏈笂浼犵煡鎯呭悓鎰忎功锛屾棤娉曞畬鎴愪换鍔�';
+          console.log('鏈笂浼犵煡鎯呭悓鎰忎功锛岄樆姝㈠畬鎴�');
+          
+          this.$modal.confirm(message + '銆傛槸鍚︾幇鍦ㄥ幓涓婁紶锛�').then(() => {
             // 璺宠浆鍒颁换鍔¤鎯呴〉涓婁紶闄勪欢
             uni.navigateTo({
               url: `/pagesTask/detail?id=${taskId}`
@@ -867,17 +973,15 @@
         }
       } catch (error) {
         uni.hideLoading();
-        console.error('妫�鏌ラ檮浠跺け璐�:', error);
+        console.error('妫�鏌ラ檮浠跺紓甯�:', error);
         
-        // 濡傛灉妫�鏌ュけ璐ワ紝璇㈤棶鐢ㄦ埛鏄惁缁х画
-        this.$modal.confirm('妫�鏌ラ檮浠剁姸鎬佸け璐ワ紝鏄惁缁х画瀹屾垚浠诲姟锛�').then(() => {
-          this.updateTaskStatus(taskId, status, remark);
-        }).catch(() => {});
+        // 濡傛灉妫�鏌ュけ璐ワ紙缃戠粶寮傚父绛夛級锛屼笉鍏佽瀹屾垚浠诲姟
+        this.$modal.showToast('妫�鏌ラ檮浠剁姸鎬佸け璐ワ紝鏃犳硶瀹屾垚浠诲姟');
       }
     },
 
     // 鑾峰彇浣嶇疆淇℃伅骞舵洿鏂扮姸鎬�
-    getLocationAndUpdateStatus(taskId, status, remark) {
+    getLocationAndUpdateStatus(taskId, status, remark, cancelReason) {
       const that = this;
 
       // 浣跨敤uni.getLocation鑾峰彇GPS浣嶇疆
@@ -904,6 +1008,11 @@
             speed: res.speed,
             heading: res.direction || res.heading,
           };
+          
+          // 濡傛灉鏈夊彇娑堝師鍥狅紝娣诲姞鍒拌姹傛暟鎹腑
+          if (cancelReason) {
+            statusData.cancelReason = cancelReason
+          }
 
           changeTaskStatus(taskId, statusData)
             .then((response) => {
@@ -926,6 +1035,11 @@
                 taskStatus: status,
                 remark: remark,
               };
+              
+              // 濡傛灉鏈夊彇娑堝師鍥狅紝娣诲姞鍒拌姹傛暟鎹腑
+              if (cancelReason) {
+                statusData.cancelReason = cancelReason
+              }
 
               changeTaskStatus(taskId, statusData)
                 .then((response) => {
@@ -1410,4 +1524,67 @@
     vertical-align: middle;
   }
 }
+
+// 鍙栨秷鍘熷洜瀵硅瘽妗嗘牱寮�
+.cancel-dialog {
+  width: 600rpx;
+  background-color: white;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  
+  .dialog-title {
+    font-size: 32rpx;
+    font-weight: bold;
+    text-align: center;
+    margin-bottom: 30rpx;
+    color: #333;
+  }
+  
+  .reason-picker {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 20rpx 30rpx;
+    background-color: #f5f5f5;
+    border-radius: 10rpx;
+    margin-bottom: 30rpx;
+    
+    .picker-label {
+      font-size: 28rpx;
+      color: #666;
+    }
+    
+    .picker-value {
+      flex: 1;
+      text-align: right;
+      margin: 0 20rpx;
+      font-size: 28rpx;
+      color: #333;
+    }
+  }
+  
+  .dialog-buttons {
+    display: flex;
+    gap: 20rpx;
+    
+    button {
+      flex: 1;
+      height: 80rpx;
+      line-height: 80rpx;
+      border-radius: 10rpx;
+      font-size: 28rpx;
+      border: none;
+    }
+    
+    .cancel-btn {
+      background-color: #f5f5f5;
+      color: #666;
+    }
+    
+    .confirm-btn {
+      background-color: #007AFF;
+      color: white;
+    }
+  }
+}
 </style>
\ No newline at end of file

--
Gitblit v1.9.1