From 2c86a8bd60deed0dd0e044bad6fb83f75d19a332 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期日, 26 十月 2025 15:05:50 +0800
Subject: [PATCH] Merge branch 'feature-task'

---
 app/pages/task/index.vue |  967 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 967 insertions(+), 0 deletions(-)

diff --git a/app/pages/task/index.vue b/app/pages/task/index.vue
new file mode 100644
index 0000000..c80265c
--- /dev/null
+++ b/app/pages/task/index.vue
@@ -0,0 +1,967 @@
+<template>
+  <view class="task-container">
+    <!-- 浠诲姟鍒楄〃澶撮儴 -->
+    <view class="task-list-section">
+      <view class="task-header">
+        <view class="header-title">浠诲姟鍒楄〃</view>
+        <view class="header-actions">
+          <button class="search-toggle-btn" @click="toggleSearch">
+            <uni-icons :type="showSearch ? 'close' : 'search'" size="20"></uni-icons>
+          </button>
+          <button class="refresh-btn" @click="refreshList">
+            <uni-icons type="refresh" size="20"></uni-icons>
+          </button>
+        </view>
+      </view>
+      
+      <!-- 鏌ヨ鏉′欢鍖哄煙 -->
+      <view class="search-section" v-show="showSearch">
+        <view class="search-form">
+          <view class="form-item">
+            <view class="form-label">浠诲姟鐘舵��</view>
+            <picker mode="selector" :range="statusOptions" @change="onStatusChange">
+              <view class="form-input picker-input">
+                {{ selectedStatusText || '鍏ㄩ儴鐘舵��' }}
+                <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+              </view>
+            </picker>
+          </view>
+          
+          <view class="form-item">
+            <view class="form-label">浠诲姟鏃堕棿</view>
+            <view class="date-range">
+              <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+              <uni-datetime-picker 
+                v-model="startDate" 
+                type="date" 
+                :placeholder="'寮�濮嬫椂闂�'"
+                class="date-input"
+              />
+              <text class="divider">鑷�</text>
+              <!-- 浣跨敤uni-datetime-picker缁勪欢 -->
+              <uni-datetime-picker 
+                v-model="endDate" 
+                type="date" 
+                :placeholder="'缁撴潫鏃堕棿'"
+                class="date-input"
+              />
+            </view>
+          </view>
+          
+          <view class="form-item">
+            <view class="form-label">杞︾墝鍙�</view>
+            <input 
+              class="form-input" 
+              placeholder="璇疯緭鍏ヨ溅鐗屽彿" 
+              v-model="searchForm.vehicle"
+            />
+          </view>
+          
+          <view class="form-item">
+            <view class="form-label">浠诲姟缂栧彿</view>
+            <input 
+              class="form-input" 
+              placeholder="璇疯緭鍏ヤ换鍔$紪鍙�" 
+              v-model="searchForm.taskNo"
+            />
+          </view>
+          
+          <view class="form-actions">
+            <button class="search-btn" @click="handleSearch">鏌ヨ</button>
+            <button class="reset-btn" @click="resetSearch">閲嶇疆</button>
+          </view>
+        </view>
+      </view>
+      
+      <view class="task-filter">
+        <scroll-view class="filter-tabs" scroll-x="true">
+          <view 
+            class="filter-item" 
+            :class="{ active: currentFilter === 'all' }"
+            @click="changeFilter('all')"
+          >
+            鍏ㄩ儴
+          </view>
+          <view 
+            class="filter-item" 
+            :class="{ active: currentFilter === 'pending' }"
+            @click="changeFilter('pending')"
+          >
+            寰呭鐞�
+          </view>
+          <view 
+            class="filter-item" 
+            :class="{ active: currentFilter === 'processing' }"
+            @click="changeFilter('processing')"
+          >
+            澶勭悊涓�
+          </view>
+          <view 
+            class="filter-item" 
+            :class="{ active: currentFilter === 'completed' }"
+            @click="changeFilter('completed')"
+          >
+            宸插畬鎴�
+          </view>
+        </scroll-view>
+      </view>
+      
+      <scroll-view class="task-list-scroll" scroll-y="true">
+        <view class="task-list">
+          <view class="task-item" v-for="task in filteredTaskList" :key="task.id">
+            <view class="task-main" @click="viewTaskDetail(task)">
+              <!-- 浠诲姟澶撮儴锛氭爣棰樺拰鐘舵�佹爣绛� -->
+              <view class="task-header">
+                <view class="task-title">{{ getTaskTypeText(task.taskType) }} - {{ task.vehicle }}</view>
+                <view class="task-status" :class="task.taskStatus === 'PENDING' ? 'status-pending' : task.taskStatus === 'DEPARTING' ? 'status-departing' : task.taskStatus === 'ARRIVED' ? 'status-arrived' : task.taskStatus === 'RETURNING' ? 'status-returning' : task.taskStatus === 'COMPLETED' ? 'status-completed' : task.taskStatus === 'CANCELLED' ? 'status-cancelled' : task.taskStatus === 'IN_PROGRESS' ? 'status-in-progress' : 'status-default'">
+                  {{ getStatusText(task.taskStatus) }}
+                </view>
+              </view>
+              
+              <!-- 浠诲姟缂栧彿鍗曠嫭涓�琛� -->
+              <view class="task-code-row">
+                <text class="task-code">{{ task.taskCode }}</text>
+              </view>
+              
+              <!-- 浠诲姟璇︾粏淇℃伅 -->
+              <view class="task-info">
+                <view class="info-row">
+                  <view class="info-item">
+                    <view class="label">鍑哄彂鍦�:</view>
+                    <view class="value">{{ task.startLocation }}</view>
+                  </view>
+                  <view class="info-item">
+                    <view class="label">鐩殑鍦�:</view>
+                    <view class="value">{{ task.endLocation }}</view>
+                  </view>
+                </view>
+                <view class="info-row">
+                  <view class="info-item">
+                    <view class="label">鍑哄彂鏃堕棿:</view>
+                    <view class="value">{{ task.startTime }}</view>
+                  </view>
+                  <view class="info-item">
+                    <view class="label">鎵ц浜哄憳:</view>
+                    <view class="value">{{ task.assignee }}</view>
+                  </view>
+                </view>
+              </view>
+            </view>
+            
+            <!-- 鎿嶄綔鎸夐挳 -->
+            <view class="task-actions">
+              <!-- 寰呭鐞嗙姸鎬�: 鏄剧ず鍑哄彂銆佸彇娑� -->
+              <template v-if="task.taskStatus === 'PENDING'">
+                <button 
+                  class="action-btn primary" 
+                  @click="handleTaskAction(task, 'depart')"
+                >
+                  鍑哄彂
+                </button>
+                <button 
+                  class="action-btn cancel" 
+                  @click="handleTaskAction(task, 'cancel')"
+                >
+                  鍙栨秷
+                </button>
+              </template>
+              
+              <!-- 鍑哄彂涓姸鎬�: 鏄剧ず宸插埌杈俱�佸己鍒剁粨鏉� -->
+              <template v-else-if="task.taskStatus === 'DEPARTING'">
+                <button 
+                  class="action-btn primary" 
+                  @click="handleTaskAction(task, 'arrive')"
+                >
+                  宸插埌杈�
+                </button>
+                <button 
+                  class="action-btn cancel" 
+                  @click="handleTaskAction(task, 'forceCancel')"
+                >
+                  寮哄埗缁撴潫
+                </button>
+              </template>
+              
+              <!-- 宸插埌杈剧姸鎬�: 鏄剧ず宸茶繑绋� -->
+              <template v-else-if="task.taskStatus === 'ARRIVED'">
+                <button 
+                  class="action-btn primary" 
+                  @click="handleTaskAction(task, 'return')"
+                >
+                  宸茶繑绋�
+                </button>
+              </template>
+              
+              <!-- 杩旂▼涓姸鎬�: 鏄剧ず宸插畬鎴� -->
+              <template v-else-if="task.taskStatus === 'RETURNING'">
+                <button 
+                  class="action-btn primary" 
+                  @click="handleTaskAction(task, 'complete')"
+                >
+                  宸插畬鎴�
+                </button>
+              </template>
+              
+              <!-- 宸插畬鎴�/宸插彇娑�: 涓嶆樉绀烘寜閽� -->
+            </view>
+          </view>
+          
+          <view class="no-data" v-if="filteredTaskList.length === 0">
+            <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+            <text>鏆傛棤浠诲姟鏁版嵁</text>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+  </view>
+</template>
+
+<script>
+  import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
+  import { listTask, changeTaskStatus } from '@/api/task'
+  import { mapState } from 'vuex'
+  import { formatDateTime } from '@/utils/common'
+  
+  export default {
+    components: {
+      uniDatetimePicker
+    },
+    data() {
+      return {
+        // 鎺у埗鏌ヨ鐣岄潰鏄剧ず/闅愯棌
+        showSearch: false,
+        
+        // 鏌ヨ鏉′欢
+        searchForm: {
+          vehicle: '',
+          taskNo: ''
+        },
+        statusOptions: ['鍏ㄩ儴鐘舵��', '寰呭鐞�', '澶勭悊涓�', '宸插畬鎴�'],
+        statusValues: ['', 'pending', 'processing', 'completed'],
+        selectedStatus: '',
+        selectedStatusText: '',
+        startDate: '',
+        endDate: '',
+        currentFilter: 'all',
+        
+        // 浠诲姟鍒楄〃
+        taskList: [],
+        loading: false,
+        refreshing: false
+      }
+    },
+    computed: {
+      ...mapState({
+        currentUser: state => state.user
+      }),
+      filteredTaskList() {
+        let filtered = this.taskList;
+        
+        // 搴旂敤绛涢�夊櫒
+        if (this.currentFilter !== 'all') {
+          filtered = filtered.filter(task => {
+            if (this.currentFilter === 'pending') return task.taskStatus === 'PENDING';
+            if (this.currentFilter === 'processing') return ['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(task.taskStatus);
+            if (this.currentFilter === 'completed') return task.taskStatus === 'COMPLETED';
+            return true;
+          });
+        }
+        
+        // 搴旂敤鐘舵�佺瓫閫�
+        if (this.selectedStatus) {
+          const statusMap = {
+            'pending': ['PENDING'],
+            'processing': ['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'],
+            'completed': ['COMPLETED']
+          }
+          const validStatuses = statusMap[this.selectedStatus];
+          if (validStatuses) {
+            filtered = filtered.filter(task => validStatuses.includes(task.taskStatus));
+          }
+        }
+        
+        // 搴旂敤杞︾墝鍙风瓫閫� - 鎼滅储assignedVehicles鏁扮粍涓殑杞﹁締
+        if (this.searchForm.vehicle) {
+          filtered = filtered.filter(task => {
+            // 鍦ㄨ溅杈嗗垪琛ㄤ腑鏌ユ壘鍖归厤鐨勮溅鐗屽彿
+            if (task.vehicleList && task.vehicleList.length > 0) {
+              return task.vehicleList.some(vehicle => 
+                vehicle.vehicleNo && vehicle.vehicleNo.includes(this.searchForm.vehicle)
+              )
+            }
+            return false
+          });
+        }
+        
+        // 搴旂敤浠诲姟缂栧彿绛涢�� - 浣跨敤taskCode鑰屼笉鏄痶askNo
+        if (this.searchForm.taskNo) {
+          filtered = filtered.filter(task => 
+            task.taskCode && task.taskCode.includes(this.searchForm.taskNo)
+          );
+        }
+        
+        // 搴旂敤鏃堕棿鑼冨洿绛涢��
+        if (this.startDate) {
+          filtered = filtered.filter(task => 
+            task.plannedStartTime && task.plannedStartTime >= this.startDate
+          );
+        }
+        
+        if (this.endDate) {
+          // 缁撴潫鏃ユ湡鍔犱竴澶╋紝浠ヤ究鍖呭惈褰撳ぉ鐨勬暟鎹�
+          const end = new Date(this.endDate);
+          end.setDate(end.getDate() + 1);
+          const endDateStr = end.toISOString().split('T')[0];
+          
+          filtered = filtered.filter(task => 
+            task.plannedStartTime && task.plannedStartTime < endDateStr
+          );
+        }
+        
+        return filtered;
+      }
+    },
+    onLoad() {
+      this.loadTaskList()
+    },
+    onPullDownRefresh() {
+      this.refreshList()
+    },
+    methods: {
+      // 鍔犺浇浠诲姟鍒楄〃
+      loadTaskList() {
+        this.loading = true
+        // 鍚庣浼氳嚜鍔ㄨ幏鍙栧綋鍓嶇敤鎴蜂俊鎭紝瀹炵幇缁煎悎鏌ヨ
+        // 缁煎悎鏌ヨ锛氬綋鍓嶇敤鎴锋墍鍦ㄦ満鏋勪换鍔� + 褰撳墠鐢ㄦ埛鍒涘缓鐨勪换鍔� + 鍒嗛厤缁欏綋鍓嶇敤鎴风殑浠诲姟
+        const queryParams = {
+          pageNum: 1,
+          pageSize: 100
+        }
+        
+        listTask(queryParams).then(response => {
+          this.loading = false
+          const data = response.data || response.rows || []
+          this.taskList = data.map(task => {
+            // 浠巃ssignedVehicles鏁扮粍涓幏鍙栬溅杈嗕俊鎭�
+            let vehicleInfo = '鏈垎閰嶈溅杈�'
+            if (task.assignedVehicles && task.assignedVehicles.length > 0) {
+              // 濡傛灉鏈夊涓溅杈�,鏄剧ず绗竴涓�,骞舵爣娉ㄦ暟閲�
+              const firstVehicle = task.assignedVehicles[0]
+              vehicleInfo = firstVehicle.vehicleNo || '鏈煡杞︾墝'
+              if (task.assignedVehicles.length > 1) {
+                vehicleInfo += ` 绛�${task.assignedVehicles.length}杈哷
+              }
+            }
+            
+            return {
+              ...task,
+              // 鏍煎紡鍖栨樉绀哄瓧娈� - 浣跨敤鍚庣杩斿洖鐨刟ssignedVehicles鏁版嵁
+              vehicle: vehicleInfo,
+              vehicleList: task.assignedVehicles || [],
+              startLocation: this.formatAddress(task.departureAddress || task.startLocation || '鏈缃�'),
+              endLocation: this.formatAddress(task.destinationAddress || task.endLocation || '鏈缃�'),
+              startTime: task.plannedStartTime ? formatDateTime(task.plannedStartTime, 'YYYY-MM-DD HH:mm') : '鏈缃�',
+              assignee: task.assigneeName || '鏈垎閰�'
+            }
+          })
+        }).catch(error => {
+          this.loading = false
+          console.error('鍔犺浇浠诲姟鍒楄〃澶辫触:', error)
+          this.$modal.showToast('鍔犺浇浠诲姟鍒楄〃澶辫触')
+        })
+      },
+      
+      // 鏍煎紡鍖栧湴鍧� - 鍙樉绀�-鍓嶉潰鐨勯儴鍒�
+      formatAddress(address) {
+        if (!address) return '鏈缃�'
+        // 濡傛灉鍦板潃鍖呭惈-锛屽彧杩斿洖-鍓嶉潰鐨勯儴鍒�
+        const dashIndex = address.indexOf('-')
+        if (dashIndex > 0) {
+          return address.substring(0, dashIndex)
+        }
+        return address
+      },
+      
+      // 鍒囨崲鏌ヨ鐣岄潰鏄剧ず/闅愯棌
+      toggleSearch() {
+        this.showSearch = !this.showSearch;
+      },
+      
+      // 鐘舵�侀�夋嫨
+      onStatusChange(e) {
+        this.selectedStatus = this.statusValues[e.detail.value];
+        this.selectedStatusText = this.statusOptions[e.detail.value];
+      },
+      
+      // 鏌ヨ
+      handleSearch() {
+        this.loadTaskList()
+        this.$modal.showToast('鏌ヨ鎴愬姛');
+        // 鏌ヨ瀹屾垚鍚庨殣钘忔煡璇㈢晫闈�
+        this.showSearch = false;
+      },
+      
+      // 閲嶇疆鏌ヨ鏉′欢
+      resetSearch() {
+        this.selectedStatus = '';
+        this.selectedStatusText = '';
+        this.startDate = '';
+        this.endDate = '';
+        this.searchForm.vehicle = '';
+        this.searchForm.taskNo = '';
+      },
+      
+      // 鍒锋柊鍒楄〃
+      refreshList() {
+        this.refreshing = true
+        this.loadTaskList()
+        setTimeout(() => {
+          this.refreshing = false
+          this.$modal.showToast('鍒楄〃宸插埛鏂�');
+          // 鍋滄涓嬫媺鍒锋柊
+          uni.stopPullDownRefresh()
+        }, 1000)
+      },
+      
+      // 绛涢��
+      changeFilter(filter) {
+        this.currentFilter = filter;
+      },
+      
+      // 鏌ョ湅浠诲姟璇︽儏
+      viewTaskDetail(task) {
+        // 璺宠浆鍒颁换鍔¤鎯呴〉闈� - 淇:浣跨敤taskId鑰屼笉鏄痠d
+        this.$tab.navigateTo(`/pages/task/detail?id=${task.taskId}`);
+      },
+      
+      // 澶勭悊浠诲姟鎿嶄綔
+      handleTaskAction(task, action) {
+        switch (action) {
+          case 'depart':
+            // 鍑哄彂 -> 鐘舵�佸彉涓哄嚭鍙戜腑
+            this.$modal.confirm('纭畾瑕佸嚭鍙戝悧锛�').then(() => {
+              this.updateTaskStatus(task.taskId, 'DEPARTING', '浠诲姟宸插嚭鍙�')
+            }).catch(() => {});
+            break;
+            
+          case 'cancel':
+            // 鍙栨秷 -> 浜屾纭鍚庣姸鎬佸彉涓哄凡鍙栨秷
+            this.$modal.confirm('纭畾瑕佸彇娑堟浠诲姟鍚楋紵').then(() => {
+              this.updateTaskStatus(task.taskId, 'CANCELLED', '浠诲姟宸插彇娑�')
+            }).catch(() => {});
+            break;
+            
+          case 'arrive':
+            // 宸插埌杈� -> 鐘舵�佸彉涓哄凡鍒拌揪
+            this.$modal.confirm('纭宸插埌杈剧洰鐨勫湴锛�').then(() => {
+              this.updateTaskStatus(task.taskId, 'ARRIVED', '宸插埌杈剧洰鐨勫湴')
+            }).catch(() => {});
+            break;
+            
+          case 'forceCancel':
+            // 寮哄埗缁撴潫 -> 鐘舵�佸彉涓哄凡鍙栨秷
+            this.$modal.confirm('纭畾瑕佸己鍒剁粨鏉熸浠诲姟鍚楋紵').then(() => {
+              this.updateTaskStatus(task.taskId, 'CANCELLED', '浠诲姟宸插己鍒剁粨鏉�')
+            }).catch(() => {});
+            break;
+            
+          case 'return':
+            // 宸茶繑绋� -> 鐘舵�佸彉涓鸿繑绋嬩腑
+            this.$modal.confirm('纭寮�濮嬭繑绋嬶紵').then(() => {
+              this.updateTaskStatus(task.taskId, 'RETURNING', '宸插紑濮嬭繑绋�')
+            }).catch(() => {});
+            break;
+            
+          case 'complete':
+            // 宸插畬鎴� -> 鐘舵�佸彉涓哄凡瀹屾垚
+            this.$modal.confirm('纭浠诲姟宸插畬鎴愶紵').then(() => {
+              this.updateTaskStatus(task.taskId, 'COMPLETED', '浠诲姟宸插畬鎴�')
+            }).catch(() => {});
+            break;
+        }
+      },
+      
+      // 鏇存柊浠诲姟鐘舵��
+      updateTaskStatus(taskId, status, remark) {
+        // 鑾峰彇GPS浣嶇疆淇℃伅
+        this.getLocationAndUpdateStatus(taskId, status, remark)
+      },
+      
+      // 鑾峰彇浣嶇疆淇℃伅骞舵洿鏂扮姸鎬�
+      getLocationAndUpdateStatus(taskId, status, remark) {
+        const that = this
+        
+        // 浣跨敤uni.getLocation鑾峰彇GPS浣嶇疆
+        uni.getLocation({
+          type: 'gcj02',
+          geocode: true,
+          altitude: true,
+          success: function(res) {
+            console.log('GPS瀹氫綅鎴愬姛:', res)
+            
+            const statusData = {
+              taskStatus: status,
+              remark: remark,
+              latitude: res.latitude,
+              longitude: res.longitude,
+              locationAddress: res.address ? res.address.street || res.address.poiName || '' : '',
+              locationProvince: res.address ? res.address.province || '' : '',
+              locationCity: res.address ? res.address.city || '' : '',
+              locationDistrict: res.address ? res.address.district || '' : '',
+              gpsAccuracy: res.accuracy,
+              altitude: res.altitude,
+              speed: res.speed,
+              heading: res.direction || res.heading
+            }
+            
+            changeTaskStatus(taskId, statusData).then(response => {
+              that.$modal.showToast('鐘舵�佹洿鏂版垚鍔�')
+              that.loadTaskList()
+            }).catch(error => {
+              console.error('鏇存柊浠诲姟鐘舵�佸け璐�:', error)
+              that.$modal.showToast('鐘舵�佹洿鏂板け璐ワ紝璇烽噸璇�')
+            })
+          },
+          fail: function(err) {
+            console.error('GPS瀹氫綅澶辫触:', err)
+            
+            that.$modal.confirm('GPS瀹氫綅澶辫触锛屾槸鍚︾户缁洿鏂扮姸鎬侊紵').then(() => {
+              const statusData = {
+                taskStatus: status,
+                remark: remark
+              }
+              
+              changeTaskStatus(taskId, statusData).then(response => {
+                that.$modal.showToast('鐘舵�佹洿鏂版垚鍔�')
+                that.loadTaskList()
+              }).catch(error => {
+                console.error('鏇存柊浠诲姟鐘舵�佸け璐�:', error)
+                that.$modal.showToast('鐘舵�佹洿鏂板け璐ワ紝璇烽噸璇�')
+              })
+            }).catch(() => {})
+          }
+        })
+      },
+      
+      getStatusText(status) {
+        const statusMap = {
+          'PENDING': '寰呭鐞�',
+          'DEPARTING': '鍑哄彂涓�',
+          'ARRIVED': '宸插埌杈�',
+          'RETURNING': '杩旂▼涓�',
+          'COMPLETED': '宸插畬鎴�',
+          'CANCELLED': '宸插彇娑�',
+          'IN_PROGRESS': '澶勭悊涓�' // 鍏煎鏃ф暟鎹�
+        }
+        return statusMap[status] || '鏈煡'
+      },
+      
+      // 鑾峰彇鐘舵�佹牱寮忕被
+      getStatusClass(status) {
+        const statusClassMap = {
+          'PENDING': 'status-pending',
+          'DEPARTING': 'status-departing',
+          'ARRIVED': 'status-arrived',
+          'RETURNING': 'status-returning',
+          'COMPLETED': 'status-completed',
+          'CANCELLED': 'status-cancelled',
+          'IN_PROGRESS': 'status-in-progress'
+        }
+        return statusClassMap[status] || 'status-default'
+      },
+      
+      getTaskTypeText(type) {
+        const typeMap = {
+          'MAINTENANCE': '缁翠慨淇濆吇',
+          'FUEL': '鍔犳补',
+          'OTHER': '鍏朵粬',
+          'EMERGENCY_TRANSFER': '杞繍浠诲姟',
+          'WELFARE': '绂忕杞�'
+        }
+        return typeMap[type] || '鏈煡绫诲瀷'
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  .task-container {
+    padding: 20rpx;
+    background-color: #f5f5f5;
+    height: 100vh;
+    display: flex;
+    flex-direction: column;
+    // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+    ::-webkit-scrollbar {
+      display: none;
+      width: 0 !important;
+      height: 0 !important;
+      background: transparent;
+    }
+    
+    // Firefox婊氬姩鏉¢殣钘�
+    * {
+      scrollbar-width: none; /* Firefox */
+    }
+    
+    // IE/Edge婊氬姩鏉¢殣钘�
+    * {
+      -ms-overflow-style: none; /* IE 10+ */
+    }
+  }
+  
+  // 浠诲姟鍒楄〃鍖哄煙
+  .task-list-section {
+    flex: 1;
+    background-color: white;
+    border-radius: 15rpx;
+    padding: 30rpx;
+    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+    display: flex;
+    flex-direction: column;
+  }
+  
+  .task-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 20rpx 0;
+    flex-shrink: 0; // 闃叉鏀剁缉
+    
+    .header-title {
+      font-size: 36rpx;
+      font-weight: bold;
+    }
+    
+    .header-actions {
+      display: flex;
+      
+      .search-toggle-btn, .refresh-btn {
+        width: 60rpx;
+        height: 60rpx;
+        border-radius: 50%;
+        background-color: #f0f0f0;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-left: 20rpx;
+      }
+    }
+  }
+  
+  // 鏌ヨ鏉′欢鍖哄煙
+  .search-section {
+    background-color: #f9f9f9;
+    border-radius: 15rpx;
+    padding: 30rpx;
+    margin: 20rpx 0;
+    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+    flex-shrink: 0; // 闃叉鏀剁缉
+    
+    .form-item {
+      margin-bottom: 30rpx;
+      
+      &:last-child {
+        margin-bottom: 0;
+      }
+      
+      .form-label {
+        font-size: 28rpx;
+        margin-bottom: 15rpx;
+        color: #333;
+      }
+      
+      .form-input {
+        height: 70rpx;
+        padding: 0 20rpx;
+        border: 1rpx solid #eee;
+        border-radius: 10rpx;
+        font-size: 28rpx;
+        
+        &.picker-input {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+        }
+      }
+      
+      .date-range {
+        display: flex;
+        align-items: center;
+        
+        .date-input {
+          flex: 1;
+          height: 70rpx;
+          padding: 0 20rpx;
+          border: 1rpx solid #eee;
+          border-radius: 10rpx;
+          font-size: 28rpx;
+          display: flex;
+          align-items: center;
+        }
+        
+        .divider {
+          margin: 0 20rpx;
+          color: #999;
+        }
+      }
+    }
+    
+    .form-actions {
+      display: flex;
+      margin-top: 20rpx;
+      
+      .search-btn, .reset-btn {
+        flex: 1;
+        height: 70rpx;
+        border-radius: 10rpx;
+        font-size: 28rpx;
+        margin: 0 10rpx;
+      }
+      
+      .search-btn {
+        background-color: #007AFF;
+        color: white;
+      }
+    }
+  }
+  
+  .task-filter {
+    margin-bottom: 30rpx;
+    flex-shrink: 0; // 闃叉鏀剁缉
+    
+    .filter-tabs {
+      white-space: nowrap;
+      padding: 10rpx 0;
+      // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+      ::-webkit-scrollbar {
+        display: none;
+        width: 0 !important;
+        height: 0 !important;
+        background: transparent;
+      }
+      
+      // Firefox婊氬姩鏉¢殣钘�
+      * {
+        scrollbar-width: none; /* Firefox */
+      }
+      
+      // IE/Edge婊氬姩鏉¢殣钘�
+      * {
+        -ms-overflow-style: none; /* IE 10+ */
+      }
+      
+      .filter-item {
+        display: inline-block;
+        padding: 15rpx 30rpx;
+        margin-right: 20rpx;
+        background-color: #f5f5f5;
+        border-radius: 30rpx;
+        font-size: 28rpx;
+        
+        &.active {
+          background-color: #007AFF;
+          color: white;
+        }
+      }
+    }
+  }
+  
+  .task-list-scroll {
+    flex: 1;
+    // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+    ::-webkit-scrollbar {
+      display: none;
+      width: 0 !important;
+      height: 0 !important;
+      background: transparent;
+    }
+    
+    // Firefox婊氬姩鏉¢殣钘�
+    * {
+      scrollbar-width: none; /* Firefox */
+    }
+    
+    // IE/Edge婊氬姩鏉¢殣钘�
+    * {
+      -ms-overflow-style: none; /* IE 10+ */
+    }
+  }
+  
+  .task-list {
+    .task-item {
+      background-color: #fafafa;
+      border-radius: 15rpx;
+      margin-bottom: 30rpx;
+      overflow: hidden;
+      
+      .task-main {
+        padding: 30rpx;
+        border-bottom: 1rpx solid #f0f0f0;
+        
+        // 浠诲姟澶撮儴锛氭爣棰樺拰鐘舵��
+        .task-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: flex-start;
+          margin-bottom: 15rpx;
+          
+          .task-title {
+            flex: 1;
+            font-size: 32rpx;
+            font-weight: bold;
+            padding-right: 20rpx;
+            line-height: 1.4;
+          }
+          
+          .task-status {
+            padding: 8rpx 20rpx;
+            border-radius: 30rpx;
+            font-size: 24rpx;
+            white-space: nowrap;
+            flex-shrink: 0;
+            
+            // 寰呭鐞� - 姗欒壊
+            &.status-pending {
+              background-color: #fff3e0;
+              color: #ff9500;
+            }
+            
+            // 鍑哄彂涓� - 钃濊壊
+            &.status-departing {
+              background-color: #e3f2fd;
+              color: #007AFF;
+            }
+            
+            // 宸插埌杈� - 绱壊
+            &.status-arrived {
+              background-color: #f3e5f5;
+              color: #9c27b0;
+            }
+            
+            // 杩旂▼涓� - 闈掕壊
+            &.status-returning {
+              background-color: #e0f2f1;
+              color: #009688;
+            }
+            
+            // 宸插畬鎴� - 缁胯壊
+            &.status-completed {
+              background-color: #e8f5e9;
+              color: #34C759;
+            }
+            
+            // 宸插彇娑� - 鐏拌壊
+            &.status-cancelled {
+              background-color: #f5f5f5;
+              color: #999;
+            }
+            
+            // 澶勭悊涓� (鍏煎鏃ф暟鎹�) - 钃濊壊
+            &.status-in-progress {
+              background-color: #e3f2fd;
+              color: #007AFF;
+            }
+            
+            // 榛樿鏍峰紡
+            &.status-default {
+              background-color: #f5f5f5;
+              color: #666;
+            }
+          }
+        }
+        
+        // 浠诲姟缂栧彿鍗曠嫭涓�琛�
+        .task-code-row {
+          margin-bottom: 15rpx;
+          padding: 10rpx 0;
+          border-bottom: 1rpx dashed #e0e0e0;
+          
+          .task-code {
+            font-size: 28rpx;
+            color: #333;
+            font-weight: 500;
+            font-family: monospace;
+          }
+        }
+        
+        .task-info {
+          .info-row {
+            display: flex;
+            margin-bottom: 15rpx;
+            
+            &:last-child {
+              margin-bottom: 0;
+            }
+            
+            .info-item {
+              flex: 1;
+              display: flex;
+              
+              .label {
+                font-size: 26rpx;
+                color: #666;
+                margin-right: 10rpx;
+                white-space: nowrap;
+              }
+              
+              .value {
+                font-size: 26rpx;
+                flex: 1;
+                word-break: break-all;
+              }
+            }
+          }
+        }
+      }
+      
+      .task-actions {
+        display: flex;
+        padding: 20rpx;
+        
+        .action-btn {
+          flex: 1;
+          height: 70rpx;
+          border-radius: 10rpx;
+          font-size: 26rpx;
+          margin: 0 5rpx;
+          background-color: #f0f0f0;
+          color: #333;
+          
+          &.primary {
+            background-color: #007AFF;
+            color: white;
+          }
+          
+          &.cancel {
+            background-color: #ff3b30;
+            color: white;
+          }
+          
+          &.disabled {
+            opacity: 0.5;
+          }
+          
+          &:first-child {
+            margin-left: 0;
+          }
+          
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+      }
+    }
+    
+    .no-data {
+      text-align: center;
+      padding: 100rpx 0;
+      color: #999;
+      
+      text {
+        display: block;
+        margin-top: 20rpx;
+      }
+    }
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.1