Files
2025-08-18 09:57:10 +08:00

820 lines
20 KiB
Vue
Raw Permalink 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="tab-menu">
<view v-for="(tab, index) in tabs" :key="tab.name" class="tab-item" :class="{ active: currentIndex === index }"
@click="switchTab(index)">
{{ tab.name }}
</view>
</view>
<uni-notice-bar show-icon scrollable text="今日放假" />
<view class="content">
<template v-if="currentIndex === 0">
<view class="order-card" v-for="(item,index) in errandOrder" :key="index">
<view class="delivery-info">
<view class="time-id">#{{item.id}}</view>
<view class="price">1.7</view>
</view>
<view class="delivery-info">
<view class="time">{{formatDate(item.pickupEndTime)}}内送达</view>
</view>
<view class="address-info">
<view class="address-item">
<view class="circle"></view>
<view class="distance">1km</view>
<view class="address-name">{{item.address}}·{{item.businessVO?.businessName}}</view>
</view>
<view class="address-item">
<view class="circle"></view>
<view class="distance">1.5km</view>
<view class="address-name">{{item.location}}</view>
</view>
</view>
<view class="button-container">
<view class="order-button" @click="plunder(item.id)">抢单</view>
</view>
</view>
</template>
<template v-if="currentIndex === 1">
<view class="order-card" v-for="(item,index) in errandOrder" :key="index" @click.stop="orderDetail(item)">
<view class="delivery-info">
<view class="time-id">#{{item.id}}</view>
<view class="price">1.7</view>
</view>
<view class="delivery-info">
<view class="time">{{formatDate(item.pickupEndTime)}}内送达</view>
</view>
<view class="address-info">
<view class="address-item">
<view class="circle"></view>
<view class="distance">1km</view>
<view class="address-name">{{item.address}}·{{item.businessVO?.businessName}}</view>
</view>
<view class="address-item">
<view class="circle"></view>
<view class="distance">1.5km</view>
<view class="address-name">{{item.location}}</view>
</view>
</view>
<view class="button-container" @click.stop="obtain(item.id)">
<view class="order-button">确认取货</view>
</view>
</view>
</template>
<template v-if="currentIndex === 2">
<view class="order-card" v-for="(item,index) in errandOrder" :key="index" @click.stop="deliveryDetail(item)">
<view class="delivery-info">
<view class="time-id">#{{item.id}}</view>
<view class="price">1.7</view>
</view>
<view class="delivery-info">
<view class="time">{{formatDate(item.pickupEndTime)}}内送达</view>
</view>
<view class="address-info">
<view class="address-item">
<view class="circle"></view>
<view class="distance">1km</view>
<view class="address-name">{{item.address}}·{{item.businessVO?.businessName}}</view>
</view>
<view class="address-item">
<view class="circle"></view>
<view class="distance">1.5km</view>
<view class="address-name">{{item.location}}</view>
</view>
</view>
<view class="button-container">
<view class="order-button">确认送达</view>
</view>
</view>
</template>
</view>
<view class="fixed-buttons">
<view class="button-container" @click="toggle('bottom')">
<uni-icons type="gear-filled" size="24"></uni-icons>
<text class="fixed-font">跑单设置</text>
</view>
<view class="button-container" @click="map">
<uni-icons type="location-filled" size="24"></uni-icons>
<text class="fixed-font">配送范围</text>
</view>
<button @click="refreshOrders" class="refresh-button">刷新订单</button>
</view>
<!-- 通弹窗 -->
<uni-popup ref="popupRef" background-color="#fff" @change="change">
<view class="popup-content" :class="{ 'popup-height': type === 'left' || type === 'right' }">
<view class="modal-header">
<button class="tab-button" :class="{ active: activeTab === 0 }" @click="switchTabs(0)">跑单设置</button>
<button class="tab-button" :class="{ active: activeTab === 1 }" @click="switchTabs(1)">运单排序</button>
</view>
<view class="modal-body">
<view v-if="activeTab === 0">
<view class="modal-item">
<text class="modal-label">配送区域</text>
<!-- 使用 currentUser distributionScope 来设置 picker 的默认值 -->
<picker :value="array.indexOf(radius.value)" :range="array" @change="bindPickerChange" class="modal-value">
<view>{{ radius.value || '修改配送区域' }}</view> <!-- 如果没有设置则显示提示 -->
</picker>
</view>
<view class="modal-item">
<text class="modal-label">同时接单量</text>
<text class="modal-value">15</text>
</view>
</view>
<view v-if="activeTab === 1">
<view class="modal-item">
<text class="modal-label">智能排序</text>
<view class="modal-value">
<text>未设置</text>
<text class="arrow">&gt;</text>
</view>
</view>
<view class="modal-list">
<view class="item" @click="handleClick(item)" v-for="(item, index) in items" :key="index"
:class="{ selected: selectedItem === item }">
{{ item }}
</view>
</view>
<view class="modal-item">
<text class="modal-label">置顶</text>
<view class="modal-value">
<switch color="#FFCC33" style="transform:scale(0.7)" />
</view>
</view>
<text class="tips">关闭之后订单将按默认顺序排序</text>
<view class="modal-list">
<view class="item" @click="handleClick(item)" v-for="(item, index) in tipsItems" :key="index"
:class="{ selected: selectedItem === item }">
{{ item }}
</view>
</view>
</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import {
ref,
computed,
onMounted
} from 'vue';
import {
apiImageUrl
} from '../../API/api';
import {
onShow
} from "@dcloudio/uni-app";
const radius=ref(uni.getStorageSync("currentUser.distributionScope"))
const currentIndex = ref(0);
const tabs = [{
name: '待抢单'
},
{
name: '待取货'
},
{
name: '待送达'
}
];
// 修改选项卡切换逻辑
const switchTab = (index) => {
currentIndex.value = index;
// 根据文档状态映射关系0-待抢单对应errandState=11-待取货对应errandState=22-待送达对应errandState=3
const stateMap = [1, 2, 3];
if (index >= 0 && index < stateMap.length) {
robOrder(stateMap[index]);
}
};
const switchTabs = (index) => {
activeTab.value = index;
};
// 定义响应式变量
const type = ref('center');
const activeTab = ref(0); // 默认激活第一个标签页
const selectedItem = ref(null);
// 弹窗引用
const popupRef = ref(null);
// 数据源
const array = ref(['1公寓', '2公寓', '3公寓', '4公寓', '5公寓', '6公寓', '7公寓', '8公寓', '9公寓', '10公寓', '11公寓', '12公寓','育才大厦']);
const index = ref(0);
const items = ref([
'考核时间从多到少',
'运单金额从高到低',
'配送距离从近到远',
'取货距离从近到远',
'推荐排序'
]);
const tipsItems = ref([
'新单置顶',
'已抢商户置顶'
]);
// 方法定义
const change = (e) => {
console.log('当前模式:' + e.type + ',状态:' + e.show);
};
const toggle = (typeValue) => {
type.value = typeValue;
popupRef.value.open(typeValue);
};
const closePopup = () => {
popupRef.value.close();
};
const map = () => {
uni.navigateTo({
url: '/pages/map/map'
})
}
// Picker 选择改变时触发
const bindPickerChange = (e) => {
console.log('picker发送选择改变携带值为', e.detail.value);
const newValue = array.value[e.detail.value];
radius.value = newValue;
// 使用当前用户信息来构建请求数据
const requestData = {
distributionScope: newValue,
errandName: currentUser.value.errandName, // 动态获取
errandPhone: currentUser.value.errandPhone, // 动态获取
gender: currentUser.value.gender, // 动态获取
id: currentUser.value.id, // 动态获取
state: currentUser.value.state // 动态获取
};
// 更新用户的配送范围
uni.request({
url: apiImageUrl + '/api/errand/update/my',
method: 'POST',
data: requestData,
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success(res) {
console.log('配送范围更新成功:', res);
console.log(res.data.code);
if(res.data.code===50001){
uni.showToast({
title:'还有未送达订单',
icon: 'fail'
});
}
else if(res.data.code===0){
uni.showToast({
title: '配送范围已更新',
icon: 'success'
});
refreshOrders();
}
},
fail(err) {
console.error('配送范围更新失败:', err);
uni.showToast({
title: '更新失败,请重试',
icon: 'none'
});
}
});
};
const handleClick = (item) => {
selectedItem.value = item;
};
const takePhoto = () => {
uni.navigateTo({
url: '/pages/takePhoto/takePhoto'
})
};
// 修改刷新订单方法
const refreshOrders = () => {
const stateMap = [1, 2, 3];
const currentState = stateMap[currentIndex.value] || 1;
robOrder(currentState);
};
// 初始化加载数据
onMounted(() => {
robOrder(1); // 初始加载待抢单数据
});
let errandOrder = ref([]);
const robOrder = (errandStateValue) => {
// 添加参数校验
if (typeof errandStateValue !== 'number' || isNaN(errandStateValue)) {
console.error("Invalid errandState value:", errandStateValue);
return;
}
// 手动构建查询字符串
const params = `errandState=${encodeURIComponent(errandStateValue.toString())}`;
uni.request({
url: apiImageUrl + '/api/errand/list/order',
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded', // 设置正确的内容类型
'cookie': uni.getStorageSync("cookie") || ''
},
data: params, // 直接使用构建好的查询字符串
success(res) {
console.log('请求成功:', res);
if (res.data.code !== 0) {
uni.showToast({
title: `请求失败:${res.data.message}`,
icon: 'none'
});
}else {
console.log(res.data.data)
errandOrder.value = res.data.data; // 更新响应式数据
console.log('Updated errandOrder:', errandOrder.value);
}
},
fail(err) {
console.log('请求失败:', err);
}
});
};
const plunder = (id) => {
console.log(id);
uni.request({
url: apiImageUrl + '/api/errand/get/order',
method: 'POST',
data: {
id: id
},
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success: (res) => { // 使用箭头函数保持上下文
console.log(res);
if (res.data.code === 0) {
uni.showToast({
title: '抢单成功',
icon: 'success',
success: () => {
// 根据当前标签页刷新数据
const stateMap = [1, 2, 3];
const currentState = stateMap[currentIndex.value];
robOrder(currentState);
// 如果是待抢单页面,额外刷新待取货列表
if (currentIndex.value === 0) {
robOrder(2);
}
}
});
} else {
uni.showToast({
title: res.data.message || '抢单失败',
icon: 'none'
});
}
},
fail: (err) => {
console.log(err);
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}
})
};
const obtain = (id) => {
uni.request({
url: apiImageUrl + '/api/errand/update/state',
method: 'POST',
data: {
errandsState: 3,
orderId: id
},
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success: (res) => {
console.log(res);
if (res.data.code === 0) {
uni.showToast({
title: '取货成功',
icon: 'success',
success: () => {
// 刷新当前标签页数据(待取货列表)
robOrder(2);
// 同时刷新待送达列表
robOrder(3);
}
});
} else {
uni.showToast({
title: res.data.description || '取货失败',
icon: 'none'
});
}
},
fail: (err) => {
console.log(err);
uni.showToast({
title: '网络异常,请检查连接',
icon: 'none'
});
}
})
};
// const send=(id)=>{
// console.log(id);
// uni.request({
// url:apiImageUrl+'/api/errand/update/state',
// method:'POST',
// data:{
// errandsState:4,
// orderId:id,
// imageAddress:"https://bpic.588ku.com/back_list_pic/22/05/07/16474c1e1553210af8360bfeed9b5134.jpg"
// },
// header: {
// 'Content-Type': 'application/json', // 确保设置正确的 Content-Type
// 'cookie': uni.getStorageSync("cookie") || ''
// },
// success(res) {
// console.log(res);
// uni.showToast({
// title: '送货成功',
// icon: 'none'
// });
// },
// fail(err) {
// console.log(err);
// uni.showToast({
// title: '送货失败',
// icon: 'none'
// });
// }
// })
// }
let currentUser = ref({});
// 获取当前用户信息
// 获取当前用户信息
const getCurrentUser = () => {
uni.request({
url: apiImageUrl + '/api/errand/get/current',
method: 'POST',
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success(res) {
console.log(res);
if (res.data.code === 0) { // 检查HTTP状态码和业务状态码
const userData = res.data.data;
currentUser.value = userData; // 更新响应式变量currentUser
// 检查用户的配送范围是否存在于我们的选项中
if (array.value.includes(userData.distributionScope)) {
radius.value = userData.distributionScope; // 保存用户的配送范围
} else {
console.warn('用户的配送范围不在预设的选项中');
// 可以选择设置一个默认值或者提示用户更新配送范围
}
}
},
fail(err) {
console.error('请求失败:', err);
}
});
};
onMounted(() => {
robOrder(1); // 初始加载待抢单数据
getCurrentUser(); // 获取当前用户信息
});
onShow(() => {
getCurrentUser()
robOrder(1);
})
const orderDetail=(item)=>{
uni.setStorageSync("orderDetail",item)
uni.navigateTo({
url:'/pages/orderDetail/orderDetail'
})
}
const deliveryDetail=(item)=>{
console.log("4567845678945678900");
console.log(item);
uni.setStorageSync("orderDetail",item)
uni.navigateTo({
url:'/pages/deliveryDetail/deliveryDetail'
})
}
// 新增时间格式化函数
const formatDate = (isoString) => {
if (!isoString) return '';
// 直接从 ISO 字符串中截取目标格式MM-DD HH:mm:ss
return isoString.slice(5, 10) + ' ' + isoString.slice(11, 19);
};
// 在订单列表页面的onShow中添加
uni.$on('refresh-delivery-list', () => {
this.robOrder(3); // 假设这是你的订单列表刷新方法
});
</script>
<style scoped lang="scss">
.time-id {
font-size: 20px;
color: #ff6700;
font-weight: 700;
}
.tab-menu {
display: flex;
justify-content: space-around;
padding: 10px 0;
background-color: #5e7dec;
color: #9cb0f4;
}
.tab-item {
padding: 10px;
cursor: pointer;
}
.tab-item.active {
color: #fff;
font-weight: bold;
}
.fixed-buttons {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
background-color: #fff;
padding: 10px;
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
}
.button-container {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 10px;
}
.button-container text {
margin-top: 5px;
}
.fixed-font {
font-size: 12px;
}
.refresh-button {
width: 60%;
background-color: pink;
border-radius: 15px;
color: #fff;
background-color: #5e7dec;
}
.button-text {
color: #fff;
font-size: 12px;
}
.text {
font-size: 12px;
color: #333;
}
.popup-content {
padding: 20px;
border-radius: 8px;
background-color: #fff;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.tab-button {
background-color: transparent;
border: none;
font-size: 16px;
cursor: pointer;
padding: 5px 10px;
&.active {
color: #007AFF;
border-bottom: 2px solid #007AFF;
}
}
.modal-title {
font-size: 18px;
font-weight: bold;
}
.modal-close {
font-size: 16px;
cursor: pointer;
}
.modal-body {
padding: 10px 0;
}
.modal-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.modal-label {
font-size: 15px;
font-weight: bold;
}
.modal-value {
font-size: 14px;
color: #333;
}
.arrow {
margin-left: 10px;
}
.modal-list {
display: grid;
grid-template-columns: 1fr 1fr;
/* 创建两列,每列占据相等的空间 */
gap: 10px;
padding: 10px 10px 10px 0;
border-radius: 5px;
}
.item {
background-color: #f1f1f1;
padding: 10px;
border-radius: 5px;
text-align: center;
cursor: pointer;
font-size: 14px;
&.selected {
background-color: #eef6ff;
color: #80a6da;
}
}
.tips {
font-size: 12px;
color: #c8c8c8;
}
// 抢单样式
.order-card {
background-color: #fff;
border-radius: 12px;
/* 增大圆角 */
padding: 10px;
/* 增大内边距 */
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.16);
/* 更深的阴影 */
width: 90%;
margin: 0 auto;
margin-bottom: 20px;
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
/* 添加过渡效果 */
}
.order-card:hover {
transform: translateY(-4px);
/* 当鼠标悬停时稍微提升 */
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
/* 更大的阴影当悬停 */
}
/* 修改前 */
.order-card:last-child {
margin-bottom: 100px;
}
/* 修改后 */
.order-card:last-child {
margin-bottom: 100px !important; /* 添加 !important 确保优先级 */
}
.delivery-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.time,
.price {
font-size: 16px;
/* 增大字体大小 */
}
.price {
color: #ff6700;
font-weight: bold;
}
.address-info {
margin-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
/* 添加底部边框 */
padding-bottom: 10px;
}
.address-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.circle {
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: #666;
font-size: 14px;
margin-right: 12px;
}
.address-name {
color: #333;
font-size: 16px;
font-weight: 600;
}
.button-container {
text-align: center;
/* 增加按钮顶部间距 */
}
.order-button {
background-color: #5e7dec;
color: #fff;
padding: 12px 24px;
/* 增大按钮尺寸 */
border-radius: 6px;
/* 圆滑按钮边缘 */
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease-in-out;
/* 添加过渡效果 */
width: 85%;
}
.order-button:hover {
background-color: #4a69bd;
/* 改变悬停颜色 */
}
.content {
padding-bottom: 50px; /* 根据底部按钮高度调整 */
}
</style>