xiaokuaisong-xiaochengxu/uniapp04/pages/goToPay/goToPay.vue

638 lines
14 KiB
Vue
Raw Normal View History

2025-04-11 06:42:29 +00:00
<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>