From 5f2ee03958a1a16dc27195c76ea7cffb422c95d1 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期五, 19 十二月 2025 22:40:34 +0800
Subject: [PATCH] feat: 任务修改接口,删除一些不要的字段同步

---
 app/pages/index.vue | 1228 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 1,205 insertions(+), 23 deletions(-)

diff --git a/app/pages/index.vue b/app/pages/index.vue
index 4646807..6579435 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -1,43 +1,1225 @@
 <template>
-  <view class="content">
-    <image class="logo" src="@/static/logo.png"></image>
-    <view class="text-area">
-      <text class="title">Hello RuoYi</text>
+  <view class="home-container">
+    <!-- 椤堕儴鐢ㄦ埛淇℃伅鍖哄煙 -->
+    <view class="user-info-section">
+      <view class="user-info-content">
+        <view class="user-details">
+          <view class="user-info-row">
+            <text class="user-name">{{ userName || "鏈櫥褰�" }}</text>
+            <text class="separator" v-if="currentUser.branchCompanyName"
+              >|</text
+            >
+            <view class="branch-company" v-if="currentUser.branchCompanyName">
+              <uni-icons
+                type="location"
+                size="16"
+                color="#666"
+                style="margin-right: 4rpx"
+              ></uni-icons>
+              <text>{{ currentUser.branchCompanyName }}</text>
+            </view>
+            <text class="separator" v-if="boundVehicle">|</text>
+            <view
+              class="vehicle-info"
+              @click.stop="goToBindVehicle"
+              v-if="boundVehicle"
+            >
+              <text>{{ boundVehicle }}</text>
+              <uni-icons
+                type="loop"
+                size="16"
+                color="#007AFF"
+                style="margin-left: 4rpx"
+              ></uni-icons>
+            </view>
+          </view>
+          <view
+            class="bind-vehicle-btn"
+            v-if="!boundVehicle"
+            @click="goToBindVehicle"
+          >
+            <uni-icons
+              type="plus-filled"
+              size="16"
+              color="#007AFF"
+              style="margin-right: 4rpx"
+            ></uni-icons>
+            <text>缁戝畾杞︾墝</text>
+          </view>
+        </view>
+      </view>
     </view>
+
+    <!-- 娑堟伅鍏ュ彛 -->
+    <view class="message-entry" @click="goToMessages">
+      <view class="message-icon">
+        <uni-icons type="chat" size="24" color="#007AFF"></uni-icons>
+      </view>
+      <view class="message-text">娑堟伅涓績</view>
+      <view class="unread-dot" v-if="unreadMessageCount > 0">{{
+        unreadMessageCount
+      }}</view>
+      <view class="arrow">
+        <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
+      </view>
+    </view>
+
+    <!-- 璁㈤槄閫氱煡鎻愮ず鍗$墖锛堟湭璁㈤槄鏃舵樉绀猴級 -->
+    <view
+      class="subscribe-banner"
+      v-if="!hasSubscribed"
+      @click="clickConfirmsubscribeTaskNotify"
+    >
+      <view class="banner-icon">
+        <uni-icons type="bell" size="28" color="#ff9500"></uni-icons>
+      </view>
+      <view class="banner-content">
+        <view class="banner-title">寮�鍚换鍔¢�氱煡</view>
+        <view class="banner-desc">鍙婃椂鎺ユ敹浠诲姟鍒嗛厤鍜岀姸鎬佹洿鏂版彁閱�</view>
+      </view>
+      <view class="banner-action">
+        <text>绔嬪嵆寮�鍚�</text>
+        <uni-icons type="arrowright" size="16" color="#007AFF"></uni-icons>
+      </view>
+    </view>
+
+    <!-- 姝e湪杩愯鐨勪换鍔℃爣棰� -->
+    <view class="running-tasks-header">
+      <text class="header-title">姝e湪杩愯鐨勪换鍔�</text>
+    </view>
+
+    <!-- 姝e湪杩愯鐨勪换鍔″垪琛� -->
+    <scroll-view 
+      class="running-tasks-section" 
+      scroll-y="true"
+      @scrolltolower="onScrollToLower"
+    >
+      <view class="task-list">
+        <view class="task-item" v-for="task in runningTasks" :key="task.id">
+          <view class="task-main" @click="viewTaskDetail(task)">
+            <!-- 浠诲姟澶撮儴锛氭爣棰樺拰鐘舵�佹爣绛� -->
+            <view class="task-header">
+              <view class="task-title">
+                {{ getTaskTypeText(task.type) }} - {{ task.vehicle }}
+                <text v-if="task.isHeadPush === '1'" class="head-push-tag">鎬�</text>
+              </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.status) }}
+              </view>
+            </view>
+
+            <!-- 浠诲姟缂栧彿鍗曠嫭涓�琛� -->
+            <view class="task-code-row">
+              <text class="task-code">{{ task.showTaskCode }}</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="runningTasks.length === 0">
+          <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+          <text>鏆傛棤姝e湪杩愯鐨勪换鍔�</text>
+        </view>
+        
+        <!-- 鍔犺浇鏇村鎻愮ず -->
+        <view class="load-more" v-if="runningTasks.length > 0 && hasMore && loading">
+          <uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons>
+          <text>姝e湪鍔犺浇鏇村鏁版嵁...</text>
+        </view>
+        <view class="load-more no-more" v-else-if="runningTasks.length > 0 && !hasMore">
+          <text>娌℃湁鏇村鏁版嵁浜�</text>
+        </view>
+      </view>
+    </scroll-view>
   </view>
 </template>
 
 <script>
