zhwl-miniapp/pages/my/refund.vue

545 lines
19 KiB
Vue
Raw Permalink Normal View History

2025-06-26 12:38:35 +08:00
<template>
<view class="uni-container">
<u-navbar :autoBack="true" left-icon-color="#fff" :placeholder="true" bgColor="#03AE80">
<view slot='center' style="font-size: 36rpx; font-weight: 500; color: #fff;">申请退款</view>
</u-navbar>
<view class="banner"></view>
<view class="waper_box" v-if="detail">
<view class="sum-box">
<view class="handle">
<view class="label">{{detail.orderItemList[0].ticketName}}</view>
<view class="price"><text class="unit"></text>{{detail.orderItemList[0].totalPrice}}</view>
</view>
<view class="box">
<view class="validity-box">
<view class="validity" v-if="detail.orderItemList[0].ticketOrderDetailList.length">有效期
<text v-if="detail.orderItemList[0].ticketValidityPeriod == '1'">
<text class="date">{{detail.orderItemList[0].ticketOrderDetailList[0].availableEndTime.split(" ")[0]}}</text>当天有效
</text>
<text v-if="detail.orderItemList[0].ticketValidityPeriod == '2'">
<text class="date">{{detail.orderItemList[0].ticketOrderDetailList[0].availableEndTime.split(" ")[0]}}</text>之前有效
</text>
<text v-if="detail.orderItemList[0].ticketValidityPeriod == '3'">
<text class="date">{{detail.orderItemList[0].validityStartTime}}</text>
<text class="date">{{detail.orderItemList[0].validityEndTime}}</text>有效
</text>
<text v-if="detail.orderItemList[0].ticketValidityPeriod == '4'">
激活后<text class="date">{{detail.orderItemList[0].buyPeriodDay}}</text>天有效
</text>
</view>
</view>
</view>
<view class="time">订单数量{{detail.orderItemList[0].ticketOrderDetailList[0].ticketPrice}} x{{detail.orderItemList[0].ticketOrderDetailList.length}}</view>
</view>
<view class="refundNum">
<view class="row">
<view class="label1">可退款数量</view>
<view class="num">{{ticketOrderDetailList.length}}</view>
</view>
<view class="row row1" v-if="detail.orderItemList[0].qrcodeRule == 2">
<view class="label2">退款数量</view>
<u-number-box :min="1" :max="ticketOrderDetailList.length" :step="1" v-model="buyNum" @change="buyNumChange"></u-number-box>
</view>
</view>
<view class="tourist-box" v-if="detail.orderItemList[0].qrcodeRule == 1">
<view class="label">可退游客</view>
<u-checkbox-group
v-model="touristChecked"
iconPlacement="right"
placement="row"
@change="checkboxChange1">
<u-checkbox activeColor="#01be69" :label="item.userName + ' ' + item.identityCard" :name="item.id" v-for="(item, index) in ticketOrderDetailList" :key="index"></u-checkbox>
</u-checkbox-group>
</view>
<view class="price-box">
<view class="box1">
<view class="label">可退金额</view>
<view class="price"><text class="unit"></text>{{refundAmount.toFixed(2)}}</view>
</view>
<view class="box1">
<view class="label1">手续费</view>
<view class="price1">{{serviceCharge}}</view>
</view>
</view>
<view class="tourist-box">
<view class="label">个人原因</view>
<u-checkbox-group
v-model="personChecked"
iconPlacement="right"
placement="row"
@change="checkboxChange2">
<u-checkbox activeColor="#01be69" :label="item.dictLabel" :name="item.dictValue" v-for="(item, index) in personalRefundList" :key="index"></u-checkbox>
</u-checkbox-group>
</view>
<view class="tourist-box">
<view class="label">商家/景区原因</view>
<u-checkbox-group
v-model="merchantChecked"
iconPlacement="right"
placement="row"
@change="checkboxChange3">
<u-checkbox activeColor="#01be69" :label="item.dictLabel" :name="item.dictValue" v-for="(item, index) in businessRefundList" :key="index"></u-checkbox>
</u-checkbox-group>
</view>
<view class="bottom" :style="'padding-bottom: ' + safeAreaBottom + 'px'">
<view class="bottom_waper">
<view class="active" @click="goRefund">申请退款</view>
</view>
</view>
</view>
<uni-popup class="popupRefund" ref="popup" background-color="#fff">
<view class="popup-content">
<image class="bgImg" src="https://common/refundPopup.png" mode=""></image>
<view class="con">
<view class="title">温馨提示</view>
<view class="text">一旦提交将无法撤销确定退款吗</view>
<view class="btn-box">
<view class="close" @click="close">取消</view>
<view class="save" @click="onRefund">确认</view>
</view>
</view>
</view>
</uni-popup>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
export default {
data() {
return {
id: '',
windowBottom: 0,
safeAreaBottom: 0,
bgColor: '#FBFBFB',
detail: null,
buyNum: 1,
refundAmount: 0,
serviceCharge: 0,
ticketOrderDetailList: [],
touristChecked: [],
personalRefundList: [],
personChecked: [],
businessRefundList: [],
merchantChecked: [],
};
},
onLoad(options) {
this.id = options.id
this.windowBottom = this.$safeAreaBottom + uni.upx2px(152);
this.safeAreaBottom = this.$safeAreaBottom || uni.upx2px(10);
this.getData()
this.commonSj()
this.commonGr()
},
methods: {
async getData() {
let info = await this.$http.getTicketOrderDetailPrepay(this.id);
this.detail = info.data;
let list = []
info.data.orderItemList[0].ticketOrderDetailList.forEach((item) => {
// 判断是否可退款
if (this.detail.orderItemList[0].refundRule != '0' && item.paymentType == '200' && item.verificationType == '0' && (item.refundStatus == '0' || item.refundStatus == '100')) {
let creaetd = parseInt(new Date(this.$utils.formatDate('Y-M-D', item.paymentTime) + ' 00:00:00').getTime() / 1000);
if (this.detail.orderItemList[0].classify == '1') {// 普通票
// 判断是否再有效期
switch (this.detail.orderItemList[0].refundRule) {
case '3':// 有效期可退
// let startTime = parseInt(new Date(this.$utils.formatDate('Y-M-D', this.detail.orderItemList[0].ticketOrderDetailList[0].availableStartTime) + ' 00:00:00').getTime() / 1000);
let endTime = parseInt(new Date(this.$utils.formatDate('Y-M-D', this.detail.orderItemList[0].ticketOrderDetailList[0].availableEndTime) + ' 23:59:59').getTime() / 1000);
let nowtime = parseInt(new Date().getTime() / 1000);
// 当前日期大于等于开始时间并且当前日期小于等于结束时间,门票可退
if (nowtime <= endTime) list.push(item);
break;
case '4':// 几天内可退
let nowdate = parseInt(new Date().getTime() / 1000);
// 当前时间减下单时间如果小于等于后台设定天数。门票可退
if (((nowdate - creaetd) / 60 / 60 / 24) <= this.detail.orderItemList[0].refundDay) list.push(item);
break;
}
} else if (this.detail.orderItemList[0].classify == '2') {// 套票
let num = 0;// 大于0代表已经使用过
// 判断是否再有效期
switch (this.detail.orderItemList[0].refundRule) {
case '3':// 有效期可退
item.orderDetailChildList.forEach((child, childIndex) => {
if (child.verificationNum > 0) num ++;
})
if (num == 0) {
// let startTime = parseInt(new Date(this.$utils.formatDate('Y-M-D', this.detail.orderItemList[0].ticketOrderDetailList[0].availableStartTime) + ' 00:00:00').getTime() / 1000);
let endTime = parseInt(new Date(this.$utils.formatDate('Y-M-D', this.detail.orderItemList[0].ticketOrderDetailList[0].availableEndTime) + ' 23:59:59').getTime() / 1000);
let nowtime = parseInt(new Date().getTime() / 1000);
// 当前日期大于等于开始时间并且当前日期小于等于结束时间,门票可退
if (nowtime <= endTime) list.push(item);
}
break;
case '4':// 几天内可退
item.orderDetailChildList.forEach((child, childIndex) => {
if (child.verificationNum > 0) num ++;
})
if (num == 0) {
let nowdate = parseInt(new Date().getTime() / 1000);
// 当前时间减下单时间如果小于等于后台设定天数。门票可退
if (((nowdate - creaetd) / 60 / 60 / 24) <= this.detail.orderItemList[0].refundDay) list.push(item);
}
break;
}
} else if (this.detail.orderItemList[0].classify == '4' || this.detail.orderItemList[0].classify == '5') {// 年卡
if (item.activationStatus == 0) list.push(item);
}
}
})
if (!list.length) {
uni.showToast({ title: '当前没有可退门票', icon: 'none', mask: true })
setTimeout(() => {
uni.navigateBack()
}, 1500)
return false;
}
this.ticketOrderDetailList = list
if (this.ticketOrderDetailList.length === 1 && !this.touristChecked.length) {
this.touristChecked = [this.ticketOrderDetailList[0].id]
}
this.calculateFee()
console.log('可退门票:')
console.log(list)
},
async commonSj() {
const params = { dictType: 'business_refund_type' }
let info = await this.$http.common(params)
if (info.code === 200) {
this.businessRefundList = info.data
} else {
uni.$u.toast(info.msg);
}
},
async commonGr() {
const params = { dictType: 'personal_refund_type' }
let info = await this.$http.common(params)
this.personalRefundList = info.data
},
async calculateFee() {
let num = 0;
if (this.detail.orderItemList[0].qrcodeRule == 1) {
num = this.touristChecked.length
} else {
num = this.buyNum
}
if (this.detail.orderItemList[0].isFee == 1) {
let availableEndTime = this.detail.orderItemList[0].ticketOrderDetailList[0].availableEndTime + ' 23:59:59';
const params = {
orderItemId: this.detail.orderItemList[0].id,
sale: this.detail.orderItemList[0].ticketOrderDetailList[0].ticketPrice,
availableEndTime: availableEndTime,
num: num
}
let info = await this.$http.calculateFee(params)
if (info.code === 200) {
this.serviceCharge = info.data
this.refundAmount = params.num * this.detail.orderItemList[0].ticketOrderDetailList[0].ticketPrice - this.serviceCharge;
} else {
uni.$u.toast(info.msg);
}
} else {
this.refundAmount = num * this.detail.orderItemList[0].ticketOrderDetailList[0].ticketPrice;
}
},
buyNumChange (e) {
this.buyNum = e.value;
this.calculateFee();
},
checkboxChange1(n) {
this.touristChecked = n
this.calculateFee()
},
checkboxChange2(n) {
this.personChecked = n
},
checkboxChange3(n) {
this.merchantChecked = n
},
goRefund() {
if (this.detail.orderItemList[0].qrcodeRule == 1) {
if (!this.touristChecked.length) {
uni.showToast({ mask: true, title: '请选择游客', icon: 'none' });
return false;
}
} else {
if (!this.buyNum) {
uni.showToast({ mask: true, title: '请选择退款数量', icon: 'none' });
return false;
}
}
if (!this.personChecked.length && !this.merchantChecked.length) {
uni.showToast({ mask: true, title: '请选择退款原因', icon: 'none' });
return false;
}
this.$refs.popup.open('center')
},
close() {
this.$refs.popup.close()
},
async onRefund() {
let data = {
orderId: this.detail.id,
totalPrice: this.refundAmount,
userId: this.detail.userId,
userName: this.detail.userName,
personalRefundType: '',
businessRefundType: '',
orderItemList: [{
orderItemId: this.detail.orderItemList[0].id,
ticketOrderDetailList: []
}]
};
if (this.personChecked.length) data.personalRefundType = this.personChecked.join(',');
if (this.merchantChecked.length) data.businessRefundType = this.merchantChecked.join(',');
if (this.detail.orderItemList[0].qrcodeRule == '2') {
data.refundQuantity = this.buyNum;
data.orderItemList[0].refundQuantity = this.buyNum;
this.detail.orderItemList[0].ticketOrderDetailList.forEach(e => {
if (data.orderItemList[0].ticketOrderDetailList.length < this.buyNum) {
if (e.refundStatus == '0' || e.refundStatus == '100') {
data.orderItemList[0].ticketOrderDetailList.push({ orderDetailId: e.id })
}
}
})
} else {
data.refundQuantity = this.touristChecked.length;
data.orderItemList[0].refundQuantity = this.touristChecked.length;
this.touristChecked.forEach(e => {
data.orderItemList[0].ticketOrderDetailList.push({ orderDetailId: e })
})
}
let info = await this.$http.toRefund(data)
if (info.code === 200) {
this.close()
uni.showToast({ title: '提交成功', mask: true, icon: 'success' });
let pages = getCurrentPages();
let prevPage = pages[pages.length - 2];
setTimeout(() => {
uni.navigateBack()
prevPage.onLoad(prevPage.options);
}, 1500)
} else uni.showToast({ title: info.msg, mask: true, icon: 'none' });
},
}
}
</script>
<style lang="scss" scoped>
.uni-container {
width: 100%;
min-height: 100vh;
box-sizing: border-box;
background: #FBFBFB;
padding-bottom: 200rpx;
.banner{ width: 100%; height: 320rpx; background: #03AE80; position: absolute; left: 0; top: 0; }
.waper_box {
width: 100%; box-sizing: border-box; padding: 32rpx; position: relative; z-index: 3;
}
.sum-box {
padding: 32rpx 24rpx;
background: #FFFFFF;
border-radius: 10rpx;
.handle {
min-height: 54rpx; box-sizing: border-box; padding-right: 180rpx; position: relative;
.label {
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 54rpx;
}
.price {
position: absolute; right: 0; top: 0;
font-weight: bold;
font-size: 42rpx;
color: #FF5833;
.unit {
font-weight: 400;
font-size: 24rpx;
color: #FF5833;
}
}
}
.box {
margin-top: 35rpx;
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
.validity-box {
min-width: 400rpx;
.validity {
font-weight: 400;
font-size: 28rpx;
color: #666666;
.date {
color: #01BE69;
}
}
}
.num {
font-weight: 400;
font-size: 28rpx;
color: #999999;
text:first-child {
margin-right: 10rpx;
}
}
}
.time {
margin-top: 12rpx;
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
}
.refundNum {
margin-top: 19rpx;
padding: 32rpx 24rpx;
background: #FFFFFF;
border-radius: 10rpx;
.row {
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
.label1 {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.num {
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
.label2 {
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
/deep/.u-number-box{
width: 198rpx; height: 100%; border-radius: 50rpx; box-sizing: border-box; border: 2rpx solid #E1E1E1;
.u-number-box__input{ width: 66rpx; margin: 0; background: transparent !important; border: 2rpx solid #E1E1E1; box-sizing: border-box; border-top: 0; border-bottom: 0; }
.u-number-box__minus, .u-number-box__plus{
background: transparent !important; width: 64rpx; height: 100% !important; padding: 0 !important;
.u-icon__icon{ font-size: 20rpx !important; color: #01BE69 !important; }
}
.u-number-box__minus--disabled .u-icon__icon{ color: #c8c9cc !important; }
}
}
.row1 {
margin-top: 32rpx;
}
}
.tourist-box {
margin-top: 24rpx;
padding: 32rpx 24rpx;
background: #FFFFFF;
border-radius: 10rpx;
.label {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.tourist-item {
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
margin-top: 30rpx;
&:first-child {
margin-top: 32rpx;
}
.name {
font-weight: 400;
font-size: 28rpx;
color: #666666;
}
}
/deep/.u-checkbox-group {
width: 100%;
flex-direction: column !important;
.u-checkbox {
width: 100%;
margin-top: 30rpx;
&:first-child {
margin-top: 32rpx;
}
.u-checkbox__icon-wrap + text {
font-weight: 400;
font-size: 28rpx !important;
color: #666666 !important;
}
}
}
}
.price-box {
margin-top: 24rpx;
padding: 32rpx 24rpx;
background: #FFFFFF;
border-radius: 10rpx;
.box1 {
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
&:last-child {
margin-top: 32rpx;
}
.label {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.price {
font-weight: bold;
font-size: 42rpx;
color: #FF5833;
.unit {
font-weight: 400;
font-size: 24rpx;
color: #FF5833;
}
}
.label1, .price1 {
font-weight: 500;
font-size: 28rpx;
color: #999999;
}
}
}
.bottom{
width: 100%;
position: fixed;
left: 0;
bottom: 0;
background: #FBFBFB;
.bottom_waper{
width: 100%;
box-sizing: border-box;
padding: 10rpx 32rpx 0;
.active {
width: 686rpx;
height: 100rpx;
line-height: 100rpx;
border-radius: 64rpx;
box-sizing: border-box;
text-align: center;
background: #03AE80;
font-weight: 400;
font-size: 42rpx;
color: #FFFFFF;
}
}
}
.popupRefund {
.btn-box {
margin-top: 63rpx;
}
}
}
</style>