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清理后台任务
---
app/pages/index.vue | 1599 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,576 insertions(+), 23 deletions(-)
diff --git a/app/pages/index.vue b/app/pages/index.vue
index 4646807..8d6dd2f 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -1,43 +1,1596 @@
<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.emergencyInfo && task.emergencyInfo.serviceOrdVip === '1'" class="vip-tag">VIP</text>
+ <text v-if="task.emergencyInfo && task.emergencyInfo.fromHq2Is === '1'" class="hq-tag">骞挎��</text>
+ </view>
+ <view
+ class="task-status"
+ :class="
+ task.taskStatus === TaskStatus.PENDING
+ ? 'status-pending'
+ : task.taskStatus === TaskStatus.NOT_CONFIRMED
+ ? 'status-not-confirmed'
+ : task.taskStatus === TaskStatus.NOT_DEPARTED
+ ? 'status-not-departed'
+ : task.taskStatus === TaskStatus.PARTIALLY_CONFIRMED
+ ? 'status-partially-confirmed'
+ : task.taskStatus === TaskStatus.DEPARTING
+ ? 'status-departing'
+ : task.taskStatus === TaskStatus.ARRIVED
+ ? 'status-arrived'
+ : task.taskStatus === TaskStatus.RETURNING
+ ? 'status-returning'
+ : task.taskStatus === TaskStatus.COMPLETED
+ ? 'status-completed'
+ : task.taskStatus === TaskStatus.CANCELLED
+ ? 'status-cancelled'
+ : task.taskStatus === TaskStatus.IN_PROGRESS
+ ? 'status-in-progress'
+ : 'status-pending'
+ "
+ >
+ {{ getStatusText(task.taskStatus) }}
+ </view>
+ </view>
+
+ <!-- 浠诲姟缂栧彿鍜屽紑濮嬫椂闂村湪鍚屼竴琛屾樉绀猴紝浣嗗垎寮�涓�浜� -->
+ <view class="task-code-row">
+ <text class="task-code">{{ task.showTaskCode }}</text>
+ <text class="task-time">{{ task.startTime }}</text>
+ </view>
+
+ <!-- 浠诲姟璇︾粏淇℃伅 -->
+ <view class="task-info">
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">鍑哄彂鍦�:</view>
+ <view class="value">{{ getStartLocationDisplay(task) }}</view>
+ </view>
+
+ </view>
+ <view class="info-row">
+ <view class="info-item">
+ <view class="label">鐩殑鍦�:</view>
+ <view class="value">{{ getEndLocationDisplay(task) }}</view>
+ </view>
+ </view>
+ <view class="info-row">
+
+ <view class="info-item">
+ <view class="label">鎵ц浜哄憳:</view>
+ <view class="value">{{ getAssigneesDisplay(task) }}</view>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="task-actions">
+ <!-- 寰呭鐞嗙姸鎬侊細鏄剧ず鍑哄彂銆佸彇娑� -->
+ <template v-if="task.taskStatus === TaskStatus.PENDING || task.taskStatus === TaskStatus.NOT_DEPARTED || task.taskStatus === TaskStatus.NOT_CONFIRMED || task.taskStatus === TaskStatus.PARTIALLY_CONFIRMED">
+ <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 === 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 === TaskStatus.ARRIVED">
+ <button
+ class="action-btn primary"
+ @click="handleTaskAction(task, 'return')"
+ >
+ 宸茶繑绋�
+ </button>
+ </template>
+
+ <!-- 杩旂▼涓姸鎬侊細鏄剧ず宸插畬鎴� -->
+ <template v-else-if="task.taskStatus === 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>
+
+ <!-- 鍙栨秷鍘熷洜閫夋嫨瀵硅瘽妗� -->
+ <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>
- export default {
- onLoad: function() {
+import { mapState } from "vuex";
+import { getMyTasks, changeTaskStatus, checkTaskConsentAttachment } from "@/api/task";
+import { getUserProfile } from "@/api/system/user";
+import { getUserBoundVehicle } from "@/api/vehicle";
+import { getUnreadCount } from "@/api/message";
+import { getDicts } from "@/api/dict";
+import { formatDateTime } from "@/utils/common";
+import subscribeManager from "@/utils/subscribe";
+import { checkTaskCanDepart } from "@/utils/taskValidator";
+import { getStatusText as getTaskStatusText, TaskStatus } from "@/utils/TaskUtil";
+
+// 浠诲姟绫诲瀷鏄犲皠锛堜复鏃跺畾涔夛紝閬垮厤瀵煎叆闂锛�
+const TASK_TYPE_MAP = {
+ MAINTENANCE: "缁翠慨淇濆吇",
+ FUEL: "鍔犳补",
+ OTHER: "鍏朵粬",
+ EMERGENCY_TRANSFER: "杞繍浠诲姟",
+ WELFARE: "绂忕杞�",
+ maintenance: "缁翠慨淇濆吇",
+ refuel: "鍔犳补",
+ inspection: "宸℃",
+ emergency: "杞繍浠诲姟",
+ welfare: "绂忕杞�"
+};
+
+// 浠诲姟鐘舵�佹槧灏勶紙涓存椂瀹氫箟锛岄伩鍏嶅鍏ラ棶棰橈級
+const TASK_STATUS_MAP = {
+ PENDING: "寰呭鐞�",
+ NOT_CONFIRMED: "瀹屽叏鏈‘璁�",
+ NOT_DEPARTED: "寰呭嚭鍙�",
+ PARTIALLY_CONFIRMED: "閮ㄥ垎纭",
+ DEPARTING: "鍑哄彂涓�",
+ ARRIVED: "宸插埌杈�",
+ RETURNING: "杩旂▼涓�",
+ COMPLETED: "宸插畬鎴�",
+ CANCELLED: "宸插彇娑�",
+ IN_PROGRESS: "浠诲姟涓�"
+};
+
+export default {
+ data() {
+ return {
+ TaskStatus, // 鏆撮湶 TaskStatus 缁欐ā鏉夸娇鐢�
+ // 鐢ㄦ埛缁戝畾鐨勮溅杈嗕俊鎭�
+ boundVehicle: "",
+ boundVehicleId: null,
+
+ // 娑堟伅鏁版嵁
+ messages: [],
+ unreadMessageCount: 0,
+
+ // 姝e湪杩愯鐨勪换鍔″垪琛�
+ allTaskList: [], // 瀛樺偍鎵�鏈変换鍔℃暟鎹�
+ displayedTaskList: [], // 瀛樺偍褰撳墠鏄剧ず鐨勪换鍔℃暟鎹�
+ loading: false,
+
+ // 璁㈤槄鐘舵��
+ hasSubscribed: false,
+
+ // 鍓嶇鍒嗛〉鐩稿叧
+ currentPage: 1,
+ pageSize: 10,
+ hasMore: true,
+
+ // 鍙栨秷鍘熷洜鐩稿叧
+ cancelReasonList: [], // 鍙栨秷鍘熷洜鍒楄〃
+ showCancelDialog: false, // 鏄剧ず鍙栨秷鍘熷洜瀵硅瘽妗�
+ selectedCancelReason: '', // 閫変腑鐨勫彇娑堝師鍥�
+ currentCancelTask: null // 褰撳墠瑕佸彇娑堢殑浠诲姟
+ };
+ },
+ computed: {
+ ...mapState({
+ userName: (state) => state.user.nickName,
+ currentUser: (state) => state.user,
+ }),
+
+ // 姝e湪杩愯鐨勪换鍔★紙寰呭鐞嗗拰鍚勭澶勭悊涓殑浠诲姟锛�
+ runningTasks() {
+ return this.displayedTaskList.filter((task) => {
+ // 鍖呭惈寰呭鐞嗐�佸嚭鍙戜腑銆佸凡鍒拌揪銆佽繑绋嬩腑绛夋墍鏈夋湭瀹屾垚鐨勭姸鎬�
+ const activeStatuses = [
+ TaskStatus.NOT_CONFIRMED,
+ TaskStatus.NOT_DEPARTED,
+ TaskStatus.PARTIALLY_CONFIRMED,
+ TaskStatus.PENDING,
+ TaskStatus.DEPARTING,
+ TaskStatus.ARRIVED,
+ TaskStatus.RETURNING,
+ TaskStatus.IN_PROGRESS,
+ ];
+ return activeStatuses.includes(task.taskStatus);
+ });
+ },
+
+ // 鑾峰彇閫変腑鐨勫彇娑堝師鍥犳爣绛撅紙鐢ㄤ簬寮圭獥鏄剧ず锛�
+ selectedCancelReasonLabel() {
+ if (!this.selectedCancelReason || !this.cancelReasonList.length) {
+ return '璇烽�夋嫨'
+ }
+ const reason = this.cancelReasonList.find(r => r.value === this.selectedCancelReason)
+ return reason ? reason.label : '璇烽�夋嫨'
+ },
+ },
+ 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();
+ // 鍔犺浇鍙栨秷鍘熷洜瀛楀吀
+ this.loadCancelReasonDict();
+ },
+ 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: task.departureAddress || task.startLocation || "鏈缃�",
+ endLocation: task.destinationAddress || task.endLocation || "鏈缃�",
+ startTime: task.plannedStartTime
+ ? (task.plannedStartTime.startsWith('1900') || task.plannedStartTime.startsWith('1970')
+ ? '鏈垎閰嶆椂闂�'
+ : 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;
+ },
+
+ // 鑾峰彇鍑哄彂鍦版樉绀哄唴瀹癸紙杞繍浠诲姟鏄剧ず杞嚭鍖婚櫌鍚嶇О锛�
+ getStartLocationDisplay(task) {
+ // 濡傛灉鏄浆杩愪换鍔′笖鏈塭mergencyInfo淇℃伅
+ if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo && task.emergencyInfo.hospitalOutName) {
+ return task.emergencyInfo.hospitalOutName;
+ }
+ // 鍏朵粬鎯呭喌浣跨敤鍘熸潵鐨剆tartLocation
+ return this.formatAddress(task.startLocation || "鏈缃�");
+ },
+
+ // 鑾峰彇鐩殑鍦版樉绀哄唴瀹癸紙杞繍浠诲姟鏄剧ず杞叆鍖婚櫌鍚嶇О鎴栬缁嗗湴鍧�锛�
+ getEndLocationDisplay(task) {
+ // 濡傛灉鏄浆杩愪换鍔′笖鏈塭mergencyInfo淇℃伅
+ // console.log("get end location display",task.taskType,task.emergencyInfo.hospitalInAddress,task.showTaskCode);
+ if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo) {
+ // console.log('杞繍浠诲姟 - 绱ф�ヤ俊鎭�:', task.emergencyInfo)
+ // 浼樺厛鏄剧ず杞叆鍖婚櫌鍚嶇О
+ // console.log("get end local",task.emergencyInfo.hospitalInAddress);
+ return task.emergencyInfo.hospitalInAddress;
+ // if (task.emergencyInfo.hospitalInName) {
+ // if(task.emergencyInfo.hospitalInName.includes("瀹朵腑")){
+ // return task.emergencyInfo.destinationAddress;
+ // }
+ // return task.emergencyInfo.hospitalInName;
+ // }
+ // // 濡傛灉娌℃湁杞叆鍖婚櫌鍚嶇О锛屼絾鏈夎浆鍏ュ尰闄㈠湴鍧�锛屽垯鏄剧ず鍦板潃
+ // if (task.emergencyInfo.hospitalInAddress) {
+ // return task.emergencyInfo.hospitalInAddress;
+ // }
+ }
+ // 鍏朵粬鎯呭喌浣跨敤鍘熸潵鐨別ndLocation
+ return this.formatAddress(task.endLocation || "鏈缃�");
+ },
+
+ // 鑾峰彇鎵ц浜哄憳鏄剧ず锛堜粠 assignees 鏁扮粍涓彁鍙� userName锛�
+ getAssigneesDisplay(task) {
+ // 濡傛灉鏈� assignees 鏁扮粍涓斾笉涓虹┖
+ if (task.assignees && task.assignees.length > 0) {
+ // 鎻愬彇鎵�鏈� userName锛岃繃婊ゆ帀绌哄��
+ const userNames = task.assignees
+ .map(assignee => assignee.userName)
+ .filter(name => name); // 杩囨护鎺� null/undefined/绌哄瓧绗︿覆
+
+ // 濡傛灉鏈夋湁鏁堢殑鐢ㄦ埛鍚嶏紝鐢ㄩ�楀彿杩炴帴
+ if (userNames.length > 0) {
+ return userNames.join('銆�');
+ }
+ }
+
+ // 濡傛灉娌℃湁 assignees 鏁扮粍锛屼娇鐢ㄦ棫鐨� assigneeName 鎴� assignee 瀛楁
+ return task.assigneeName || task.assignee || '鏈垎閰�';
+ },
+
+ // 杞崲鐘舵�佹牸寮忥紙灏嗘暟鎹簱鐘舵�佽浆鎹负UI浣跨敤鐨勭姸鎬侊級
+ convertStatus(dbStatus) {
+ const statusMap = {
+ PENDING: "pending",
+ NOT_CONFIRMED: "pending",
+ NOT_DEPARTED: "pending",
+ PARTIALLY_CONFIRMED: "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}`);
+ },
+
+ // 澶勭悊浠诲姟鎿嶄綔
+ async handleTaskAction(task, action) {
+ switch (action) {
+ case "depart":
+ // 鍑哄彂 -> 鐘舵�佸彉涓哄嚭鍙戜腑
+ // 鏄剧ず鍔犺浇鎻愮ず
+ uni.showLoading({
+ title: "妫�鏌ヤ换鍔$姸鎬�...",
+ });
+
+ try {
+ // 璋冪敤宸ュ叿绫绘鏌ヤ换鍔℃槸鍚﹀彲浠ュ嚭鍙戯紙鍖呭惈鍩烘湰鏍¢獙鍜屽啿绐佹鏌ワ級
+ const checkResult = await checkTaskCanDepart(task);
+
+ uni.hideLoading();
+
+ console.log("鍑哄彂妫�鏌ョ粨鏋�:", checkResult);
+ console.log("valid:", checkResult.valid);
+ console.log("conflicts:", checkResult.conflicts);
+
+ if (!checkResult.valid) {
+ // 鏍¢獙澶辫触锛屾樉绀烘彁绀轰俊鎭苟鎻愪緵璺宠浆閫夐」
+ const conflicts = checkResult.conflicts || [];
+ const conflictInfo = conflicts.length > 0 ? conflicts[0] : null;
+
+ console.log("鍐茬獊淇℃伅:", conflictInfo);
+
+ // 濡傛灉鏈夊啿绐佷换鍔′俊鎭紝鎻愪緵璺宠浆鎸夐挳
+ if (conflictInfo && conflictInfo.taskId) {
+ console.log(
+ "鏄剧ず甯﹁烦杞寜閽殑寮圭獥锛屼换鍔D:",
+ conflictInfo.taskId
+ );
+
+ const conflictTaskId = conflictInfo.taskId;
+ const message =
+ checkResult.message || conflictInfo.message || "瀛樺湪鍐茬獊浠诲姟";
+
+ uni.showModal({
+ title: "鎻愮ず",
+ content: message,
+ confirmText: "鍘诲鐞�",
+ cancelText: "鐭ラ亾浜�",
+ success: function (res) {
+ console.log("寮圭獥鐐瑰嚮缁撴灉:", res);
+ if (res.confirm) {
+ // 鐢ㄦ埛鐐瑰嚮"鐜板湪鍘诲鐞�"锛岃烦杞埌鍐茬獊浠诲姟璇︽儏椤�
+ console.log("鍑嗗璺宠浆鍒颁换鍔¤鎯呴〉:", conflictTaskId);
+ uni.navigateTo({
+ url: `/pagesTask/detail?id=${conflictTaskId}`,
+ });
+ }
+ },
+ fail: function (err) {
+ console.error("鏄剧ず寮圭獥澶辫触:", err);
+ },
+ });
+ } else {
+ // 娌℃湁鍐茬獊浠诲姟ID锛屽彧鏄剧ず鎻愮ず
+ console.log("鏄剧ず鏅�氭彁绀哄脊绐�");
+ uni.showModal({
+ title: "鎻愮ず",
+ content: checkResult.message || "浠诲姟鏍¢獙澶辫触",
+ showCancel: false,
+ confirmText: "鐭ラ亾浜�",
+ fail: function (err) {
+ console.error("鏄剧ず寮圭獥澶辫触:", err);
+ },
+ });
+ }
+ return;
+ }
+
+ // 鎵�鏈夋鏌ラ�氳繃锛屽彲浠ュ嚭鍙�
+ this.$modal
+ .confirm("纭畾瑕佸嚭鍙戝悧锛�")
+ .then(() => {
+ this.updateTaskStatus(task.taskId, TaskStatus.DEPARTING, "浠诲姟宸插嚭鍙�");
+ })
+ .catch(() => {});
+ } catch (error) {
+ uni.hideLoading();
+ console.error("妫�鏌ヤ换鍔$姸鎬佸け璐�:", error);
+ // 妫�鏌ュけ璐ユ椂锛屼粛鐒跺厑璁稿嚭鍙�
+ this.$modal
+ .confirm("妫�鏌ヤ换鍔$姸鎬佸け璐ワ紝鏄惁缁х画鍑哄彂锛�")
+ .then(() => {
+ this.updateTaskStatus(task.taskId, TaskStatus.DEPARTING, "浠诲姟宸插嚭鍙�");
+ })
+ .catch(() => {});
+ }
+ break;
+
+ case "cancel":
+ // 鍙栨秷 -> 鏄剧ず鍙栨秷鍘熷洜閫夋嫨瀵硅瘽妗�
+ this.currentCancelTask = task;
+ this.showCancelReasonDialog();
+ break;
+
+ case "arrive":
+ // 宸插埌杈� -> 鐘舵�佸彉涓哄凡鍒拌揪
+ this.$modal
+ .confirm("纭宸插埌杈剧洰鐨勫湴锛�")
+ .then(() => {
+ this.updateTaskStatus(task.taskId, TaskStatus.ARRIVED, "宸插埌杈剧洰鐨勫湴");
+ })
+ .catch(() => {});
+ break;
+
+ case "forceCancel":
+ // 寮哄埗缁撴潫 -> 鐘舵�佸彉涓哄凡鍙栨秷
+ this.$modal
+ .confirm("纭畾瑕佸己鍒剁粨鏉熸浠诲姟鍚楋紵")
+ .then(() => {
+ this.updateTaskStatus(task.taskId, TaskStatus.CANCELLED, "浠诲姟宸插己鍒剁粨鏉�");
+ })
+ .catch(() => {});
+ break;
+
+ case "return":
+ // 宸茶繑绋� -> 鐘舵�佸彉涓鸿繑绋嬩腑
+ this.$modal
+ .confirm("纭寮�濮嬭繑绋嬶紵")
+ .then(() => {
+ this.updateTaskStatus(task.taskId, TaskStatus.RETURNING, "宸插紑濮嬭繑绋�");
+ })
+ .catch(() => {});
+ break;
+
+ case "complete":
+ // 宸插畬鎴� -> 鐘舵�佸彉涓哄凡瀹屾垚
+ // 闇�瑕佹鏌ユ槸鍚︿笂浼犱簡鐭ユ儏鍚屾剰涔�
+ this.checkConsentAttachmentAndThen(task.taskId, TaskStatus.COMPLETED, "浠诲姟宸插畬鎴�");
+ break;
+ }
+ },
+
+ // 鏇存柊浠诲姟鐘舵��
+ updateTaskStatus(taskId, status, remark) {
+ // 鑾峰彇GPS浣嶇疆淇℃伅
+ 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 {
+ uni.showLoading({
+ title: '妫�鏌ラ檮浠�...'
+ });
+
+ // 娉ㄦ剰锛氳繖閲屼細琚姹傛嫤鎴櫒澶勭悊锛宑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 && response.code === 200) {
+ // 宸蹭笂浼犵煡鎯呭悓鎰忎功锛岀户缁洿鏂扮姸鎬�
+ console.log('宸蹭笂浼犵煡鎯呭悓鎰忎功锛岀户缁畬鎴愪换鍔�');
+ this.$modal
+ .confirm("纭浠诲姟宸插畬鎴愶紵")
+ .then(() => {
+ this.updateTaskStatus(taskId, status, remark);
+ })
+ .catch(() => {});
+ } else {
+ // 鏈笂浼犵煡鎯呭悓鎰忎功鎴栧叾浠栭敊璇紝闃绘瀹屾垚
+ const message = (response && response.msg) || '浠诲姟鏈笂浼犵煡鎯呭悓鎰忎功锛屾棤娉曞畬鎴愪换鍔�';
+ console.log('鏈笂浼犵煡鎯呭悓鎰忎功锛岄樆姝㈠畬鎴�');
+
+ this.$modal.confirm(message + '銆傛槸鍚︾幇鍦ㄥ幓涓婁紶锛�').then(() => {
+ // 璺宠浆鍒颁换鍔¤鎯呴〉涓婁紶闄勪欢
+ this.$tab.navigateTo(`/pagesTask/detail?id=${taskId}`);
+ }).catch(() => {});
+ }
+ } catch (error) {
+ uni.hideLoading();
+ console.error('妫�鏌ラ檮浠跺紓甯�:', error);
+
+ // 濡傛灉妫�鏌ュけ璐ワ紙缃戠粶寮傚父绛夛級锛屼笉鍏佽瀹屾垚浠诲姟
+ this.$modal.showToast('妫�鏌ラ檮浠剁姸鎬佸け璐ワ紝鏃犳硶瀹屾垚浠诲姟');
+ }
+ },
+
+ // 鑾峰彇浣嶇疆淇℃伅骞舵洿鏂扮姸鎬�
+ getLocationAndUpdateStatus(taskId, status, remark, cancelReason) {
+ 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,
+ };
+
+ // 濡傛灉鏈夊彇娑堝師鍥狅紝娣诲姞鍒拌姹傛暟鎹腑
+ if (cancelReason) {
+ statusData.cancelReason = cancelReason
+ }
+
+ 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,
+ };
+
+ // 濡傛灉鏈夊彇娑堝師鍥狅紝娣诲姞鍒拌姹傛暟鎹腑
+ if (cancelReason) {
+ statusData.cancelReason = cancelReason
+ }
+
+ changeTaskStatus(taskId, statusData)
+ .then((response) => {
+ that.$modal.showToast("鐘舵�佹洿鏂版垚鍔�");
+ that.loadRunningTasks();
+ })
+ .catch((error) => {
+ console.error("鏇存柊浠诲姟鐘舵�佸け璐�:", error);
+ that.$modal.showToast("鐘舵�佹洿鏂板け璐ワ紝璇烽噸璇�");
+ });
+ })
+ .catch(() => {});
+ },
+ });
+ },
+
+ // 鑾峰彇浠诲姟绫诲瀷鏂囨湰
+ getTaskTypeText(type) {
+ return TASK_TYPE_MAP[type] || "鏈煡绫诲瀷";
+ },
+
+ // 鑾峰彇浠诲姟鐘舵�佹枃鏈�
+ getStatusText(status) {
+ return TASK_STATUS_MAP[status] || "鏈煡";
+ },
+
+ 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+ */
+ }
+}
+
+// 鐢ㄦ埛淇℃伅鍖哄煙
+.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-not-confirmed {
+ background-color: #fff3e0;
+ color: #ff9500;
+ }
+ &.status-not-departed {
+ background-color: #fff3e0;
+ color: #ff9500;
+ }
+ &.status-partially-confirmed {
+ 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;
+ display: flex;
+ justify-content: space-between;
+
+ .task-code {
+ font-size: 28rpx;
+ color: #333;
+ font-weight: 500;
+ font-family: monospace;
+ }
+
+ .task-time {
+ 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;
+ overflow-wrap: break-word;
+ line-height: 1.5;
+ max-height: none;
+ overflow: visible;
+ }
+ }
+ }
+ }
+ }
+
+ .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;
+ }
+ }
+
+ .vip-tag {
+ display: inline-block;
+ padding: 2rpx 8rpx;
+ font-size: 20rpx;
+ color: #fff;
+ background-color: #ff0000;
+ border-radius: 4rpx;
+ margin-left: 10rpx;
+ vertical-align: middle;
+ }
+
+ .hq-tag {
+ display: inline-block;
+ padding: 2rpx 8rpx;
+ font-size: 20rpx;
+ color: #fff;
+ background-color: #5856d6;
+ border-radius: 4rpx;
+ margin-left: 10rpx;
+ 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