-  export default {
-    onLoad: function() {
+import { mapState } from "vuex";
+import { getMyTasks, changeTaskStatus } from "@/api/task";
+import { getUserProfile } from "@/api/system/user";
+import { getUserBoundVehicle } from "@/api/vehicle";
+import { getUnreadCount } from "@/api/message";
+import { formatDateTime } from "@/utils/common";
+import subscribeManager from "@/utils/subscribe";
+
+export default {
+  data() {
+    return {
+      // 鐢ㄦ埛缁戝畾鐨勮溅杈嗕俊鎭�
+      boundVehicle: "",
+      boundVehicleId: null,
+
+      // 娑堟伅鏁版嵁
+      messages: [],
+      unreadMessageCount: 0,
+
+      // 姝e湪杩愯鐨勪换鍔″垪琛�
+      allTaskList: [], // 瀛樺偍鎵�鏈変换鍔℃暟鎹�
+      displayedTaskList: [], // 瀛樺偍褰撳墠鏄剧ず鐨勪换鍔℃暟鎹�
+      loading: false,
+
+      // 璁㈤槄鐘舵��
+      hasSubscribed: false,
+      
+      // 鍓嶇鍒嗛〉鐩稿叧
+      currentPage: 1,
+      pageSize: 10,
+      hasMore: true,
+    };
+  },
+  computed: {
+    ...mapState({
+      userName: (state) => state.user.nickName,
+      currentUser: (state) => state.user,
+    }),
+
+    // 姝e湪杩愯鐨勪换鍔★紙寰呭鐞嗗拰鍚勭澶勭悊涓殑浠诲姟锛�
+    runningTasks() {
+      return this.displayedTaskList.filter((task) => {
+        // 鍖呭惈寰呭鐞嗐�佸嚭鍙戜腑銆佸凡鍒拌揪銆佽繑绋嬩腑绛夋墍鏈夋湭瀹屾垚鐨勭姸鎬�
+        return [
+          "PENDING",
+          "DEPARTING",
+          "ARRIVED",
+          "RETURNING",
+          "IN_PROGRESS",
+        ].includes(task.taskStatus);
+      });
+    },
+  },
+  onLoad() {
+    // 妫�鏌ョ敤鎴锋槸鍚﹀凡鐧诲綍
+    const userId = this.currentUser.userId;
+    if (!userId) {
+      console.log("鐢ㄦ埛鏈櫥褰曪紝璺宠繃鍔犺浇鏁版嵁");
+      return;
     }
-  }
+
+    // 妫�鏌ヨ闃呯姸鎬侊紙鍏堟鏌ユ湰鍦帮紝鍚庨潰浼氭鏌ュ井淇″畼鏂圭姸鎬侊級
+    this.hasSubscribed = true;//subscribeManager.checkLocalSubscribeStatus();
+
+    // 鑷姩璁㈤槄锛堝鏋滄湭璁㈤槄鍒欐樉绀虹‘璁ゅ脊绐楋級
+    // this.autoSubscribeOnLaunch();
+
+    // 鍔犺浇鐢ㄦ埛缁戝畾杞﹁締淇℃伅
+    this.loadUserVehicle();
+    // 鍔犺浇姝e湪杩愯鐨勪换鍔�
+    this.loadRunningTasks();
+    // 鍔犺浇鏈娑堟伅鏁伴噺
+    this.loadUnreadMessageCount();
+  },
+  onShow() {
+    // 妫�鏌ョ敤鎴锋槸鍚﹀凡鐧诲綍
+    const userId = this.currentUser.userId;
+    if (!userId) {
+      console.log("鐢ㄦ埛鏈櫥褰曪紝璺宠繃鍔犺浇鏁版嵁");
+      return;
+    }
+
+    // 姣忔鏄剧ず椤甸潰鏃跺埛鏂颁换鍔″垪琛ㄣ�佺粦瀹氳溅杈嗗拰娑堟伅鏁伴噺
+    this.loadUserVehicle();
+    // 閲嶆柊鍔犺浇浠诲姟鍒楄〃鏃堕噸缃垎椤�
+    this.currentPage = 1;
+    this.hasMore = true;
+    this.loadRunningTasks();
+    this.loadUnreadMessageCount();
+  },
+  onPullDownRefresh() {
+    // 涓嬫媺鍒锋柊鏃堕噸缃垎椤靛弬鏁�
+    this.currentPage = 1;
+    this.hasMore = true;
+    // 涓嬫媺鍒锋柊
+    this.loadRunningTasks();
+    setTimeout(() => {
+      uni.stopPullDownRefresh();
+    }, 1000);
+  },
+  methods: {
+    // 婊氬姩鍒板簳閮ㄦ椂鍔犺浇鏇村
+    onScrollToLower() {
+      if (this.hasMore && !this.loading) {
+        this.loadMoreTasks();
+      }
+    },
+    
+    // 鑷姩璁㈤槄锛堝皬绋嬪簭鍚姩鏃惰皟鐢級
+    autoSubscribeOnLaunch() {
+      subscribeManager.autoSubscribe()
+        .then((result) => {
+          if (result.skipped) {
+            console.log('鐢ㄦ埛宸茶闃咃紝鏃犻渶閲嶅璁㈤槄');
+            this.hasSubscribed = true;
+          } else if (result.success) {
+            this.hasSubscribed = true;
+            console.log('鑷姩璁㈤槄鎴愬姛');
+          } else {
+            // 璁㈤槄澶辫触鎴栬鎷掔粷锛屾洿鏂扮姸鎬�
+            this.hasSubscribed = false;
+          }
+          
+          // 濡傛灉杩斿洖浜嗙姸鎬佷俊鎭紝杈撳嚭璇︾粏鐘舵��
+          if (result.status) {
+            console.log('璇︾粏璁㈤槄鐘舵�侊細', result.status);
+          }
+        })
+        .catch((error) => {
+          console.log('鑷姩璁㈤槄鍙栨秷鎴栧け璐ワ細', error);
+          this.hasSubscribed = false;
+        });
+    },
+
+    // 鍔犺浇鐢ㄦ埛缁戝畾鐨勮溅杈嗕俊鎭�
+    loadUserVehicle() {
+      const userId = this.currentUser.userId;
+      if (!userId) {
+        console.error("鐢ㄦ埛鏈櫥褰曪紝鏃犳硶鑾峰彇缁戝畾杞﹁締淇℃伅");
+        this.boundVehicle = "";
+        this.boundVehicleId = null;
+        return;
+      }
+
+      getUserBoundVehicle(userId)
+        .then((response) => {
+          if (response.code === 200 && response.data) {
+            const vehicle = response.data;
+            this.boundVehicle = vehicle.vehicleNumber || "鏈煡杞︾墝";
+            this.boundVehicleId = vehicle.vehicleId;
+            console.log("鐢ㄦ埛缁戝畾杞﹁締:", this.boundVehicle);
+          } else {
+            this.boundVehicle = "";
+            this.boundVehicleId = null;
+          }
+        })
+        .catch((error) => {
+          console.error("鑾峰彇缁戝畾杞﹁締淇℃伅澶辫触:", error);
+          this.boundVehicle = "";
+          this.boundVehicleId = null;
+        });
+    },
+
+    // 鍔犺浇鏈娑堟伅鏁伴噺
+    loadUnreadMessageCount() {
+      // 妫�鏌ョ敤鎴锋槸鍚﹀凡鐧诲綍
+      const userId = this.currentUser.userId;
+      if (!userId) {
+        console.log("鐢ㄦ埛鏈櫥褰曪紝璺宠繃鑾峰彇鏈娑堟伅鏁伴噺");
+        return;
+      }
+
+      getUnreadCount()
+        .then((response) => {
+          if (response.code === 200) {
+            this.unreadMessageCount = response.data || 0;
+            // 鏇存柊TabBar寰芥爣
+            this.updateTabBarBadge(this.unreadMessageCount);
+          }
+        })
+        .catch((error) => {
+          console.error("鑾峰彇鏈娑堟伅鏁伴噺澶辫触:", error);
+        });
+    },
+
+    // 鏇存柊TabBar寰芥爣
+    updateTabBarBadge(count) {
+      if (count > 0) {
+        uni.setTabBarBadge({
+          index: 3, // 娑堟伅椤甸潰鍦╰abBar涓殑绱㈠紩
+          text: count > 99 ? "99+" : count.toString(),
+        });
+      } else {
+        uni.removeTabBarBadge({
+          index: 3,
+        });
+      }
+    },
+
+    // 鍔犺浇鐢ㄦ埛淇℃伅锛堜繚鐣欎互鍏煎涔嬪墠鐨勪唬鐮侊級
+    loadUserProfile() {
+      const userId = this.currentUser.userId;
+      if (!userId) {
+        console.error("鐢ㄦ埛鏈櫥褰曪紝鏃犳硶鑾峰彇鐢ㄦ埛淇℃伅");
+        return;
+      }
+
+      getUserProfile()
+        .then((response) => {
+          const userInfo = response.data || response;
+          // 鑾峰彇鐢ㄦ埛缁戝畾鐨勮溅杈嗕俊鎭�
+          if (userInfo.boundVehicle) {
+            this.boundVehicle = userInfo.boundVehicle.vehicleNumber;
+            this.boundVehicleId = userInfo.boundVehicle.vehicleId;
+          }
+        })
+        .catch((error) => {
+          console.error("鑾峰彇鐢ㄦ埛淇℃伅澶辫触:", error);
+        });
+    },
+
+    // 鍔犺浇姝e湪杩愯鐨勪换鍔�
+    loadRunningTasks() {
+      const userId = this.currentUser.userId;
+      if (!userId) {
+        console.error("鐢ㄦ埛鏈櫥褰曪紝鏃犳硶鍔犺浇浠诲姟鍒楄〃");
+        return;
+      }
+
+      this.loading = true;
+      // 浣跨敤 /task/my 鎺ュ彛鑾峰彇褰撳墠鐢ㄦ埛鐩稿叧鐨勬墍鏈変换鍔★紙鐢ㄦ埛鍒涘缓銆佸垎閰嶇粰鐢ㄦ埛銆佹墽琛屼汉鏄敤鎴凤級
+      getMyTasks()
+        .then((response) => {
+          this.loading = false;
+          // 鏍规嵁鍚庣杩斿洖鐨勬暟鎹粨鏋勮繘琛岃В鏋�
+          const data = response.data || response.rows || response || [];
+          
+          // 濡傛灉鏄涓�椤碉紝鐩存帴鏇挎崲鏁版嵁锛涘惁鍒欒拷鍔犳暟鎹�
+          if (this.currentPage === 1) {
+            this.allTaskList = data;
+          } else {
+            this.allTaskList = [...this.allTaskList, ...data];
+          }
+          
+          // 鏍煎紡鍖栦换鍔℃暟鎹�
+          this.allTaskList = this.allTaskList
+            .filter((task) => {
+              // 鍙樉绀烘湭瀹屾垚鍜屾湭鍙栨秷鐨勪换鍔�
+              return (
+                task.taskStatus !== "COMPLETED" &&
+                task.taskStatus !== "CANCELLED"
+              );
+            })
+            .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,
+                // 鏍煎紡鍖栨樉绀哄瓧娈�
+                id: task.taskId,
+                type: task.taskType,
+                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 || "鏈垎閰�",
+                taskNo: task.taskCode || "鏈煡缂栧彿",
+                status: this.convertStatus(task.taskStatus), // 杞崲鐘舵�佹牸寮忎互鍏煎鏃I
+              };
+            });
+
+          // 鏇存柊鏄剧ず鐨勪换鍔″垪琛�
+          this.updateDisplayedTaskList();
+        })
+        .catch((error) => {
+          this.loading = false;
+          console.error("鍔犺浇浠诲姟鍒楄〃澶辫触:", error);
+        });
+    },
+    
+    // 鏇存柊鏄剧ず鐨勪换鍔″垪琛紙鍓嶇鍒嗛〉锛�
+    updateDisplayedTaskList() {
+      const start = 0;
+      const end = this.currentPage * this.pageSize;
+      this.displayedTaskList = this.allTaskList.slice(start, end);
+      this.hasMore = end < this.allTaskList.length;
+    },
+    
+    // 鍔犺浇鏇村浠诲姟锛堝墠绔垎椤碉級
+    loadMoreTasks() {
+      if (!this.hasMore || this.loading) return;
+      
+      this.currentPage++;
+      this.updateDisplayedTaskList();
+    },
+
+    // 鏍煎紡鍖栧湴鍧� - 鍙樉绀�-鍓嶉潰鐨勯儴鍒�
+    formatAddress(address) {
+      if (!address) return "鏈缃�";
+      const dashIndex = address.indexOf("-");
+      if (dashIndex > 0) {
+        return address.substring(0, dashIndex);
+      }
+      return address;
+    },
+
+    // 杞崲鐘舵�佹牸寮忥紙灏嗘暟鎹簱鐘舵�佽浆鎹负UI浣跨敤鐨勭姸鎬侊級
+    convertStatus(dbStatus) {
+      const statusMap = {
+        PENDING: "pending",
+        DEPARTING: "processing",
+        ARRIVED: "processing",
+        RETURNING: "processing",
+        IN_PROGRESS: "processing",
+        COMPLETED: "completed",
+        CANCELLED: "cancelled",
+      };
+      return statusMap[dbStatus] || "pending";
+    },
+    // 璺宠浆鍒扮粦瀹氳溅杈嗛〉闈�
+    goToBindVehicle() {
+      // 璺宠浆鍒扮粦瀹氳溅杈嗙殑椤甸潰
+      this.$tab.navigateTo("/pages/bind-vehicle");
+    },
+
+    // 璺宠浆鍒版秷鎭〉闈�
+    goToMessages() {
+      this.$tab.switchTab("/pages/message/index");
+    },
+
+    // 鏌ョ湅浠诲姟璇︽儏
+    viewTaskDetail(task) {
+      // 璺宠浆鍒颁换鍔¤鎯呴〉闈� - 浣跨敤taskId
+      this.$tab.navigateTo(`/pagesTask/detail?id=${task.taskId || task.id}`);
+    },
+
+    // 澶勭悊浠诲姟鎿嶄綔
+    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.loadRunningTasks();
+            })
+            .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.loadRunningTasks();
+                })
+                .catch((error) => {
+                  console.error("鏇存柊浠诲姟鐘舵�佸け璐�:", error);
+                  that.$modal.showToast("鐘舵�佹洿鏂板け璐ワ紝璇烽噸璇�");
+                });
+            })
+            .catch(() => {});
+        },
+      });
+    },
+
+    // 鑾峰彇鐘舵�佹牱寮忕被
+    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";
+    },
+
+    getStatusText(status) {
+      // 鏀寔鏂版棫涓ょ鐘舵�佹牸寮�
+      const statusMap = {
+        // 鏂版牸寮忥紙鏁版嵁搴撶姸鎬侊級
+        PENDING: "寰呭鐞�",
+        DEPARTING: "鍑哄彂涓�",
+        ARRIVED: "宸插埌杈�",
+        RETURNING: "杩旂▼涓�",
+        COMPLETED: "宸插畬鎴�",
+        CANCELLED: "宸插彇娑�",
+        IN_PROGRESS: "澶勭悊涓�",
+        // 鏃ф牸寮忥紙UI鐘舵�侊級
+        pending: "寰呭鐞�",
+        processing: "澶勭悊涓�",
+        completed: "宸插畬鎴�",
+      };
+      return statusMap[status] || "鏈煡";
+    },
+
+    getTaskTypeText(type) {
+      const typeMap = {
+        // 鏂版牸寮忥紙鏁版嵁搴撶被鍨嬶級
+        MAINTENANCE: "缁翠慨淇濆吇",
+        FUEL: "鍔犳补",
+        OTHER: "鍏朵粬",
+        EMERGENCY_TRANSFER: "杞繍浠诲姟",
+        WELFARE: "绂忕杞�",
+        // 鏃ф牸寮忥紙UI绫诲瀷锛�
+        maintenance: "缁翠慨淇濆吇",
+        refuel: "鍔犳补",
+        inspection: "宸℃",
+        emergency: "杞繍浠诲姟",
+        welfare: "绂忕杞�",
+      };
+      return typeMap[type] || "鏈煡绫诲瀷";
+    },
+
+    clickConfirmsubscribeTaskNotify() {
+      subscribeManager.subscribeWithConfirm()
+        .then((result) => {
+          if (result.success) {
+            this.hasSubscribed = true;
+          }
+        })
+        .catch((error) => {
+          console.log('璁㈤槄鍙栨秷鎴栧け璐ワ細', error);
+        });
+    },
+
+    // 璁㈤槄浠诲姟閫氱煡锛堢洿鎺ヨ皟鐢紝涓嶆樉绀虹‘璁ゅ脊绐楋級
+    subscribeTaskNotify() {
+      subscribeManager.subscribeDirect()
+        .then((result) => {
+          if (result.success) {
+            this.hasSubscribed = true;
+          }
+        })
+        .catch((error) => {
+          console.log('璁㈤槄澶辫触锛�', error);
+        });
+    },
+  },
+};
 </script>
 
