Files
xiaokuaisong-paotui/distribution/pages/index/index.vue

820 lines
20 KiB
Vue
Raw Normal View History

2025-08-18 09:57:10 +08:00
<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>