cashier_app/pagesOrder/tuikuan/tuikuan.vue

347 lines
9.4 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="min-page bg-gray u-p-30">
<view class="bg-fff u-p-l-30 u-p-r-30 ">
<view class="myTabs u-m-t-20">
<my-tabs :list="pageData.tabsList" :modelValue="pageData.tabsIndex" :textKey="'label'" @change="tabsChange"></my-tabs>
</view>
</view>
<view v-if="pageData.tabsIndex == 2" class="bg-fff u-p-24 border-r-12 u-flex u-row-between" style="margin-top: 30rpx;">
<up-input type="digit" placeholder="请输入退款金额" @change="parseIntNumber($event)" border="surround" v-model="pageData.modify" >
<template #prefix>
<up-text text="¥" margin="0 3px 0 0" type="tips" ></up-text>
</template>
</up-input>
</view>
<view class="u-m-t-24 u-font-24 u-font-24">
<text class="color-red">*</text>
<text>客座费只能全退</text>
</view>
<view v-if="pageData.tabsIndex != 2" class="bg-fff border-r-12 list u-m-t-32">
<view class="u-flex u-row-between border-top item u-p-t-32 u-p-b-32"
v-for="(item,index) in orderDetail.goodsList" :key="index">
<view>
<view>{{item.productName}}</view>
<view class="u-m-t-10 color-999 u-font-24">{{item.skuName||""}}</view>
<view class="u-m-t-10 color-999 u-font-24">最多可退×{{item.num}}</view>
</view>
<template v-if="item.productId=='-999'">
<view class="u-flex">
<view class="color-red" >¥{{item.priceAmount}}</view>
<view class="u-flex u-m-l-32 u-col-center">
<view class="u-m-l-28 u-m-r-28">x{{item.number}}</view>
</view>
</view>
</template>
<template v-else>
<view class="u-flex">
<view class="color-red" v-if="!item.userCouponId">¥{{item.priceAmount}}</view>
<view class="u-flex u-m-l-32 u-col-center">
<up-icon @click="changeItem(item,-1)" :size="20" name="minus-circle"></up-icon>
<view class="u-m-l-28 u-m-r-28">{{item.number}}</view>
<up-icon @click="changeItem(item,1)" :color="$utils.ColorMain" :size="20"
name="plus-circle-fill"></up-icon>
</view>
</view>
</template>
</view>
</view>
<template v-if="!option.userCouponId">
<view class="bg-fff u-m-t-32 u-p-24 border-r-12 u-flex u-row-between" >
<view>支付金额</view>
<view>
{{to2(orderDetail.info.payAmount)}}元
</view>
</view>
<view class="bg-fff u-m-t-32 u-p-24 border-r-12 u-flex u-row-between" >
<view>剩余可退金额</view>
<view class="color-red">
{{to2(orderDetail.info.payAmount - orderDetail.info.refundAmount)}}元
</view>
</view>
<view class="bg-fff u-m-t-32 u-p-24 border-r-12 u-flex u-row-between" >
<view>退款金额</view>
<view class="color-red">
{{to2(pageData.tabsIndex == 1 ? alltuikuanPrice : (pageData.tabsIndex == 2 ? pageData.modify : tuikuanPrice))}}元
</view>
</view>
</template>
<!-- <view class="bg-fff u-p-24 border-r-12 u-m-t-32">
<view>退回优惠券</view>
<view class="u-font-24 color-999 u-m-t-16" v-if="!option.userCouponId">
该订单未使用优惠券
</view>
</view> -->
<view class="bg-fff u-p-24 border-r-12 u-m-t-32">
<view>
<text class="color-red">*</text>
<text>退款原因</text>
</view>
<view class="u-m-t-24 u-flex u-flex-wrap gap-28">
<view class="tag" @click="changeTuiKuanSel(index)" :class="{active:index==tuikuan.sel}"
v-for="(item,index) in tuikuan.list" :key="index">
{{item}}
</view>
</view>
<view class="u-m-t-24">
<up-textarea placeholder="选填" v-model="note"></up-textarea>
</view>
</view>
<view style="height: 200rpx;"></view>
<view class="fixed-b">
<up-button text="确认退款" @click="tuikuanConfirm" shape="circle" type="primary" size="large"
:color="$utils.ColorMain"></up-button>
</view>
<confirmRefundPopup ref="refundPopup" />
</view>
</template>
<script setup>
import { computed, reactive, ref, watch } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import confirmRefundPopup from './components/confirmRefundPopup.vue';
import {hasPermission} from '@/commons/utils/hasPermission.js'
import { refundOrder } from '@/http/api/order.js'
import { mathFloorPrice } from '@/commons/utils/goodsUtil.js'
let note = ref('')
const tuikuan = reactive({
list: ['点错', '数量点错', '客人要求', '协商退费'],
sel: -1
})
const pageData = reactive({
tabsList: [
{label: '部分退款', value: 0},
{label: '全部退款', value: 1},
{label: '自定义退款', value: 2},
],
tabsIndex: 0,
modify: '',
})
const option=reactive({
productId:'-999'
})
const orderDetail = reactive({
goodsList: [],
info: {},
seatFee: {
totalAmount: 0
}
})
const refundPopup = ref(null);
onLoad((opt) => {
orderDetail.info = JSON.parse(opt.orderInfo)
orderDetail.goodsList = JSON.parse(opt.goodsList)
option.productId = orderDetail.goodsList[0].productId
option.orderId = orderDetail.goodsList[0].orderId
})
/**
* tabs切换
* @param {Object} i
*/
function tabsChange(i) {
pageData.tabsIndex = pageData.tabsList[i].value
if( pageData.tabsIndex == 0){ // 部分退款
orderDetail.goodsList.map(v => {
v.number = '0.00'
})
}
if( pageData.tabsIndex == 1){ // 全部退款
orderDetail.goodsList.map(v => {
v.number = v.num.toFixed(2)
})
}
if( pageData.tabsIndex == 2){ // 自定义退款
orderDetail.goodsList.map(v => {
v.number = '0.00'
})
}
}
function changeTuiKuanSel(i) {
tuikuan.sel = i
}
function parseIntNumber (e) {
if ( e > (orderDetail.info.payAmount - orderDetail.info.refundAmount) ) {
setTimeout(()=>{
pageData.modify = (orderDetail.info.payAmount - orderDetail.info.refundAmount).toFixed(2)
},100)
}
}
/**
* 菜品总数量
*/
const totalNumber = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
return prve + cur.num * 1
}, 0)
})
/**
* 退款菜品总数量
*/
const tuikuanNumber = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
return prve + cur.number * 1
}, 0)
})
/**
* 退款总金额
*/
const tuikuanPrice = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
const n= mathFloorPrice(cur.number * cur.unitPrice,cur)
return (parseFloat(prve) + parseFloat(n)).toFixed(2)
}, 0)
})
/**
* 剩余退款金额
*/
const surplusRefundPrice = computed(() => {
return orderDetail.info.payAmount - orderDetail.goodsList.reduce((prve, cur) => {
const n = parseFloat( mathFloorPrice(cur.refundNum * cur.unitPrice,cur))
return (parseFloat(prve) + parseFloat(n)).toFixed(2)*1
}, 0)
})
/**
* 退款总金额
*/
const alltuikuanPrice = computed(() => {
return orderDetail.info.payAmount - orderDetail.goodsList.reduce((prve, cur) => {
const n = parseFloat( mathFloorPrice(cur.refundNum * cur.unitPrice,cur))
return (parseFloat(prve) + parseFloat(n)).toFixed(2)*1
}, 0)
})
function to2(n) {
return Number(n).toFixed(2);
}
function changeItem(item, step) {
if( item.num <= 0){
return
}
if(item.productId=='-999'){
return
}
if( pageData.tabsIndex != 0) {
return;
}
let newval = item.number * 1 + step * 1;
if (newval <= 0) {
newval = 0;
}
if (newval >= (item.num)) {
newval = item.num
}
console.log(totalNumber.value)
console.log(tuikuanNumber.value)
item.number = newval.toFixed(2);
pageData.tabsIndex = totalNumber.value == tuikuanNumber.value ? 1 : 0;
}
/**
* 确认退款
*/
let params;
async function tuikuanConfirm() {
const canTuikuan=await hasPermission('允许退款')
if(!canTuikuan){
return uni.$utils.showToast('您没有退款权限')
}
if (pageData.tabsIndex != 2&&tuikuanNumber.value <= 0) {
return uni.$utils.showToast('退款商品数量不能为0')
}
const selTag=tuikuan.list[tuikuan.sel]
const noteResult=`${selTag?selTag:''}${note.value?(','+note.value):''}`
if (!noteResult) {
return uni.$utils.showToast('请输入或选择退款原因!')
}
params = {
orderId: option.orderId,
refundReason: noteResult,
refundDetails: orderDetail.goodsList.filter(v=>v.number*1).map(v=>{
return {
id:v.id,
returnAmount: v.number * 1 * v.unitPrice,
num: v.number * 1
}
})
}
if( pageData.tabsIndex == 2){
params.modify = true
params.refundAmount = (pageData.modify*1).toFixed(2)
} else {
params.modify = false
params.refundAmount = pageData.tabsIndex == 1 ? alltuikuanPrice.value : tuikuanPrice.value
}
if ( pageData.tabsIndex == 2 && params.refundAmount > orderDetail.info.payAmount){
return uni.$utils.showToast('退款金额不能大于付款金额!')
}
if( uni.getStorageSync("shopInfo").isReturnPwd == 1){
refundPopup.value.open(params.refundAmount, refundPost);
return;
}
refundPost()
}
async function refundPost (payPassword) {
if( payPassword ){
params.pwd = payPassword
}
await refundOrder(params)
uni.$utils.showToast('退款请求提交成功')
setTimeout(()=>{
uni.navigateBack({delta:1})
},500)
}
</script>
<style lang="scss" scoped>
.fixed-b {
position: fixed;
left: 110rpx;
right: 110rpx;
bottom: calc(env(safe-area-inset-bottom) + 32rpx);
/* #ifdef H5 */
bottom: 100rpx;
/* #endif */
}
.gap-28 {
gap: 28rpx;
font-size: 24rpx;
}
.list {
padding: 0 24rpx;
}
.list .item:first-child {
border: none;
}
.tag {
padding: 8rpx 16rpx 6rpx 16rpx;
border: 1px solid #E5E5E5;
border-radius: 4rpx;
&.active {
border-color: #E6F0FF;
color: $my-main-color;
}
}
</style>