xiaokuaisong-xiaochengxu/uniapp04/pages/goToPay/goToPay.vue
2025-04-11 14:42:29 +08:00

638 lines
14 KiB
Vue
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="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>