| | |
| | | <view class="section-title">基本信息</view> |
| | | <view class="info-item"> |
| | | <view class="label">任务编号</view> |
| | | <view class="value">{{ taskDetail.taskCode }}</view> |
| | | <view class="value"> |
| | | {{ taskDetail.showTaskCode }} |
| | | <text v-if="taskDetail.isHeadPush === '1'" class="head-push-tag">总</text> |
| | | </view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">任务类型</view> |
| | |
| | | <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> |
| | | </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> |
| | |
| | | <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 |
| | |
| | | > |
| | | 修改 |
| | | </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> |
| | | |
| | | <!-- 出发中状态: 显示编辑、已到达、强制结束 --> |
| | |
| | | > |
| | | 修改 |
| | | </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> |
| | | |
| | | <!-- 已到达状态: 显示编辑、已返程 --> |
| | |
| | | > |
| | | 修改 |
| | | </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> |
| | | |
| | | <!-- 返程中状态: 显示编辑、已完成 --> |
| | |
| | | > |
| | | 修改 |
| | | </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> |
| | | |
| | | <!-- 已完成/已取消: 不显示按钮,但如果是转运任务则显示结算按钮 --> |
| | |
| | | </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: { |
| | |
| | | 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') { |
| | |
| | | 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) { |
| | |
| | | |
| | | // 返回上一页 |
| | | goBack() { |
| | | uni.navigateBack() |
| | | // 检查是否有页面可以返回 |
| | | uni.navigateBack({ |
| | | delta: 1, |
| | | fail: () => { |
| | | // 如果无法返回,则跳转到任务列表页面 |
| | | uni.switchTab({ |
| | | url: '/pages/task/index' |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 处理编辑按钮 |
| | |
| | | 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 |
| | | }) |
| | |
| | | handleTaskAction(action) { |
| | | switch (action) { |
| | | case 'depart': |
| | | // 出发 -> 检查车辆是否有其他正在进行中的任务 |
| | | this.checkVehicleAndDepart(); |
| | | this.ensureReadyThenDepart(); |
| | | break; |
| | | |
| | | case 'cancel': |
| | |
| | | }, |
| | | |
| | | // 检查车辆状态并出发 |
| | | 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('显示带跳转按钮的弹窗,任务ID:', 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; |
| | | } |
| | | |
| | | // 车辆没有其他正在进行中的任务,可以出发 |
| | | // 所有检查通过,可以出发 |
| | | 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 |
| | |
| | | // 附件删除成功回调 |
| | | 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('无法识别执行人ID') |
| | | 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() |
| | | }, |
| | | |
| | | // 获取执行人员的key值 |
| | | getAssigneeKey(assignee, index) { |
| | | // 确保返回有效的字符串key |
| | | if (!assignee) return 'assignee-' + index; |
| | | // 优先使用userId,其次是userName,最后使用index |
| | | const key = assignee.userId || assignee.userName || index; |
| | | return 'assignee-' + (key !== null && key !== undefined ? key : index); |
| | | }, |
| | | |
| | | // 获取支付记录的key值 |
| | | getPaymentKey(payment, index) { |
| | | // 确保返回有效的字符串key |
| | | if (!payment) return 'payment-' + index; |
| | | // 优先使用id,其次使用index |
| | | const key = payment.id || index; |
| | | return 'payment-' + (key !== null && key !== undefined ? key : index); |
| | | }, |
| | | |
| | | } |
| | | } |
| | | </script> |
| | |
| | | } |
| | | } |
| | | |
| | | // 总部推送标记样式 |
| | | .head-push-tag { |
| | | color: #ff0000; |
| | | font-size: 24rpx; |
| | | font-weight: bold; |
| | | margin-left: 10rpx; |
| | | padding: 2rpx 8rpx; |
| | | border: 1rpx solid #ff0000; |
| | | border-radius: 4rpx; |
| | | } |
| | | |
| | | .detail-content { |
| | | padding: 20rpx; |
| | | height: calc(100vh - 220rpx); // 减去header(100rpx)和按钮区域(120rpx)的高度 |
| | |
| | | } |
| | | } |
| | | |
| | | // 执行人员列表样式 |
| | | .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; |