638 lines
14 KiB
Vue
638 lines
14 KiB
Vue
<template>
|
||
<view class="notice">
|
||
<uni-notice-bar show-icon scrollable text="3分钟内未支付,订单将自动取消" />
|
||
</view>
|
||
<view class="order-page">
|
||
<view class="header">
|
||
<view class="status" :id="statusId">
|
||
待支付,请尽快支付
|
||
</view>
|
||
|
||
</view>
|
||
<view class="order-summary">
|
||
<view class="order-info">
|
||
<view class="uni-px-5 uni-pb-5">
|
||
<uni-data-checkbox v-model="radio1" :localdata="sex"></uni-data-checkbox>
|
||
</view>
|
||
<!-- <text><uni-tag :inverted="true" text="确认订单" type="primary" @click="submitOrder" /></text> -->
|
||
</view>
|
||
<view class="address" v-if="radio1 === 2">
|
||
<picker @change="bindPickerChange" :value="index" :range="array">
|
||
<view class="uni-input">地址:{{selectedApartmentName ? selectedApartmentName : '请选择公寓'}}</view>
|
||
</picker>
|
||
<!-- 时间 -->
|
||
<template class="time-picker">
|
||
<view class="align-center justify-between default-flex secondBox" @click="showTime">
|
||
<view class="default-flex align-center">
|
||
<view class="t666 f28">
|
||
配送时间:
|
||
</view>
|
||
</view>
|
||
<view class="tDesc">
|
||
<view class="sTime">{{ sendTime || '请选择配送时间' }}</view>
|
||
<view class="bj">
|
||
<img src="https://yujia-shanghai-bucket.oss-cn-shanghai.aliyuncs.com/small-program/yvmuShop/timeEdit.png"
|
||
alt="">
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<distribution-box ref="dsbonBox" :get-time.sync="sendTime"
|
||
@timeSelected="handleTimeSelected"></distribution-box>
|
||
</template>
|
||
</view>
|
||
<view class="pay-button" @click="submitOrder">
|
||
去支付¥{{orderItem.totalPrice}}
|
||
</view>
|
||
</view>
|
||
<view class="order-items">
|
||
<view class="businessDetail">
|
||
<image class="item-image" :src="orderItem.businessVO?.businessImages"></image>
|
||
{{orderItem.businessVO?.businessName}}
|
||
</view>
|
||
<view class="order-item" v-for="item in orderItem.orderDetailsVOList">
|
||
<image class="item-image" :src="item.dishesVO.dishesImage"></image>
|
||
<view class="item-info">
|
||
<view class="item-name">{{item.dishesVO.dishesName}}</view>
|
||
<view class="item-description">{{item.quantity}}×{{item.dishesVO.dishesName}}</view>
|
||
<view class="item-price">¥{{item.dishesVO.dishesPrice}}</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="total" v-if="radio1===1||radio1===2">
|
||
<text>打包费</text>
|
||
<text>¥1</text>
|
||
</view>
|
||
<view class="total" v-if="radio1 === 2">
|
||
<text>配送费</text>
|
||
<text>¥1.7</text>
|
||
</view>
|
||
<view class="total">
|
||
<text>实付款</text>
|
||
<text>¥{{orderItem.totalPrice}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="order-details">
|
||
<view class="detail">
|
||
<text>备注</text>
|
||
<text @click="goToRemark">{{ orderItem.notes ? orderItem.notes : '去备注' }}</text>
|
||
</view>
|
||
<view class="detail">
|
||
<text>手机号</text>
|
||
<text>{{orderItem.phone}}</text>
|
||
</view>
|
||
<view class="detail">
|
||
<text>发票信息</text>
|
||
<text>暂不支持</text>
|
||
</view>
|
||
<view class="detail">
|
||
<text>订单号码</text>
|
||
<text>{{orderItem.pickupCode}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
onMounted,
|
||
onActivated,
|
||
ref
|
||
} from 'vue'
|
||
import DistributionBox from './distributionBox.vue';
|
||
import {
|
||
apiImageUrl
|
||
} from '../../API/api'
|
||
import {
|
||
onLoad,
|
||
onUnload
|
||
} from '@dcloudio/uni-app';
|
||
|
||
onUnload(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
});
|
||
});
|
||
|
||
const radio1 = ref(0);
|
||
const statusId = ref(null);
|
||
const array = ref(['1公寓', '2公寓', '3公寓', '4公寓', '5公寓', '6公寓', '7公寓', '8公寓', '9公寓', '10公寓', '11公寓', '12公寓', '育才大厦']);
|
||
const index = ref(0);
|
||
const sex = ref([{
|
||
text: '堂食',
|
||
value: 0
|
||
},
|
||
{
|
||
text: '自提',
|
||
value: 1
|
||
},
|
||
{
|
||
text: '跑腿',
|
||
value: 2
|
||
}
|
||
]);
|
||
|
||
function bindPickerChange(e) {
|
||
const selectedIndex = e.detail.value;
|
||
console.log('picker发送选择改变,携带值为', selectedIndex);
|
||
index.value = selectedIndex;
|
||
const selectedApartment = array.value[selectedIndex];
|
||
console.log('您选择了:', selectedApartment);
|
||
selectedApartmentName.value = selectedApartment; // 存储所选公寓名称
|
||
}
|
||
const selectedApartmentName = ref('');
|
||
uni.$on('updateRemark', (newRemark) => {
|
||
orderItem.value.notes = newRemark;
|
||
});
|
||
|
||
const orderItem = ref(null);
|
||
const getOrder = () => {
|
||
const notPay = uni.getStorageSync("notPay")
|
||
uni.request({
|
||
url: apiImageUrl + '/api/orders/get/my',
|
||
method: 'GET',
|
||
data: {
|
||
id: notPay
|
||
//id:133
|
||
},
|
||
header: {
|
||
'Content-Type': 'application/json', // 确保设置正确的 Content-Type
|
||
'cookie': uni.getStorageSync("cookie") || ''
|
||
},
|
||
success(res) {
|
||
console.log("获取订单成功");
|
||
if (res.data && res.data.data) {
|
||
// 更新响应式变量
|
||
orderItem.value = res.data.data;
|
||
console.log(orderItem.value);
|
||
// 根据 orderItem.pickupMethod 设置 radio1 的值
|
||
if (orderItem.value.pickupMethod !== undefined) {
|
||
radio1.value = orderItem.value.pickupMethod;
|
||
}
|
||
}
|
||
},
|
||
fail() {
|
||
console.log("获取订单失败");
|
||
}
|
||
})
|
||
|
||
}
|
||
|
||
const isoStart = ref('');
|
||
const isoEnd = ref('');
|
||
|
||
const submitOrder = () => {
|
||
console.log("我选择的radio1的值:", radio1.value,
|
||
"我选择的公寓:", selectedApartmentName.value,
|
||
"我选择的时间:", sendTime.value);
|
||
|
||
const notPay = uni.getStorageSync("notPay");
|
||
|
||
uni.request({
|
||
url: `${apiImageUrl}/api/orders/updateOrder`,
|
||
method: 'POST',
|
||
data: {
|
||
location: selectedApartmentName.value,
|
||
notes: orderItem.value?.notes || "", // 使用订单中的备注,如果不存在则为空字符串
|
||
orderId: notPay,
|
||
pickupMethod: radio1.value, // 使用当前选中的配送方式
|
||
pickupStartTime: isoStart.value, // 注意这里使用的是 .value
|
||
pickupEndTime: isoEnd.value, // 注意这里使用的是 .value
|
||
},
|
||
header: {
|
||
'Content-Type': 'application/json', // 确保设置正确的 Content-Type
|
||
'cookie': uni.getStorageSync("cookie") || ''
|
||
},
|
||
success(res) {
|
||
console.log("更新订单", res); // 确保这里可以打印出 res
|
||
orderItem.value.pickupMethod = radio1.value;
|
||
if(res.data.code===0){
|
||
goToPayment()
|
||
}else {
|
||
uni.showToast({
|
||
title:'支付失败'
|
||
})
|
||
}
|
||
},
|
||
fail(err) {
|
||
console.log("更新订单失败", err);
|
||
}
|
||
});
|
||
};
|
||
onMounted(() => {
|
||
getOrder();
|
||
});
|
||
|
||
onActivated(() => {
|
||
getOrder();
|
||
});
|
||
|
||
const goToPayment = () => {
|
||
const notPay = uni.getStorageSync("notPay")
|
||
my.request({
|
||
url: apiImageUrl + '/api/Alipay/payment/create',
|
||
method: 'GET',
|
||
data: {
|
||
id: notPay
|
||
},
|
||
header: {
|
||
'Content-Type': 'application/json',
|
||
'cookie': uni.getStorageSync("cookie") || ''
|
||
},
|
||
success: function(result) {
|
||
console.log("reasaaaaaaaaaa");
|
||
console.log(result);
|
||
console.log("tradeNo的值为:");
|
||
console.log(result.data.data);
|
||
my.tradePay({
|
||
tradeNO: result.data.data,
|
||
success: (res) => {
|
||
console.log('成功调用')
|
||
console.log(res);
|
||
if (res.resultCode == 9000) {
|
||
uni.setStorageSync('orderId', notPay);
|
||
uni.navigateTo({
|
||
url: '/pages/testFive/testFive'
|
||
});
|
||
uni.removeStorageSync('cartItems');
|
||
}
|
||
|
||
},
|
||
fail: (res) => {
|
||
my.alert({
|
||
content: JSON.stringify(res),
|
||
})
|
||
console.log('失败');
|
||
console.log(res);
|
||
}
|
||
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
|
||
// 时间戳
|
||
const orderCreateTime = Date.now();
|
||
const paymentTimeout = 3 * 60 * 1000; // 15分钟转换为毫秒
|
||
|
||
// 更新剩余时间的函数
|
||
const updateTimer = () => {
|
||
const elapsedTime = Date.now() - orderCreateTime;
|
||
if (elapsedTime > paymentTimeout) {
|
||
console.log('超时啦');
|
||
clearInterval(intervalId); // 清除定时器
|
||
formattedTime.value = '已超时';
|
||
} else {
|
||
const remainingTime = paymentTimeout - elapsedTime;
|
||
const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));
|
||
const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);
|
||
formattedTime.value = `待支付,${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||
}
|
||
};
|
||
|
||
const computed = {
|
||
statusId() {
|
||
// Logic to compute statusId
|
||
return someValue;
|
||
}
|
||
};
|
||
|
||
// 响应式数据
|
||
const formattedTime = ref('待支付,剩余14:48');
|
||
const intervalId = ref(null);
|
||
|
||
// 设置一个每秒更新一次的定时器
|
||
onMounted(() => {
|
||
intervalId.value = setInterval(updateTimer, 1000);
|
||
updateTimer(); // 立即执行一次以显示正确的初始时间
|
||
});
|
||
|
||
// 设置一个15分钟后触发的超时处理
|
||
setTimeout(() => {
|
||
if (!formattedTime.value.includes('已超时')) {
|
||
console.log('超时啦');
|
||
clearInterval(intervalId.value); // 清除定时器
|
||
uni.showToast({
|
||
title: '支付已超时',
|
||
duration: 2000
|
||
})
|
||
const orderItemId = orderItem.value.id
|
||
const tradeNo = uni.getStorageSync("tradeNo");
|
||
uni.request({
|
||
url: apiImageUrl + '/api/Alipay/test/close',
|
||
method: 'GET',
|
||
data: {
|
||
orderId: orderItemId,
|
||
out_trade_no: tradeNo
|
||
},
|
||
success(res) {
|
||
console.log("成功");
|
||
console.log(res);
|
||
},
|
||
fail() {
|
||
console.log("失败");
|
||
}
|
||
});
|
||
// uni.reLaunch({
|
||
// url:'/pages/index/index'
|
||
// })
|
||
uni.showToast({
|
||
title: '订单超时,已为您自动取消喽',
|
||
duration: 2000
|
||
})
|
||
formattedTime.value = '已超时';
|
||
}
|
||
}, paymentTimeout);
|
||
|
||
const closeOrder = () => {
|
||
const orderItemId = orderItem.value.id
|
||
const tradeNo = uni.getStorageSync("tradeNo");
|
||
uni.request({
|
||
url: apiImageUrl + '/api/Alipay/test/close',
|
||
method: 'GET',
|
||
data: {
|
||
orderId: orderItemId,
|
||
out_trade_no: tradeNo
|
||
},
|
||
success(res) {
|
||
console.log("成功");
|
||
console.log(res);
|
||
},
|
||
fail() {
|
||
console.log("失败");
|
||
}
|
||
});
|
||
};
|
||
|
||
const goToRemark = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/goToRemark/goToRemark'
|
||
})
|
||
}
|
||
const sendTime = ref('');
|
||
const dsbonBox = ref(null);
|
||
|
||
const showTime = () => {
|
||
if (dsbonBox.value) {
|
||
dsbonBox.value.showBox();
|
||
}
|
||
};
|
||
|
||
const handleTimeSelected = (time) => {
|
||
console.log('Selected Time:', time);
|
||
|
||
const [date, duration] = time.split(' ');
|
||
const [startHour, endHour] = duration.split('-');
|
||
|
||
// 修改:移除时区部分
|
||
isoStart.value = `${date}T${startHour}:00`; // 原格式含+08:00
|
||
isoEnd.value = `${date}T${endHour}:00`; // 现改为纯时间格式
|
||
|
||
console.log('Start Time:', isoStart.value);
|
||
console.log('End Time:', isoEnd.value);
|
||
|
||
sendTime.value = time;
|
||
};
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.order-page {
|
||
background-color: #f5f5f5;
|
||
padding: 20px;
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.back-button,
|
||
.customer-service {
|
||
width: 30px;
|
||
height: 30px;
|
||
}
|
||
|
||
.status {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.address {
|
||
width: 100%;
|
||
height: 20px;
|
||
color: #666;
|
||
padding-bottom: 10px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.notice {
|
||
height: 40px;
|
||
}
|
||
|
||
.order-summary {
|
||
background-color: #fff;
|
||
padding: 20px;
|
||
border-radius: 10px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.order-info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.time-picker {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.pay-button {
|
||
background-color: #007bff;
|
||
color: #fff;
|
||
padding: 10px 0px;
|
||
border-radius: 20px;
|
||
font-size: 18px;
|
||
text-align: center;
|
||
// ceshi
|
||
position: relative;
|
||
/* 确保按钮定位上下文 */
|
||
z-index: 1;
|
||
/* 设置较高的z-index值,确保按钮始终位于顶部 */
|
||
margin-top: 40px;
|
||
/* 如果需要,增加上边距避免与其他元素重叠 */
|
||
}
|
||
|
||
.order-options {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.option {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin: 10px;
|
||
}
|
||
|
||
.businessDetail {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 15px;
|
||
font-weight: 700;
|
||
|
||
.item-image {
|
||
width: 60rpx; /* 适当缩小店铺图标 */
|
||
height: 60rpx;
|
||
border-radius: 8px;
|
||
margin-right: 15px;
|
||
}
|
||
}
|
||
|
||
.order-items {
|
||
background-color: #fff;
|
||
padding: 20px;
|
||
border-radius: 10px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.item image {
|
||
width: 80px;
|
||
height: 80px;
|
||
margin-right: 20px;
|
||
}
|
||
|
||
|
||
.item-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.total {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.order-details {
|
||
background-color: #fff;
|
||
padding: 20px;
|
||
border-radius: 10px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.detail {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
|
||
/* */
|
||
.order-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.item-image {
|
||
width: 80px;
|
||
height: 80px;
|
||
margin-right: 20px;
|
||
}
|
||
|
||
.item-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.item-name {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.item-description {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.item-price {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
text-align: right;
|
||
}
|
||
|
||
.text {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-top: 5px;
|
||
}
|
||
|
||
.uni-px-5 {
|
||
padding-left: 10px;
|
||
padding-right: 10px;
|
||
}
|
||
|
||
.uni-pb-5 {
|
||
padding-bottom: 10px;
|
||
}
|
||
|
||
.button-update {
|
||
width: 30px;
|
||
height: 30px;
|
||
background-color: pink;
|
||
border-radius: 15px;
|
||
}
|
||
|
||
/* 时间选择器 */
|
||
.bgff {
|
||
background-color: pink;
|
||
}
|
||
|
||
.justify-between {
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.default-flex {
|
||
display: flex;
|
||
}
|
||
|
||
.align-center {
|
||
align-items: center;
|
||
}
|
||
|
||
.mr-2 {
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.secondBox {
|
||
padding: 30rpx 0rpx 0rpx 0rpx;
|
||
|
||
.lImg {
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
}
|
||
|
||
.bj {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
}
|
||
|
||
.tDesc {
|
||
font-size: 28rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
color: #666;
|
||
|
||
.sTime {
|
||
margin-right: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
</style> |