-<style>
-  .content {
+<style lang="scss">
+.home-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+ */
+  }
+}
+
+// 鎬婚儴鎺ㄩ�佹爣璁版牱寮�
+.head-push-tag {
+  color: #ff0000;
+  font-size: 24rpx;
+  font-weight: bold;
+  margin-left: 10rpx;
+  padding: 2rpx 8rpx;
+  border: 1rpx solid #ff0000;
+  border-radius: 4rpx;
+}
+
+// 鐢ㄦ埛淇℃伅鍖哄煙
+.user-info-section {
+  background-color: white;
+  border-radius: 15rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+  flex-shrink: 0; // 闃叉鏀剁缉
+
+  .user-info-content {
     display: flex;
-    flex-direction: column;
+    justify-content: space-between;
+    align-items: center;
+
+    .user-details {
+      flex: 1;
+
+      .user-info-row {
+        display: flex;
+        align-items: center;
+        flex-wrap: wrap;
+        margin-bottom: 12rpx;
+
+        .user-name {
+          font-size: 32rpx;
+          font-weight: bold;
+          color: #333;
+        }
+
+        .separator {
+          margin: 0 12rpx;
+          color: #ddd;
+          font-size: 28rpx;
+        }
+
+        .branch-company {
+          font-size: 26rpx;
+          color: #666;
+          display: flex;
+          align-items: center;
+        }
+
+        .vehicle-info {
+          font-size: 26rpx;
+          color: #007aff;
+          display: flex;
+          align-items: center;
+        }
+      }
+
+      .bind-vehicle-btn {
+        font-size: 26rpx;
+        color: #007aff;
+        display: flex;
+        align-items: center;
+
+        &:active {
+          opacity: 0.7;
+        }
+      }
+    }
+  }
+}
+
+// 娑堟伅鍏ュ彛
+.message-entry {
+  display: flex;
+  align-items: center;
+  background-color: white;
+  border-radius: 15rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+  position: relative;
+
+  .message-icon {
+    margin-right: 20rpx;
+  }
+
+  .message-text {
+    flex: 1;
+    font-size: 32rpx;
+    color: #333;
+  }
+
+  .unread-dot {
+    position: absolute;
+    top: 15rpx;
+    right: 60rpx;
+    background-color: #ff4d4f;
+    color: white;
+    border-radius: 50%;
+    width: 32rpx;
+    height: 32rpx;
+    display: flex;
     align-items: center;
     justify-content: center;
+    font-size: 20rpx;
   }
 
-  .logo {
-    height: 200rpx;
-    width: 200rpx;
-    margin-top: 200rpx;
-    margin-left: auto;
-    margin-right: auto;
-    margin-bottom: 50rpx;
+  .arrow {
+    margin-left: 20rpx;
+  }
+}
+
+// 璁㈤槄閫氱煡妯箙
+.subscribe-banner {
+  display: flex;
+  align-items: center;
+  background: linear-gradient(135deg, #fff9e6 0%, #fff3e0 100%);
+  border-radius: 15rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 10rpx rgba(255, 149, 0, 0.1);
+  border: 1rpx solid #ffe0b2;
+
+  .banner-icon {
+    margin-right: 20rpx;
+    flex-shrink: 0;
   }
 
-  .text-area {
+  .banner-content {
+    flex: 1;
+
+    .banner-title {
+      font-size: 30rpx;
+      font-weight: bold;
+      color: #333;
+      margin-bottom: 8rpx;
+    }
+
+    .banner-desc {
+      font-size: 24rpx;
+      color: #666;
+      line-height: 1.4;
+    }
+  }
+
+  .banner-action {
     display: flex;
-    justify-content: center;
+    align-items: center;
+    padding: 12rpx 24rpx;
+    background-color: white;
+    border-radius: 30rpx;
+    flex-shrink: 0;
+
+    text {
+      font-size: 26rpx;
+      color: #007aff;
+      margin-right: 4rpx;
+    }
   }
 
-  .title {
-    font-size: 36rpx;
-    color: #8f8f94;
+  &:active {
+    opacity: 0.9;
   }
-</style>
+}
+
+// 姝e湪杩愯鐨勪换鍔℃爣棰�
+.running-tasks-header {
+  margin-bottom: 20rpx;
+  flex-shrink: 0; // 闃叉鏀剁缉
+
+  .header-title {
+    font-size: 36rpx;
+    font-weight: bold;
+    color: #333;
+  }
+}
+
+// 姝e湪杩愯鐨勪换鍔″垪琛�
+.running-tasks-section {
+  flex: 1;
+  background-color: white;
+  border-radius: 15rpx;
+  padding: 30rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+  // 闅愯棌婊氬姩鏉′絾淇濇寔婊氬姩鍔熻兘
+  ::-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;
+      }
+    }
+    
+    .load-more {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding: 20rpx 0;
+      color: #999;
+      font-size: 28rpx;
+      
+      &.no-more {
+        color: #666;
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.1