Files
medical-mall/pages/mall/delivery/task-detail.uvue
2026-01-27 17:52:58 +08:00

428 lines
9.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="task-detail-container">
<!-- 顶部导航栏 -->
<view class="page-header">
<!-- 左上角:返回上一页按钮 -->
<view class="nav-left" @click="goBack">
<text class="nav-icon">←</text>
<text class="nav-title">返回</text>
</view>
<!-- 页面标题居中 -->
<text class="page-title">任务详情</text>
<!-- 右上角留空 -->
<view class="nav-right"></view>
</view>
<!-- 任务详情卡片 -->
<view class="task-card">
<view class="task-header">
<text class="task-id">任务 #{{ task?.id?.slice(-6) || '未知' }}</text>
<view class="task-status" :class="'status-' + (task?.status || 0)">
{{ getTaskStatusText(task?.status) }}
</view>
</view>
<view class="task-info">
<view class="info-item">
<text class="info-label">取货地址:</text>
<text class="info-value">{{ getAddressText(task?.pickup_address) }}</text>
</view>
<view class="info-item">
<text class="info-label">送达地址:</text>
<text class="info-value">{{ getAddressText(task?.delivery_address) }}</text>
</view>
<view class="info-item" v-if="task?.distance">
<text class="info-label">距离:</text>
<text class="info-value">{{ task.distance }}km</text>
</view>
<view class="info-item" v-if="task?.estimated_time">
<text class="info-label">预计时间:</text>
<text class="info-value">{{ task.estimated_time }}分钟</text>
</view>
<view class="info-item" v-if="task?.delivery_fee">
<text class="info-label">配送费:</text>
<text class="info-value">¥{{ task.delivery_fee }}</text>
</view>
<view class="info-item" v-if="task?.created_at">
<text class="info-label">创建时间:</text>
<text class="info-value">{{ formatTime(task.created_at) }}</text>
</view>
</view>
<view class="task-actions">
<button class="action-btn" @click="contactCustomer">联系客户</button>
<button class="action-btn primary" @click="completeTask">完成配送</button>
</view>
</view>
<!-- 任务备注 -->
<view v-if="task?.remark" class="task-remark">
<text class="remark-title">备注:</text>
<text class="remark-text">{{ task.remark }}</text>
</view>
<!-- 联系客户按钮(重复显示,符合截图) -->
<view class="contact-client">
<button class="contact-btn" @click="contactCustomer">联系客户</button>
</view>
<!-- 查看详情按钮(实际就是返回上一页) -->
<view class="view-detail">
<button class="detail-btn" @click="goBack">返回</button>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, onMounted } from 'vue'
// 响应式数据
const task = ref(null)
// ✅ 关键:在 setup 中无法直接访问 onLoad所以改用以下方式
// 方案:通过 getCurrentPages() 获取当前页面参数
function getQueryParams() {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
return currentPage.options || {}
}
// 在 onMounted 中获取参数
onMounted(() => {
const query = getQueryParams()
const taskId = query.id
if (!taskId) {
uni.showToast({
title: '任务ID不能为空',
icon: 'none'
})
console.error('❌ 未获取到 taskIdquery:', query)
return
}
loadTaskDetail(taskId)
})
// 其他方法保持不变...
function loadTaskDetail(taskId: string) {
const mockTasks = [
{
id: 'task001',
order_id: 'ORD20250122001',
pickup_address: { address: '深圳市南山区科技园南区深圳湾科技生态园' },
delivery_address: { address: '深圳市南山区蛇口海上世界广场' },
distance: 8.2,
estimated_time: 25,
delivery_fee: 12.0,
status: 3,
remark: '联系电话: 13800138000',
created_at: '2025-01-22 14:00:00'
},
// 更多模拟数据...
]
const foundTask = mockTasks.find(t => t.id === taskId)
if (foundTask) {
task.value = foundTask
console.log('✅ 加载任务成功:', task.value)
} else {
uni.showToast({ title: '未找到该任务', icon: 'none' })
console.warn('⚠️ 任务ID不存在:', taskId)
}
}
// 其他方法...
function getTaskStatusText(status: number): string {
const statusMap = {
1: '待接单',
2: '已接单',
3: '配送中',
4: '已完成',
5: '已取消'
}
return statusMap[status] || '未知'
}
function getAddressText(address: UTSJSONObject): string {
return address?.['address'] as string || '地址信息'
}
function formatTime(dateStr: string): string {
if (!dateStr) return '未知时间'
const date = new Date(dateStr)
const now = new Date()
const diff = now.getTime() - date.getTime()
const hours = Math.floor(diff / (1000 * 60 * 60))
if (hours < 1) return '刚刚'
if (hours < 24) return `${hours}小时前`
return `${Math.floor(hours / 24)}天前`
}
function contactCustomer() {
uni.showActionSheet({
itemList: ['拨打电话', '发送短信'],
success: (res) => {
if (res.tapIndex === 0) {
uni.makePhoneCall({ phoneNumber: '13800138000' })
}
}
})
}
function completeTask() {
if (task.value?.status !== 3) {
uni.showToast({ title: '当前任务不是“配送中”状态', icon: 'none' })
return
}
task.value.status = 4
uni.showToast({ title: '任务已完成', icon: 'success' })
}
function goBack() {
uni.navigateBack()
}
</script>
<style scoped>
.task-detail-container {
background-color: #f5f5f5;
min-height: 100vh;
padding: 20rpx 30rpx;
}
/* 导航栏样式 */
.page-header {
background-color: #fff;
padding: 20rpx 30rpx;
border-bottom: 1rpx solid #e9ecef;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
position: relative;
min-height: 80rpx;
}
.nav-left {
position: absolute;
top: 20rpx;
left: 30rpx;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
padding: 10rpx;
border-radius: 8rpx;
transition: background-color 0.2s ease;
}
.nav-left:hover {
background-color: #f0f0f0;
}
.nav-left:active {
background-color: #e0e0e0;
}
.nav-icon {
font-size: 36rpx;
color: #333;
margin-bottom: 5rpx;
}
.nav-title {
font-size: 28rpx;
color: #333;
font-weight: 500;
text-align: center;
}
.page-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-top: 20rpx;
}
.nav-right {
width: 1rpx;
height: 1rpx;
}
/* 任务详情卡片 */
.task-card {
background-color: #fff;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
border-left: 6rpx solid #74b9ff;
margin-top: 20rpx;
}
.task-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.task-id {
font-size: 28rpx;
font-weight: 500;
color: #333;
}
.task-status {
font-size: 22rpx;
padding: 6rpx 12rpx;
border-radius: 20rpx;
font-weight: 500;
color: white;
}
.status-1 {
background: #ffeb3b;
color: #333;
}
.status-3 {
background: #2196f3;
color: white;
}
.status-4 {
background: #4caf50;
color: white;
}
.task-info {
display: flex;
flex-direction: column;
gap: 10rpx;
padding: 15rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.info-item {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #666;
}
.info-label {
font-weight: 500;
min-width: 100rpx;
}
.info-value {
flex: 1;
word-break: break-all;
}
.task-actions {
display: flex;
gap: 20rpx;
margin-top: 20rpx;
}
.action-btn {
flex: 1;
height: 80rpx;
border-radius: 8rpx;
font-size: 28rpx;
border: none;
font-weight: bold;
padding: 0 10rpx;
box-sizing: border-box;
}
.action-btn:hover {
background-color: #45a049; /* 按钮悬停效果 */
}
.action-btn:active {
background-color: #3d8b40; /* 按钮点击效果 */
}
.action-btn.primary {
background-color: #4CAF50;
color: #fff;
}
/* 任务备注 */
.task-remark {
background-color: #fff;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
margin-top: 20rpx;
}
.remark-title {
font-size: 28rpx;
font-weight: 500;
color: #333;
margin-bottom: 10rpx;
}
.remark-text {
font-size: 24rpx;
color: #666;
line-height: 1.5;
}
/* 联系客户按钮 */
.contact-client {
margin-top: 20rpx;
}
.contact-btn {
width: 100%;
height: 80rpx;
background-color: #f0f0f0;
color: #333;
border: none;
border-radius: 8rpx;
font-size: 28rpx;
font-weight: bold;
cursor: pointer;
transition: background-color 0.2s ease;
}
.contact-btn:hover {
background-color: #e0e0e0;
}
.contact-btn:active {
background-color: #d0d0d0;
}
/* 查看详情按钮 */
.view-detail {
margin-top: 20rpx;
}
.detail-btn {
width: 100%;
height: 80rpx;
background-color: #4CAF50;
color: #fff;
border: none;
border-radius: 8rpx;
font-size: 28rpx;
font-weight: bold;
cursor: pointer;
transition: background-color 0.2s ease;
}
.detail-btn:hover {
background-color: #45a049;
}
.detail-btn:active {
background-color: #3d8b40;
}
</style>