429 lines
10 KiB
Vue
429 lines
10 KiB
Vue
<script setup>
|
||
import {
|
||
ref,
|
||
onMounted
|
||
} from 'vue';
|
||
import {
|
||
onLoad
|
||
} from '@dcloudio/uni-app';
|
||
import {
|
||
apiImageUrl
|
||
} from '../../API/api';
|
||
|
||
const orderDetail = ref(uni.getStorageSync('orderDetail'));
|
||
|
||
// 公寓位置映射表
|
||
const apartmentLocations = {
|
||
"1公寓": {
|
||
latitude: 45.878148,
|
||
longitude: 126.542369
|
||
},
|
||
"2公寓": {
|
||
latitude: 45.878016,
|
||
longitude: 126.542924
|
||
},
|
||
"3公寓": {
|
||
latitude: 45.878117,
|
||
longitude: 126.543476
|
||
},
|
||
"4公寓": {
|
||
latitude: 45.878118,
|
||
longitude: 126.54415
|
||
},
|
||
"5公寓": {
|
||
latitude: 45.878978,
|
||
longitude: 126.54127
|
||
},
|
||
"6公寓": {
|
||
latitude: 45.878982,
|
||
longitude: 126.541879
|
||
},
|
||
"9公寓": {
|
||
latitude: 45.878435,
|
||
longitude: 126.544863
|
||
},
|
||
"10公寓": {
|
||
latitude: 45.879196,
|
||
longitude: 126.543891
|
||
},
|
||
"11公寓": {
|
||
latitude: 45.879157,
|
||
longitude: 126.542722
|
||
},
|
||
"12公寓": {
|
||
latitude: 45.875638,
|
||
longitude: 126.540502
|
||
},
|
||
"育才大厦": {
|
||
latitude: 45.875638,
|
||
longitude: 126.540502
|
||
},
|
||
};
|
||
|
||
|
||
// 格式化日期函数保持不变
|
||
const formatDate = (dateString) => {
|
||
const date = new Date(dateString);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const hours = String(date.getHours()).padStart(2, '0');
|
||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
};
|
||
|
||
// 处理取货逻辑保持不变
|
||
const handlePickup = (id, imageUrl) => {
|
||
uni.showLoading({
|
||
title: '提交中...',
|
||
mask: true
|
||
});
|
||
uni.request({
|
||
url: apiImageUrl + '/api/errand/update/state',
|
||
method: 'POST',
|
||
data: {
|
||
errandsState: 4,
|
||
orderId: id,
|
||
imageAddress: imageUrl
|
||
},
|
||
header: {
|
||
'Content-Type': 'application/json', // 确保设置正确的 Content-Type
|
||
'cookie': uni.getStorageSync("cookie") || ''
|
||
},
|
||
success(res) {
|
||
console.log(res);
|
||
uni.hideLoading();
|
||
if (res.data.code === 0) {
|
||
uni.showToast({
|
||
title: '成功送达',
|
||
icon: 'none',
|
||
duration: 2000,
|
||
success: () => {
|
||
// 获取页面栈
|
||
const pages = getCurrentPages();
|
||
// 获取上一页和上上页实例
|
||
const prevPage = pages[pages.length - 3]; // 返回两级页面
|
||
|
||
// 执行刷新逻辑
|
||
if (prevPage && prevPage.robOrder) {
|
||
prevPage.robOrder(3); // 刷新待送达列表
|
||
}
|
||
|
||
// 返回两级页面
|
||
uni.navigateBack({
|
||
delta: 2,
|
||
success: () => {
|
||
// 通过事件总线触发刷新
|
||
uni.$emit('refresh-delivery-list');
|
||
}
|
||
});
|
||
}
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: res.data.message || '送达失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
fail(err) {
|
||
console.log(err);
|
||
uni.showToast({
|
||
title: '网络异常,请检查连接',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
};
|
||
|
||
// 联系商家和联系用户的逻辑保持不变
|
||
const handleContact = (item) => {
|
||
uni.makePhoneCall({
|
||
phoneNumber: item
|
||
});
|
||
};
|
||
|
||
const handleCall = (item) => {
|
||
console.log(item)
|
||
uni.makePhoneCall({
|
||
phoneNumber: item
|
||
});
|
||
};
|
||
|
||
// 初始化响应式变量
|
||
const latitude = ref(''); // 用户当前位置纬度
|
||
const longitude = ref(''); // 用户当前位置经度
|
||
const includePoints = ref([]); // 用于自动缩放的地图点集
|
||
const covers = ref([]); // 存储覆盖物
|
||
|
||
// 页面加载时获取位置信息
|
||
onMounted(() => {
|
||
getLocation();
|
||
});
|
||
|
||
// 获取用户当前位置并更新地图上的标记
|
||
function getLocation() {
|
||
uni.getLocation({
|
||
type: 'gcj02', // 返回可以用于uni.openLocation的坐标
|
||
success(res) {
|
||
console.log('当前位置的经度:' + res.longitude);
|
||
console.log('当前位置的纬度:' + res.latitude);
|
||
|
||
// 更新响应式数据
|
||
latitude.value = res.latitude;
|
||
longitude.value = res.longitude;
|
||
|
||
// 更新用户当前位置的标记信息
|
||
updateCover(res.latitude, res.longitude, 2, '我的位置', '/static/logo.png'); // 用户使用特定图标
|
||
|
||
// 根据orderDetail.location设置目标公寓的位置
|
||
if (orderDetail.value.location in apartmentLocations) {
|
||
const targetApartment = apartmentLocations[orderDetail.value.location];
|
||
updateCover(targetApartment.latitude, targetApartment.longitude, 1, orderDetail.value.location,
|
||
'/static/errand.jpg'); // 跑腿员使用特定图标
|
||
|
||
// 更新includePoints数组,确保地图包含两个位置
|
||
includePoints.value = [{
|
||
latitude: targetApartment.latitude,
|
||
longitude: targetApartment.longitude
|
||
}, // 目标公寓的位置
|
||
{
|
||
latitude: res.latitude,
|
||
longitude: res.longitude
|
||
} // 用户的位置
|
||
];
|
||
} else {
|
||
console.warn(`未找到名为"${orderDetail.value.location}"的公寓位置`);
|
||
}
|
||
},
|
||
fail(err) {
|
||
console.error('获取位置失败', err);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 更新覆盖物
|
||
function updateCover(lat, lng, id, title, iconPath) {
|
||
const position = {
|
||
id: id,
|
||
latitude: lat,
|
||
longitude: lng,
|
||
iconPath: iconPath, // 标记图标路径,现在通过参数传递
|
||
width: 30,
|
||
height: 30,
|
||
title: title // 可选:标记点标题
|
||
};
|
||
|
||
// 查找是否已存在指定ID的位置标记
|
||
const existingIndex = covers.value.findIndex(item => item.id === position.id);
|
||
|
||
if (existingIndex !== -1) {
|
||
// 如果存在则更新
|
||
covers.value[existingIndex] = position;
|
||
} else {
|
||
// 如果不存在则添加
|
||
covers.value.push(position);
|
||
}
|
||
}
|
||
|
||
const takephoto = () => {
|
||
uni.chooseImage({
|
||
count: 1, // 默认9,这里设置为1因为只需要一张照片
|
||
sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||
sourceType: ['camera'], // 从相机选择
|
||
success: function(res) {
|
||
const tempFilePaths = res.tempFilePaths; // 拍照后返回的临时文件路径数组
|
||
uploadPhoto(tempFilePaths[0]);
|
||
}
|
||
});
|
||
};
|
||
|
||
const uploadPhoto = (filePath) => {
|
||
uni.uploadFile({
|
||
url: `${apiImageUrl}/api/file/upload/server`, // 接口地址
|
||
filePath: filePath,
|
||
name: 'file',
|
||
formData: {
|
||
biz: 'takeout' // 根据要求填写的biz参数
|
||
},
|
||
header: {
|
||
'Content-Type': 'application/json', // 确保设置正确的 Content-Type
|
||
'cookie': uni.getStorageSync("cookie") || ''
|
||
},
|
||
success(res) {
|
||
console.log('上传成功', res);
|
||
const imageUrl = JSON.parse(res.data).data;
|
||
handlePickup(orderDetail.value.id, imageUrl);
|
||
},
|
||
fail(err) {
|
||
console.error('上传失败', err);
|
||
}
|
||
});
|
||
};
|
||
</script>
|
||
|
||
|
||
|
||
<template>
|
||
<view class="page">
|
||
<!-- 地图 -->
|
||
<view>
|
||
<map style="width:100%; height: 300px;" :latitude="latitude" :longitude="longitude" :markers="covers"
|
||
:include-points="includePoints">
|
||
</map>
|
||
</view>
|
||
<!-- 订单详情部分保持不变 -->
|
||
<view class="header">
|
||
<text class="location">取</text>
|
||
<text class="distance">1km</text>
|
||
<text class="store-name">{{orderDetail.address}}</text>
|
||
</view>
|
||
<view class="header">
|
||
<text class="location">送</text>
|
||
<text class="distance">1km</text>
|
||
<text class="store-name">{{orderDetail.location}}</text>
|
||
</view>
|
||
<view class="buttons">
|
||
<!-- <button class="button" @click="handlePickup(orderDetail.id)">我已取到</button> -->
|
||
<view class="icon-container">
|
||
<!-- 第一个图标和文字 -->
|
||
<view class="icon-wrapper" @click="handleCall(orderDetail.businessVO?.businessPhone)">
|
||
<uni-icons type="phone" size="30"></uni-icons>
|
||
<text>联系商家</text>
|
||
</view>
|
||
|
||
<!-- 第二个图标和文字 -->
|
||
<view class="icon-wrapper" @click="handleContact(orderDetail.phone)">
|
||
<uni-icons type="phone-filled" size="30"></uni-icons>
|
||
<text>联系用户</text>
|
||
</view>
|
||
|
||
<!-- 第三个图标和文字 -->
|
||
<view class="icon-wrapper">
|
||
<!-- <uni-icons type="camera" size="30" @click="handlePickup(orderDetail.id)"></uni-icons> -->
|
||
<uni-icons type="camera" size="30" @click="takephoto(orderDetail.id)"></uni-icons>
|
||
<text>拍照送达</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="order-details">
|
||
<text class="title">跑单详情</text>
|
||
<view class="detail">
|
||
<text>取餐地址:</text>
|
||
<text>{{orderDetail.address}}</text>
|
||
</view>
|
||
<view class="detail">
|
||
<text>下单时间:</text>
|
||
<text>{{formatDate(orderDetail.createTime)}}</text>
|
||
</view>
|
||
<view class="detail">
|
||
<text>送达时间:</text>
|
||
<text style="color: red;">{{formatDate(orderDetail.pickupEndTime)}}</text>
|
||
</view>
|
||
<view class="detail">
|
||
<text>送达地址:</text>
|
||
<text>{{orderDetail.location}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.page {
|
||
padding: 20px;
|
||
background-color: #fff;
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.location {
|
||
width: 24px;
|
||
/* 稍微增大圆形 */
|
||
height: 24px;
|
||
background-color: #ff6700;
|
||
color: #fff;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
border-radius: 50%;
|
||
margin-right: 12px;
|
||
font-size: 12px;
|
||
/* 调整文本大小 */
|
||
font-weight: bold;
|
||
}
|
||
|
||
.distance {
|
||
color: #999;
|
||
font-size: 12px;
|
||
padding-right: 5px;
|
||
}
|
||
|
||
.store-name {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.buttons {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.button {
|
||
width: 100%;
|
||
padding: 10px;
|
||
margin: 10px 0;
|
||
text-align: center;
|
||
background-color: #2877f2;
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
line-height: inherit;
|
||
}
|
||
|
||
.order-details {
|
||
margin-top: 20px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.title {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.detail {
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 5px 0;
|
||
}
|
||
|
||
/* 定义图标容器的样式 */
|
||
.icon-container {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
/* 水平均匀分布 */
|
||
align-items: center;
|
||
/* 垂直居中对齐 */
|
||
}
|
||
|
||
/* 定义每个图标和文字组合的样式 */
|
||
.icon-wrapper {
|
||
display: flex;
|
||
flex-direction: column;
|
||
/* 将子元素垂直排列 */
|
||
align-items: center;
|
||
/* 子元素水平居中对齐 */
|
||
}
|
||
|
||
/* 可选:定义文本标签的样式 */
|
||
.icon-wrapper text {
|
||
margin-top: 5px;
|
||
/* 文字与图标之间的间距 */
|
||
}
|
||
</style> |