From c098f1e3a3e052aa3d65584aae6dc003a70d75ad Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期二, 16 十二月 2025 00:09:14 +0800
Subject: [PATCH] feat: 停止轮询 uncount
---
app/pagesTask/detail.vue | 609 ++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 511 insertions(+), 98 deletions(-)
diff --git a/app/pagesTask/detail.vue b/app/pagesTask/detail.vue
index 781b0d4..17289aa 100644
--- a/app/pagesTask/detail.vue
+++ b/app/pagesTask/detail.vue
@@ -12,7 +12,7 @@
<view class="section-title">鍩烘湰淇℃伅</view>
<view class="info-item">
<view class="label">浠诲姟缂栧彿</view>
- <view class="value">{{ taskDetail.taskCode }}</view>
+ <view class="value">{{ taskDetail.showTaskCode }}</view>
</view>
<view class="info-item">
<view class="label">浠诲姟绫诲瀷</view>
@@ -28,19 +28,63 @@
<view class="label">鎵ц杞﹁締</view>
<view class="value">{{ getVehicleInfo(taskDetail) }}</view>
</view>
- <view class="info-item">
- <view class="label">鎵ц浜哄憳</view>
- <view class="value">{{ taskDetail.assigneeName || '鏈垎閰�' }}</view>
+ </view>
+
+ <!-- 鎵ц浜哄憳鍒楄〃 -->
+ <view class="detail-section">
+ <view class="section-title">鎵ц浜哄憳</view>
+ <view v-if="taskDetail.assignees && taskDetail.assignees.length > 0" class="assignee-list">
+ <view
+ class="assignee-item"
+ v-for="(assignee, index) in taskDetail.assignees"
+ :key="getAssigneeKey(assignee, index)"
+ >
+ <view class="assignee-index">{{ index + 1 }}</view>
+ <view class="assignee-info">
+ <view class="assignee-name">
+ {{ assignee.userName }}
+ <view v-if="assignee.isPrimary === '1'" class="primary-badge">
+ <uni-icons type="star-filled" size="12" color="#ff9500"></uni-icons>
+ <text>璐熻矗浜�</text>
+ </view>
+ </view>
+ <view class="assignee-role">
+ <view
+ class="role-tag"
+ :class="{
+ 'role-driver': assignee.userType === 'driver',
+ 'role-doctor': assignee.userType === 'doctor',
+ 'role-nurse': assignee.userType === 'nurse'
+ }"
+ >
+ {{ getUserTypeLabel(assignee.userType) }}
+ </view>
+ <view
+ class="ready-badge"
+ :class="{
+ 'ready': isAssigneeReady(assignee),
+ 'unready': !isAssigneeReady(assignee)
+ }"
+ >
+ {{ isAssigneeReady(assignee) ? '宸插氨缁�' : '鏈氨缁�' }}
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else class="empty-assignee">
+ <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+ <text>鏆傛棤鎵ц浜哄憳</text>
</view>
</view>
<view class="detail-section">
<view class="section-title">鏃堕棿淇℃伅</view>
<view class="info-item">
- <view class="label">璁″垝寮�濮嬫椂闂�</view>
+ <view class="label">棰勭害鏃堕棿</view>
<view class="value">{{ displayPlannedStartTime }}</view>
</view>
- <view class="info-item">
+ <view class="info-item" v-if="taskDetail.plannedEndTime">
<view class="label">璁″垝缁撴潫鏃堕棿</view>
<view class="value">{{ displayPlannedEndTime }}</view>
</view>
@@ -96,12 +140,12 @@
</view>
</view>
- <view class="detail-section" v-if="taskDetail.taskDescription">
+ <view class="detail-section" v-if="taskDetail.taskDescription && taskDetail.taskType !== 'EMERGENCY_TRANSFER'">
<view class="section-title">浠诲姟鎻忚堪</view>
<view class="description">{{ taskDetail.taskDescription }}</view>
</view>
- <view class="detail-section" v-if="taskDetail.remark">
+ <view class="detail-section" v-if="taskDetail.remark && taskDetail.taskType !== 'EMERGENCY_TRANSFER'">
<view class="section-title">澶囨敞淇℃伅</view>
<view class="description">{{ taskDetail.remark }}</view>
</view>
@@ -215,8 +259,8 @@
<view class="section-title">鏀粯璁板綍</view>
<view
class="payment-record-item"
- v-for="payment in paymentInfo.paidPayments"
- :key="payment.id"
+ v-for="(payment, index) in paymentInfo.paidPayments"
+ :key="getPaymentKey(payment, index)"
>
<view class="payment-header">
<view
@@ -327,18 +371,27 @@
>
淇敼
</button>
- <button
- class="action-btn primary"
- @click="handleTaskAction('depart')"
- >
- 鍑哄彂
- </button>
- <button
- class="action-btn cancel"
- @click="handleTaskAction('cancel')"
- >
- 鍙栨秷
- </button>
+ <template v-if="isCurrentUserAssignee()">
+ <button
+ v-if="showAssigneeReadyFeature() && isMultipleAssignees() && !isCurrentUserReady()"
+ class="action-btn primary"
+ @click="handleReadyAction()"
+ >
+ 灏辩华
+ </button>
+ <button
+ class="action-btn primary"
+ @click="handleDepartAction()"
+ >
+ 鍑哄彂
+ </button>
+ <button
+ class="action-btn cancel"
+ @click="handleTaskAction('cancel')"
+ >
+ 鍙栨秷
+ </button>
+ </template>
</template>
<!-- 鍑哄彂涓姸鎬�: 鏄剧ず缂栬緫銆佸凡鍒拌揪銆佸己鍒剁粨鏉� -->
@@ -349,18 +402,20 @@
>
淇敼
</button>
- <button
- class="action-btn primary"
- @click="handleTaskAction('arrive')"
- >
- 宸插埌杈�
- </button>
- <button
- class="action-btn cancel"
- @click="handleTaskAction('forceCancel')"
- >
- 寮哄埗缁撴潫
- </button>
+ <template v-if="isCurrentUserAssignee()">
+ <button
+ class="action-btn primary"
+ @click="handleTaskAction('arrive')"
+ >
+ 宸插埌杈�
+ </button>
+ <button
+ class="action-btn cancel"
+ @click="handleTaskAction('forceCancel')"
+ >
+ 寮哄埗缁撴潫
+ </button>
+ </template>
</template>
<!-- 宸插埌杈剧姸鎬�: 鏄剧ず缂栬緫銆佸凡杩旂▼ -->
@@ -371,12 +426,14 @@
>
淇敼
</button>
- <button
- class="action-btn primary"
- @click="handleTaskAction('return')"
- >
- 宸茶繑绋�
- </button>
+ <template v-if="isCurrentUserAssignee()">
+ <button
+ class="action-btn primary"
+ @click="handleTaskAction('return')"
+ >
+ 宸茶繑绋�
+ </button>
+ </template>
</template>
<!-- 杩旂▼涓姸鎬�: 鏄剧ず缂栬緫銆佸凡瀹屾垚 -->
@@ -387,12 +444,14 @@
>
淇敼
</button>
- <button
- class="action-btn primary"
- @click="handleTaskAction('complete')"
- >
- 宸插畬鎴�
- </button>
+ <template v-if="isCurrentUserAssignee()">
+ <button
+ class="action-btn primary"
+ @click="handleTaskAction('complete')"
+ >
+ 宸插畬鎴�
+ </button>
+ </template>
</template>
<!-- 宸插畬鎴�/宸插彇娑�: 涓嶆樉绀烘寜閽紝浣嗗鏋滄槸杞繍浠诲姟鍒欐樉绀虹粨绠楁寜閽� -->
@@ -410,11 +469,13 @@
</template>
<script>
- import { getTask, changeTaskStatus } from '@/api/task'
+ import { getTask, changeTaskStatus, setAssigneeReady } from '@/api/task'
import { checkVehicleActiveTasks } from '@/api/task'
import { getPaymentInfo } from '@/api/payment'
import { formatDateTime } from '@/utils/common'
+ import { validateTaskForDepart, validateTaskForSettlement, getTaskVehicleId, checkTaskCanDepart } from '@/utils/taskValidator'
import AttachmentUpload from './components/AttachmentUpload.vue'
+ import config from '@/config'
export default {
components: {
@@ -466,28 +527,48 @@
if (!this.taskDetail || !this.taskDetail.plannedStartTime) {
return '鏈缃�'
}
- return formatDateTime(this.taskDetail.plannedStartTime, 'YYYY-MM-DD HH:mm')
+ const formatted = formatDateTime(this.taskDetail.plannedStartTime, 'YYYY-MM-DD HH:mm')
+ // 濡傛灉骞翠唤鏄�1900,琛ㄧず鏃犳晥鏃ユ湡,鏄剧ず涓烘湭璁剧疆
+ if (formatted && formatted.startsWith('1900')) {
+ return '鏈缃�'
+ }
+ return formatted
},
// 鏄剧ず璁″垝缁撴潫鏃堕棿
displayPlannedEndTime() {
if (!this.taskDetail || !this.taskDetail.plannedEndTime) {
return '鏈缃�'
}
- return formatDateTime(this.taskDetail.plannedEndTime, 'YYYY-MM-DD HH:mm')
+ const formatted = formatDateTime(this.taskDetail.plannedEndTime, 'YYYY-MM-DD HH:mm')
+ // 濡傛灉骞翠唤鏄�1900,琛ㄧず鏃犳晥鏃ユ湡,鏄剧ず涓烘湭璁剧疆
+ if (formatted && formatted.startsWith('1900')) {
+ return '鏈缃�'
+ }
+ return formatted
},
// 鏄剧ず瀹為檯寮�濮嬫椂闂�
displayActualStartTime() {
if (!this.taskDetail || !this.taskDetail.actualStartTime) {
return '鏈缃�'
}
- return formatDateTime(this.taskDetail.actualStartTime, 'YYYY-MM-DD HH:mm')
+ const formatted = formatDateTime(this.taskDetail.actualStartTime, 'YYYY-MM-DD HH:mm')
+ // 濡傛灉骞翠唤鏄�1900,琛ㄧず鏃犳晥鏃ユ湡,鏄剧ず涓烘湭璁剧疆
+ if (formatted && formatted.startsWith('1900')) {
+ return '鏈缃�'
+ }
+ return formatted
},
// 鏄剧ず瀹為檯缁撴潫鏃堕棿
displayActualEndTime() {
if (!this.taskDetail || !this.taskDetail.actualEndTime) {
return '鏈缃�'
}
- return formatDateTime(this.taskDetail.actualEndTime, 'YYYY-MM-DD HH:mm')
+ const formatted = formatDateTime(this.taskDetail.actualEndTime, 'YYYY-MM-DD HH:mm')
+ // 濡傛灉骞翠唤鏄�1900,琛ㄧず鏃犳晥鏃ユ湡,鏄剧ず涓烘湭璁剧疆
+ if (formatted && formatted.startsWith('1900')) {
+ return '鏈缃�'
+ }
+ return formatted
}
},
onLoad(options) {
@@ -511,12 +592,12 @@
getTask(this.taskId).then(response => {
this.taskDetail = response.data || response
// 璋冭瘯锛氭墦鍗拌繑鍥炵殑鏁版嵁
- console.log('浠诲姟璇︽儏瀹屾暣鏁版嵁:', JSON.stringify(this.taskDetail, null, 2))
- console.log('浠诲姟绫诲瀷瀛楁鍊�:', this.taskDetail.taskType)
- console.log('浠诲姟鐘舵�佸瓧娈靛��:', this.taskDetail.taskStatus)
- console.log('鍑哄彂鍦板潃:', this.taskDetail.departureAddress)
- console.log('鐩殑鍦板潃:', this.taskDetail.destinationAddress)
- console.log('杞繍浠诲姟淇℃伅 (emergencyInfo):', this.taskDetail.emergencyInfo)
+ // console.log('浠诲姟璇︽儏瀹屾暣鏁版嵁:', JSON.stringify(this.taskDetail, null, 2))
+ // console.log('浠诲姟绫诲瀷瀛楁鍊�:', this.taskDetail.taskType)
+ // console.log('浠诲姟鐘舵�佸瓧娈靛��:', this.taskDetail.taskStatus)
+ // console.log('鍑哄彂鍦板潃:', this.taskDetail.departureAddress)
+ // console.log('鐩殑鍦板潃:', this.taskDetail.destinationAddress)
+ // console.log('杞繍浠诲姟淇℃伅 (emergencyInfo):', this.taskDetail.emergencyInfo)
// 濡傛灉鏄浆杩愪换鍔★紝鍔犺浇鏀粯淇℃伅
if (this.taskDetail.taskType === 'EMERGENCY_TRANSFER') {
@@ -580,9 +661,9 @@
return remaining > 0 ? remaining.toFixed(2) : '0.00'
},
- // 鑾峰彇杞﹁締淇℃伅
+ // 鑾峰彇杞﹁締淇℃伅锛堜慨澶嶏細闃叉 assignedVehicles 涓� null锛�
getVehicleInfo(task) {
- if (task.assignedVehicles && task.assignedVehicles.length > 0) {
+ if (task.assignedVehicles && Array.isArray(task.assignedVehicles) && task.assignedVehicles.length > 0) {
const firstVehicle = task.assignedVehicles[0]
let vehicleInfo = firstVehicle.vehicleNo || '鏈煡杞︾墝'
if (task.assignedVehicles.length > 1) {
@@ -621,7 +702,16 @@
// 杩斿洖涓婁竴椤�
goBack() {
- uni.navigateBack()
+ // 妫�鏌ユ槸鍚︽湁椤甸潰鍙互杩斿洖
+ uni.navigateBack({
+ delta: 1,
+ fail: () => {
+ // 濡傛灉鏃犳硶杩斿洖锛屽垯璺宠浆鍒颁换鍔″垪琛ㄩ〉闈�
+ uni.switchTab({
+ url: '/pages/task/index'
+ })
+ }
+ })
},
// 澶勭悊缂栬緫鎸夐挳
@@ -685,8 +775,27 @@
return typeMap[type] || '鏈煡绫诲瀷'
},
+ // 鑾峰彇鐢ㄦ埛绫诲瀷鏍囩
+ getUserTypeLabel(userType) {
+ const typeMap = {
+ 'driver': '鍙告満',
+ 'doctor': '鍖荤敓',
+ 'nurse': '鎶ゅ+'
+ }
+ return typeMap[userType] || userType || '鏈煡'
+ },
+
// 澶勭悊缁撶畻
handleSettlement() {
+ // 鏍¢獙浠诲姟鏄惁鍙互缁撶畻
+ const validation = validateTaskForSettlement(this.taskDetail)
+ if (!validation.valid) {
+ this.$modal.confirm(`${validation.message}锛岄渶瑕佸厛淇敼浠诲姟鍚庢墠鑳界粨绠椼�傛槸鍚︾幇鍦ㄥ幓淇敼锛焋).then(() => {
+ this.handleEdit()
+ }).catch(() => {})
+ return
+ }
+
uni.navigateTo({
url: '/pagesTask/settlement?taskId=' + this.taskId
})
@@ -696,8 +805,7 @@
handleTaskAction(action) {
switch (action) {
case 'depart':
- // 鍑哄彂 -> 妫�鏌ヨ溅杈嗘槸鍚︽湁鍏朵粬姝e湪杩涜涓殑浠诲姟
- this.checkVehicleAndDepart();
+ this.ensureReadyThenDepart();
break;
case 'cancel':
@@ -738,60 +846,84 @@
},
// 妫�鏌ヨ溅杈嗙姸鎬佸苟鍑哄彂
- checkVehicleAndDepart() {
- // 鑾峰彇浠诲姟杞﹁締ID
- const vehicleId = this.getVehicleId();
- if (!vehicleId) {
- this.$modal.showToast('鏈壘鍒颁换鍔¤溅杈嗕俊鎭�');
- return;
- }
-
+ async checkVehicleAndDepart() {
// 鏄剧ず鍔犺浇鎻愮ず
uni.showLoading({
- title: '妫�鏌ヨ溅杈嗙姸鎬�...'
+ title: '妫�鏌ヤ换鍔$姸鎬�...'
});
- checkVehicleActiveTasks(vehicleId).then(response => {
+ try {
+ // 璋冪敤宸ュ叿绫绘鏌ヤ换鍔℃槸鍚﹀彲浠ュ嚭鍙戯紙鍖呭惈鍩烘湰鏍¢獙鍜屽啿绐佹鏌ワ級
+ const checkResult = await checkTaskCanDepart(this.taskDetail)
+
uni.hideLoading();
- const activeTasks = response.data || [];
+ console.log('鍑哄彂妫�鏌ョ粨鏋�:', checkResult);
+ console.log('valid:', checkResult.valid);
+ console.log('conflicts:', checkResult.conflicts);
- // 杩囨护鎺夊綋鍓嶄换鍔℃湰韬�
- const otherActiveTasks = activeTasks.filter(task => task.taskId !== this.taskId);
-
- if (otherActiveTasks.length > 0) {
- // 杞﹁締鏈夊叾浠栨鍦ㄨ繘琛屼腑鐨勪换鍔�
- const task = otherActiveTasks[0];
- const taskStatus = this.getStatusText(task.taskStatus);
- const message = `璇ヨ溅杈嗗凡鏈夋鍦ㄨ浆杩愪腑鐨勪换鍔★紒
-
-浠诲姟鍗曞彿锛�${task.taskCode}
-浠诲姟鐘舵�侊細${taskStatus}
-
-璇峰厛瀹屾垚褰撳墠浠诲姟鍚庡啀鍑哄彂鏂颁换鍔°�俙;
+ if (!checkResult.valid) {
+ // 鏍¢獙澶辫触锛屾樉绀烘彁绀轰俊鎭苟鎻愪緵璺宠浆閫夐」
+ const conflicts = checkResult.conflicts || [];
+ const conflictInfo = conflicts.length > 0 ? conflicts[0] : null;
- uni.showModal({
- title: '鎻愮ず',
- content: message,
- showCancel: false,
- confirmText: '鎴戠煡閬撲簡'
- });
+ 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.redirectTo({
+ 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;
}
- // 杞﹁締娌℃湁鍏朵粬姝e湪杩涜涓殑浠诲姟锛屽彲浠ュ嚭鍙�
+ // 鎵�鏈夋鏌ラ�氳繃锛屽彲浠ュ嚭鍙�
this.$modal.confirm('纭畾瑕佸嚭鍙戝悧锛�').then(() => {
this.updateTaskStatus('DEPARTING', '浠诲姟宸插嚭鍙�')
}).catch(() => {});
- }).catch(error => {
+ } catch (error) {
uni.hideLoading();
- console.error('妫�鏌ヨ溅杈嗙姸鎬佸け璐�:', error);
+ console.error('妫�鏌ヤ换鍔$姸鎬佸け璐�:', error);
// 妫�鏌ュけ璐ユ椂锛屼粛鐒跺厑璁稿嚭鍙�
- this.$modal.confirm('妫�鏌ヨ溅杈嗙姸鎬佸け璐ワ紝鏄惁缁х画鍑哄彂锛�').then(() => {
+ this.$modal.confirm('妫�鏌ヤ换鍔$姸鎬佸け璐ワ紝鏄惁缁х画鍑哄彂锛�').then(() => {
this.updateTaskStatus('DEPARTING', '浠诲姟宸插嚭鍙�')
}).catch(() => {});
- });
+ }
},
// 鑾峰彇浠诲姟杞﹁締ID
@@ -1136,7 +1268,165 @@
// 闄勪欢鍒犻櫎鎴愬姛鍥炶皟
onAttachmentDeleted(attachmentId) {
console.log('闄勪欢鍒犻櫎鎴愬姛:', attachmentId)
- }
+ },
+
+ // 鏄惁鏄剧ず鈥滃氨缁�濆姛鑳斤紙閰嶇疆寮�鍏筹級
+ showAssigneeReadyFeature() {
+ return !!(config && config.features && config.features.showAssigneeReadyButton)
+ },
+
+ // 褰撳墠鐢ㄦ埛鏄惁涓鸿鎵ц浜�
+ isAssigneeSelf(assignee) {
+ const userId = this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.userId
+ return assignee && (assignee.userId === userId || assignee.oaUserId === userId)
+ },
+
+ // 鎵ц浜虹偣鍑烩�滃氨缁��
+ markAssigneeReady(assignee) {
+ if (!assignee || !this.taskDetail) {
+ this.$modal.showToast('鎵ц浜烘垨浠诲姟淇℃伅涓嶅瓨鍦�')
+ return
+ }
+ const userId = assignee.userId || assignee.oaUserId
+ if (!userId) {
+ this.$modal.showToast('鏃犳硶璇嗗埆鎵ц浜篒D')
+ return
+ }
+ this.$modal.showLoading && this.$modal.showLoading('鎻愪氦涓�...')
+ setAssigneeReady(this.taskId).then(() => {
+ this.$modal.hideLoading && this.$modal.hideLoading()
+ this.$modal.showToast('宸插氨缁�')
+ // 鍒锋柊浠诲姟璇︽儏
+ this.loadTaskDetail()
+ }).catch(err => {
+ this.$modal.hideLoading && this.$modal.hideLoading()
+ console.error('鏍囪灏辩华澶辫触:', err)
+ this.$modal.showToast('鏍囪灏辩华澶辫触')
+ })
+ },
+
+ // 鏄惁褰撳墠鐢ㄦ埛鏄换鍔℃墽琛屼汉
+ isCurrentUserAssignee() {
+ const userId = this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.userId;
+ console.log("褰撳墠鐢ㄦ埛ID:", userId)
+ const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+ return list.some(a => a && (a.userId === userId || a.oaUserId === userId))
+ },
+
+ // 鏄惁澶氫汉鎵ц
+ isMultipleAssignees() {
+ const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+ return list.length > 1
+ },
+
+ // 鎵ц浜烘槸鍚﹀凡灏辩华
+ isAssigneeReady(assignee) {
+ if (!assignee) return false
+ return assignee.isReady === '1' || assignee.ready === true || assignee.readyStatus === 'READY' || assignee.readyFlag === 'Y'
+ },
+
+ // 鎵�鏈夋墽琛屼汉鏄惁宸插氨缁�
+ areAllAssigneesReady() {
+ const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+ if (list.length === 0) return false
+ return list.every(a => this.isAssigneeReady(a))
+ },
+
+ // 鑾峰彇褰撳墠鐢ㄦ埛瀵瑰簲鐨勬墽琛屼汉璁板綍
+ getCurrentUserAssignee() {
+ const userId = this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.userId
+ console.log('userId', userId)
+ const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+ return list.find(a => a && (a.userId === userId || a.oaUserId === userId)) || null
+ },
+
+ // 鎿嶄綔鍖哄氨缁寜閽紙澶氫汉浠诲姟锛�
+ markCurrentAssigneeReady() {
+ const me = this.getCurrentUserAssignee()
+ if (!me) {
+ this.$modal.showToast('浠呬换鍔℃墽琛屼汉鍙搷浣�')
+ return
+ }
+ this.markAssigneeReady(me)
+ },
+
+ // 褰撳墠鐢ㄦ埛鏄惁宸插氨缁�
+ isCurrentUserReady() {
+ const me = this.getCurrentUserAssignee()
+ return me ? this.isAssigneeReady(me) : false
+ },
+
+ // 澶勭悊灏辩华鎸夐挳鐐瑰嚮
+ async handleReadyAction() {
+ const me = this.getCurrentUserAssignee()
+ if (!me) {
+ this.$modal.showToast('浠呬换鍔℃墽琛屼汉鍙搷浣�')
+ return
+ }
+ try {
+ await setAssigneeReady(this.taskId)
+ this.$modal.showToast('宸插氨缁�')
+ // 鍒锋柊浠诲姟璇︽儏
+ await this.loadTaskDetail()
+ } catch (err) {
+ console.error('鏍囪灏辩华澶辫触:', err)
+ this.$modal.showToast('鏍囪灏辩华澶辫触')
+ }
+ },
+
+ // 澶勭悊鍑哄彂鎸夐挳鐐瑰嚮
+ async handleDepartAction() {
+ if (!this.taskDetail) return
+
+ const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+
+ // 濡傛灉寮�鍚簡灏辩华鍔熻兘涓旀槸澶氫汉浠诲姟锛岄渶瑕佹鏌ユ墍鏈変汉鏄惁灏辩华
+ if (this.showAssigneeReadyFeature() && list.length > 1) {
+ if (!this.areAllAssigneesReady()) {
+ this.$modal.showToast('鍏朵粬浜烘湭灏辩华锛屾墍鏈変汉灏辩华鍚庢墠鑳藉嚭鍙�')
+ return
+ }
+ }
+
+ // 鍗曚汉浠诲姟鎴栨湭寮�鍚氨缁姛鑳斤細鑷姩鏍囪灏辩华
+ if (this.showAssigneeReadyFeature() && list.length === 1) {
+ const me = this.getCurrentUserAssignee()
+ if (me && !this.isAssigneeReady(me)) {
+ try {
+ await setAssigneeReady(this.taskId)
+ } catch (e) {
+ console.error('鑷姩灏辩华澶辫触:', e)
+ }
+ }
+ }
+
+ // 鎵ц鍑哄彂娴佺▼
+ this.checkVehicleAndDepart()
+ },
+
+ // 鍑哄彂鍓嶄繚璇佸氨缁紙淇濈暀鍚戝悗鍏煎锛�
+ async ensureReadyThenDepart() {
+ this.handleDepartAction()
+ },
+
+ // 鑾峰彇鎵ц浜哄憳鐨刱ey鍊�
+ getAssigneeKey(assignee, index) {
+ // 纭繚杩斿洖鏈夋晥鐨勫瓧绗︿覆key
+ if (!assignee) return 'assignee-' + index;
+ // 浼樺厛浣跨敤userId锛屽叾娆℃槸userName锛屾渶鍚庝娇鐢╥ndex
+ const key = assignee.userId || assignee.userName || index;
+ return 'assignee-' + (key !== null && key !== undefined ? key : index);
+ },
+
+ // 鑾峰彇鏀粯璁板綍鐨刱ey鍊�
+ getPaymentKey(payment, index) {
+ // 纭繚杩斿洖鏈夋晥鐨勫瓧绗︿覆key
+ if (!payment) return 'payment-' + index;
+ // 浼樺厛浣跨敤id锛屽叾娆′娇鐢╥ndex
+ const key = payment.id || index;
+ return 'payment-' + (key !== null && key !== undefined ? key : index);
+ },
+
}
}
</script>
@@ -1205,6 +1495,129 @@
}
}
+ // 鎵ц浜哄憳鍒楄〃鏍峰紡
+ .assignee-list {
+ .assignee-item {
+ display: flex;
+ align-items: center;
+ padding: 20rpx;
+ margin-bottom: 15rpx;
+ background-color: #f9f9f9;
+ border-radius: 10rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .assignee-index {
+ width: 50rpx;
+ height: 50rpx;
+ border-radius: 50%;
+ background-color: #007AFF;
+ color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 24rpx;
+ font-weight: bold;
+ margin-right: 20rpx;
+ flex-shrink: 0;
+ }
+
+ .assignee-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 10rpx;
+
+ .assignee-name {
+ display: flex;
+ align-items: center;
+ font-size: 30rpx;
+ color: #333;
+ font-weight: 500;
+
+ .primary-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4rpx;
+ margin-left: 12rpx;
+ padding: 4rpx 12rpx;
+ background-color: #fff3e0;
+ border-radius: 6rpx;
+
+ text {
+ font-size: 20rpx;
+ color: #ff9500;
+ font-weight: normal;
+ }
+ }
+ }
+
+ .assignee-role {
+ .role-tag {
+ display: inline-block;
+ padding: 4rpx 12rpx;
+ border-radius: 6rpx;
+ font-size: 22rpx;
+ color: white;
+
+ &.role-driver {
+ background-color: #007AFF;
+ }
+
+ &.role-doctor {
+ background-color: #34C759;
+ }
+
+ &.role-nurse {
+ background-color: #AF52DE;
+ }
+ }
+
+ .assignee-ready-btn {
+ margin-left: 12rpx;
+ padding: 8rpx 16rpx;
+ font-size: 24rpx;
+ border-radius: 6rpx;
+ background-color: #34C759;
+ color: #fff;
+ border: none;
+ }
+ .ready-badge {
+ display: inline-block;
+ margin-left: 12rpx;
+ padding: 4rpx 12rpx;
+ font-size: 22rpx;
+ border-radius: 6rpx;
+ &.ready {
+ background-color: #e6ffed;
+ color: #34C759;
+ }
+ &.unready {
+ background-color: #f0f0f0;
+ color: #999;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .empty-assignee {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 60rpx 0;
+ color: #999;
+
+ text {
+ margin-top: 20rpx;
+ font-size: 28rpx;
+ }
+ }
+
.info-item {
display: flex;
margin-bottom: 20rpx;
--
Gitblit v1.9.1