From d9b53b20bbfde4824321cdfe5f35cc15777ba1ae Mon Sep 17 00:00:00 2001 From: chen-xin-zhi <3588068430@qq.com> Date: Fri, 28 Feb 2025 12:03:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E7=9C=9F=E4=BA=A7=E5=93=81=E5=B7=B2?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/book/component/bookingSelected.vue | 21 +- pages/book/component/cancelOrder.vue | 33 +- pages/book/component/confirmBookingInfo.vue | 101 ++++- pages/book/component/deleteOrder.vue | 98 +++++ .../photoProductDetail/photoProductDetail.vue | 26 +- pages/book/photoProducts/photoProducts.vue | 4 +- .../photoProductsOrder/photoProductsOrder.vue | 94 ++++- .../photoProductsOrderDetail.vue | 350 ++++++++++++++---- pages/home/home.vue | 2 +- pages/mine/main/main.vue | 17 +- 10 files changed, 652 insertions(+), 94 deletions(-) create mode 100644 pages/book/component/deleteOrder.vue diff --git a/pages/book/component/bookingSelected.vue b/pages/book/component/bookingSelected.vue index 1aa00ea..0f0b497 100644 --- a/pages/book/component/bookingSelected.vue +++ b/pages/book/component/bookingSelected.vue @@ -11,7 +11,7 @@ </view> <image class="self-start image_2" - src="https://ide.code.fun/api/image?token=67be7f674ae84d0012275313&name=eb8ebca982e7a2e39bcab657cf891791.png" + :src="obj.introImg" /> <text class="self-start font text_2">拍摄人数</text> </view> @@ -75,7 +75,7 @@ <text class="font_3">说明</text> </view> <text class="font text_7">定金:</text> - <text class="font text_8">¥129.00</text> + <text class="font text_8">¥{{ totalPrice.toFixed(2) }}</text> </view> <view @click="jumpToOrder" class="flex-col justify-start items-center text-wrapper_2"> <text class="text_9">确定</text></view> @@ -96,6 +96,8 @@ const number = ref(1) const field = ref('室内') const feeTips = ref(null) + const obj = ref('') + const totalPrice = ref(0) onMounted(() => { emitter.on('closeFeeTips', () => { @@ -105,19 +107,30 @@ } }) }) + + emitter.on('getProductObj', (val:any) => { + obj.value = val + totalPrice.value = val.price + console.log(totalPrice.value) + }) }) const sub = () => { if (number.value > 1) { number.value -- + totalPrice.value = number.value * obj.value.price } } const add = () => { - number.value ++ + if (number.value < obj.value.maxNumber) { + number.value ++ + totalPrice.value = number.value * obj.value.price + } } const handlerRadioChange = (e:any) => { field.value = e.detail.value + console.log(field.value) } const closePopup = () => { @@ -130,7 +143,7 @@ const jumpToOrder = () => { uni.navigateTo({ - url: '/pages/book/photoProductsOrder/photoProductsOrder' + url: '/pages/book/photoProductsOrder/photoProductsOrder?field=' + field.value + '&number=' + number.value + '&id=' + obj.value.id }) } diff --git a/pages/book/component/cancelOrder.vue b/pages/book/component/cancelOrder.vue index 8912d9d..11ea614 100644 --- a/pages/book/component/cancelOrder.vue +++ b/pages/book/component/cancelOrder.vue @@ -3,16 +3,47 @@ <text class="self-center text">确认取消该订单?</text> <view class="flex-row justify-between self-stretch mt-33"> <view class="flex-col justify-start items-center text-wrapper" @click="cancel"><text class="font text_2">取消</text></view> - <view class="flex-col justify-start items-center text-wrapper_2" @click="cancel"><text class="font text_3">确定</text></view> + <view class="flex-col justify-start items-center text-wrapper_2" @click="confirm"><text class="font text_3">确定</text></view> </view> </view> </template> <script setup lang="ts"> +import { onMounted, ref } from 'vue'; import emitter from '../../../utils/emitter'; +import { baseUrl } from '../../../api/request'; + + const oid = ref(0) + const cookie = wx.getStorageSync("cookie") //请求头 + onMounted(() => { + emitter.on('sendBookingOrderId', (orderId:any) => { + oid.value = orderId + console.log(oid.value) + }) + }) + + const cancelBookingOrder = async () => { + const res = await uni.request({ + url: baseUrl + '/advanceOrder/cancel/id', + method: 'POST', + header: { + cookie + }, + data: { + id: oid.value + } + }) + console.log(res.data.data) + } const cancel = () => { emitter.emit('closeCancelOrderPopup') } + + const confirm = async () => { + await cancelBookingOrder() + emitter.emit('closeCancelOrderPopup') + emitter.emit('flushAdvanceOrderList') + } </script> <style scoped lang="scss"> diff --git a/pages/book/component/confirmBookingInfo.vue b/pages/book/component/confirmBookingInfo.vue index 5469034..10c132c 100644 --- a/pages/book/component/confirmBookingInfo.vue +++ b/pages/book/component/confirmBookingInfo.vue @@ -1,10 +1,10 @@ <template> <view class="flex-col page"> <text class="self-center text">请确认您的预约信息</text> - <text class="self-start font text_2">写真产品:汉服—曲裾系列</text> - <text class="self-start font text_3">拍摄时间:2025-05-01 16:00</text> - <text class="self-start font text_4">拍摄人数:3人</text> - <text class="self-start font text_5">拍摄场地:室外</text> + <text class="self-start font text_2">写真产品:{{ orderObj.name }}</text> + <text class="self-start font text_3">拍摄时间:{{ orderObj.bookingDate }} {{ orderObj.bookingTime }}</text> + <text class="self-start font text_4">拍摄人数:{{ orderObj.number }}人</text> + <text class="self-start font text_5">拍摄场地:{{ orderObj.field }}</text> <view @click="closeConfirmBookingPopup" class="flex-col justify-start items-center self-stretch text-wrapper"> <text class="font text_6">确定</text> </view> @@ -14,15 +14,100 @@ <script setup lang="ts"> import { onMounted, ref } from 'vue'; import emitter from '../../../utils/emitter'; +import { baseUrl } from '../../../api/request'; +const cookie = wx.getStorageSync("cookie") //请求头 - - + const orderObj = ref({}) + const isIndoors = ref(0) onMounted(() => { - + emitter.on('getBookingOrderData', (val:any) => { + orderObj.value = val + console.log(val) + }) }) - const closeConfirmBookingPopup = () => { + const closeConfirmBookingPopup = async () => { emitter.emit('closeConfirmBookingInfo') + emitter.emit('openMask') + await createOrder() + } + + + const createOrder = async () => { + if (orderObj.value.field === '室内') { + isIndoors.value = 1 + } + const res = await uni.request({ + url: baseUrl + '/advanceOrder/add', + method: 'POST', + header: { + cookie + }, + data: { + photoProductId: orderObj.value.id, + contactsId: orderObj.value.contactId, + specificDate: orderObj.value.bookingDate, + timePoint: orderObj.value.bookingTime, + isIndoors: isIndoors.value, + isMakeup: 1, + isPhotography: 1, + quantity: orderObj.value.number + } + }) + console.log('订单id==========================>', res.data.data) + if (res.data.code === 1) { + wxPay(res.data.data) + } + + } + + + const wxPay = async ( oid )=> { //传入订单id + try { + const res = await uni.request({ + url: baseUrl + '/wechat/payment/photo/create', + method: 'POST', + header: { + 'cookie': wx.getStorageSync("cookie") + }, + data: { id: oid } + }) + const paymentData = res.data.data + wx.requestPayment({ + appid: paymentData.appId, + nonceStr: paymentData.nonceStr, + package: paymentData.packageVal, + paySign: paymentData.paySign, + timeStamp: paymentData.timeStamp, + signType: paymentData.signType, + success(res) { + uni.showModal({ + content: '支付成功', + showCancel: false + }) + console.log('支付成功res--->',res); + }, + fail(e) { + uni.showModal({ + content: '支付失败,原因为:' + e.errMsg, + showCancel: false + }) + console.log('e.errMsg--->',e.errMsg); + }, + complete() { + uni.redirectTo({ + url: '/pages/book/photoProductsOrderDetail/photoProductsOrderDetail' + }) + } + }) + + }catch(error) { + console.error('支付请求失败',error); + uni.showModal({ + content: '支付请求失败,请重试', + showCancel: false + }) + } } </script> diff --git a/pages/book/component/deleteOrder.vue b/pages/book/component/deleteOrder.vue new file mode 100644 index 0000000..eb87c23 --- /dev/null +++ b/pages/book/component/deleteOrder.vue @@ -0,0 +1,98 @@ +<template> + <view class="flex-col page"> + <text class="self-center text">确认删除该订单?</text> + <view class="flex-row justify-between self-stretch mt-33"> + <view class="flex-col justify-start items-center text-wrapper" @click="cancel"><text class="font text_2">取消</text></view> + <view class="flex-col justify-start items-center text-wrapper_2" @click="confirm"><text class="font text_3">确定</text></view> + </view> + </view> +</template> + +<script setup lang="ts"> +import { onMounted, ref } from 'vue'; +import emitter from '../../../utils/emitter'; +import { baseUrl } from '../../../api/request'; + + const oid = ref(0) + const cookie = wx.getStorageSync("cookie") //请求头 + onMounted(() => { + emitter.on('sendDeleteOrderId', (orderId:any) => { + oid.value = orderId + console.log(oid.value) + }) + }) + + const deleteBookingOrder = async () => { + const res = await uni.request({ + url: baseUrl + '/advanceOrder/delete', + method: 'POST', + header: { + cookie + }, + data: { + id: oid.value + } + }) + console.log(res.data.data) + } + const cancel = () => { + emitter.emit('closeDeleteOrderPopup') + } + + const confirm = async () => { + await deleteBookingOrder() + emitter.emit('closeDeleteOrderPopup') + emitter.emit('flushAdvanceOrderList') + } +</script> + +<style scoped lang="scss"> + .mt-33 { + margin-top: 77.59rpx; + } + .page { + padding: 65.83rpx 73.45rpx 58.78rpx; + background-color: #ffffff; + border-radius: 25.02rpx; + width: 100%; + overflow-y: auto; + overflow-x: hidden; + height: 100%; + } + .text { + color: #000000; + font-size: 37.32rpx; + font-family: FZSongKeBenXiuKaiS-R-GB; + line-height: 41.66rpx; + } + .text-wrapper { + padding: 23.51rpx 0; + background-color: #d9d9d9; + border-radius: 47.02rpx; + width: 216.3rpx; + height: 84.64rpx; + margin-right: 20rpx; + } + .font { + font-size: 37.62rpx; + font-family: FZSongKeBenXiuKaiS-R-GB; + line-height: 35.41rpx; + } + .text_2 { + color: #000000; + font-size: 30rpx; + } + .text-wrapper_2 { + padding: 23.51rpx 0; + background-color: #ffb6b9; + border-radius: 47.02rpx; + width: 216.3rpx; + height: 84.64rpx; + margin-left: 20rpx; + } + .text_3 { + color: #ffffff; + font-size: 30rpx; + } + @import url(../../../common/css/global.css); +</style> \ No newline at end of file diff --git a/pages/book/photoProductDetail/photoProductDetail.vue b/pages/book/photoProductDetail/photoProductDetail.vue index ae1f27a..ea599e3 100644 --- a/pages/book/photoProductDetail/photoProductDetail.vue +++ b/pages/book/photoProductDetail/photoProductDetail.vue @@ -63,13 +63,18 @@ import {nextTick, onMounted, ref} from 'vue' import emitter from "../../../utils/emitter"; import bookingSelectedVue from "../component/bookingSelected.vue"; - const obj = ref({}) + import { baseUrl } from "../../../api/request"; + const cookie = wx.getStorageSync("cookie") //请求头 + const id = ref({}) const bookingSelected = ref(null) + const obj = ref({}) onLoad((options) => { console.log(options) - obj.value = JSON.parse(options.obj) + id.value = options.id + getPhotoProductsById() }) + onMounted(() => { emitter.on('closeBookingPopup', () => { nextTick(() => { @@ -81,7 +86,24 @@ }) + const getPhotoProductsById = async () => { + const res = await uni.request({ + url: baseUrl + '/photoProducts/list/detail', + method: 'POST', + header: { + cookie + }, + data: { + id: id.value + } + }) + console.log(res.data.data) + obj.value = res.data.data + } + + const openBookingPopup = () => { + emitter.emit('getProductObj', obj.value) bookingSelected.value.open('bottom') } diff --git a/pages/book/photoProducts/photoProducts.vue b/pages/book/photoProducts/photoProducts.vue index 84add1f..56614e5 100644 --- a/pages/book/photoProducts/photoProducts.vue +++ b/pages/book/photoProducts/photoProducts.vue @@ -38,7 +38,7 @@ </view> <text class="font_2 text pos_3">{{ categoryName }}</text> <view class="flex-col group pos_4"> - <view class="flex-row justify-between relative list-item_2 mt-13" @click="jumpToDetail(item)" + <view class="flex-row justify-between relative list-item_2 mt-13" @click="jumpToDetail(item.id)" v-for="(item, index) in photoProducts" :key="index"> <view class="flex-row self-center"> <image @@ -122,7 +122,7 @@ const jumpToDetail = (val:any) => { uni.navigateTo({ - url: '../photoProductDetail/photoProductDetail?obj=' + JSON.stringify(val) + url: '../photoProductDetail/photoProductDetail?id=' + val }) } diff --git a/pages/book/photoProductsOrder/photoProductsOrder.vue b/pages/book/photoProductsOrder/photoProductsOrder.vue index bc5c5f2..ebff554 100644 --- a/pages/book/photoProductsOrder/photoProductsOrder.vue +++ b/pages/book/photoProductsOrder/photoProductsOrder.vue @@ -14,7 +14,7 @@ class="shrink-0 image_2" src="https://ide.code.fun/api/image?token=67be7f674ae84d0012275313&name=d756fec34c69604dfbd42c6d155690f0.png" /> - <text class="font text_3 ml-10">{{ contactInfo.name }} {{ contactInfo.phone }}</text> + <text class="font text_3 ml-10">{{ contactTemplateString }}</text> </view> <view class="flex-row items-center group"> <image @@ -59,8 +59,8 @@ /> <view class="flex-col items-start ml-11"> <text class="font_2 text_8">{{ photoProduct.name }}</text> - <text class="font_6 text_9 mt-10">拍摄人数:1人</text> - <text class="font_6 text_10 mt-10">拍摄场地:室外</text> + <text class="font_6 text_9 mt-10">拍摄人数:{{ number }}人</text> + <text class="font_6 text_10 mt-10">拍摄场地:{{ field }}</text> <text class="font_6 text_12 mt-10">预约门店:哈尔滨师范大学</text> </view> </view> @@ -75,7 +75,7 @@ <view class="flex-row justify-between items-center section_6 pos_9"> <view class="flex-row items-baseline"> <text class="font text_13">定金:</text> - <text class="font text_14">¥{{ photoProduct.price.toFixed(2) }}</text> + <text class="font text_14">¥{{ totalPrice.toFixed(2) }}</text> </view> <view class="flex-col justify-start items-center text-wrapper_2" @click="confirm"><text class="font_2 text_15">确定</text></view> </view> @@ -99,6 +99,8 @@ </view> </uni-popup> + <!-- 遮罩层 --> + <view v-if="isShow" class="overlay"></view> </template> <script setup lang="ts"> @@ -108,6 +110,8 @@ import { baseUrl } from '../../../api/request'; import contactsComponentVue from '../../order/component/contactsComponent.vue'; import confirmBookingInfoVue from '../component/confirmBookingInfo.vue'; + import { onLoad } from "@dcloudio/uni-app"; + const cookie = wx.getStorageSync("cookie") //请求头 const photoProduct = ref({}) const bookingDateVOList = ref([]) @@ -128,6 +132,34 @@ const confirmBookingInfo = ref(null) const contactInfo = ref({}) + const field = ref('') + const number = ref(0) + const id = ref(0) + const totalPrice = ref(0) + + const isShow = ref(false) + let loading = false; + + const contactTemplateString = ref('请选择') + + + function showLoading() { + if (!loading) { + wx.showLoading({ + title: '加载中...', + }); + loading = true; + } + } + + function hideLoading() { + if (loading) { + wx.hideLoading(); + loading = false; + } + } + + const openTipsPopup = () => { bookingTips.value.open('center') @@ -138,9 +170,39 @@ } const confirm = () => { + if (contactTemplateString.value === null || contactTemplateString.value === undefined || contactTemplateString.value === '请选择') { + uni.showToast({ + title: '请选择联系人', + icon: 'error' + }) + return ; + } + if (bookingTime.value === null || bookingTime.value == undefined || bookingTime.value === '请选择') { + uni.showToast({ + title: '请填写预约时间', + icon: 'error' + }) + return ; + } + emitter.emit('getBookingOrderData', { + field: field.value, + number: number.value, + id: id.value, + contactId: contactInfo.value.id, + name: photoProduct.value.name, + bookingDate: bookingDate.value, + bookingTime: bookingTime.value + }) confirmBookingInfo.value.open('center') } + onLoad((options) => { + console.log(options) + field.value = options.field + number.value = options.number + id.value = options.id + }) + onMounted(() => { getDefaultAddress() @@ -163,6 +225,7 @@ emitter.on('contactsNowInfo', (val) =>{ contactInfo.value = val + contactTemplateString.value = val.name + ' ' + val.phone console.log(val) }) @@ -174,7 +237,16 @@ }) }) + emitter.on('openMask', () => { + showLoading() + isShow.value = true + }) + // emitter.on('closeMask', () => { + // hideLoading() + // isShow.value = false + // }) + }) @@ -186,11 +258,12 @@ cookie }, data: { - id: 70 + id: id.value } }) console.log(res.data.data) photoProduct.value = res.data.data + totalPrice.value = photoProduct.value.price * number.value bookingDateVOList.value = res.data.data.bookingDateVOList timeSelectedStyle.value = new Array(bookingDateVOList.value.length).fill(null).map(() => ({ backgroundColor: '#F3F3F3', @@ -293,6 +366,7 @@ for(let key in res.data.data) { if(res.data.data[key].isDefault === 1) { contactInfo.value = res.data.data[key] + contactTemplateString.value = contactInfo.value.name + ' ' + contactInfo.value.phone } } } @@ -304,6 +378,16 @@ <style scoped lang="scss"> +.overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.4); /* 半透明黑色背景 */ + z-index: 999; +} + .confirm-book-info { justify-content: center; background-color: #fff; diff --git a/pages/book/photoProductsOrderDetail/photoProductsOrderDetail.vue b/pages/book/photoProductsOrderDetail/photoProductsOrderDetail.vue index a295181..a4af5cc 100644 --- a/pages/book/photoProductsOrderDetail/photoProductsOrderDetail.vue +++ b/pages/book/photoProductsOrderDetail/photoProductsOrderDetail.vue @@ -12,14 +12,14 @@ <view class="flex-col justify-start items-center" v-if="isShow[1]" style="border: 1.88rpx solid #E79EA1; width: 90rpx; margin-top: 5rpx;"></view> </view> <view class="flex-col justify-start" @click="changeState(2)"> - <text class="font text_3">已付款</text> + <text class="font text_3">已完成</text> <view class="flex-col justify-start items-center" v-if="isShow[2]" style="border: 1.88rpx solid #E79EA1; width: 90rpx; margin-top: 5rpx;"></view> </view> </view> <!-- <view class="flex-col justify-start items-center group_2"><view class="section_3"></view></view> --> </view> <view class="flex-col pos_2"> - <view class="flex-col mt-20 list-item" v-for="(item, index) in items" :key="index"> + <view class="flex-col mt-20 list-item" v-for="(item, index) in advanceOrderList" :key="index"> <view class="flex-col"> <view class="flex-row items-center group_3" style="display: flex; justify-content: space-between; align-items: center;"> @@ -28,23 +28,23 @@ <text class="font_2">订单号</text> <text class="font_3 text_4">:</text> </view> - <view><text class="font_4 text_5">E20241005095840091406189</text></view> + <view><text class="font_4 text_5">{{ item.orderNumber }}</text></view> </view> <view> - <text class="font_5 text_6">{{ formattedTime }}</text> - <text class="font_6 text_7">待拍摄</text> + <text v-if="item.orderStatus === '待支付'" class="font_5 text_6">{{ item.countdown }}</text> + <text class="font_6 text_7">{{ item.orderStatus }}</text> </view> </view> <view class="flex-row group_5"> <image class="image" - src="https://ide.code.fun/api/image?token=67bfb6134ae84d0012276837&name=1c1a8926b9cbd08850c51818af39ae2b.png" + :src="item.photoProductsSnapshot.introImg" /> <view class="flex-col items-start flex-1 group_6 ml-19"> - <text class="font_7 text_8">汉服—曲裾系列</text> - <text class="font_8 mt-43">¥138.00</text> + <text class="font_7 text_8">{{ item.photoProductsSnapshot.name}}</text> + <text class="font_8 mt-43">¥{{ item.totalAmount.toFixed(2) }}</text> </view> </view> </view> @@ -54,7 +54,7 @@ <view class="mt-8 flex-col self-stretch"> <text class="self-start font_7 text_10">预约门店:哈尔滨师范大学</text> <view class="flex-row justify-between items-center self-stretch group_7"> - <text class="font_7 text_11">到店时间:2025-03-10 16:00</text> + <text class="font_7 text_11">到店时间:{{ item.specificDate }} {{ item.timePoint }}</text> <image class="image_2" src="https://ide.code.fun/api/image?token=67bfb6134ae84d0012276837&name=d52c7b6dae8656c06b3be0bbcd17f959.png" @@ -62,24 +62,33 @@ /> </view> <view class="flex-row justify-between items-baseline self-stretch"> - <text class="font_9">拍摄人数:1人</text> + <text class="font_9">拍摄人数:{{ item.quantity }}人</text> <text class="font_10 text_12" @click="nav">导航</text> </view> </view> - <text class="mt-8 self-start font_7 text_13">拍摄场地:室外</text> + <text class="mt-8 self-start font_7 text_13">拍摄场地:{{ item.isIndoors == 1 ? '室内' : '室外' }}</text> </view> <view class="flex-row justify-end items-center group_8"> <text class="font_2 text_14">实付款:</text> - <text class="font_8">¥138.00</text> + <text class="font_8">¥{{ item.totalAmount.toFixed(2) }}</text> </view> <view class="flex-row justify-center group_9"> - <view class="flex-col justify-start items-center text-wrapper_2"> + + <view style="opacity: 0; border: none" v-if="item.orderStatus !== '待支付'" class="ml-10 flex-col justify-start items-center text-wrapper_2"> + </view> + <view style="opacity: 0; border: none" v-if="item.orderStatus !== '待支付'" class="ml-10 flex-col justify-start items-center text-wrapper_3"> + </view> + + <button v-if="item.orderStatus !== '交易关闭'" open-type="contact" bindcontact="handleContact" session-from="sessionFrom" class="flex-col justify-start items-center text-wrapper_2"> <text class="font_6 text_15">联系客服</text> - </view> - <view class="ml-10 flex-col justify-start items-center text-wrapper_2" @click="openCancelBookingOrderPopup"> + </button> + <view v-if="item.orderStatus === '交易关闭'" class="ml-10 flex-col justify-start items-center text-wrapper_2" @click="openDeleteBookingOrderPopup(item.id)"> + <text class="font_6">删除订单</text> + </view> + <view v-if="item.orderStatus === '待支付'" class="ml-10 flex-col justify-start items-center text-wrapper_2" @click="openCancelBookingOrderPopup(item.id)"> <text class="font_6">取消订单</text> </view> - <view class="ml-10 flex-col justify-start items-center text-wrapper_3"> + <view v-if="item.orderStatus === '待支付'" @click="wxPay(item.id)" class="ml-10 flex-col justify-start items-center text-wrapper_3"> <text class="font_11 text_16">去付款</text> </view> </view> @@ -88,27 +97,39 @@ </view> </view> - <uni-popup ref="cancelBookingOrder" :maskClick="true" :animation="false"> + <uni-popup ref="cancelBookingOrder" :maskClick="false" :animation="false"> <view class="cancel-booking-order"> <cancelOrderVue></cancelOrderVue> </view> </uni-popup> + + + <uni-popup ref="deleteBookingOrder" :maskClick="false" :animation="false"> + <view class="cancel-booking-order"> + <deleteOrderVue></deleteOrderVue> + </view> + </uni-popup> + + <!-- 遮罩层 --> + <view v-if="isShowMask" class="overlay"></view> </template> <script setup lang="ts"> - import {computed, nextTick, onMounted, onUnmounted, ref} from 'vue' + import {computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref} from 'vue' import emitter from '../../../utils/emitter'; import cancelOrderVue from '../component/cancelOrder.vue'; - const items = ref([null, null, null]) + import deleteOrderVue from '../component/deleteOrder.vue'; + import { onLoad } from "@dcloudio/uni-app"; + import { baseUrl } from '../../../api/request'; + const cookie = wx.getStorageSync("cookie") //请求头 const isShow = ref([true, false, false]) const cancelBookingOrder = ref(null) + const deleteBookingOrder = ref(null) + const advanceOrderList = ref([]) + const isShowMask = ref(false) - - - - - onMounted(() => { - startCountdown() + onMounted( async () => { + await getAdvanceOrder() emitter.on('closeCancelOrderPopup', () => { nextTick(() => { if (cancelBookingOrder.value) { @@ -116,57 +137,49 @@ } }) }) + + emitter.on('closeDeleteOrderPopup', () => { + nextTick(() => { + if (deleteBookingOrder.value) { + deleteBookingOrder.value.close() + } + }) + }) + + emitter.on('flushAdvanceOrderList', () => { + getAdvanceOrder() + }) }) - - onUnmounted(() => { - if (timer) { - clearInterval(timer) - } - }) - - let timer = null; - // 尝试从 localStorage 获取上次保存的倒计时时间 - const savedTime = wx.getStorageSync('remainingTime'); - const remainingTime = ref(savedTime ? parseInt(savedTime) : 1800); // 30分钟 (1800秒) - - // 计算分钟和秒 - const formattedTime = computed(() => { - const minutes = Math.floor(remainingTime.value / 60); - const seconds = remainingTime.value % 60; - return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`; - }); - - const startCountdown = () => { - // 每秒更新一次倒计时 - timer = setInterval(() => { - if (remainingTime.value > 0) { - remainingTime.value--; - wx.setStorageSync('remainingTime', remainingTime.value.toString()); - } else { - cancelOrder(); // 倒计时结束,取消订单 - } - }, 1000); - }; - - const cancelOrder = () => { - // 这里调用取消订单的接口 - // 假设 cancelOrderApi 是一个取消订单的请求 - console.log('订单已取消'); // 实际取消订单的代码 - wx.removeStorageSync('remainingTime'); - clearInterval(timer); // 清除定时器 - }; - - - - const openCancelBookingOrderPopup = () => { - cancelBookingOrder.value.open('center') + + const getAdvanceOrder = async () => { + const res = await uni.request({ + url: baseUrl + '/advanceOrder/list/my', + method: 'POST', + header: { + cookie + } + }) + advanceOrderList.value = res.data.data + console.log(res.data.data) + advanceOrderList.value.forEach((order) => { + startCountdown(order) + }) } + const openCancelBookingOrderPopup = (orderId:any) => { + emitter.emit('sendBookingOrderId', orderId) + cancelBookingOrder.value.open('center') + } + const openDeleteBookingOrderPopup = (orderId:any) => { + emitter.emit('sendDeleteOrderId', orderId) + deleteBookingOrder.value.open('center') + } + - const changeState = (index:any) => { + const changeState = async (index:any) => { if (!isShow.value[index]) { for (var i = 0; i < 3; i ++ ) { if (i == index) { @@ -176,6 +189,13 @@ } } } + await getAdvanceOrder() + if (index == 1) { + advanceOrderList.value = advanceOrderList.value.filter(item => item.orderStatus === '待发货') + } + if (index == 2) { + advanceOrderList.value = advanceOrderList.value.filter(item => item.orderStatus === '交易成功') + } } const nav = () => { @@ -189,10 +209,202 @@ } }) } + + + const wxPay = async ( oid )=> { //传入订单id + showLoading() + isShowMask.value = true + try { + const res = await uni.request({ + url: baseUrl + '/wechat/payment/photo/create', + method: 'POST', + header: { + 'cookie': wx.getStorageSync("cookie") + }, + data: { id: oid } + }) + const paymentData = res.data.data + wx.requestPayment({ + appid: paymentData.appId, + nonceStr: paymentData.nonceStr, + package: paymentData.packageVal, + paySign: paymentData.paySign, + timeStamp: paymentData.timeStamp, + signType: paymentData.signType, + success(res) { + uni.showModal({ + content: '支付成功', + showCancel: false + }) + console.log('支付成功res--->',res); + }, + fail(e) { + uni.showModal({ + content: '支付失败,原因为:' + e.errMsg, + showCancel: false + }) + console.log('e.errMsg--->',e.errMsg); + }, + complete() { + uni.redirectTo({ + url: '/pages/book/photoProductsOrderDetail/photoProductsOrderDetail' + }) + } + }) + + }catch(error) { + console.error('支付请求失败',error); + uni.showModal({ + content: '支付请求失败,请重试', + showCancel: false + }) + } + } + + let loading = false; + function showLoading() { + if (!loading) { + wx.showLoading({ + title: '加载中...', + }); + loading = true; + } + } + + function hideLoading() { + if (loading) { + wx.hideLoading(); + loading = false; + } + } + + + + + + + + + + + + + + + // 时间格式化函数,处理后端返回的时间 + const parseDate = (dateString) => { + const [date, time] = dateString.split(' '); + const [year, month, day] = date.split('-').map(Number); + const [hour, minute, second] = time.split(':').map(Number); + return new Date(year, month - 1, day, hour, minute, second); // JavaScript Date的月份是从0开始的 + }; + + // 给订单创建时间加上30分钟 + const add30Minutes = (createdTime) => { + const date = parseDate(createdTime); + date.setMinutes(date.getMinutes() + 31); // 加上30分钟 + return Math.floor(date.getTime() / 1000); // 返回时间戳(秒) + }; + + // 启动每个订单的倒计时(仅对待支付订单有效) + const startCountdown = (order) => { + if (order.orderStatus === '待支付') { + order.endTime = add30Minutes(order.createTime); // 设置最终取消时间 + order.countdownInterval = setInterval(() => { + const now = Math.floor(Date.now() / 1000); // 获取当前时间的时间戳(秒) + const remainingTime = order.endTime - now; + + if (remainingTime <= 0) { + order.countdown = '00:00'; + clearInterval(order.countdownInterval); // 清除定时器 + getAdvanceOrder() + uni.showModal({ + title: '提示', + content: '订单超时未支付,交易关闭', + showCancel: false + }) + + } else { + const minutes = Math.floor(remainingTime / 60); // 计算剩余分钟 + const seconds = remainingTime % 60; // 计算剩余秒数 + order.countdown = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`; + } + }, 1000); + } + }; + + // 在组件挂载时启动待支付订单的倒计时 + + + // 在组件卸载时清除所有定时器,避免内存泄漏 + onBeforeUnmount(() => { + advanceOrderList.value.forEach(order => { + if (order.countdownInterval) { + clearInterval(order.countdownInterval); + } + }); + }); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + </script> <style scoped lang="scss"> + +.overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.4); /* 半透明黑色背景 */ + z-index: 999; +} .cancel-booking-order { // height: 800rpx; margin-top: -150rpx; diff --git a/pages/home/home.vue b/pages/home/home.vue index 3afc53e..148a223 100644 --- a/pages/home/home.vue +++ b/pages/home/home.vue @@ -83,7 +83,7 @@ const getMyUser = async () =>{ } const jump_xiezhen =()=>{ //跳转写真预约 uni.navigateTo({ - url: '../../pages/booking/respectable/respectable' + url: '/pages/book/photoProducts/photoProducts' }) } const jump_feiyi =()=>{ //跳转非遗工坊 diff --git a/pages/mine/main/main.vue b/pages/mine/main/main.vue index f198c87..bd0d5be 100644 --- a/pages/mine/main/main.vue +++ b/pages/mine/main/main.vue @@ -56,7 +56,7 @@ <view class="divider pos_4"></view> </view> </view> - <view class="flex-row justify-between group_4"> + <view class="flex-row justify-between group_4" @click="jumpToBookingOrder"> <view class="flex-row items-center"> <image class="shrink-0 image_8" src="https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FOfemexvK-booking.png" /> @@ -67,7 +67,7 @@ </view> <view class="flex-col group_5"> <view class="divider view"></view> - <view class="flex-row justify-between items-center group_6"> + <view class="flex-row justify-between items-center group_6" @click="jumpToMyCoupon"> <view class="flex-row items-center"> <image class="shrink-0 image_10" src="https://carbon2.obs.cn-north-4.myhuaweicloud.com:443/feiyi%2Ftest%2F0%2FqihgypDY-coupon.png" /> @@ -126,6 +126,19 @@ const goto = (tab) => { url: '/pages/mine/mineorders/mineorders?zt='+JSON.stringify(tab) }) } + +const jumpToBookingOrder = () => { + uni.navigateTo({ + url: '/pages/book/photoProductsOrderDetail/photoProductsOrderDetail' + }) +} + +const jumpToMyCoupon = () => { + uni.navigateTo({ + url: '/pages/coupon/MyCoupon/MyCoupon' + }) +} + const getFonts = () => { //导入字体 uni.loadFontFace({ family: 'FangZhengFonts',