first
This commit is contained in:
168
pagesOrder/detail/components/extra.vue
Normal file
168
pagesOrder/detail/components/extra.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<view class="default-box-padding bg-fff border-r-12 u-m-t-20"
|
||||
v-if="packeFee>0||data.priceAmount>0||data.returnAmount>0">
|
||||
<view class="u-flex u-row-between">
|
||||
<view class="font-bold">附加费</view>
|
||||
<template v-if="extraCanTuicai(orderInfo,data)">
|
||||
<my-button plain shape="circle" :width="160" :height="56" @click="tuicai">退菜</my-button>
|
||||
</template>
|
||||
<template v-if=" extraCanTuiKuan(orderInfo,data)">
|
||||
<my-button plain shape="circle" :width="160" :height="56" @click="tuikuan">退款</my-button>
|
||||
</template>
|
||||
</view>
|
||||
<view>
|
||||
<template v-if="data.status!='return'&&data.status!='refund'&&data.status!='refunding'">
|
||||
<view class="u-flex u-row-between u-m-t-24" v-if="data.priceAmount*1>0">
|
||||
<view>{{data.productName||'餐位费'}}</view>
|
||||
<view>x{{data.num||0}}</view>
|
||||
<view class="price-min-width">¥{{seatFeePrice}}</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="u-flex u-row-between u-m-t-24 color-999">
|
||||
<view class="u-flex">
|
||||
<view class="line-th ">{{data.productName||'餐位费'}}</view>
|
||||
<view class="tag yitui u-m-l-10">{{data.status=='refunding'?'退款中': '已退'}}</view>
|
||||
</view>
|
||||
<view class="line-th">x{{data.num||0}}</view>
|
||||
<view class="line-th">¥{{seatFeePrice}}</view>
|
||||
<!-- <view class="line-th">¥{{data.priceAmount||data.returnAmount}}</view> -->
|
||||
</view>
|
||||
</template>
|
||||
<!-- <view class="u-flex u-row-right u-m-t-24">
|
||||
<template v-if="orderInfo.status=='unpaid'&&data.status!='return'">
|
||||
<my-button plain shape="circle" :width="160" :height="56" @click="tuicai">退菜</my-button>
|
||||
</template>
|
||||
<template v-if="orderInfo.status=='closed'&&data.status!='return'">
|
||||
<my-button plain shape="circle" :width="160" :height="56" @click="tuikuan">退款</my-button>
|
||||
</template>
|
||||
</view> -->
|
||||
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24" v-if="packeFee>0">
|
||||
<view>打包费</view>
|
||||
<view>x{{packeNumbber}}</view>
|
||||
<view class="price-min-width">¥{{packeFee}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
computed
|
||||
} from 'vue'
|
||||
import {
|
||||
returnCanComputedGoodsArr,
|
||||
canComputedPackFee,
|
||||
returnPackFee,isTui,
|
||||
isTuiCai,
|
||||
isGift,
|
||||
canTuiKuan,
|
||||
canTuicai,
|
||||
numSum
|
||||
} from '@/commons/utils/goodsUtil.js'
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
priceAmount: 0,
|
||||
returnAmount: 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
orderInfo: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
amount: 0,
|
||||
detailList: []
|
||||
}
|
||||
}
|
||||
},
|
||||
table: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
const canTuiKuanPrice = computed(() => {
|
||||
return props.orderInfo.detailList.filter(v =>!isTui(v)&& !v.userCouponId)
|
||||
.reduce((a, b) => {
|
||||
return a + b.priceAmount * 1
|
||||
}, 0)
|
||||
})
|
||||
const seatFeePrice = computed(() => {
|
||||
const item = props.data
|
||||
if (props.data.returnAmount) {
|
||||
return props.data.returnAmount
|
||||
}
|
||||
console.log(item);
|
||||
if (props.orderInfo.pointsDiscountAmount > 0 || props.orderInfo.fullCouponDiscountAmount > 0) {
|
||||
return item.canReturnAmount
|
||||
// const shengyuKeTui=canTuiKuanPrice.value
|
||||
// const bili = Math.floor((item.priceAmount / shengyuKeTui) * 100) / 100
|
||||
// return Math.floor((props.orderInfo.amount-props.orderInfo.refundAmount) * bili * 100) / 100
|
||||
} else {
|
||||
return item.priceAmount
|
||||
}
|
||||
})
|
||||
|
||||
function extraCanTuicai(orderInfo, data) {
|
||||
return orderInfo.status == 'unpaid' && data.status != 'return' && data.priceAmount * 1 > 0
|
||||
}
|
||||
|
||||
function extraCanTuiKuan(orderInfo, data) {
|
||||
return orderInfo.status == 'closed' && data.status != 'refund' && data.priceAmount * 1 > 0
|
||||
}
|
||||
const packeNumbber = computed(() => {
|
||||
if (!props.orderInfo.detailList) {
|
||||
return 0
|
||||
}
|
||||
return props.orderInfo.detailList.reduce((prve, cur) => {
|
||||
return prve + (cur.packAmount > 0 ? cur.num : 0)
|
||||
}, 0)
|
||||
})
|
||||
const packeFee = computed(() => {
|
||||
if (!props.orderInfo.detailList) {
|
||||
return 0
|
||||
}
|
||||
const arr = returnCanComputedGoodsArr(props.orderInfo.detailList)
|
||||
console.log(arr);
|
||||
return returnPackFee(arr)
|
||||
})
|
||||
|
||||
const statusMap = {
|
||||
unpaid: '未支付'
|
||||
}
|
||||
const emits = defineEmits(['tuicai', 'tuikuan', 'printOrder'])
|
||||
|
||||
function returnStatus(status) {
|
||||
return statusMap[status] || ''
|
||||
}
|
||||
|
||||
function tuikuan() {
|
||||
emits('tuikuan', {...props.data,priceAmount:props.data.canReturnAmount})
|
||||
}
|
||||
|
||||
function tuicai() {
|
||||
emits('tuicai', props.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tag {
|
||||
padding: 0 6rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
|
||||
&.yitui {
|
||||
background-color: rgb(188, 188, 188);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.price-min-width {
|
||||
min-width: 100rpx;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
548
pagesOrder/detail/components/list - 副本.vue
Normal file
548
pagesOrder/detail/components/list - 副本.vue
Normal file
@@ -0,0 +1,548 @@
|
||||
<template>
|
||||
<view class="default-box-padding bg-fff border-r-24 u-m-t-32" v-if="data.length">
|
||||
<view class=" font-bold u-p-b-32 border-bottom u-m-b-24" v-if="orderInfo.tableName">
|
||||
<text class="">桌号:</text>
|
||||
<text class="">{{orderInfo.tableName||""}}</text>
|
||||
</view>
|
||||
<view class=" color-999 border-bottom u-p-b-24">
|
||||
<text>共</text>
|
||||
<text class="color-333 "> {{goodsNumber}}</text>
|
||||
<text>份菜品</text>
|
||||
</view>
|
||||
<view class="u-m-b-20 " v-for="(order,orderIndex) in data" :key="orderIndex">
|
||||
<view class="u-p-t-24"> 第{{ order.placeNum }}次下单
|
||||
</view>
|
||||
<view class="u-m-t-24 list">
|
||||
<view class="item u-m-b-32" v-for="(item,index) in order.info" :key="index">
|
||||
<view class="u-flex u-col-top">
|
||||
<view class="u-flex">
|
||||
<image class="img" :src="item.coverImg||item.productImg" mode=""></image>
|
||||
</view>
|
||||
<view class="u-p-l-32 u-flex-1">
|
||||
<view class="u-flex u-row-between u-col-top">
|
||||
|
||||
<view class="">
|
||||
<view class="u-flex">
|
||||
<view class="tui" v-if="isTui(item)">
|
||||
{{item.status=='refunding'?'退款中':'已退'}}
|
||||
</view>
|
||||
<view
|
||||
:class="{'line-th':item.status=='return'||item.status=='refund'||item.status=='refunding'}">
|
||||
{{item.name||item.productName}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-m-t-8">
|
||||
<view class="u-m-r-20 u-flex " v-if="item.gift">
|
||||
<uni-tag text="赠送"
|
||||
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
|
||||
</uni-tag>
|
||||
</view>
|
||||
<view class="u-m-r-20 u-flex " v-if="item.userCouponId">
|
||||
<uni-tag :text=" productCouponDikou(item)"
|
||||
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
|
||||
</uni-tag>
|
||||
</view>
|
||||
<view class="u-m-r-20 u-flex" v-if="item.pack">
|
||||
<uni-tag
|
||||
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
|
||||
size="small" text="打包" inverted type="success" />
|
||||
</view>
|
||||
<view class="u-m-r-20 u-font-24 u-flex" v-if="item.returnAmount">
|
||||
<view class="color-666">退款金额:</view>
|
||||
<view class="color-999 u-m-l-6">{{item.returnAmount}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="color-999 u-font-24 u-m-t-8">{{item.productSkuName||''}}</view>
|
||||
|
||||
|
||||
<view class="u-m-t-12 color-666 u-font-24" v-if="item.note">
|
||||
备注:{{item.note}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-text-right u-m-t-28">
|
||||
<template v-if="isTui(item)">
|
||||
<view>¥0.00</view>
|
||||
<view class="line-th color-666 ">¥{{returnTotalMoney(item)}}
|
||||
</view>
|
||||
</template>
|
||||
<template v-else-if="isGift(item)||item.userCouponId">
|
||||
<view>¥0.00</view>
|
||||
<view class="line-th color-666 ">¥{{returnTotalMoney(item)}}
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="returnCanTuiMoney(item)*1!=returnTotalMoney(item)*1">
|
||||
<view>¥{{returnCanTuiMoney(item)}}</view>
|
||||
<view class=" color-666 line-th">
|
||||
¥{{returnTotalMoney(item)}}</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>¥{{returnTotalMoney(item)}}</view>
|
||||
</template>
|
||||
<!-- <template
|
||||
v-if="user.isVip&&item.isMember&&returnVipMoney(item)>0&&returnVipMoney(item)!=returnTotalMoney(item)">
|
||||
<view>¥{{returnVipMoney(item)}}</view>
|
||||
<view class=" color-666 line-th">
|
||||
¥{{returnTotalMoney(item)}}</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>¥{{returnTotalMoney(item)}}</view>
|
||||
</template> -->
|
||||
</template>
|
||||
<view class="u-m-t-22 color-999 u-font-24">X{{item.number||item.num}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="canTuicai(orderInfo,item)">
|
||||
<view class="u-flex u-row-right gap-20 u-m-t-24">
|
||||
<!-- <my-button :height="60" color="#333" plain type="cancel" shape="circle">更多操作</my-button> -->
|
||||
<my-button :width="128" :height="48" plain shape="circle" @tap="tuicai(item,index)"><text
|
||||
class="no-wrap">退菜</text></my-button>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="canTuiKuan(orderInfo,item)">
|
||||
<view class="u-flex u-row-right gap-20 u-m-t-20">
|
||||
<my-button :width="128" :height="48" plain shape="circle" @tap="tuikuan(item,index)"><text
|
||||
class="no-wrap">{{item.userCouponId?'退券':'退款' }}</text> </my-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="bg-gray u-p-20 u-m-t-20" v-if="orderInfo.remark">
|
||||
<view>备注</view>
|
||||
<view class="u-m-t-10">{{orderInfo.remark}}</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-flex u-row-between border-top u-p-t-32">
|
||||
<view>
|
||||
<template v-if="orderInfo.status=='unpaid'">
|
||||
<view class="tag no-pay">
|
||||
未支付
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="orderInfo.status=='refund'">
|
||||
<view class="tag refund">
|
||||
退款成功
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<view class="u-flex">
|
||||
<view class="u-flex u-m-r-24" v-if="youhuiAllPrice>0">
|
||||
<view class="color-red u-m-r-6 ">
|
||||
已优惠¥{{youhuiAllPrice}}
|
||||
</view>
|
||||
<up-icon name="info-circle" color="#999" :size="14" @click="youhuiDetailShow"></up-icon>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<text>小计¥</text>
|
||||
<text class="font-bold u-font-32">{{allPrice}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template v-if="orderInfo.refundAmount">
|
||||
<view class="u-flex u-row-between u-m-t-32">
|
||||
<view>退款金额</view>
|
||||
<view class="color-999">
|
||||
<text class="">{{(orderInfo.refundAmount).toFixed(2)}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-32">
|
||||
<view>退款原因</view>
|
||||
<view class="color-999">
|
||||
<text class="">{{orderInfo.refundRemark||''}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-32 u-p-b-24 border-bottom">
|
||||
<view></view>
|
||||
<view class="">
|
||||
<text class="">退款成功</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view class="u-flex u-row-between u-m-t-20">
|
||||
<view></view>
|
||||
<view>
|
||||
<text>总计¥</text>
|
||||
<text class="font-bold u-font-32">{{to2(allPrice*1+seatFeePrice*1+packFee*1) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-20" v-if="orderInfo.status=='closed'">
|
||||
<view></view>
|
||||
<view>
|
||||
<text>实付¥</text>
|
||||
<text class="font-bold u-font-32">{{to2(orderInfo.amount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="u-flex u-row-between u-m-t-20">
|
||||
<view></view>
|
||||
<view>
|
||||
<text>原价¥</text>
|
||||
<text class="font-bold u-font-32">{{to2(orderInfo.originAmount||0) }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="u-m-t-24">
|
||||
<my-button @tap="printOrder" type="cancel" :color="color.ColorMain">重新打印</my-button>
|
||||
</view>
|
||||
</view>
|
||||
<up-popup :round="10" :show="pop.youhui" mode="center" closeOnClickOverlay @close="youhuiDetailHide">
|
||||
<view class="u-p-30" style="width: 80vw;">
|
||||
<view class="font-bold u-text-center">优惠详情</view>
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-flex u-row-between u-m-b-18" v-if="vipDiscountPrice*1>0">
|
||||
<view>会员优惠</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{vipDiscountPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-b-18" v-if="discountAmount">
|
||||
<view>打折</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{to2(discountAmount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between " v-if="orderInfo.fullCouponDiscountAmount*1>0">
|
||||
<view>满减券抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{to2(orderInfo.fullCouponDiscountAmount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-18" v-if="productCouponDiscountAmount*1>0">
|
||||
<view>商品券抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text> {{productCouponDiscountAmount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="u-flex u-row-between u-m-t-18"
|
||||
v-if="orderInfo.productCouponDiscountAmount||productCoupPrice*1>0">
|
||||
<view>商品券抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text> {{to2(orderInfo.productCouponDiscountAmount||productCoupPrice) }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="u-flex u-row-between u-m-t-18" v-if="orderInfo.pointsDiscountAmount">
|
||||
<view>积分抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{to2(orderInfo.pointsDiscountAmount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</up-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
computed,
|
||||
reactive
|
||||
} from 'vue';
|
||||
import color from '@/commons/color.js'
|
||||
import {
|
||||
hasPermission
|
||||
} from '@/commons/utils/hasPermission.js'
|
||||
import {
|
||||
isTui,
|
||||
isTuiCai,
|
||||
isGift,
|
||||
canTuiKuan,
|
||||
canTuicai,
|
||||
numSum
|
||||
} from '@/commons/utils/goodsUtil.js'
|
||||
const pop = reactive({
|
||||
youhui: false
|
||||
})
|
||||
|
||||
function youhuiDetailShow() {
|
||||
pop.youhui = true
|
||||
}
|
||||
|
||||
function productCouponDikou(item) {
|
||||
return '商品券抵扣¥' + returnProductCoupPrice(item)
|
||||
}
|
||||
|
||||
function youhuiDetailHide() {
|
||||
pop.youhui = false
|
||||
}
|
||||
const props = defineProps({
|
||||
orderInfo: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seatFee: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
id: '',
|
||||
isVip: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function returnProductCoupPrice(item) {
|
||||
if (!item.isMember) {
|
||||
return item.price * item.num
|
||||
}
|
||||
const price = item.memberPrice ? item.memberPrice : item.price
|
||||
return price * item.num
|
||||
}
|
||||
const productCouponDiscountAmount = computed(() => {
|
||||
// if(props.orderInfo.productCouponDiscountAmount){
|
||||
// return orderInfo.productCouponDiscountAmount.toFixed(2)
|
||||
// }
|
||||
if (!props.data.length) {
|
||||
return 0
|
||||
}
|
||||
const n = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.userCouponId).reduce((a, b) => {
|
||||
return a + returnProductCoupPrice(b)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
console.log(n);
|
||||
return n.toFixed(2)
|
||||
})
|
||||
const emits = defineEmits(['tuicai', 'tuikuan', 'printOrder'])
|
||||
|
||||
function returnVipMoney(item) {
|
||||
if (!item.memberPrice || !props.user.isVip) {
|
||||
return 0
|
||||
}
|
||||
return (item.memberPrice * item.num).toFixed(2)
|
||||
}
|
||||
|
||||
function returnTotalMoney(item) {
|
||||
return (item.price * item.num).toFixed(2)
|
||||
}
|
||||
|
||||
const canTuiKuanPrice = computed(() => {
|
||||
return props.data.reduce((prve,cur)=>{
|
||||
// const curTotal=cur.info.filter(v=>!v.userCouponId).reduce((a,b)=>{
|
||||
// return a+b.priceAmount*1
|
||||
// },0)
|
||||
const curTotal=cur.info.filter(v=>canTuiKuan(props.orderInfo,v)&&!v.userCouponId).reduce((a,b)=>{
|
||||
return a+b.priceAmount*1
|
||||
},0)
|
||||
return prve+curTotal
|
||||
},0)
|
||||
})
|
||||
function returnCanTuiMoney(item) {
|
||||
console.log(canTuiKuanPrice.value);
|
||||
if(props.orderInfo.status=='unpaid'){
|
||||
return returnTotalMoney(item)
|
||||
}else{
|
||||
return (item.priceAmount/(canTuiKuanPrice.value+seatFeePrice.value*1)*props.orderInfo.amount).toFixed(2)
|
||||
}
|
||||
}
|
||||
|
||||
function to2(n) {
|
||||
if (!n) {
|
||||
return 0
|
||||
}
|
||||
return n.toFixed(2)
|
||||
}
|
||||
|
||||
function tuicai(item, index) {
|
||||
emits('tuicai', item, index)
|
||||
}
|
||||
|
||||
function tuikuan(item, index) {
|
||||
hasPermission('允许退款').then(res => {
|
||||
if (res) {
|
||||
emits('tuikuan', {...item,priceAmount:returnCanTuiMoney(item)}, index)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function printOrder() {
|
||||
emits('printOrder')
|
||||
}
|
||||
|
||||
|
||||
const seatFeePrice = computed(() => {
|
||||
if (!props.seatFee.priceAmount) {
|
||||
return 0
|
||||
}
|
||||
const n = props.seatFee.priceAmount * (isTui(props.seatFee) ? 0 : 1)
|
||||
return n.toFixed(2)
|
||||
})
|
||||
const discountAmount = computed(() => {
|
||||
if (props.orderInfo.discountAmount) {
|
||||
return props.orderInfo.discountAmount
|
||||
}
|
||||
console.log(props.orderInfo.originAmount * (1 - props.orderInfo.discountRatio));
|
||||
return (props.orderInfo.originAmount * (1 - props.orderInfo.discountRatio))
|
||||
})
|
||||
const goodsOriginAllPrice = computed(() => {
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.reduce((a,
|
||||
b) => {
|
||||
return a + (b.num * b.price)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
|
||||
|
||||
|
||||
const freePrice = computed(() => {
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.gift == true || isGift(v)).reduce((a,
|
||||
b) => {
|
||||
const price = (b.isMember && b.memberPrice) ? b.memberPrice : b.price
|
||||
return a + (b.num * price)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
const vipDiscountPrice = computed(() => {
|
||||
if (!props.user.isVip) {
|
||||
return 0
|
||||
}
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.gift != true && v.status !== "return" && (v.isMember &&
|
||||
v.memberPrice) && (v.memberPrice != v.price)).reduce((
|
||||
a,
|
||||
b) => {
|
||||
return a + (b.num * (b.price - b.memberPrice))
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
|
||||
const productCoupPrice = computed(() => {
|
||||
if (props.orderInfo.status == 'closed') {
|
||||
return props.orderInfo.productCouponDiscountAmount
|
||||
}
|
||||
const goodsPrice = props.data.reduce((a, b) => {
|
||||
const curTotal = b.info.filter(v => v.gift != true && v.userCouponId).reduce((prve,
|
||||
cur) => {
|
||||
const isVip = props.user.isVip && cur.isMember
|
||||
const memberPrice = cur.memberPrice ? cur.memberPrice : cur.price
|
||||
const price = isVip ? memberPrice : cur.price
|
||||
const curTotal = price * cur.num
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return a + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
|
||||
const youhuiAllPrice = computed(() => {
|
||||
return (freePrice.value * 1 + vipDiscountPrice.value * 1 + props.orderInfo.fullCouponDiscountAmount + props
|
||||
.orderInfo.pointsDiscountAmount + (props.orderInfo.status == 'unpaid' ? productCoupPrice.value :
|
||||
productCouponDiscountAmount.value) * 1 + (props.orderInfo.discountAmount ||
|
||||
0)).toFixed(2)
|
||||
|
||||
})
|
||||
const packFee = computed(() => {
|
||||
//不是退菜只要有打包费的都计算,包括赠送
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.status !== "return").reduce((a,
|
||||
b) => {
|
||||
return a + b.packAmount
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
|
||||
})
|
||||
const allPrice = computed(() => {
|
||||
const n = goodsOriginAllPrice.value - youhuiAllPrice.value
|
||||
return (n < 0 ? 0 : n).toFixed(2)
|
||||
|
||||
// if (props.orderInfo.status == 'unpaid') {
|
||||
// const n = goodsOriginAllPrice.value - youhuiAllPrice.value
|
||||
// return (n < 0 ? 0 : n).toFixed(2)
|
||||
// }
|
||||
// return props.orderInfo.amount
|
||||
})
|
||||
|
||||
const goodsNumber = computed(() => {
|
||||
let result = 0
|
||||
result = props.data.reduce((a, b) => {
|
||||
const bTotal = b.info.reduce((prve, cur) => {
|
||||
return prve + (cur.number || cur.num) * 1;
|
||||
}, 0);
|
||||
return a + bTotal
|
||||
}, 0)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.img {
|
||||
width: 152rpx;
|
||||
height: 152rpx;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.border-r-24 {
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.border-bottom {
|
||||
// border-color: rgb(240, 240, 240);
|
||||
border-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.line-th {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 4rpx 8rpx 2rpx 10rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
|
||||
&.no-pay {
|
||||
background-color: rgb(170, 170, 170);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.refund {
|
||||
background-color: #FCE7E7;
|
||||
padding: 8rpx 20rpx 6rpx 22rpx;
|
||||
color: #EB4F4F;
|
||||
}
|
||||
}
|
||||
|
||||
.tui {
|
||||
background-color: rgb(239, 239, 239);
|
||||
border-radius: 4rpx;
|
||||
margin-right: 6rpx;
|
||||
color: #666;
|
||||
padding: 0 4rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
</style>
|
||||
612
pagesOrder/detail/components/list.vue
Normal file
612
pagesOrder/detail/components/list.vue
Normal file
@@ -0,0 +1,612 @@
|
||||
<template>
|
||||
<view class="default-box-padding bg-fff border-r-24 u-m-t-32" v-if="data.length">
|
||||
<view class=" font-bold u-p-b-32 border-bottom u-m-b-24" v-if="orderInfo.tableName">
|
||||
<text class="">桌号:</text>
|
||||
<text class="">{{orderInfo.tableName||""}}</text>
|
||||
</view>
|
||||
<view class=" color-999 border-bottom u-p-b-24">
|
||||
<text>共</text>
|
||||
<text class="color-333 "> {{goodsNumber}}</text>
|
||||
<text>份菜品</text>
|
||||
</view>
|
||||
<view class="u-m-b-20 " v-for="(order,orderIndex) in data" :key="orderIndex">
|
||||
<view class="u-p-t-24"> 第{{ order.placeNum }}次下单
|
||||
</view>
|
||||
<view class="u-m-t-24 list">
|
||||
<view class="item u-m-b-32" v-for="(item,index) in order.info" :key="index">
|
||||
<view class="u-flex u-col-top">
|
||||
<view class="u-flex">
|
||||
<image class="img" :src="item.coverImg||item.productImg" mode=""></image>
|
||||
</view>
|
||||
<view class="u-p-l-32 u-flex-1">
|
||||
<view class="u-flex u-row-between u-col-top">
|
||||
|
||||
<view class="">
|
||||
<view class="u-flex">
|
||||
<view class="tui" v-if="isTui(item)">
|
||||
{{item.status=='refunding'?'退款中':'已退'}}
|
||||
</view>
|
||||
<view
|
||||
:class="{'line-th':item.status=='return'||item.status=='refund'||item.status=='refunding'}">
|
||||
{{item.name||item.productName}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-m-t-8">
|
||||
<view class="u-m-r-20 u-flex " v-if="item.gift">
|
||||
<uni-tag text="赠送"
|
||||
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
|
||||
</uni-tag>
|
||||
</view>
|
||||
<view class="u-m-r-20 u-flex " v-if="item.userCouponId">
|
||||
<uni-tag :text=" productCouponDikou(item)"
|
||||
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
|
||||
</uni-tag>
|
||||
</view>
|
||||
<view class="u-m-r-20 u-flex" v-if="item.pack">
|
||||
<uni-tag
|
||||
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
|
||||
size="small" text="打包" inverted type="success" />
|
||||
</view>
|
||||
<view class="u-m-r-20 u-font-24 u-flex" v-if="item.returnAmount">
|
||||
<view class="color-666">退款金额:</view>
|
||||
<view class="color-999 u-m-l-6">{{item.returnAmount}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="color-999 u-font-24 u-m-t-8">{{item.productSkuName||''}}</view>
|
||||
|
||||
|
||||
<view class="u-m-t-12 color-666 u-font-24" v-if="item.note">
|
||||
备注:{{item.note}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-text-right u-m-t-28">
|
||||
<template v-if="isTui(item)">
|
||||
<view>¥0.00</view>
|
||||
<view class="line-th color-666 ">¥{{returnTotalMoney(item)}}
|
||||
</view>
|
||||
</template>
|
||||
<template v-else-if="isGift(item)||item.userCouponId">
|
||||
<view>¥0.00</view>
|
||||
<view class="line-th color-666 ">¥{{returnTotalMoney(item)}}
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="returnCanTuiMoney(item)*1!=returnTotalMoney(item)*1">
|
||||
<view>¥{{returnCanTuiMoney(item)}}</view>
|
||||
<view class=" color-666 line-th">
|
||||
¥{{returnTotalMoney(item)}}</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>¥{{returnTotalMoney(item)}}</view>
|
||||
</template>
|
||||
<!-- <template
|
||||
v-if="user.isVip&&item.isMember&&returnVipMoney(item)>0&&returnVipMoney(item)!=returnTotalMoney(item)">
|
||||
<view>¥{{returnVipMoney(item)}}</view>
|
||||
<view class=" color-666 line-th">
|
||||
¥{{returnTotalMoney(item)}}</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>¥{{returnTotalMoney(item)}}</view>
|
||||
</template> -->
|
||||
</template>
|
||||
<view class="u-m-t-22 color-999 u-font-24">X{{item.number||item.num}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="canTuicai(orderInfo,item)">
|
||||
<view class="u-flex u-row-right gap-20 u-m-t-24">
|
||||
<!-- <my-button :height="60" color="#333" plain type="cancel" shape="circle">更多操作</my-button> -->
|
||||
<my-button :width="128" :height="48" plain shape="circle" @tap="tuicai(item,index)"><text
|
||||
class="no-wrap">退菜</text></my-button>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="canTuiKuan(orderInfo,item)">
|
||||
<view class="u-flex u-row-right gap-20 u-m-t-20">
|
||||
<my-button :width="128" :height="48" plain shape="circle" @tap="tuikuan(item,index)"><text
|
||||
class="no-wrap">{{item.userCouponId?'退券':'退款' }}</text> </my-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="bg-gray u-p-20 u-m-t-20" v-if="orderInfo.remark">
|
||||
<view>备注</view>
|
||||
<view class="u-m-t-10">{{orderInfo.remark}}</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-flex u-row-between border-top u-p-t-32">
|
||||
<view>
|
||||
<template v-if="orderInfo.status=='unpaid'">
|
||||
<view class="tag no-pay">
|
||||
未支付
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="orderInfo.status=='refund'">
|
||||
<view class="tag refund">
|
||||
退款成功
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<view class="u-flex">
|
||||
<view class="u-flex u-m-r-24" v-if="youhuiAllPrice>0">
|
||||
<view class="color-red u-m-r-6 ">
|
||||
已优惠¥{{youhuiAllPrice}}
|
||||
</view>
|
||||
<!-- <up-icon name="info-circle" color="#999" :size="14" @click="youhuiDetailShow"></up-icon> -->
|
||||
</view>
|
||||
<view>
|
||||
<text>小计¥</text>
|
||||
<text class="font-bold u-font-32">{{allPrice}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template v-if="orderInfo.refundAmount">
|
||||
<view class="u-flex u-row-between u-m-t-32">
|
||||
<view>退款金额</view>
|
||||
<view class="color-999">
|
||||
<text class="">{{(orderInfo.refundAmount).toFixed(2)}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-32">
|
||||
<view>退款原因</view>
|
||||
<view class="color-999">
|
||||
<text class="">{{orderInfo.refundRemark||''}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-32 u-p-b-24 border-bottom">
|
||||
<view></view>
|
||||
<view class="">
|
||||
<text class="">退款成功</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view class="u-flex u-row-between u-m-t-20">
|
||||
<view></view>
|
||||
<template v-if="orderInfo.status=='unpaid'">
|
||||
<view>
|
||||
<text>总计¥</text>
|
||||
<text class="font-bold u-font-32">{{orderInfo.amount }}</text>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>
|
||||
<text>总计¥</text>
|
||||
<text class="font-bold u-font-32">{{orderInfo.amount}}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
<!-- <view class="u-flex u-row-between u-m-t-20" v-if="orderInfo.status=='closed'">
|
||||
<view></view>
|
||||
<view>
|
||||
<text>实付¥</text>
|
||||
<text class="font-bold u-font-32">{{to2(orderInfo.amount) }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- <view class="u-flex u-row-between u-m-t-20">
|
||||
<view></view>
|
||||
<view>
|
||||
<text>原价¥</text>
|
||||
<text class="font-bold u-font-32">{{to2(orderInfo.originAmount||0) }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="u-m-t-24">
|
||||
<my-button @tap="printOrder" type="cancel" :color="color.ColorMain">重新打印</my-button>
|
||||
</view>
|
||||
</view>
|
||||
<up-popup :round="10" :show="pop.youhui" mode="center" closeOnClickOverlay @close="youhuiDetailHide">
|
||||
<view class="u-p-30" style="width: 80vw;">
|
||||
<view class="font-bold u-text-center">优惠详情</view>
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-flex u-row-between u-m-b-18" v-if="vipDiscountPrice*1>0">
|
||||
<view>会员优惠</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{vipDiscountPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-b-18" v-if="discountAmount">
|
||||
<view>打折</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{to2(discountAmount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between " v-if="orderInfo.fullCouponDiscountAmount*1>0">
|
||||
<view>满减券抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{to2(orderInfo.fullCouponDiscountAmount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-18" v-if="productCouponDiscountAmount*1>0">
|
||||
<view>商品券抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text> {{productCouponDiscountAmount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="u-flex u-row-between u-m-t-18"
|
||||
v-if="orderInfo.productCouponDiscountAmount||productCoupPrice*1>0">
|
||||
<view>商品券抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text> {{to2(orderInfo.productCouponDiscountAmount||productCoupPrice) }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="u-flex u-row-between u-m-t-18" v-if="orderInfo.pointsDiscountAmount">
|
||||
<view>积分抵扣</view>
|
||||
<view class="color-red">
|
||||
<text>¥</text>
|
||||
<text>{{to2(orderInfo.pointsDiscountAmount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</up-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
computed,
|
||||
reactive
|
||||
} from 'vue';
|
||||
import color from '@/commons/color.js'
|
||||
import {
|
||||
hasPermission
|
||||
} from '@/commons/utils/hasPermission.js'
|
||||
import {
|
||||
isTui,
|
||||
isTuiCai,
|
||||
isGift,
|
||||
canTuiKuan,
|
||||
canTuicai,
|
||||
numSum
|
||||
} from '@/commons/utils/goodsUtil.js'
|
||||
const pop = reactive({
|
||||
youhui: false
|
||||
})
|
||||
|
||||
function youhuiDetailShow() {
|
||||
pop.youhui = true
|
||||
}
|
||||
|
||||
function productCouponDikou(item) {
|
||||
return '商品券抵扣¥' + returnProductCoupPrice(item)
|
||||
}
|
||||
|
||||
function youhuiDetailHide() {
|
||||
pop.youhui = false
|
||||
}
|
||||
const props = defineProps({
|
||||
orderInfo: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seatFee: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
id: '',
|
||||
isVip: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function returnProductCoupPrice(item) {
|
||||
if (!item.isMember) {
|
||||
return item.price * item.num
|
||||
}
|
||||
const price = item.memberPrice ? item.memberPrice : item.price
|
||||
return price * item.num
|
||||
}
|
||||
const productCouponDiscountAmount = computed(() => {
|
||||
// if(props.orderInfo.productCouponDiscountAmount){
|
||||
// return orderInfo.productCouponDiscountAmount.toFixed(2)
|
||||
// }
|
||||
if (!props.data.length) {
|
||||
return 0
|
||||
}
|
||||
const n = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.userCouponId).reduce((a, b) => {
|
||||
return a + returnProductCoupPrice(b)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
console.log(n);
|
||||
return n.toFixed(2)
|
||||
})
|
||||
const emits = defineEmits(['tuicai', 'tuikuan', 'printOrder'])
|
||||
|
||||
function returnVipMoney(item) {
|
||||
if (!item.memberPrice || !props.user.isVip) {
|
||||
return 0
|
||||
}
|
||||
return (item.memberPrice * item.num).toFixed(2)
|
||||
}
|
||||
|
||||
function returnTotalMoney(item) {
|
||||
return (item.price * item.num).toFixed(2)
|
||||
}
|
||||
|
||||
const canTuiKuanPrice = computed(() => {
|
||||
const goodsTotal= props.data.reduce((prve, cur) => {
|
||||
// const curTotal=cur.info.filter(v=>!v.userCouponId).reduce((a,b)=>{
|
||||
// return a+b.priceAmount*1
|
||||
// },0)
|
||||
const curTotal = cur.info.filter(v => !isTui(v)&& !v.userCouponId)
|
||||
.reduce((a, b) => {
|
||||
return a + b.priceAmount * 1
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
console.log(goodsTotal);
|
||||
console.log(seatFeePrice.value);
|
||||
return (goodsTotal+seatFeePrice.value*1).toFixed(2)
|
||||
})
|
||||
const TuiKuanPrice = computed(() => {
|
||||
return props.data.reduce((prve, cur) => {
|
||||
// const curTotal=cur.info.filter(v=>!v.userCouponId).reduce((a,b)=>{
|
||||
// return a+b.priceAmount*1
|
||||
// },0)
|
||||
const curTotal = cur.info.filter(v => isTui(v)&&!v.userCouponId)
|
||||
.reduce((a, b) => {
|
||||
return a + b.priceAmount * 1
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
})
|
||||
const noTuiKuanPrice=computed(()=>{
|
||||
return props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => !isTui(v)&&!v.userCouponId)
|
||||
.reduce((a, b) => {
|
||||
return a + b.priceAmount * 1
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
})
|
||||
const cantuiSeatFee=computed(()=>{
|
||||
let seatFee=props.orderInfo.seatInfo?(props.orderInfo.seatInfo.priceAmount):0
|
||||
const bili = Math.floor((seatFee / canTuiKuanPrice.value) * 100) / 100
|
||||
seatFee= Math.floor((props.orderInfo.amount-props.orderInfo.refundAmount) * bili * 100) / 100
|
||||
return seatFee
|
||||
})
|
||||
function returnCanTuiMoney(item) {
|
||||
return props.orderInfo.status == 'unpaid'? item.priceAmount: item.canReturnAmount
|
||||
if (props.orderInfo.status == 'unpaid') {
|
||||
return returnTotalMoney(item)
|
||||
} else {
|
||||
if(props.orderInfo.pointsDiscountAmount>0||props.orderInfo.fullCouponDiscountAmount>0){
|
||||
return item.canReturnAmount
|
||||
// const bili=Math.floor((item.priceAmount/canTuiKuanPrice.value )*100)/100
|
||||
// return Math.floor((allPrice.value)*bili*100)/100
|
||||
}else{
|
||||
return item.priceAmount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function to2(n) {
|
||||
if (!n) {
|
||||
return 0
|
||||
}
|
||||
return n.toFixed(2)
|
||||
}
|
||||
|
||||
function tuicai(item, index) {
|
||||
emits('tuicai', item, index)
|
||||
}
|
||||
|
||||
function tuikuan(item, index) {
|
||||
hasPermission('允许退款').then(res => {
|
||||
if (res) {
|
||||
emits('tuikuan', {
|
||||
...item,
|
||||
priceAmount: item.canReturnAmount
|
||||
}, index)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function printOrder() {
|
||||
emits('printOrder')
|
||||
}
|
||||
|
||||
|
||||
const seatFeePrice = computed(() => {
|
||||
if (!props.seatFee.priceAmount) {
|
||||
return 0
|
||||
}
|
||||
const n = props.seatFee.priceAmount * (isTui(props.seatFee) ? 0 : 1)
|
||||
return n.toFixed(2)
|
||||
})
|
||||
const discountAmount = computed(() => {
|
||||
if (props.orderInfo.discountAmount) {
|
||||
return props.orderInfo.discountAmount
|
||||
}
|
||||
console.log(props.orderInfo.originAmount * (1 - props.orderInfo.discountRatio));
|
||||
return (props.orderInfo.originAmount * (1 - props.orderInfo.discountRatio))
|
||||
})
|
||||
const goodsOriginAllPrice = computed(() => {
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.reduce((a,
|
||||
b) => {
|
||||
return a + (b.num * b.price)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
|
||||
|
||||
|
||||
const freePrice = computed(() => {
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.gift == true || isGift(v)).reduce((a,
|
||||
b) => {
|
||||
const price = (b.isMember && b.memberPrice) ? b.memberPrice : b.price
|
||||
return a + (b.num * price)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
const vipDiscountPrice = computed(() => {
|
||||
if (!props.user.isVip) {
|
||||
return 0
|
||||
}
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.gift != true && v.status !== "return" && (v.isMember &&
|
||||
v.memberPrice) && (v.memberPrice != v.price)).reduce((
|
||||
a,
|
||||
b) => {
|
||||
return a + (b.num * (b.price - b.memberPrice))
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
|
||||
const productCoupPrice = computed(() => {
|
||||
if (props.orderInfo.status == 'closed') {
|
||||
return props.orderInfo.productCouponDiscountAmount
|
||||
}
|
||||
const goodsPrice = props.data.reduce((a, b) => {
|
||||
const curTotal = b.info.filter(v => v.gift != true && v.userCouponId).reduce((prve,
|
||||
cur) => {
|
||||
const isVip = props.user.isVip && cur.isMember
|
||||
const memberPrice = cur.memberPrice ? cur.memberPrice : cur.price
|
||||
const price = isVip ? memberPrice : cur.price
|
||||
const curTotal = price * cur.num
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return a + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
|
||||
const youhuiAllPrice = computed(() => {
|
||||
const n= props.orderInfo.originAmount-props.orderInfo.amount+vipDiscountPrice.value*1
|
||||
return (n<0?0:n).toFixed(2)
|
||||
// if(props.orderInfo.status!='unpaid'){
|
||||
// const seatfee=(props.orderInfo.amount==0&&allPrice.value==0)?seatFeePrice.value:0
|
||||
// return (goodsOriginAllPrice.value-allPrice.value+seatfee*1).toFixed(2)
|
||||
// }
|
||||
// return (freePrice.value * 1 + vipDiscountPrice.value * 1 + props.orderInfo.fullCouponDiscountAmount + props
|
||||
// .orderInfo.pointsDiscountAmount + (props.orderInfo.status == 'unpaid' ? productCoupPrice.value :
|
||||
// productCouponDiscountAmount.value) * 1 + (props.orderInfo.discountAmount ||
|
||||
// 0)).toFixed(2)
|
||||
|
||||
})
|
||||
const packFee = computed(() => {
|
||||
//不是退菜只要有打包费的都计算,包括赠送
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.filter(v => v.status !== "return").reduce((a,
|
||||
b) => {
|
||||
return a + b.packAmount
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
|
||||
})
|
||||
const allPrice = computed(() => {
|
||||
|
||||
|
||||
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||
const curTotal = cur.info.reduce((a,
|
||||
b) => {
|
||||
return a +(props.orderInfo.status == 'unpaid'?b.priceAmount:b.canReturnAmount*1)
|
||||
}, 0)
|
||||
return prve + curTotal
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
if (props.orderInfo.status == 'unpaid') {
|
||||
const n = goodsOriginAllPrice.value - youhuiAllPrice.value
|
||||
return (n < 0 ? 0 : n).toFixed(2)
|
||||
}
|
||||
const returnAmount=props.orderInfo.seatInfo&&props.orderInfo.seatInfo.returnAmount?props.orderInfo.seatInfo.returnAmount:0
|
||||
const canReturnAmount=props.orderInfo.seatInfo&&props.orderInfo.seatInfo.canReturnAmount?props.orderInfo.seatInfo.canReturnAmount:0
|
||||
const total=props.orderInfo.amount-(returnAmount?returnAmount:canReturnAmount)
|
||||
return (total<=0?0:total).toFixed(2)
|
||||
})
|
||||
|
||||
const goodsNumber = computed(() => {
|
||||
let result = 0
|
||||
result = props.data.reduce((a, b) => {
|
||||
const bTotal = b.info.reduce((prve, cur) => {
|
||||
return prve + (cur.number || cur.num) * 1;
|
||||
}, 0);
|
||||
return a + bTotal
|
||||
}, 0)
|
||||
return result
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.img {
|
||||
width: 152rpx;
|
||||
height: 152rpx;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.border-r-24 {
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.border-bottom {
|
||||
// border-color: rgb(240, 240, 240);
|
||||
border-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.line-th {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 4rpx 8rpx 2rpx 10rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
|
||||
&.no-pay {
|
||||
background-color: rgb(170, 170, 170);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.refund {
|
||||
background-color: #FCE7E7;
|
||||
padding: 8rpx 20rpx 6rpx 22rpx;
|
||||
color: #EB4F4F;
|
||||
}
|
||||
}
|
||||
|
||||
.tui {
|
||||
background-color: rgb(239, 239, 239);
|
||||
border-radius: 4rpx;
|
||||
margin-right: 6rpx;
|
||||
color: #666;
|
||||
padding: 0 4rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
</style>
|
||||
88
pagesOrder/detail/components/order.vue
Normal file
88
pagesOrder/detail/components/order.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<view class="default-box-padding bg-fff border-r-12 u-m-t-24">
|
||||
<view class="u-flex u-row-between">
|
||||
<view>订单状态</view>
|
||||
<view>{{returnStatus(data.status)}}</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24">
|
||||
<view>订单类型</view>
|
||||
<view>{{returnUseType(data.useType)}}</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24">
|
||||
<view>桌位号</view>
|
||||
<view>{{table.name||data.tableName}}</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24" v-if="seatFee.number">
|
||||
<view>就餐人数</view>
|
||||
<view>{{seatFee.number||''}}</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24">
|
||||
<view>支付方式</view>
|
||||
<view>{{data.payType||''}}</view>
|
||||
</view>
|
||||
<!-- <view class="u-flex u-row-between u-m-t-24">
|
||||
<view>预约时间</view>
|
||||
<view></view>
|
||||
</view> -->
|
||||
<view class="u-flex u-row-between u-m-t-24">
|
||||
<view>下单时间</view>
|
||||
<view><up-text v-if="data.createdAt" mode="date" format="yyyy-mm-dd hh:MM:ss"
|
||||
:text="data.createdAt"></up-text></view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24">
|
||||
<view>订单编号</view>
|
||||
<view class="u-flex">
|
||||
<view>{{data.orderNo}}</view>
|
||||
<view v-if="data.orderNo" class="u-m-l-6">
|
||||
<up-copy :content="data.orderNo" >
|
||||
<up-icon name="/static/copy.svg" :size="16"></up-icon>
|
||||
</up-copy>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-24 u-col-top">
|
||||
<view class="no-wrap">商家备注</view>
|
||||
<view class="u-p-l-32 " style="max-width: 522rpx; word-wrap: break-word;">
|
||||
{{data.remark}}
|
||||
</view>
|
||||
<!-- <my-button plain shape="circle" :width="160" :height="60">编辑</my-button> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import orderEnum from '@/commons/orderEnum.js'
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
table: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
seatFee: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
totalNumber: 0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function returnStatus(status) {
|
||||
const item = orderEnum.status.find(v => v.key == status)
|
||||
return item ? item.label : ''
|
||||
}
|
||||
|
||||
function returnUseType(useType) {
|
||||
if (!useType) {
|
||||
return ''
|
||||
}
|
||||
return useType == "takeout" ? '自取' : '堂食';
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
34
pagesOrder/detail/components/step.vue
Normal file
34
pagesOrder/detail/components/step.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<view class="default-box-padding bg-fff border-r-12 u-m-t-20">
|
||||
<my-step :list="recoders.list"></my-step>
|
||||
<!-- <up-steps :dot="true" current="0" direction="column">
|
||||
<up-steps-item title="2024-09-02 09:19" :itemStyle="itemStyle" desc="[东风(id:124413)]使用代客下单提交。(未打印预结单)">
|
||||
</up-steps-item>
|
||||
<up-steps-item title="2024-09-02 09:19" desc="[东风(id:124413)]使用代客下单提交。(未打印预结单)">
|
||||
</up-steps-item>
|
||||
</up-steps> -->
|
||||
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive
|
||||
} from 'vue';
|
||||
import color from '@/commons/color.js'
|
||||
const itemStyle = reactive({
|
||||
color: 'rgb(255,0,0)'
|
||||
})
|
||||
const recoders = reactive({
|
||||
list:[
|
||||
{title:'2024-09-15',content:'[东风(id:124413)]使用代客下单提交。(未打印预结单)'},
|
||||
{title:'2024-09-15',content:'[东风(id:124413)]使用代客下单提交。(未打印预结单)'},
|
||||
{title:'2024-09-15',content:'[东风(id:124413)]使用代客下单提交。(未打印预结单)'}
|
||||
],
|
||||
active:0
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
232
pagesOrder/detail/components/tuicai.vue
Normal file
232
pagesOrder/detail/components/tuicai.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<my-model title="退菜" ref="model" @close="onModelClose" @open="onModelOpen">
|
||||
<template #desc>
|
||||
<view class="u-p-30 u-text-left">
|
||||
<view>
|
||||
{{data.productName}}
|
||||
</view>
|
||||
<view class="u-flex u-m-t-32" :class="{'gray':data.productId=='-999'}">
|
||||
<up-number-box :min="1" :max="data.num" :buttonSize="44" v-model="number" integer :disabled="data.productId=='-999'">
|
||||
<template #minus>
|
||||
<view class="minus number-box-btn">
|
||||
</view>
|
||||
</template>
|
||||
<template #input>
|
||||
<view class="u-flex-1 u-row-center u-text-center input">
|
||||
<up-input
|
||||
:disabled="data.productId=='-999'"
|
||||
@change="parseIntNumber($event,false)" @blur="parseIntNumber($event,true)"
|
||||
v-model="number" border="none" type="number"></up-input>
|
||||
</view>
|
||||
</template>
|
||||
<template #plus>
|
||||
<view class="plus number-box-btn">
|
||||
<up-icon v-if="data.productId=='-999'" name="plus" color="#ccc" size="16" bold></up-icon>
|
||||
<up-icon v-else name="plus" color="#999" size="16" bold></up-icon>
|
||||
</view>
|
||||
</template>
|
||||
</up-number-box>
|
||||
</view>
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-font-24">
|
||||
<text class="color-999">退菜理由</text>
|
||||
<text class="color-red">*</text>
|
||||
</view>
|
||||
<view class="u-flex u-flex-wrap u-m-t-24">
|
||||
<view class="u-flex u-m-r-16 u-m-b-16" v-for="(item,index) in tags" :key="index">
|
||||
<up-tag @click="changeTagSel(item)" :text="item.label" plain borderColor="#E6FOFF"
|
||||
color="#318AFE" v-if="item.checked"> </up-tag>
|
||||
<up-tag @click="changeTagSel(item)" borderColor="#E5E5E5" color="#666" :text="item.label"
|
||||
plain v-else> </up-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-24">
|
||||
<up-textarea v-model="form.note" placeholder="备注"></up-textarea>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template #btn>
|
||||
<view class="u-p-t-18 u-p-l-30 u-p-r-30 u-p-b-10">
|
||||
<my-button box-shadow shape="circle" @tap="confirm">确认退菜</my-button>
|
||||
<view class="u-m-t-10">
|
||||
<my-button @tap="onModelClose" shape="circle" bgColor="#fff" type="cancel"
|
||||
box-shadow>取消</my-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
</my-model>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
import infoBox from '@/commons/utils/infoBox.js'
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
productId:'-999'
|
||||
}
|
||||
}
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const form = reactive({
|
||||
note: ''
|
||||
})
|
||||
const emits = defineEmits(['update:show', 'confirm'])
|
||||
let model = ref(null)
|
||||
let modelShow = ref(props.show)
|
||||
let number = ref(1)
|
||||
const tags = ref([{
|
||||
label: "点错",
|
||||
checked: false
|
||||
}, {
|
||||
label: "不想要了",
|
||||
checked: false
|
||||
}, {
|
||||
label: "食材不足",
|
||||
checked: false
|
||||
}, {
|
||||
label: "等待时间过长",
|
||||
checked: false
|
||||
}])
|
||||
let timer = null
|
||||
|
||||
function parseIntNumber(val, isNow) {
|
||||
console.log(val);
|
||||
let newval = parseInt(val)
|
||||
if (newval > props.data.num) {
|
||||
newval = props.data.num
|
||||
}
|
||||
if (newval < 1) {
|
||||
newval = 1
|
||||
}
|
||||
if (isNow) {
|
||||
number.value = parseInt(newval)
|
||||
return
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
number.value = newval
|
||||
}, 100)
|
||||
}
|
||||
|
||||
function changeTagSel(item) {
|
||||
item.checked = !item.checked
|
||||
}
|
||||
watch(() => props.show, (newval) => {
|
||||
modelShow.value = newval
|
||||
})
|
||||
watch(() => modelShow.value, (newval) => {
|
||||
emits('update:show', newval)
|
||||
if (newval) {
|
||||
open()
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
})
|
||||
|
||||
function toggleModelShow(show) {
|
||||
modelShow.value = show ? true : false
|
||||
}
|
||||
|
||||
|
||||
function onModelClose() {
|
||||
number.value=1
|
||||
modelShow.value = false
|
||||
}
|
||||
|
||||
function onModelOpen() {
|
||||
modelShow.value = true
|
||||
}
|
||||
|
||||
function open() {
|
||||
model.value.open()
|
||||
if(props.data.productId=='-999'){
|
||||
number.value=props.data.num
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
model.value.close()
|
||||
tags.value.map(v=>{
|
||||
v.checked=false
|
||||
})
|
||||
form.note=''
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
const selTag = tags.value.filter(item => item.checked).map(item => item.label).join(",")
|
||||
const note = selTag + (form.note.length > 0 ? "," + form.note : "");
|
||||
console.log({
|
||||
note,
|
||||
num: number.value
|
||||
});
|
||||
if (!note) {
|
||||
return infoBox.showToast("请输入退菜原因");
|
||||
}
|
||||
emits('confirm', {
|
||||
note,
|
||||
num: number.value
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.number-box-btn {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 122rpx;
|
||||
height: 84rpx;
|
||||
background: #F7F7FA;
|
||||
border-radius: 8rpx 0rpx 0rpx 8rpx;
|
||||
border: 2rpx solid #F9F9F9;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input {
|
||||
border: 2rpx solid #F9F9F9;
|
||||
}
|
||||
|
||||
::v-deep .u-input__content__field-wrapper__field {
|
||||
height: 84rpx;
|
||||
}
|
||||
|
||||
::v-deep .uni-input-input {
|
||||
text-align: center;
|
||||
}
|
||||
.gray{
|
||||
.minus::after{
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
}
|
||||
.minus {
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 28rpx;
|
||||
height: 0rpx;
|
||||
border: 1px solid #999999;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .u-border {
|
||||
border-width: 1px !important;
|
||||
}
|
||||
|
||||
::v-deep .u-number-box {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
89
pagesOrder/detail/components/user.vue
Normal file
89
pagesOrder/detail/components/user.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<view class="u-font-28 default-box-padding u-relative bg-fff border-r-12 u-overflow-hide">
|
||||
<template v-if="orderInfo.status=='unpaid'">
|
||||
<view class="change u-absolute color-fff left-top" @click="chooseUser">切换</view>
|
||||
</template>
|
||||
<template v-if="user.id">
|
||||
<view class="u-flex u-row-between u-m-t-20 border-bottom u-p-b-20">
|
||||
<view class="u-flex">
|
||||
<up-avatar :size="30" :src="user.headImg"></up-avatar>
|
||||
<view class="color-666 u-m-l-30">{{user.telephone||'未绑定手机号'}}</view>
|
||||
</view>
|
||||
<view>
|
||||
<my-button @click="toOrder" :height="60" plain shape="circle">他的订单</my-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="u-flex u-row-between u-m-t-20 border-bottom u-p-b-24">
|
||||
<view class="u-flex">
|
||||
<up-avatar :size="30" :src="user.headImg"></up-avatar>
|
||||
<view class="color-666 u-m-l-30">{{'服务员下单'}}</view>
|
||||
</view>
|
||||
<view>
|
||||
<my-button width="128" height="48" @click="toOrder" :height="60" plain shape="circle">
|
||||
<text class="u-font-24 no-wrap">他的订单</text>
|
||||
</my-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<view class="u-flex u-m-t-24 u-row-between u-font-28">
|
||||
<view class="">
|
||||
<view class="font-bold ">{{user.amount}}</view>
|
||||
<view class="color-666 u-m-t-8 u-font-24">余额</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<view class="font-bold">{{user.accountPoints}}</view>
|
||||
<view class="color-666 u-m-t-8 u-font-24">积分</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<view class="font-bold u-text-center">{{user.orderNumber||0}}</view>
|
||||
<view class="color-666 u-m-t-8 u-font-24">订单数量</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import go from '@/commons/utils/go.js'
|
||||
const props = defineProps({
|
||||
orderInfo: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
status:''
|
||||
}
|
||||
},
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
id:'',
|
||||
headImg:'',
|
||||
telephone:'',
|
||||
amount:'0.00',
|
||||
accountPoints:'0.00'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function toOrder(){
|
||||
go.to('PAGES_ORDER_INDEX',{
|
||||
userId:props.user.id||'',
|
||||
type:'user'
|
||||
})
|
||||
}
|
||||
|
||||
function chooseUser() {
|
||||
go.to('PAGES_CHOOSE_USER')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.change {
|
||||
padding: 2rpx 22rpx 4rpx 14rpx;
|
||||
border-radius: 18rpx 0rpx 18rpx 0rpx;
|
||||
background: linear-gradient( 139deg, #74B0FF 0%, #318AFE 100%);
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
||||
381
pagesOrder/detail/detail.vue
Normal file
381
pagesOrder/detail/detail.vue
Normal file
@@ -0,0 +1,381 @@
|
||||
<template>
|
||||
<view class="min-page bg-gray u-font-28 u-p-30">
|
||||
<user-vue :orderInfo="orderDetail.info" :user="user"></user-vue>
|
||||
<!-- <view class="default-box-padding bg-fff border-r-12 u-m-t-32">
|
||||
<text class="">桌位号:</text>
|
||||
<text class="">{{orderDetail.info.tableName}}</text>
|
||||
</view> -->
|
||||
<goods-list @printOrder="onPrintOrder" @tuikuan="onTuikuan" :orderInfo="orderDetail.info"
|
||||
:user="user"
|
||||
:data="orderDetail.goodsList" :seatFee="orderDetail.seatFee" @tuicai="onTuiCai"></goods-list>
|
||||
<!-- <template v-if="orderDetail.seatFee.totalNumber&&orderDetail.seatFee.totalAmount"> -->
|
||||
|
||||
<!-- <view class="default-box-padding bg-fff border-r-12 u-m-t-20 u-flex u-row-between" v-if="orderDetail.info.discountAmount>0">
|
||||
<view>服务员改价</view>
|
||||
<view class="color-red">-¥{{orderDetail.info.discountAmount}}</view>
|
||||
</view> -->
|
||||
<template v-if="true">
|
||||
<extra-vue @tuicai="onSeatFeeTuicai" @tuikuan="onSeatFeeTuiKuan" :orderInfo="orderDetail.info"
|
||||
:data="orderDetail.seatFee"></extra-vue>
|
||||
</template>
|
||||
<order-vue :data="orderDetail.info" :table="options" :seatFee="orderDetail.seatFee"></order-vue>
|
||||
<!-- <step-vue></step-vue> -->
|
||||
<view style="height: 200rpx;"></view>
|
||||
<view class="u-fixed bottom bg-fff ">
|
||||
<view class="u-flex u-abso">
|
||||
<template v-if="orderDetail.info.useType=='takeout'||!orderDetail.info.tableId||orderDetail.info.useType=='dine-in-before'">
|
||||
<view class="u-flex-1" v-if="orderDetail.info.status=='unpaid'">
|
||||
<my-button @tap="toPay" borderRadius="100rpx" shape="circle"
|
||||
type="primary">结账</my-button>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="orderDetail.info.status=='unpaid'">
|
||||
<view class="u-flex-1">
|
||||
<my-button @tap="diancan" color="#fff" bgColor="rgb(57,53,52)" borderRadius="100rpx 0 0 100rpx" fontWeight="700"
|
||||
shape="circle" plain type="primary">加菜</my-button>
|
||||
</view>
|
||||
<view class="u-flex-1">
|
||||
<my-button @tap="toPay" borderRadius="0 100rpx 100rpx 0" shape="circle" fontWeight="700"
|
||||
type="primary">结账</my-button>
|
||||
</view>
|
||||
</template>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<tuicai-vue @confirm="tuicaiConfirm" v-model:show="tuicai.show" :data="tuicai.selGoods"></tuicai-vue>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as Api from '@/http/yskApi/Instead.js'
|
||||
import * as orderApi from '@/http/yskApi/order.js'
|
||||
import {queryAllShopUser} from '@/http/yskApi/shop-user.js'
|
||||
import {
|
||||
objToArrary
|
||||
} from '@/commons/utils/returrn-data.js'
|
||||
import userVue from './components/user.vue';
|
||||
import orderVue from './components/order.vue';
|
||||
import goodsList from './components/list.vue';
|
||||
import stepVue from './components/step.vue';
|
||||
import extraVue from './components/extra.vue';
|
||||
import tuicaiVue from './components/tuicai.vue';
|
||||
import go from '@/commons/utils/go.js'
|
||||
import infoBox from '@/commons/utils/infoBox.js'
|
||||
import {hasPermission} from '@/commons/utils/hasPermission.js'
|
||||
import {
|
||||
onLoad,
|
||||
onShow,
|
||||
onHide
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
reactive,
|
||||
ref
|
||||
} from 'vue';
|
||||
import OrderDetail from './page.js'
|
||||
const tuicai = reactive({
|
||||
show: false,
|
||||
isSeatFee: false,
|
||||
selGoods: {}
|
||||
})
|
||||
|
||||
function onSeatFeeTuicai(seatFee) {
|
||||
seatFee={...seatFee,num:seatFee.num,productName:seatFee.productName}
|
||||
console.log(seatFee);
|
||||
tuicai.show = true
|
||||
tuicai.isSeatFee = seatFee
|
||||
tuicai.selGoods = seatFee
|
||||
}
|
||||
//是否有允许退款权限
|
||||
async function hasTuiKuan(){
|
||||
const isHas=await hasPermission('允许退款')
|
||||
return isHas
|
||||
}
|
||||
|
||||
async function onSeatFeeTuiKuan(seatFee) {
|
||||
console.log(seatFee);
|
||||
const canTuikuan=await hasTuiKuan()
|
||||
if(!canTuikuan){
|
||||
return
|
||||
}
|
||||
const {
|
||||
id,cartId,
|
||||
productId,
|
||||
productSkuId,
|
||||
productName,
|
||||
num,
|
||||
priceAmount,
|
||||
price
|
||||
} = seatFee
|
||||
go.to('PAGES_ORDER_TUIKUAN', {
|
||||
orderId:orderDetail.info.id,
|
||||
id,
|
||||
cartId,
|
||||
productId,
|
||||
productSkuId,
|
||||
productName,
|
||||
num,
|
||||
number: 0,
|
||||
productSkuName: '',
|
||||
priceAmount,
|
||||
price
|
||||
})
|
||||
}
|
||||
|
||||
function onTuiCai(goods, index) {
|
||||
console.log(goods);
|
||||
tuicai.show = true
|
||||
tuicai.selGoods = goods
|
||||
}
|
||||
async function tuicaiConfirm(e) {
|
||||
console.log(tuicai.selGoods);
|
||||
const res = await Api.$returnCart({
|
||||
...e,
|
||||
cartId: tuicai.selGoods.hasOwnProperty('cartId') ? tuicai.selGoods.cartId : tuicai.selGoods.id,
|
||||
tableId: orderDetail.info.tableId,
|
||||
})
|
||||
tuicai.show = false
|
||||
init()
|
||||
}
|
||||
|
||||
|
||||
async function printDishes() {
|
||||
try {
|
||||
const res = await Api.$printDishes({
|
||||
tableId: orderDetail.info.tableId
|
||||
})
|
||||
infoBox.showToast('已发送打印请求')
|
||||
} catch (e) {
|
||||
infoBox.showToast('发送打印请求失败')
|
||||
//TODO handle the exception
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onPrintOrder() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '是否打印当前台桌菜品',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
printDishes()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async function onTuikuan(goods, index) {
|
||||
const canTuikuan=await hasTuiKuan()
|
||||
if(!canTuikuan){
|
||||
return
|
||||
}
|
||||
console.log(goods);
|
||||
const {
|
||||
id,
|
||||
productId,
|
||||
productSkuId,
|
||||
productName,
|
||||
productSkuName,
|
||||
cartId,
|
||||
orderId,
|
||||
num,
|
||||
priceAmount,
|
||||
price,userCouponId
|
||||
} = goods
|
||||
go.to('PAGES_ORDER_TUIKUAN', {
|
||||
id,
|
||||
cartId,
|
||||
orderId,
|
||||
productId,
|
||||
productSkuId,
|
||||
productName,
|
||||
num,
|
||||
number: 0,
|
||||
productSkuName: productSkuName || '',
|
||||
priceAmount:priceAmount?priceAmount:(num*price).toFixed(2),
|
||||
price,
|
||||
userCouponId:userCouponId?userCouponId:''
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
const uiPage = new OrderDetail()
|
||||
setTimeout(() => {
|
||||
uiPage.setVal('user', {
|
||||
name: 1
|
||||
})
|
||||
}, 1500)
|
||||
|
||||
async function diancan() {
|
||||
const canXiadan=await hasPermission('允许下单')
|
||||
if(!canXiadan){
|
||||
return
|
||||
}
|
||||
clearEmit()
|
||||
go.to('PAGES_CREATE_ORDER', {
|
||||
tableId: options.tableId || orderDetail.info.tableId,
|
||||
name: options.name || orderDetail.info.tableName,
|
||||
masterId:orderDetail.info.masterId,
|
||||
type: 'add'
|
||||
})
|
||||
}
|
||||
|
||||
async function toPay() {
|
||||
const canJieZhang=await hasPermission('允许收款')
|
||||
if(!canJieZhang){
|
||||
return
|
||||
}
|
||||
const memberId=orderDetail.info.memberId||''
|
||||
clearEmit()
|
||||
go.to('PAGES_ORDER_PAY', {
|
||||
tableId: options.tableId|| orderDetail.info.tableId,
|
||||
tableName: options.name,
|
||||
masterId: options.masterId,
|
||||
orderId: orderDetail.info.id,
|
||||
discount: 1,
|
||||
memberId
|
||||
})
|
||||
}
|
||||
|
||||
const orderDetail = reactive({
|
||||
goodsList: [],
|
||||
info: {},
|
||||
seatFee: {
|
||||
totalAmount: 0
|
||||
}
|
||||
})
|
||||
const options = reactive({})
|
||||
async function init() {
|
||||
const res = await orderApi.tbOrderInfoDetail(options.id)
|
||||
if(res.memberId){
|
||||
queryAllShopUser({id:res.memberId}).then(res=>{
|
||||
if(res.content[0]){
|
||||
user.value=res.content[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
if (res.detailList.length) {
|
||||
uni.setStorageSync('useType', res.detailList[0].useType)
|
||||
}
|
||||
const masterId = res.masterId
|
||||
options.masterId = res.masterId
|
||||
// if (res.status == 'unpaid') {
|
||||
if (false) {
|
||||
const {
|
||||
records,
|
||||
seatFee
|
||||
} = await Api.getCart({
|
||||
masterId,
|
||||
tableId: res.tableId,
|
||||
page: 1,
|
||||
size: 200
|
||||
})
|
||||
orderDetail.goodsList = records
|
||||
orderDetail.seatFee = seatFee ? seatFee : orderDetail.seatFee
|
||||
} else {
|
||||
const goodsMap = {}
|
||||
for (let i in res.detailList) {
|
||||
const goods = res.detailList[i]
|
||||
if (goods.productName != '客座费') {
|
||||
if (goodsMap.hasOwnProperty(goods.placeNum)) {
|
||||
goodsMap[goods.placeNum].push(goods)
|
||||
} else {
|
||||
goodsMap[goods.placeNum] = [goods]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
console.log(res.seatInfo);
|
||||
orderDetail.seatFee = res.seatInfo|| {
|
||||
// name: '客座费',
|
||||
// number: res.seatCount,
|
||||
// num: res.seatCount,
|
||||
// totalNumber: res.seatCount,
|
||||
// priceAmount: res.seatAmount,
|
||||
// status:'',
|
||||
totalNumber:0,
|
||||
}
|
||||
orderDetail.goodsList = Object.entries(goodsMap).map(([key, value]) => ({
|
||||
info: value,
|
||||
placeNum: key
|
||||
}))
|
||||
console.log(orderDetail.goodsList);
|
||||
}
|
||||
orderDetail.info = res
|
||||
}
|
||||
|
||||
function watchEmit() {
|
||||
uni.$off('orderDetail:update')
|
||||
uni.$once('orderDetail:update', (newval) => {
|
||||
console.log(newval);
|
||||
init()
|
||||
})
|
||||
}
|
||||
|
||||
// 监听选择用户事件
|
||||
let user = ref({
|
||||
headImg:'',
|
||||
telephone:'',
|
||||
amount:'0.00',
|
||||
accountPoints:'0.00'
|
||||
})
|
||||
//更新选择用户
|
||||
async function setUser(par) {
|
||||
const submitPar = {
|
||||
orderId:options.id||'',
|
||||
masterId: options.masterId,
|
||||
tableId: options.tableId|| orderDetail.info.tableId,
|
||||
vipUserId: user.value.id ? user.value.id : '',
|
||||
type: user.value.id ? 0 : 1 //0 设置 1 取消
|
||||
}
|
||||
Object.assign(submitPar, par)
|
||||
const res=await Api.$setUser(submitPar)
|
||||
init()
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
function clearEmit(){
|
||||
uni.$off('choose-user')
|
||||
uni.$off('orderDetail:update')
|
||||
}
|
||||
|
||||
function watchChooseuser() {
|
||||
uni.$off('choose-user')
|
||||
uni.$on('choose-user', (data) => {
|
||||
console.log(data);
|
||||
user.value = data
|
||||
setUser()
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
watchEmit()
|
||||
watchChooseuser()
|
||||
init()
|
||||
})
|
||||
onLoad((opt) => {
|
||||
Object.assign(options, opt)
|
||||
console.log(options);
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bottom {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 68rpx;
|
||||
|
||||
.u-abso {
|
||||
bottom: 84rpx;
|
||||
left: 28rpx;
|
||||
right: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
23
pagesOrder/detail/page.js
Normal file
23
pagesOrder/detail/page.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import {
|
||||
reactive, ref
|
||||
} from 'vue';
|
||||
function isSameType(a, b) {
|
||||
return a instanceof b === true || b instanceof a === true;
|
||||
}
|
||||
class OrderDetail {
|
||||
constructor(data) {
|
||||
const user ={}
|
||||
const table = {}
|
||||
const goodsList =[]
|
||||
const orderInfo = {}
|
||||
this.data=reactive({
|
||||
user,table,goodsList,orderInfo
|
||||
})
|
||||
Object.assign(this, data)
|
||||
}
|
||||
setVal(key,val){
|
||||
this.data[key]=val
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderDetail
|
||||
270
pagesOrder/index/compoents/filter.vue
Normal file
270
pagesOrder/index/compoents/filter.vue
Normal file
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="u-flex bg-fff u-p-l-28 u-p-r-28 u-row-between">
|
||||
<view class="u-rela time-item tranistion-2" @click="changeTimeDataSel(index)"
|
||||
:class="{active:timeData.sel==index}" v-for="(item,index) in timeData.list" :key="index">
|
||||
{{item.label}}
|
||||
</view>
|
||||
<view class="u-rela time-item tranistion-2" @click="changeTimeDataSel(-1)"
|
||||
:class="{active:timeData.sel==-1}">自定义</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-t-2 bg-fff u-col-center u-flex u-p-l-28 u-p-r-28 u-p-t-30 u-row-between">
|
||||
<view class="status-item " @click="changeStatusSel(item.value)" :class="{active:statusData.sel==item.value}"
|
||||
v-for="(item,index) in statusData.list" :key="index">
|
||||
{{item.label}}
|
||||
</view>
|
||||
<view class="status-item u-flex" @click="moreShowOpen">
|
||||
<image src="@/pagesOrder/static/image/icon-search.svg" style="width: 38rpx;height: 30rpx;" mode="">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <template v-if="type&&userShow">
|
||||
<view class="u-p-l-28 u-flex u-p-r-28 u-p-t-10 bg-gray" v-if="userShow">
|
||||
<view class="time-area u-font-24 color-main u-flex">
|
||||
<up-avatar :size="22" :src="user.headImg"></up-avatar>
|
||||
<view class="u-m-l-10 u-m-r-10">
|
||||
<text v-if="user.id">{{user.telephone||user.nickName}}</text>
|
||||
<text v-else>服务员下单</text>
|
||||
</view>
|
||||
<up-icon name="close-circle-fill" :color="color.ColorMain" @click="userShowClose"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-p-l-28 u-flex u-p-r-28 u-p-t-10 bg-gray" v-else>
|
||||
<view class="time-area u-font-24 color-main u-flex">
|
||||
<up-avatar :size="22" ></up-avatar>
|
||||
<view class="u-m-l-10 u-m-r-10">
|
||||
服务员下单
|
||||
</view>
|
||||
<up-icon name="close-circle-fill" :color="color.ColorMain" @click="userShowClose"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
</template> -->
|
||||
|
||||
|
||||
<!-- <view class="u-p-l-28 u-flex u-p-r-28 u-p-t-10 bg-gray" v-if="time.length">
|
||||
<view class="time-area u-font-24 color-main u-flex">
|
||||
<uni-dateformat format="yyyy-MM-dd hh:mm:ss" :date="time[0]"></uni-dateformat>
|
||||
<text class="u-p-l-10 u-p-r-10">至</text>
|
||||
<uni-dateformat format="yyyy-MM-dd hh:mm:ss" :date="time[1]"></uni-dateformat>
|
||||
</view>
|
||||
</view> -->
|
||||
<my-date-pickerview @confirm="datePickerConfirm" ref="datePicker" mode="all"></my-date-pickerview>
|
||||
<!-- 更多状态选择筛选 -->
|
||||
<up-popup :round="10" :show="statusData.moreShow" :closeable="true" @close="moreShowHide">
|
||||
<view class="u-text-center font-bold u-font-32 u-p-t-30">选择状态</view>
|
||||
<view style="height: 20rpx;"></view>
|
||||
<view class="u-p-30 all-list u-flex u-flex-wrap gap-20">
|
||||
<view class="all-list-item" :class="{active:statusItemIndex==statusData.allListSel}"
|
||||
@click="changeAllListSel(statusItemIndex,statusItem)"
|
||||
v-for="(statusItem,statusItemIndex) in statusData.allList" :key="statusItemIndex">
|
||||
{{statusItem.label}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-p-t-30 u-p-b-30 u-p-l-20 u-p-r-20 gap-20">
|
||||
<up-button @click="moreShowHide">取消</up-button>
|
||||
<up-button type="primary" @click="statusConfirm">确定</up-button>
|
||||
</view>
|
||||
</up-popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import orderEnum from '@/commons/orderEnum.js'
|
||||
import * as $time from '@/commons/utils/dayjs-time.js';
|
||||
import color from '@/commons/color.js';
|
||||
import {
|
||||
reactive,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
|
||||
const emits = defineEmits(['update:time', 'update:status','clearUser','updateStatus'])
|
||||
|
||||
function userShowClose() {
|
||||
userShow.value = false
|
||||
emits('clearUser')
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
time: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
status: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
user: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
userId: ''
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
type:{
|
||||
type:String,
|
||||
default:''//user 查看具体用户订单
|
||||
}
|
||||
})
|
||||
let userShow = ref(props.type? true : false)
|
||||
console.log(props.type);
|
||||
watch(() => props.type, (newval) => {
|
||||
console.log(newval);
|
||||
if (newval) {
|
||||
userShow.value = true
|
||||
}
|
||||
})
|
||||
|
||||
let datePicker = ref(null)
|
||||
// 示例使用
|
||||
const today = $time.getTodayTimestamps();
|
||||
const yesterday = $time.getYesterdayTimestamps();
|
||||
const thisWeek = $time.getThisWeekTimestamps();
|
||||
const thisMonth = $time.getThisMonthTimestamps();
|
||||
const timeData = reactive({
|
||||
list: [today, yesterday, thisWeek, thisMonth],
|
||||
sel: 0
|
||||
})
|
||||
|
||||
function changeTimeDataSel(i) {
|
||||
timeData.sel = i
|
||||
if (i == -1) {
|
||||
datePicker.value.open()
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => timeData.sel, (newval) => {
|
||||
|
||||
const data = timeData.list[newval]
|
||||
if (newval != -1) {
|
||||
emits('update:time', [data.start, data.end])
|
||||
}
|
||||
})
|
||||
|
||||
const statusData = reactive({
|
||||
allList: orderEnum.status,
|
||||
moreShow: false,
|
||||
allListSel: -1,
|
||||
list: [{
|
||||
label: '全部',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '待支付',
|
||||
value: 'unpaid'
|
||||
},
|
||||
// {
|
||||
// label: '待完成',
|
||||
// value: ''
|
||||
// },
|
||||
{
|
||||
label: '已完成',
|
||||
value: 'closed'
|
||||
},
|
||||
// {
|
||||
// label: '未支付',
|
||||
// value: 'unpaid'
|
||||
// },
|
||||
{
|
||||
label: '已退款',
|
||||
value: 'refund'
|
||||
}
|
||||
],
|
||||
sel: ''
|
||||
})
|
||||
|
||||
function moreShowHide() {
|
||||
statusData.moreShow = false
|
||||
}
|
||||
|
||||
function moreShowOpen() {
|
||||
statusData.moreShow = true
|
||||
}
|
||||
|
||||
function changeStatusSel(i) {
|
||||
statusData.sel = i
|
||||
emits('updateStatus', i)
|
||||
}
|
||||
|
||||
function datePickerConfirm(e) {
|
||||
console.log(e);
|
||||
emits('update:time', [e.start, e.end])
|
||||
}
|
||||
|
||||
function changeAllListSel(i,item) {
|
||||
statusData.allListSel = i
|
||||
console.log(i);
|
||||
}
|
||||
function statusConfirm(){
|
||||
const status=statusData.allList[statusData.allListSel].key
|
||||
statusData.sel=status
|
||||
emits('updateStatus',status)
|
||||
moreShowHide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.status-item {
|
||||
color: #666;
|
||||
transition: all .2s ease-in-out;
|
||||
padding-bottom: 24rpx;
|
||||
|
||||
&.active {
|
||||
color: $my-main-color;
|
||||
}
|
||||
}
|
||||
|
||||
.all-list-item {
|
||||
text-align: center;
|
||||
width: 156rpx;
|
||||
white-space: nowrap;
|
||||
color: #666;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
transition: all .2s ease-in-out;
|
||||
border: 1px solid #eee;
|
||||
|
||||
&.active {
|
||||
color: $my-main-color;
|
||||
border-color: $my-main-color;
|
||||
}
|
||||
}
|
||||
|
||||
.time-item {
|
||||
color: #666;
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 4rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 4rpx 4rpx 4rpx 4rpx;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $my-main-color;
|
||||
// font-size: 32rpx;
|
||||
transform: scale(1.1);
|
||||
transform-origin: center;
|
||||
font-weight: 700;
|
||||
|
||||
&::after {
|
||||
background: #318AFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time-area {
|
||||
background: #E6F0FF;
|
||||
border-radius: 100px;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
</style>
|
||||
289
pagesOrder/index/compoents/order-item.vue
Normal file
289
pagesOrder/index/compoents/order-item.vue
Normal file
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<view class="bg-fff item" @click="toDetail">
|
||||
<view class="u-flex u-p-b-22 border-bottom u-row-between u-col-center">
|
||||
<view class="u-flex u-col-bottom">
|
||||
<template v-if="data.tableName">
|
||||
<view class="u-flex u-col-center">
|
||||
<view class="u-font-40 color-333">{{data.tableName}}</view>
|
||||
<view class="line" style="height: 16px;"></view>
|
||||
</view>
|
||||
</template>
|
||||
<view class="">{{data.masterId}}</view>
|
||||
</view>
|
||||
<view class="u-flex">
|
||||
<view>
|
||||
<text :class="[data.status]">{{returnStatus(data.status)}}</text>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class=" color-main">
|
||||
<text>
|
||||
{{sendTypeFilter(data.sendType)}}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-26">
|
||||
<view class="u-flex u-col-bottom u-font-24 color-999">
|
||||
<up-avatar :size="33"></up-avatar>
|
||||
<view class="u-m-l-16">{{formatTime(data.createdAt)}}</view>
|
||||
</view>
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-font-32">{{goosZhonglei}}种商品,共{{goodsNumber}}件</view>
|
||||
<view class="border-bottom u-p-b-32">
|
||||
<view class="" v-for="(item,index) in data.detailList" :key="index">
|
||||
<view class="u-flex u-row-between u-col-top u-m-t-32" v-if="item.productId!=-999">
|
||||
<view>
|
||||
<view class=""> {{item.productName}}</view>
|
||||
<view class="color-999 u-font-24 u-m-t-8">
|
||||
{{item.productSkuName}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-flex-1 u-row-right">
|
||||
<view>×{{item.num}}</view>
|
||||
<template v-if="item.gift||item.userCouponId">
|
||||
<view class="u-text-right u-relative" :style="computedPriceStyle()">
|
||||
<text class="line-th">¥{{goodsPriceAmount(item)}}</text>
|
||||
<view class="u-absolute" style="bottom: 100%;right: 0;">
|
||||
¥0
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else-if="item.isMember&&data.memberId&&item.memberPrice&&item.memberPrice!=item.price">
|
||||
<view class="u-text-right u-relative" :style="computedPriceStyle()">
|
||||
<text class="line-th">¥{{goodsPriceAmount(item)}}</text>
|
||||
<view class="u-absolute" style="bottom: 100%;right: 0;">
|
||||
¥{{goodsVipPriceAmount(item)}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="u-text-right u-relative" :style="computedPriceStyle()">
|
||||
<text>¥{{goodsPriceAmount(item)}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="border-bottom u-p-t-32 u-p-b-32"
|
||||
v-if="data.packFee>0||(data.seatInfo&&data.seatInfo.priceAmount>0)">
|
||||
<view class="u-flex u-row-between u-col-top" v-if="data.packFee>0">
|
||||
<view class="no-wrap u-m-r-32">打包费</view>
|
||||
<view>¥{{data.packFee||0}}</view>
|
||||
</view>
|
||||
<view style="height: 32rpx;" v-if="data.packFee>0&&data.seatInfo&&data.seatInfo.priceAmount>0"></view>
|
||||
<view class="u-flex u-row-between u-col-top" v-if="data.seatInfo&&data.seatInfo.priceAmount>0">
|
||||
<view class="no-wrap u-m-r-32">{{data.seatInfo.productName}}</view>
|
||||
<view>¥{{data.seatInfo.priceAmount}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="border-bottom u-p-b-32 u-m-t-32"
|
||||
v-if="data.fullCouponDiscountAmount>0||data.productCouponDiscountAmount>0||data.pointsDiscountAmount>0">
|
||||
<view class="u-flex u-row-between u-col-top" v-if="data.fullCouponDiscountAmount>0">
|
||||
<view class="no-wrap u-m-r-32">满减券抵扣</view>
|
||||
<view class="color-red">-¥{{data.fullCouponDiscountAmount||0}}</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-32 u-col-top" v-if="data.productCouponDiscountAmount>0">
|
||||
<view class="no-wrap u-m-r-32">商品券抵扣</view>
|
||||
<view class="color-red">-¥{{data.productCouponDiscountAmount||0}}</view>
|
||||
</view>
|
||||
<view class="u-flex u-row-between u-m-t-32 u-col-top" v-if="data.pointsDiscountAmount>0">
|
||||
<view class="no-wrap u-m-r-32">积分抵扣</view>
|
||||
<view class="color-red">-¥{{data.pointsDiscountAmount||0}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
<view class="u-flex u-row-between border-bottom u-m-t-32 u-p-b-32 u-col-top">
|
||||
<view class="no-wrap u-m-r-32">订单备注</view>
|
||||
<view>{{data.remark||'无'}}</view>
|
||||
</view>
|
||||
<view class="u-m-t-32">
|
||||
<view class="u-flex u-row-right">
|
||||
<text>总计¥</text>
|
||||
<text class="font-bold u-font-32">{{data.orderAmount}}</text>
|
||||
</view>
|
||||
<view class="u-flex u-row-right u-m-t-24">
|
||||
<view class="print" @click.stop="print(item)">重新打印</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dayjs from 'dayjs';
|
||||
import orderEnum from '@/commons/orderEnum.js'
|
||||
import go from '@/commons/utils/go.js'
|
||||
import {
|
||||
isTui,
|
||||
canTuiKuan,
|
||||
canTuicai
|
||||
} from '@/commons/utils/goodsUtil.js'
|
||||
import {
|
||||
computed,
|
||||
reactive,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
const emits = defineEmits(['printOrder'])
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
packFee: 0,
|
||||
seatInfo: {
|
||||
productName: '客座费',
|
||||
priceAmount: 0
|
||||
},
|
||||
detailList: []
|
||||
}
|
||||
}
|
||||
},
|
||||
index: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
let $goodsMap = {}
|
||||
let goosZhonglei = ref(0)
|
||||
let goodsNumber = ref(0)
|
||||
|
||||
const priceSize = 9
|
||||
let minWidth=ref(36)
|
||||
function goodsPriceAmount(item) {
|
||||
const total=(item.price * item.num).toFixed(2)
|
||||
const minW=total.length * priceSize + 15
|
||||
minWidth.value=minW<minWidth.value?minWidth.value:minW
|
||||
return total
|
||||
}
|
||||
|
||||
function goodsVipPriceAmount(item) {
|
||||
const price = item.memberPrice ? item.memberPrice : item.price
|
||||
return (price * item.num).toFixed(2)
|
||||
}
|
||||
// const packeFee=computed(()=>{
|
||||
// return props.data.detailList.reduce((prve,cur)=>{
|
||||
// return prve+cur.packAmount
|
||||
// },0).toFixed(2)
|
||||
// })
|
||||
function computedPriceStyle() {
|
||||
return {
|
||||
'min-width':minWidth.value + 'px'
|
||||
}
|
||||
}
|
||||
// const computedPriceStyle = computed(() => {
|
||||
|
||||
// })
|
||||
|
||||
function goodsMapInit() {
|
||||
for (let i in props.data.detailList) {
|
||||
const goods = props.data.detailList[i]
|
||||
if ($goodsMap.hasOwnProperty(goods.productId)) {
|
||||
$goodsMap[goods.productId] += goods.num * 1
|
||||
goodsNumber.value += goods.num * 1
|
||||
} else {
|
||||
$goodsMap[goods.productId] = goods.num * 1
|
||||
goosZhonglei.value += 1
|
||||
goodsNumber.value += goods.num * 1
|
||||
}
|
||||
}
|
||||
}
|
||||
goodsMapInit()
|
||||
watch(() => props.data.detailList.length, (newval) => {
|
||||
goodsNumber.value = 0
|
||||
goodsMapInit()
|
||||
})
|
||||
|
||||
|
||||
function formatTime(time) {
|
||||
return dayjs(time).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
|
||||
function returnStatus(status) {
|
||||
const item = orderEnum.status.find(v => v.key == status)
|
||||
return item ? item.label : ''
|
||||
}
|
||||
|
||||
function sendTypeFilter(t) {
|
||||
console.log(t);
|
||||
if (t) {
|
||||
const item = orderEnum.sendType.find(item => item.key == t)
|
||||
return item ? item.label : '';
|
||||
} else {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
function toDetail() {
|
||||
go.to('PAGES_ORDER_DETAIL', {
|
||||
id: props.data.id
|
||||
})
|
||||
}
|
||||
|
||||
function print(item) {
|
||||
emits('printOrder', props.data)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.border-bottom {
|
||||
border-bottom: 1rpx solid #E5E5E5;
|
||||
}
|
||||
|
||||
.u-font-40 {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 16rpx 24rpx 32rpx 24rpx;
|
||||
border-radius: 18rpx 18rpx 18rpx 18rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.unpaid {
|
||||
color: #FD7B49;
|
||||
}
|
||||
|
||||
.print {
|
||||
padding: 6rpx 14rpx 8rpx 18rpx;
|
||||
border: 1px solid $my-main-color;
|
||||
color: $my-main-color;
|
||||
font-size: 24rpx;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 14px;
|
||||
width: 1px;
|
||||
background-color: #E5E5E5;
|
||||
margin: 0 12rpx;
|
||||
}
|
||||
|
||||
.row {
|
||||
.top {
|
||||
display: flex;
|
||||
|
||||
.name {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.num {
|
||||
width: 20%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.price {
|
||||
width: 30%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
34
pagesOrder/index/compoents/order-list.vue
Normal file
34
pagesOrder/index/compoents/order-list.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<view class="list">
|
||||
<view v-for="(item,index) in list" :key="index">
|
||||
<order-item @printOrder="print" :key="index" :data="item" :index="index"></order-item>
|
||||
</view>
|
||||
<view v-if="hasAjax&&!list.length">
|
||||
<my-img-empty tips="亲,你还没有订单哦~"></my-img-empty>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import orderItem from './order-item.vue';
|
||||
const props=defineProps({
|
||||
list:{
|
||||
type:Array,
|
||||
default:()=>[]
|
||||
},
|
||||
hasAjax:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
}
|
||||
})
|
||||
const emits=defineEmits(['printOrder'])
|
||||
function print(item) {
|
||||
emits('printOrder',item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list {
|
||||
padding: 32rpx 28rpx;
|
||||
}
|
||||
</style>
|
||||
152
pagesOrder/index/index.vue
Normal file
152
pagesOrder/index/index.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<view class="min-page bg-gray u-font-28">
|
||||
<up-sticky offset-top="0">
|
||||
<view class="top">
|
||||
<view class="search bg-fff u-p-t-32 u-p-l-28 u-p-r-28 u-p-b-32">
|
||||
<up-search v-bind="search" v-model="search.val" @search="searchConfirm" @clear="searchConfirm" @custom="searchConfirm"></up-search>
|
||||
</view>
|
||||
<filter-vue @clearUser="clearQueryUser" @updateStatus="updateQuery('status',$event)" v-model:time="order.data.query.createdAt" :user="user" :type="option.type"></filter-vue>
|
||||
</view>
|
||||
</up-sticky>
|
||||
|
||||
<order-list @printOrder="onPrintOrder" :hasAjax="order.data.hasAjax" :list="order.data.list"></order-list>
|
||||
<template v-if="order.data.list.length>0">
|
||||
<my-pagination @change="pageChange" :totalElements="order.data.total"></my-pagination>
|
||||
</template>
|
||||
<view style="height: 100rpx;"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {onLoad,onShow,onPullDownRefresh} from '@dcloudio/uni-app'
|
||||
import * as Api from '@/http/yskApi/order.js'
|
||||
import {queryAllShopUser} from '@/http/yskApi/shop-user.js'
|
||||
|
||||
|
||||
import LIST from '@/commons/class/list.js'
|
||||
import {$printOrder} from '@/http/yskApi/Instead.js'
|
||||
import filterVue from './compoents/filter.vue';
|
||||
import orderList from './compoents/order-list.vue';
|
||||
import infoBox from '@/commons/utils/infoBox.js'
|
||||
import {
|
||||
reactive, ref, watch
|
||||
} from 'vue';
|
||||
import {getTodayTimestamps} from '@/commons/utils/dayjs-time.js';
|
||||
const search = reactive({
|
||||
val: '',
|
||||
placeholder: '搜索单号/商品名称',
|
||||
shape: 'square',
|
||||
inputStyle: {
|
||||
borderRadius: '12rpx'
|
||||
},
|
||||
actionStyle: {
|
||||
textAlign: 'right'
|
||||
}
|
||||
})
|
||||
|
||||
const today = getTodayTimestamps();
|
||||
const order=new LIST({
|
||||
list: [],
|
||||
query: {
|
||||
createdAt: [today.start,today.end],
|
||||
id: "",
|
||||
orderNo: "",
|
||||
orderType: "0",
|
||||
page: 0,
|
||||
pageSize: 10,
|
||||
payType: "",
|
||||
productName: "",
|
||||
status: "",
|
||||
userId:''
|
||||
}
|
||||
})
|
||||
console.log(order.data);
|
||||
function clearQueryUser(){
|
||||
order.setQuery('userId','')
|
||||
}
|
||||
function pageChange(e){
|
||||
const newPage=e-1
|
||||
order.setVal('page',newPage)
|
||||
order.setQuery('page',newPage)
|
||||
init()
|
||||
}
|
||||
function updateQuery(key,e){
|
||||
order.setQuery(key,e)
|
||||
}
|
||||
watch(()=>order.data.query.createdAt,(newval)=>{
|
||||
init()
|
||||
})
|
||||
watch(()=>order.data.query.status,(newval)=>{
|
||||
init()
|
||||
})
|
||||
watch(()=>order.data.query.userId,(newval)=>{
|
||||
init()
|
||||
})
|
||||
function searchConfirm(){
|
||||
order.setQuery('page',0)
|
||||
init()
|
||||
}
|
||||
async function init() {
|
||||
console.log(order.data.query);
|
||||
const {content,totalElements}=await Api.tbOrderInfoData({...order.data.query,page:order.data.query.page,keyword:search.val})
|
||||
uni.stopPullDownRefresh()
|
||||
order.setVal('list',content)
|
||||
console.log(order.data.list);
|
||||
order.setVal('total',totalElements)
|
||||
order.setVal('hasAjax',true)
|
||||
}
|
||||
onPullDownRefresh(()=>{
|
||||
order.setQuery('page',0)
|
||||
init()
|
||||
})
|
||||
|
||||
let user=ref({
|
||||
userId:''
|
||||
})
|
||||
const option=reactive({type:''})
|
||||
onLoad((opt)=>{
|
||||
Object.assign(option,opt)
|
||||
if(opt&&JSON.stringify(opt)!='{}'){
|
||||
order.setQuery('userId',opt.userId?opt.userId:'')
|
||||
if(opt.userId){
|
||||
queryAllShopUser({id:opt.userId}).then(res=>{
|
||||
user.value=res.content[0]||opt
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onShow(init)
|
||||
async function printOrder(item){
|
||||
try{
|
||||
console.log(item);
|
||||
const res= await $printOrder({
|
||||
tableId:item.tableId
|
||||
})
|
||||
infoBox.showToast('已发送打印请求')
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
infoBox.showToast('发送打印请求失败')
|
||||
//TODO handle the exception
|
||||
}
|
||||
|
||||
}
|
||||
function onPrintOrder(e){
|
||||
console.log(e);
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '是否打印该订单',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
printOrder(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.top {
|
||||
background-color: #E5E5E5;
|
||||
}
|
||||
</style>
|
||||
195
pagesOrder/pay-order/components/edit-accountPoints.vue
Normal file
195
pagesOrder/pay-order/components/edit-accountPoints.vue
Normal file
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<my-model ref="model" :title="title" iconColor="#000" @close="resetForm">
|
||||
<template #desc>
|
||||
<view class="u-text-left u-p-30 color-666 u-font-28">
|
||||
<view class="u-m-t-32 u-flex ">
|
||||
<view class="" v-if="accountPoints.calcRes.usable">
|
||||
<text class="color-red">*</text>
|
||||
<text class=""
|
||||
v-if="accountPoints.calcRes.equivalentPoints">100积分等于{{to2(accountPoints.calcRes.equivalentPoints*100)}}元,</text>
|
||||
<text>
|
||||
最大抵扣积分{{accountPoints.calcRes.maxUsablePoints}}
|
||||
</text>
|
||||
<text>,
|
||||
最小抵扣积分0
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-40 u-flex ">
|
||||
<view>积分</view>
|
||||
<view class="u-m-l-32 border u-p-l-10 u-p-r-10 u-flex-1">
|
||||
<uni-easyinput type="number" @input="pointsInput" @change="pointsChange" paddingNone
|
||||
:inputBorder="false" v-model="form.points" placeholder="输入积分抵扣数量"></uni-easyinput>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template #btn>
|
||||
<view class="u-p-30">
|
||||
<view class="u-m-t-10">
|
||||
<my-button @tap="confirm" shape="circle" fontWeight="700">修改</my-button>
|
||||
<view class="">
|
||||
<my-button @tap="close" type="cancel" bgColor="#fff">取消</my-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</my-model>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
nextTick,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
import myModel from '@/components/my-components/my-model.vue'
|
||||
import myButton from '@/components/my-components/my-button.vue'
|
||||
import myTabs from '@/components/my-components/my-tabs.vue'
|
||||
import infoBox from '@/commons/utils/infoBox.js'
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '积分抵扣'
|
||||
},
|
||||
accountPoints:{
|
||||
type:Object,
|
||||
default:()=>{
|
||||
return {
|
||||
calcRes:{
|
||||
usable: false,
|
||||
unusableReason: '',
|
||||
minDeductionPoints: 0,
|
||||
maxUsablePoints: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
price: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
function to2(n) {
|
||||
if (!n) {
|
||||
return ''
|
||||
}
|
||||
return n.toFixed(2)
|
||||
}
|
||||
|
||||
function pointsInput(e){
|
||||
setTimeout(()=>{
|
||||
form.points=Math.floor(e)
|
||||
},100)
|
||||
}
|
||||
|
||||
|
||||
function pointsChange(newval) {
|
||||
form.points=Math.floor(newval)
|
||||
if (newval < 0) {
|
||||
form.points = 0
|
||||
return infoBox.showToast('积分抵扣不能小于0')
|
||||
}
|
||||
if (newval > props.accountPoints.calcRes.maxUsablePoints) {
|
||||
form.points = props.price
|
||||
return infoBox.showToast('积分抵扣不能大于'+props.accountPoints.calcRes.maxUsablePoints)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const form = reactive({
|
||||
points: props.price,
|
||||
})
|
||||
watch(() => props.price, (newval) => {
|
||||
form.points = newval
|
||||
})
|
||||
|
||||
function resetForm() {
|
||||
form.points=0
|
||||
}
|
||||
|
||||
const model = ref(null)
|
||||
|
||||
function open() {
|
||||
model.value.open()
|
||||
form.points = props.price
|
||||
}
|
||||
|
||||
function close() {
|
||||
model.value.close()
|
||||
}
|
||||
const emits = defineEmits(['confirm'])
|
||||
|
||||
function confirm() {
|
||||
emits('confirm',Math.floor(form.points) )
|
||||
close()
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.border {
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
.lh34 {
|
||||
line-height: 34rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
background-color: #fff;
|
||||
border: 1px solid #E5E5E5;
|
||||
line-height: inherit;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
&.active {
|
||||
border-color: #E6F0FF;
|
||||
color: $my-main-color;
|
||||
}
|
||||
}
|
||||
|
||||
.hover-class {
|
||||
background-color: #E5E5E5;
|
||||
}
|
||||
|
||||
.discount {
|
||||
.u-absolute {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.bg1 {
|
||||
background: #F7F7FA;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 0 80rpx;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 1px solid #E5E5E5;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.input-box {
|
||||
padding: 22rpx 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.placeholder-class {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
938
pagesOrder/pay-order/pay-order.vue
Normal file
938
pagesOrder/pay-order/pay-order.vue
Normal file
@@ -0,0 +1,938 @@
|
||||
<template>
|
||||
<view class="bg-gray min-page u-p-30 u-font-28">
|
||||
<view class="u-p-t-60 u-p-b-60 u-text-center">
|
||||
<template v-if="originPrice!=payPrice">
|
||||
<view class="u-font-32 ">
|
||||
<text class="price-fuhao">¥</text>
|
||||
<!-- <text class="font-bold price">{{discount.currentPrice?discount.currentPrice:order.amount}}</text> -->
|
||||
<text class="font-bold price">{{payPrice}}</text>
|
||||
</view>
|
||||
<view class="u-m-t-10 color-999 old-price">
|
||||
<text class="">¥</text>
|
||||
<text class=" ">{{originPrice}}</text>
|
||||
</view>
|
||||
<view class="u-m-t-10 u-flex u-row-center color-main">
|
||||
<view @click="discountShow">修改</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="u-font-32 ">
|
||||
<text class="price-fuhao">¥</text>
|
||||
<text class="font-bold price">{{originPrice}}</text>
|
||||
</view>
|
||||
<view class="u-m-t-10 u-flex u-row-center color-main">
|
||||
<view @click="discountShow">修改</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
<view class="content bg-fff border-r-12">
|
||||
<view class="u-p-l-26 u-p-r-26 card top u-m-t-30">
|
||||
<view class="border-bottom-dashed u-p-b-30 u-p-t-30" v-if="vipDiscount*1>0">
|
||||
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between ">
|
||||
<view>会员优惠</view>
|
||||
<view class="color-red">
|
||||
-¥{{vipDiscount}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="border-bottom-dashed u-p-b-30 u-p-t-30">
|
||||
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between " @click="toQuan">
|
||||
<view>优惠券</view>
|
||||
<view class="color-999 u-flex u-col-center">
|
||||
<text>选择优惠券</text>
|
||||
<view class="u-flex u-col-center">
|
||||
<uni-icons type="right" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-24" v-if="pays.quan.length>0">
|
||||
<view class="u-flex u-p-l-24 u-p-r-24 u-m-t-24 u-row-between "
|
||||
v-for="(item,index) in pays.quan" :key="index">
|
||||
<view class="u-flex">
|
||||
<view class="hui">减</view>
|
||||
<view class="u-m-l-18">{{item.name}}</view>
|
||||
<view class="u-m-l-18 color-999">x{{item.num}}</view>
|
||||
</view>
|
||||
<view class="u-flex">
|
||||
<view class="color-red">
|
||||
-¥{{item.discountAmount}}
|
||||
</view>
|
||||
<view class="u-m-l-12" @click="delQuan(index)">
|
||||
<up-icon :size="16" name="minus-circle-fill" color="rgb(255, 0, 0)"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="border-bottom u-p-b-30" v-if="discount.value||accountPoints.sel">
|
||||
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between u-p-t-30 " v-if="discount.value">
|
||||
<view>服务员改价</view>
|
||||
<view class=" u-flex u-col-center">
|
||||
<text style="color: rgb(255, 95, 46);">-¥{{to2(discount.value)}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between u-p-t-30 "
|
||||
v-if="accountPoints.price&&accountPoints.sel">
|
||||
<view>积分抵扣</view>
|
||||
<view class=" u-flex u-col-center">
|
||||
<text style="color: rgb(255, 95, 46);">-¥{{to2(accountPoints.price)}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="bg-fff border-r-12 ">
|
||||
<view class="u-p-t-30 u-p-l-50 u-p-r-50 card bottom">
|
||||
<my-tabs :list="pays.list" v-model="pays.selIndex"></my-tabs>
|
||||
<template v-if="pays.selIndex==0">
|
||||
<view class="list">
|
||||
<view class="item" @click="changePayType(index,item)" :class="{disabled:item.disabled}"
|
||||
v-for="(item,index) in pays.payTypes.list" :key="index">
|
||||
<view class="u-flex u-row-between u-p-t-30 u-p-b-30 border-bottom">
|
||||
<view class="u-flex">
|
||||
<image class="icon" :src="item.icon" mode=""></image>
|
||||
<text class="u-m-l-10 no-wrap">{{item.payName}}</text>
|
||||
</view>
|
||||
<view class="u-flex color-999 u-font-24">
|
||||
<view class="u-m-r-20" v-if="item.payType=='vipPay'&&user.id"
|
||||
@click.stop="chooseUser">
|
||||
<view>
|
||||
<text>会员:</text>
|
||||
<text class="u-m-r-4">{{user.telephone||user.nickName}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<text>余额:</text>
|
||||
<text>¥{{user.amount||'0'}}</text>
|
||||
</view>
|
||||
<!-- <view>
|
||||
<text>积分:</text>
|
||||
<text>{{user.accountPoints||'0'}}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
<view :class="{op3:item.disabled}">
|
||||
<my-radio @click="changePayType(index,item)"
|
||||
:modelValue="index==pays.payTypes.selIndex">
|
||||
</my-radio>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="border-bottom-dashed "></view>
|
||||
<view class="u-flex u-row-between u-p-t-24" v-if="user.id" @click="changeAccountPoints">
|
||||
<view class="u-flex ">
|
||||
<view class="">积分抵扣</view>
|
||||
<view class="color-999 u-m-l-10">
|
||||
<text>(</text>
|
||||
<text>{{user.accountPoints||'0'}}</text>
|
||||
<text>)</text>
|
||||
</view>
|
||||
<!-- <view><text class="color-red font-bold">{{accountPoints.price}}</text>元</view> -->
|
||||
</view>
|
||||
<view class="u-flex">
|
||||
|
||||
<view class="u-flex">
|
||||
<view><text>{{accountPoints.num}}</text></view>
|
||||
<view v-if="accountPoints.calcRes.usable" @click.stop="refPointsOpen">
|
||||
<up-icon name="edit-pen" size="16" color="#999"></up-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="u-m-l-32 u-relative" v-if="accountPoints.calcRes.usable">
|
||||
<view class="u-absolute position-all"></view>
|
||||
<my-radio :modelValue="accountPoints.sel">
|
||||
</my-radio>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="color-999 u-font-24 u-m-t-16">
|
||||
<view class="" v-if="accountPoints.calcRes.unusableReason">
|
||||
<text class="color-red">*</text>
|
||||
<text>{{accountPoints.calcRes.unusableReason}}</text>
|
||||
</view>
|
||||
<view class="" v-if="accountPoints.calcRes.usable">
|
||||
<text class="color-red">*</text>
|
||||
<text class=""
|
||||
v-if="accountPoints.calcRes.equivalentPoints">100积分等于{{to2(accountPoints.calcRes.equivalentPoints*100)}}元,</text>
|
||||
<text>
|
||||
最大抵扣积分{{accountPoints.calcRes.maxUsablePoints}}
|
||||
</text>
|
||||
<text>,
|
||||
最小抵扣积分0
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-60 u-p-b-30">
|
||||
<my-button @click="payOrderClick">确认付款</my-button>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="pays.selIndex==1">
|
||||
<view class="u-font-32 u-m-t-40 u-text-center">请让顾客使用微信/支付宝扫码</view>
|
||||
<view class="u-flex u-row-center u-m-t-40">
|
||||
<up-qrcode cid="code" :size="140" :val="payCodeUrl"></up-qrcode>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 二维码支付扫码 -->
|
||||
<template v-if="pays.selIndex==1">
|
||||
<view class="card border-bottom top u-m-t-32">
|
||||
|
||||
</view>
|
||||
<view class="bg-fff card bottom border-r-12 u-p-32">
|
||||
<view class="font-bold u-font-32 u-text-center">
|
||||
¥{{payPrice}}</view>
|
||||
<view class="u-flex u-row-center u-m-t-24">
|
||||
<template v-if="order.status=='unpaid'">
|
||||
<up-loading-icon size="14" text="等待支付"></up-loading-icon>
|
||||
</template>
|
||||
<template v-if="order.status=='closed'">
|
||||
<view class="u-flex pay-success">
|
||||
<up-icon color="#5CBB6F" name="checkmark-circle-fill"></up-icon>
|
||||
<view class="u-m-l-6">支付成功</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
|
||||
<edit-discount :nowPrice="order.amount-productCouponDiscountAmount-fullCouponDiscountAmount"
|
||||
@confirm="editDiscountConfirm" title="优惠金额" :ref="setModel" name="editMoney"
|
||||
:price="order.amount-productCouponDiscountAmount" :discount="discount.discount"></edit-discount>
|
||||
|
||||
<up-modal :title="modal.title" :content="modal.content" :show="modal.show" :confirmText="modal.confirmText"
|
||||
:cancelText="modal.cancelText" showCancelButton closeOnClickOverlay @confirm="confirmModelConfirm"
|
||||
@cancel="confirmModelCancel" @close="confirmModelCancel" width="300px" />
|
||||
|
||||
<edit-accountPoints @confirm="pointsConfirm" :price="accountPoints.num" :accountPoints="accountPoints"
|
||||
ref="refPoints"></edit-accountPoints>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
onMounted,
|
||||
watch,
|
||||
ref,
|
||||
onBeforeUnmount,
|
||||
computed
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad,
|
||||
onBackPress,
|
||||
onShow
|
||||
} from '@dcloudio/uni-app'
|
||||
import go from '@/commons/utils/go.js'
|
||||
import * as Api from '@/http/yskApi/Instead.js'
|
||||
import {
|
||||
queryAllShopUser
|
||||
} from '@/http/yskApi/shop-user.js'
|
||||
import {
|
||||
hasPermission
|
||||
} from '@/commons/utils/hasPermission.js'
|
||||
import * as orderApi from '@/http/yskApi/order.js'
|
||||
import infoBox from '@/commons/utils/infoBox.js'
|
||||
import editDiscount from '@/components/my-components/edit-discount.vue'
|
||||
import editAccountPoints from './components/edit-accountPoints.vue'
|
||||
import {
|
||||
returnGoodsPayPriceMap,
|
||||
returnProCoupStartIndex,
|
||||
returnProductCoupAllPrice,
|
||||
returnProductCanUseNum
|
||||
} from '../quan_util.js'
|
||||
|
||||
const modal = reactive({
|
||||
title: '提示',
|
||||
cancelText: '取消',
|
||||
confirmText: '确认',
|
||||
content: '',
|
||||
key: 'cash',
|
||||
show: false,
|
||||
data: ''
|
||||
})
|
||||
|
||||
function confirmModelCancel() {
|
||||
if (modal.key == 'fullCoupon') {
|
||||
// 取消改价
|
||||
discount.discount = 100
|
||||
discount.value = 0
|
||||
}
|
||||
confirmModelClose()
|
||||
}
|
||||
|
||||
function confirmModelClose() {
|
||||
modal.show = false
|
||||
modal.key = ''
|
||||
modal.data = ''
|
||||
}
|
||||
|
||||
function cashConfirmShow() {
|
||||
modal.content = '是否确认已现金收款' + payPrice.value
|
||||
modal.key = 'cash'
|
||||
modal.show = true
|
||||
}
|
||||
async function confirmModelConfirm() {
|
||||
if (modal.key == 'cash') {
|
||||
await pay()
|
||||
confirmModelCancel()
|
||||
return
|
||||
}
|
||||
if (modal.key == 'fullCoupon') {
|
||||
//删除满减券
|
||||
const index = pays.quan.findIndex(v => v.type == 1)
|
||||
pays.quan.splice(index, 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//商品数量从0到n每一个对应的价格
|
||||
let $goodsPayPriceMap = {}
|
||||
|
||||
const refPoints = ref(null)
|
||||
|
||||
function delQuan(i) {
|
||||
pays.quan.splice(i, 1)
|
||||
}
|
||||
|
||||
function refPointsOpen() {
|
||||
if (!accountPoints.calcRes.usable && accountPoints.sel) {
|
||||
return
|
||||
}
|
||||
refPoints.value.open()
|
||||
}
|
||||
const accountPoints = reactive({
|
||||
sel: false,
|
||||
num: 0,
|
||||
calcRes: {
|
||||
usable: false,
|
||||
unusableReason: '',
|
||||
minDeductionPoints: 0,
|
||||
maxUsablePoints: 0
|
||||
},
|
||||
price: 0
|
||||
})
|
||||
|
||||
function pointsConfirm(e) {
|
||||
accountPoints.num = e
|
||||
}
|
||||
async function calcUsablePoints(orderAmount) {
|
||||
if (!order.memberId) {
|
||||
return
|
||||
}
|
||||
console.log(orderAmount);
|
||||
const res = await Api.$calcUsablePoints({
|
||||
memberId: order.memberId,
|
||||
orderAmount: orderAmount ? orderAmount : payPrice.value
|
||||
})
|
||||
accountPoints.calcRes = res
|
||||
accountPoints.num = res.maxUsablePoints
|
||||
return res;
|
||||
}
|
||||
watch(() => accountPoints.sel, (newval) => {
|
||||
if (newval) {
|
||||
calcDeDuctionPoints()
|
||||
}
|
||||
})
|
||||
async function calcDeDuctionPoints() {
|
||||
if (accountPoints.num <= 0) {
|
||||
accountPoints.price = 0
|
||||
return ''
|
||||
}
|
||||
const res = await Api.$calcDeDuctionPoints({
|
||||
memberId: order.memberId,
|
||||
orderAmount: originPrice.value,
|
||||
points: accountPoints.num
|
||||
})
|
||||
if (res) {
|
||||
accountPoints.price = res
|
||||
}
|
||||
return res
|
||||
}
|
||||
watch(() => accountPoints.num, (newval) => {
|
||||
if (!newval) {
|
||||
accountPoints.price = 0
|
||||
return
|
||||
}
|
||||
calcDeDuctionPoints()
|
||||
})
|
||||
|
||||
function changeAccountPoints() {
|
||||
if (!accountPoints.calcRes.usable) {
|
||||
return
|
||||
}
|
||||
accountPoints.sel = !accountPoints.sel
|
||||
if (!accountPoints.sel) {
|
||||
accountPoints.num = 0
|
||||
}
|
||||
}
|
||||
|
||||
function toQuan() {
|
||||
console.log(order);
|
||||
if (!order.memberId) {
|
||||
return infoBox.showToast('请先选择会员', 0.5).then(() => {
|
||||
chooseUser()
|
||||
})
|
||||
}
|
||||
go.to('PAGES_ORDER_QUAN', {
|
||||
orderId: order.id,
|
||||
memberId: order.memberId,
|
||||
orderPrice: (payPrice.value * 1 + coupAllPrice.value * 1).toFixed(2)
|
||||
})
|
||||
}
|
||||
async function discountShow() {
|
||||
const bol = await hasPermission('yun_xu_da_zhe')
|
||||
if (bol) {
|
||||
showModel('editMoney', true)
|
||||
}
|
||||
}
|
||||
let option = {
|
||||
isNowPay: false
|
||||
}
|
||||
let payFinish = ref(false)
|
||||
onBackPress(() => {
|
||||
uni.$emit('orderDetail:update')
|
||||
console.log('onBackPress');
|
||||
// uni.$emit('update:createOrderIndex')
|
||||
// if (option.isNowPay&&!payFinish.value) {
|
||||
// infoBox.showToast('先付费模式,请先结算订单')
|
||||
// return true
|
||||
// }
|
||||
// return false
|
||||
})
|
||||
|
||||
let timer = null
|
||||
|
||||
let user = ref({
|
||||
amount: 0
|
||||
});
|
||||
|
||||
function clear() {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
|
||||
function to2(n) {
|
||||
if (!n) {
|
||||
return ''
|
||||
}
|
||||
return Number(n).toFixed(2)
|
||||
}
|
||||
const pays = reactive({
|
||||
list: ['扫码收款', '二维码收款'],
|
||||
selIndex: 0,
|
||||
payTypes: {
|
||||
list: [],
|
||||
selIndex: 0
|
||||
},
|
||||
quan: []
|
||||
})
|
||||
|
||||
function chooseUser() {
|
||||
go.to('PAGES_CHOOSE_USER')
|
||||
}
|
||||
//更新选择用户
|
||||
function setUser(par) {
|
||||
console.log(option);
|
||||
const submitPar = {
|
||||
tableId: order.tableId,
|
||||
orderId: order.id,
|
||||
masterId: order.masterId,
|
||||
vipUserId: user.value.id ? user.value.id : '',
|
||||
type: user.value.id ? 0 : 1 //0 设置 1 取消
|
||||
}
|
||||
Object.assign(submitPar, par)
|
||||
return Api.$setUser(submitPar)
|
||||
}
|
||||
|
||||
function watchChooseuser() {
|
||||
uni.$off('choose-user')
|
||||
uni.$on('choose-user', (data) => {
|
||||
console.log(data);
|
||||
pays.quan = []
|
||||
setUser({
|
||||
vipUserId: data.id ? data.id : '',
|
||||
type: data.id ? 0 : 1 //0 设置 1 取消
|
||||
}).then(res => {
|
||||
user.value = data
|
||||
order.memberId = data.id
|
||||
init()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function setQuan(arr) {
|
||||
console.log(arr);
|
||||
discount.discount = 100
|
||||
discount.value = 0
|
||||
discount.currentPrice = order.amount
|
||||
const manjianCoup = arr.filter(v => v.type == 1 && v.num >= 1)
|
||||
let productCoup = arr.filter(v => v.type == 2)
|
||||
console.log(productCoup);
|
||||
//商品券分组
|
||||
let coupMap = {}
|
||||
for (let i in productCoup) {
|
||||
const coup = productCoup[i]
|
||||
if (coupMap.hasOwnProperty(coup.proId)) {
|
||||
coupMap[coup.proId].push(coup)
|
||||
} else {
|
||||
coupMap[coup.proId] = [coup]
|
||||
}
|
||||
}
|
||||
console.log(coupMap);
|
||||
for (let key in coupMap) {
|
||||
const arr = coupMap[key]
|
||||
for (let i in arr) {
|
||||
const coup = arr[i]
|
||||
const proCoupStartIndex = returnProCoupStartIndex(arr, i)
|
||||
console.log(proCoupStartIndex);
|
||||
const coupUseNum = returnProductCanUseNum($goodsPayPriceMap[coup.proId], proCoupStartIndex,
|
||||
coup.num)
|
||||
const num = Math.min($goodsPayPriceMap[coup.proId].length, coupUseNum)
|
||||
coup.num = num
|
||||
console.log($goodsPayPriceMap[coup.proId]);
|
||||
const findGoods = order.detailList.find(v => v.productId == coup.proId)
|
||||
const isMember = findGoods.isMember
|
||||
coup.discountAmount = returnProductCoupAllPrice($goodsPayPriceMap[coup.proId],
|
||||
proCoupStartIndex, num, isMember).toFixed(2)
|
||||
}
|
||||
}
|
||||
productCoup = productCoup.filter(v => v.num >= 1)
|
||||
console.log(productCoup);
|
||||
pays.quan = [...manjianCoup, ...productCoup]
|
||||
console.log(pays.quan);
|
||||
}
|
||||
|
||||
function watchChooseQuan() {
|
||||
uni.$off('choose-quan')
|
||||
uni.$on('choose-quan', (arr) => {
|
||||
setQuan(arr)
|
||||
})
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
watchChooseuser()
|
||||
watchChooseQuan()
|
||||
})
|
||||
|
||||
watch(() => pays.selIndex, (newval) => {
|
||||
clearInterval(timer)
|
||||
if (newval) {
|
||||
timer = setInterval(() => {
|
||||
orderApi.tbOrderInfoDetail(order.orderId).then(res => {
|
||||
order.status = res.status
|
||||
if (res.status == 'closed') {
|
||||
paySuccess()
|
||||
}
|
||||
})
|
||||
}, 2000)
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
const models = new Map();
|
||||
|
||||
function setModel(el) {
|
||||
if (el && el.$attrs['name']) {
|
||||
models.set(el.$attrs['name'], el);
|
||||
}
|
||||
}
|
||||
|
||||
function showModel(key) {
|
||||
const model = models.get(key)
|
||||
model && model.open()
|
||||
}
|
||||
|
||||
//打折相关数据
|
||||
const discount = reactive({
|
||||
discount: 100,
|
||||
currentPrice: 0,
|
||||
value: 0
|
||||
})
|
||||
|
||||
function editDiscountConfirm(form) {
|
||||
console.log(form);
|
||||
accountPoints.sel = false
|
||||
Object.assign(discount, {
|
||||
...form,
|
||||
value: form.price - form.currentPrice
|
||||
})
|
||||
const fullCoupon = pays.quan.find(v => v.type == 1)
|
||||
if (fullCoupon && form.currentPrice < fullCoupon.fullAmount) {
|
||||
modal.content = '改价后价格不满足满减券最低满减需求' + fullCoupon.fullAmount + '元'
|
||||
modal.key = 'fullCoupon'
|
||||
modal.show = true
|
||||
modal.cancelText = '取消改价'
|
||||
modal.confirmText = '删除满减券'
|
||||
}
|
||||
getPayUrl()
|
||||
}
|
||||
|
||||
async function getPayType() {
|
||||
const payTypeList = await Api.$getPayType()
|
||||
pays.payTypes.list = payTypeList.map(v => {
|
||||
return {
|
||||
...v,
|
||||
disabled: false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function changePayType(i, item) {
|
||||
if (item.disabled) {
|
||||
return infoBox.showToast(item.payName + '不可用')
|
||||
}
|
||||
pays.payTypes.selIndex = i
|
||||
if (item.payType == 'vipPay' && !user.value.id) {
|
||||
chooseUser()
|
||||
}
|
||||
}
|
||||
let payStatus = '';
|
||||
//支付成功回调
|
||||
function paySuccess() {
|
||||
infoBox.showToast('支付成功')
|
||||
payStatus = 'success'
|
||||
setTimeout(() => {
|
||||
// uni.$emit('orderDetail:update')
|
||||
payFinish.value = true
|
||||
uni.$emit('get:table')
|
||||
uni.$emit('update:orderDetail')
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
|
||||
function payOrderClick() {
|
||||
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType
|
||||
console.log(payType);
|
||||
if (payType == 'scanCode' || payType == 'deposit') {
|
||||
return saomaPay()
|
||||
}
|
||||
if (payType == 'cash' && payPrice.value * 1 > 0) {
|
||||
return cashConfirmShow()
|
||||
}
|
||||
payOrder()
|
||||
}
|
||||
const tipsMap = {
|
||||
paying: '支付中',
|
||||
success: '已支付成功'
|
||||
}
|
||||
async function payOrder() {
|
||||
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType
|
||||
if (payType == 'vipPay' && user.value.amount * 1 < order.amount * 1) {
|
||||
infoBox.showToast('余额不足')
|
||||
return
|
||||
}
|
||||
|
||||
if (payStatus) {
|
||||
return infoBox.showToast(tipsMap[payStatus])
|
||||
}
|
||||
try {
|
||||
pay()
|
||||
} catch (e) {
|
||||
//TODO handle the exception
|
||||
payStatus = ''
|
||||
}
|
||||
}
|
||||
async function pay(par) {
|
||||
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType
|
||||
payStatus = 'paying'
|
||||
await Api.$payOrder({
|
||||
tableId: order.tableId,
|
||||
masterId: order.masterId,
|
||||
orderId: order.id || order.orderId,
|
||||
payType,
|
||||
vipUserId: order.memberId,
|
||||
discount: discount.discount / 100,
|
||||
code: '',
|
||||
pointsNum: accountPoints.sel ? accountPoints.num : 0,
|
||||
userCouponInfos: pays.quan.map(v => {
|
||||
return {
|
||||
userCouponId: v.id,
|
||||
num: v.num
|
||||
}
|
||||
}),
|
||||
...par
|
||||
})
|
||||
paySuccess()
|
||||
}
|
||||
|
||||
const order = reactive({
|
||||
amount: 0
|
||||
})
|
||||
|
||||
|
||||
|
||||
function saomaPay() {
|
||||
const item = pays.payTypes.list[pays.payTypes.selIndex]
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
success: function(res) {
|
||||
console.log('条码类型:' + res.scanType);
|
||||
console.log('条码内容:' + res.result);
|
||||
pay({
|
||||
code: res.result
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
watch(() => pays.payTypes.selIndex, (newval) => {
|
||||
// const item = pays.payTypes.list[newval]
|
||||
// if (item.payType == "vipPay") {
|
||||
// return
|
||||
// }
|
||||
// if (item.payType == "deposit") {
|
||||
// //储值卡支付
|
||||
// return saomaPay('deposit')
|
||||
// }
|
||||
// if (item.payType == "scanCode") {
|
||||
// //扫码支付
|
||||
// return saomaPay('scanCode')
|
||||
// }
|
||||
})
|
||||
let payCodeUrl = ref('')
|
||||
async function init() {
|
||||
const orderRes = await orderApi.tbOrderInfoDetail(order.orderId)
|
||||
Object.assign(order, orderRes)
|
||||
$goodsPayPriceMap = returnGoodsPayPriceMap(order.detailList)
|
||||
const hasSelQuan = orderRes.couponInfoList ? JSON.parse(orderRes.couponInfoList) : {
|
||||
fullReductionCoupon: [],
|
||||
productCoupon: []
|
||||
};
|
||||
const fullReductionCoupon = hasSelQuan.fullReductionCoupon.filter(v => v.type == 1)
|
||||
const productCoupon = hasSelQuan.productCoupon.filter(v => v.type == 2)
|
||||
setQuan([...fullReductionCoupon, ...productCoupon])
|
||||
|
||||
if (orderRes.memberId) {
|
||||
calcUsablePoints()
|
||||
if (orderRes.pointsNum) {
|
||||
accountPoints.sel = true
|
||||
}
|
||||
queryAllShopUser({
|
||||
id: orderRes.memberId
|
||||
}).then(res => {
|
||||
if (res.content[0]) {
|
||||
user.value = res.content[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getPayUrl() {
|
||||
orderApi.$getOrderPayUrl({
|
||||
orderId: order.id,
|
||||
payAmount: payPrice.value
|
||||
}).then(res => {
|
||||
payCodeUrl.value = res
|
||||
})
|
||||
}
|
||||
const coupAllPrice = computed(() => {
|
||||
const n = pays.quan.reduce((prve, cur) => {
|
||||
return prve + cur.discountAmount * 1
|
||||
}, 0)
|
||||
return n
|
||||
})
|
||||
const payPrice = computed(() => {
|
||||
// const discountPrice = discount.currentPrice ? discount.currentPrice : order.amount
|
||||
// const calcPrice = discountPrice - coupAllPrice.value - accountPoints.price * (accountPoints.sel ? 1 : 0)
|
||||
// return (calcPrice <= 0 ? 0 : calcPrice).toFixed(2)
|
||||
const total = (originPrice.value) - vipDiscount.value - productCouponDiscountAmount.value - discount
|
||||
.value -
|
||||
fullCouponDiscountAmount.value - accountPoints.price * (accountPoints.sel ? 1 : 0)
|
||||
return (total < 0 ? 0 : total).toFixed(2)
|
||||
})
|
||||
const vipDiscount = computed(() => {
|
||||
if (!user.value.isVip) {
|
||||
return 0
|
||||
}
|
||||
const goodsPrice = order.detailList.filter(v => v.gift != true && v.status !== "return" && (v.isMember &&
|
||||
v.memberPrice) && (v.memberPrice != v.price)).reduce((
|
||||
a,
|
||||
b) => {
|
||||
return a + (b.num * (b.price - b.memberPrice))
|
||||
}, 0)
|
||||
return goodsPrice.toFixed(2)
|
||||
})
|
||||
const originPrice = computed(() => {
|
||||
const n = (order.amount || 0) * 1 + vipDiscount.value * 1 + (order.fullCouponDiscountAmount || 0) + (order
|
||||
.productCouponDiscountAmount || 0) +
|
||||
(order.pointsDiscountAmount || 0)
|
||||
|
||||
return n.toFixed(2)
|
||||
})
|
||||
const fullCouponDiscountAmount = computed(() => {
|
||||
return pays.quan.filter(v => v.type == 1).reduce((prve, cur) => {
|
||||
return prve + cur.discountAmount * 1
|
||||
}, 0)
|
||||
})
|
||||
const productCouponDiscountAmount = computed(() => {
|
||||
return pays.quan.filter(v => v.type == 2).reduce((prve, cur) => {
|
||||
return prve + cur.discountAmount * 1
|
||||
}, 0)
|
||||
})
|
||||
watch(() => payPrice.value, (newval) => {
|
||||
getPayUrl()
|
||||
if (newval <= 0) {
|
||||
const arr = ['cash', 'vipPay']
|
||||
pays.payTypes.list.map(v => {
|
||||
if (arr.includes(v.payType)) {
|
||||
v.disabled = false
|
||||
} else {
|
||||
v.disabled = true
|
||||
}
|
||||
})
|
||||
const index = pays.payTypes.list.findIndex(v => !v.disabled)
|
||||
pays.payTypes.selIndex = index
|
||||
} else {
|
||||
pays.payTypes.list.map(v => {
|
||||
v.disabled = false
|
||||
})
|
||||
}
|
||||
})
|
||||
const pointCanDicountPrice = computed(() => {
|
||||
const total = (order.amount || 0) - productCouponDiscountAmount.value - discount.value -
|
||||
fullCouponDiscountAmount.value
|
||||
return (total < 0 ? 0 : total).toFixed(2)
|
||||
})
|
||||
watch(() => pointCanDicountPrice.value, (newval) => {
|
||||
calcUsablePoints()
|
||||
})
|
||||
|
||||
onLoad(async (opt) => {
|
||||
console.log(opt);
|
||||
option = opt
|
||||
Object.assign(order, opt)
|
||||
getPayType()
|
||||
init()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
console.log('onBeforeUnmount');
|
||||
clear()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$quan-color: #318AFE;
|
||||
|
||||
.op3 {
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.hui {
|
||||
// background-color: $quan-color;
|
||||
background-image: linear-gradient(to right bottom, rgb(254, 103, 4), rgb(241, 50, 42));
|
||||
padding: 4rpx 10rpx;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 0 5px #E5E5E5;
|
||||
}
|
||||
|
||||
.pay-success {
|
||||
color: #5CBB6F;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.border-bottom-dashed {
|
||||
border-bottom: 1px dashed #bbb;
|
||||
}
|
||||
|
||||
.border-bottom {
|
||||
border-color: rgb(240, 240, 240);
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
&.disabled {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.item:last-child {
|
||||
.border-bottom {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.old-price {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.price-fuhao {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
$dotSize: 20rpx;
|
||||
$position: calc($dotSize / (-2));
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
|
||||
&::after,
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
background-color: #F9F9F9;
|
||||
width: $dotSize;
|
||||
height: $dotSize;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.top {
|
||||
&::after {
|
||||
right: $position;
|
||||
bottom: $position;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: $position;
|
||||
bottom: $position;
|
||||
}
|
||||
}
|
||||
|
||||
&.bottom {
|
||||
&::after {
|
||||
right: $position;
|
||||
top: $position;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: $position;
|
||||
top: $position;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
580
pagesOrder/quan/quan.vue
Normal file
580
pagesOrder/quan/quan.vue
Normal file
@@ -0,0 +1,580 @@
|
||||
<template>
|
||||
<view class="u-p-l-30 u-p-r-30 u-p-t-30 u-font-28 ">
|
||||
<up-sticky offset-top="0">
|
||||
<my-tabs v-model="myQuan.types.sel" :list="myQuan.types.list"></my-tabs>
|
||||
</up-sticky>
|
||||
<view class="u-m-t-32">
|
||||
<template v-if="myQuan.types.sel==0">
|
||||
<view class="" @click="changeFullReductionCouponSel(item)"
|
||||
v-for="(item,index) in myQuan.res.fullReductionCoupon" :class="{filtergray:!item.use}" :key="index">
|
||||
<view class="quan u-row-between u-flex u-col-center u-m-b-32 border-r-10 ">
|
||||
<view class="no-use" v-if="!item.use">
|
||||
<image class="img" src="/pagesOrder/static/image/no-use.svg" mode=""></image>
|
||||
</view>
|
||||
<view class="sel u-abso" v-if="item.id==myQuan.fullReductionCouponSel.id ">
|
||||
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
||||
</view>
|
||||
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24 left">
|
||||
<view class="u-flex">
|
||||
<view class="hui">减</view>
|
||||
<view class="u-m-l-18">{{item.name}}</view>
|
||||
</view>
|
||||
<view class=" u-m-t-20 u-flex">
|
||||
<view>有效期:</view>
|
||||
<view class="u-font-24 u-m-l-6"> {{dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-10 color-999 u-font-24">
|
||||
{{ formatStr(item.useRestrictions)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="right u-flex u-flex-col u-row-between">
|
||||
<view class="u-flex u-row-center u-font-36 ">
|
||||
¥{{item.discountAmount}}
|
||||
</view>
|
||||
<view class="u-flex u-font-24">
|
||||
满{{item.fullAmount}}可用
|
||||
</view>
|
||||
<view class="u-flex ">
|
||||
<view class="use-btn" @click.stop="toEmitChooseQuan(item)">去使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="myQuan.res.fullReductionCoupon.length<=0&&myQuan.hasAjax">
|
||||
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-if="myQuan.types.sel==1">
|
||||
<view class="" @click="changeProductCoupon(item)" v-for="(item,index) in myQuan.res.productCoupon"
|
||||
:class="{filtergray:!item.use}" :key="index">
|
||||
<view class="quan goods u-row-between u-flex u-col-center u-m-b-32 border-r-10 u-relative">
|
||||
<view class="no-use" v-if="!item.use">
|
||||
<image class="img" src="/pagesOrder/static/image/no-use.svg" mode=""></image>
|
||||
</view>
|
||||
<view class="sel u-abso" v-if="item.checked">
|
||||
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
||||
</view>
|
||||
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24 left">
|
||||
<view class="u-flex">
|
||||
<up-image width="80rpx" height="80rpx" :src="item.productCover"></up-image>
|
||||
<view class="u-m-l-18">
|
||||
<view class="u-m-l-18">{{item.productName}}</view>
|
||||
<view class="u-m-l-18 u-m-t-10 u-font-24 color-666">x{{item.num}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class=" u-m-t-14 u-flex">
|
||||
<view>有效期:</view>
|
||||
<view class="u-font-24 u-m-l-6"> {{dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-10 color-999 u-font-24">
|
||||
{{ formatStr(item.useRestrictions)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="right u-flex u-flex-col u-col-bottom u-row-center">
|
||||
<!-- <view class="u-flex u-row-center w-full">
|
||||
<view class="color-red font-bold u-m-b-24 ">¥{{item.discountAmount}}</view>
|
||||
</view> -->
|
||||
<view class="u-flex ">
|
||||
<view class="use-btn" @click.stop="toEmitChooseQuan(item)">去使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<template v-if="myQuan.res.productCoupon.length<=0&&myQuan.hasAjax">
|
||||
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
<view :style="{height:safebottomHeight+'px'}"></view>
|
||||
<view class="fixed-b bottom safe-bottom border-top">
|
||||
|
||||
<view class="u-m-b-32 u-flex u-row-between u-p-t-10">
|
||||
<view class="u-flex">
|
||||
<text>抵扣金额:</text>
|
||||
<text class="color-red">¥</text>
|
||||
<text class="color-red">{{discountAmount}}</text>
|
||||
</view>
|
||||
<view class="u-flex u-relative">
|
||||
<text>支付金额:</text>
|
||||
<text class="color-red">¥</text>
|
||||
<text class="color-red">{{payPrice }}</text>
|
||||
<view class="u-absolute u-flex u-row-between" style="bottom: 100%;right: 0;"
|
||||
v-if="payPrice*1!=option.orderPrice*1">
|
||||
<view class="u-flex line-th color-999">
|
||||
<text class="">¥</text>
|
||||
<text class="">{{option.orderPrice}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-flex gap-20">
|
||||
<up-button shape="circle" plain @click="back">
|
||||
<view class="font-bold">取消</view>
|
||||
</up-button>
|
||||
<up-button shape="circle" type="primary" @click="toEmitChooseQuan()">
|
||||
<view class="font-bold">确定</view>
|
||||
</up-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<up-modal :title="modal.title" :content="modal.content" :show="modal.clear" :confirmText="modal.confirmText"
|
||||
:cancelText="modal.cancelText" showCancelButton closeOnClickOverlay @confirm="confirmModelConfirm"
|
||||
@cancel="confirmModelCancel" @close="setModalShow('clear',false)" width="300px" />
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
watch,
|
||||
computed,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
import color from '@/commons/color.js'
|
||||
import dayjs from 'dayjs';
|
||||
import {
|
||||
getSafeBottomHeight
|
||||
} from '@/commons/utils/safe-bottom.js'
|
||||
import go from '@/commons/utils/go.js'
|
||||
import {
|
||||
onLoad,
|
||||
onReady
|
||||
} from '@dcloudio/uni-app'
|
||||
import * as orderApi from '@/http/yskApi/order.js'
|
||||
import {
|
||||
$activateByOrderId
|
||||
} from '@/http/yskApi/Instead.js'
|
||||
import infoBox from '@/commons/utils/infoBox.js'
|
||||
import {
|
||||
queryAllShopUser
|
||||
} from '@/http/yskApi/shop-user.js'
|
||||
import {
|
||||
returnNewGoodsList,
|
||||
returnCoupCanUse,
|
||||
returnCouponAllPrice,
|
||||
returnProductCoupon,
|
||||
returnCanUseFullReductionCoupon
|
||||
} from '../quan_util.js'
|
||||
|
||||
const modal = reactive({
|
||||
title: '提示',
|
||||
cancelText: '取消',
|
||||
confirmText: '确定',
|
||||
content: '',
|
||||
key: '',
|
||||
clear: false,
|
||||
data: ''
|
||||
})
|
||||
|
||||
function confirmModelCancel() {
|
||||
setModalShow('clear', false, '')
|
||||
}
|
||||
async function confirmModelConfirm() {
|
||||
if (modal.key == 'clear') {
|
||||
myQuan.fullReductionCouponSel = {
|
||||
id: ''
|
||||
}
|
||||
const item = modal.data
|
||||
item.checked = !item.checked
|
||||
const CheckedArr = myQuan.res.productCoupon.filter(v => v.checked)
|
||||
const noCheckedArr = myQuan.res.productCoupon.filter(v => !v.checked)
|
||||
noCheckedArr.map(v => {
|
||||
console.log(returnCoupCanUse(canDikouGoodsArr, v, CheckedArr));
|
||||
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr)
|
||||
})
|
||||
setModalShow('clear', false, '')
|
||||
}
|
||||
}
|
||||
|
||||
function setModalShow(key = 'show', show = true, data) {
|
||||
modal.key = key
|
||||
modal[key] = show
|
||||
modal.data = data
|
||||
}
|
||||
|
||||
|
||||
|
||||
function back() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
let order = ref({
|
||||
|
||||
})
|
||||
let canDikouGoodsArr = []
|
||||
const myQuan = reactive({
|
||||
fullReductionCouponSel: {
|
||||
id: ''
|
||||
},
|
||||
res: {
|
||||
fullReductionCoupon: [],
|
||||
productCoupon: []
|
||||
},
|
||||
types: {
|
||||
list: ['满减券(单选)', '商品券(多选)'],
|
||||
sel: 0
|
||||
},
|
||||
list: [],
|
||||
sel: -1,
|
||||
hasAjax: false
|
||||
})
|
||||
|
||||
function changeProductCoupon(item) {
|
||||
if (!item.use) {
|
||||
return
|
||||
}
|
||||
if (myQuan.fullReductionCouponSel.id && !item.checked) {
|
||||
const goodsQuan = myQuan.res.productCoupon.filter(v => v.checked)
|
||||
const fullReductionCoupon = myQuan.fullReductionCouponSel.id ? [myQuan.fullReductionCouponSel] : []
|
||||
let coupArr = [...goodsQuan, item]
|
||||
const payPrice = option.orderPrice - returnCouponAllPrice(coupArr, canDikouGoodsArr, user.value)
|
||||
if (payPrice<=0) {
|
||||
modal.content = '选择该商品券后支付金额将为0,继续选择将取消选择的满减券'
|
||||
modal.cancelText = '取消'
|
||||
modal.confirmText = '继续选择'
|
||||
setModalShow('clear', true, item)
|
||||
return
|
||||
}
|
||||
if (myQuan.fullReductionCouponSel.fullAmount > payPrice) {
|
||||
modal.content = '选择该商品券后将不满足选择抵扣券的最低满减需求,继续选择将取消选择的满减券'
|
||||
modal.cancelText = '取消'
|
||||
modal.confirmText = '继续选择'
|
||||
setModalShow('clear', true, item)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
item.checked = !item.checked
|
||||
const CheckedArr = myQuan.res.productCoupon.filter(v => v.checked)
|
||||
if (CheckedArr.length <= 0) {
|
||||
return myQuan.res.productCoupon.map(v => {
|
||||
v.use = true
|
||||
})
|
||||
}
|
||||
const noCheckedArr = myQuan.res.productCoupon.filter(v => !v.checked)
|
||||
noCheckedArr.map(v => {
|
||||
console.log(returnCoupCanUse(canDikouGoodsArr, v, CheckedArr));
|
||||
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr)
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
function changeFullReductionCouponSel(item) {
|
||||
if (!item.use) {
|
||||
return
|
||||
}
|
||||
console.log(item);
|
||||
if (item.id == myQuan.fullReductionCouponSel.id) {
|
||||
myQuan.fullReductionCouponSel = {
|
||||
id: ''
|
||||
}
|
||||
} else {
|
||||
myQuan.fullReductionCouponSel = item
|
||||
}
|
||||
myQuan.res.fullReductionCoupon = returnCanUseFullReductionCoupon($fullReductionCoupon, payPrice.value, myQuan
|
||||
.fullReductionCouponSel)
|
||||
}
|
||||
|
||||
function formatStr(str) {
|
||||
console.log(str);
|
||||
if(!str){
|
||||
return ''
|
||||
}
|
||||
const reg=/^[,]+|[,]+$/g;
|
||||
return `${str}`.replace(reg, '')
|
||||
}
|
||||
|
||||
function toUse(item) {
|
||||
|
||||
}
|
||||
let user = reactive({
|
||||
isVip: false
|
||||
})
|
||||
|
||||
let $fullReductionCoupon = []
|
||||
let $productCoupon = []
|
||||
async function getQuan() {
|
||||
order.value = await orderApi.tbOrderInfoDetail(option.orderId)
|
||||
if (order.value.memberId) {
|
||||
const userRes = await queryAllShopUser({
|
||||
id: order.value.memberId
|
||||
})
|
||||
if (userRes.content[0]) {
|
||||
user.value = userRes.content[0]
|
||||
}
|
||||
}
|
||||
|
||||
console.log(order.value);
|
||||
const res = await $activateByOrderId({
|
||||
orderId: option.orderId,
|
||||
memberId: option.memberId
|
||||
})
|
||||
canDikouGoodsArr = returnNewGoodsList(order.value.detailList || [])
|
||||
res.fullReductionCoupon = res.fullReductionCoupon.map((v) => {
|
||||
if(option.orderPrice<=0){
|
||||
return {...v,use:false}
|
||||
}else{
|
||||
return{
|
||||
...v,
|
||||
use:v.use && option.orderPrice * 1 >= v
|
||||
.fullAmount * 1
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
res.productCoupon = res.productCoupon.map(v => {
|
||||
const calcCoup = returnProductCoupon(v, canDikouGoodsArr, user.value)
|
||||
return {
|
||||
...calcCoup,
|
||||
checked: false,
|
||||
use:option.orderPrice<=0?false:v.use
|
||||
}
|
||||
}).filter((v) => v.use);
|
||||
$fullReductionCoupon = res.fullReductionCoupon
|
||||
$productCoupon = res.productCoupon
|
||||
myQuan.res = res
|
||||
myQuan.hasAjax = true;
|
||||
}
|
||||
const option = reactive({
|
||||
orderId: '',
|
||||
memberId: '',
|
||||
orderPrice: 0
|
||||
})
|
||||
|
||||
function toEmitChooseQuan(item) {
|
||||
let arr = []
|
||||
if (item) {
|
||||
arr = [item]
|
||||
} else {
|
||||
if (myQuan.fullReductionCouponSel.id) {
|
||||
arr.push(myQuan.fullReductionCouponSel)
|
||||
}
|
||||
const goodsQuan = myQuan.res.productCoupon.filter(v => v.checked)
|
||||
arr.push(...goodsQuan)
|
||||
}
|
||||
uni.$emit('choose-quan', arr)
|
||||
back()
|
||||
}
|
||||
const discountAmount = computed(() => {
|
||||
const goodsQuan = myQuan.res.productCoupon.filter(v => v.checked)
|
||||
const fullReductionCoupon = myQuan.fullReductionCouponSel.id ? [myQuan.fullReductionCouponSel] : []
|
||||
let coupArr = [...fullReductionCoupon, ...goodsQuan]
|
||||
return returnCouponAllPrice(coupArr, canDikouGoodsArr, user.value)
|
||||
})
|
||||
const payPrice = computed(() => {
|
||||
const pay = option.orderPrice - discountAmount.value
|
||||
return (pay < 0 ? 0 : pay).toFixed(2)
|
||||
})
|
||||
watch(() => myQuan.types.sel, (newval) => {
|
||||
if (newval == 0) {
|
||||
myQuan.res.fullReductionCoupon = returnCanUseFullReductionCoupon($fullReductionCoupon, payPrice.value,
|
||||
myQuan.fullReductionCouponSel)
|
||||
}
|
||||
if (newval == 1) {
|
||||
|
||||
}
|
||||
})
|
||||
onLoad((opt) => {
|
||||
Object.assign(option, opt)
|
||||
getQuan()
|
||||
})
|
||||
let safebottomHeight = ref(0)
|
||||
onReady(() => {
|
||||
getSafeBottomHeight('bottom', 0).then(height => {
|
||||
console.log(height);
|
||||
safebottomHeight.value = height
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// $quan-color:rgb(233, 77, 60);
|
||||
$quan-color: #318AFE;
|
||||
|
||||
.no-use {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
|
||||
.fixed-b {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
background-color: #fff;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.bg-gray {
|
||||
border-radius: 18rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.price1 {
|
||||
color: rgb(255, 107, 0);
|
||||
}
|
||||
|
||||
.payType {
|
||||
.radio {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgb(255, 212, 0);
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 40rpx;
|
||||
opacity: 0;
|
||||
|
||||
}
|
||||
|
||||
.active {
|
||||
.radio {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.left-block {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -30rpx;
|
||||
display: block;
|
||||
width: 12rpx;
|
||||
top: 0;
|
||||
background-color: rgb(255, 212, 0);
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.filtergray {
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
.radio {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgb(255, 255, 255);
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 40rpx;
|
||||
|
||||
&.active {}
|
||||
}
|
||||
|
||||
.use-btn {
|
||||
background-color: #fff;
|
||||
border-radius: 100rpx;
|
||||
padding: 4rpx 20rpx;
|
||||
color: $quan-color;
|
||||
}
|
||||
|
||||
.u-font-40 {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.yilingqu {
|
||||
position: absolute;
|
||||
bottom: 20rpx;
|
||||
right: 20rpx;
|
||||
}
|
||||
|
||||
.lingqu {
|
||||
position: absolute;
|
||||
bottom: 20rpx;
|
||||
right: 20rpx;
|
||||
background-color: rgb(255, 207, 0);
|
||||
padding: 10rpx 30rpx;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-color: $my-main-color;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.hui {
|
||||
// background-color: $quan-color;
|
||||
background-image: linear-gradient(to right bottom, rgb(254, 103, 4), rgb(241, 50, 42));
|
||||
padding: 4rpx 10rpx;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.quan {
|
||||
border: 1px solid rgb(238, 238, 238);
|
||||
position: relative;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0 0 5px #eee;
|
||||
overflow: hidden;
|
||||
.left{
|
||||
max-width: 70%;
|
||||
}
|
||||
.sel {
|
||||
padding: 2rpx 4rpx;
|
||||
position: absolute;
|
||||
background-color: $quan-color;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-radius: 0 0 24rpx 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 20rpx 24rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: $quan-color;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.goods {
|
||||
.right {
|
||||
background-color: #fff;
|
||||
position: initial;
|
||||
|
||||
.use-btn {
|
||||
padding: 10rpx 40rpx;
|
||||
color: #fff;
|
||||
background-color: $quan-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
padding: 30rpx 30rpx 80rpx 30rpx;
|
||||
}
|
||||
</style>
|
||||
250
pagesOrder/quan_util.js
Normal file
250
pagesOrder/quan_util.js
Normal file
@@ -0,0 +1,250 @@
|
||||
export function isTui(item) {
|
||||
return item.status == 'return' || item.status == 'refund' || item.status == 'refunding'
|
||||
}
|
||||
//是否使用会员价
|
||||
export function isUseVipPrice(vipUser,goods){
|
||||
return vipUser.id&&vipUser.isVip&&goods.isMember
|
||||
}
|
||||
|
||||
//计算商品券优惠价格
|
||||
export function returnProductCouponPrice(coup, goodsArr, vipUser) {
|
||||
const item = goodsArr.find(v => v.productId == coup.proId);
|
||||
if (!item) {
|
||||
return 0
|
||||
}
|
||||
const memberPrice = item.memberPrice ? item.memberPrice : item.price;
|
||||
const price = item ? (isUseVipPrice(vipUser,item) ? memberPrice : item.price) : 0;
|
||||
return price * coup.num
|
||||
|
||||
}
|
||||
//返回新的商品列表,过滤掉退菜的,退单的商品
|
||||
export function returnNewGoodsList(arr) {
|
||||
let goodsMap = {}
|
||||
return arr.filter(v => !isTui(v))
|
||||
}
|
||||
//根据当前购物车商品以及数量,已选券对应商品数量,判断该商品券是否可用
|
||||
export function returnCoupCanUse(goodsArr = [], coup, selCoupArr = []) {
|
||||
// if(!coup.use){
|
||||
// return false
|
||||
// }
|
||||
const findGoods = goodsArr.filter(v => v.productId == coup.proId)
|
||||
if (!findGoods.length) {
|
||||
return false
|
||||
}
|
||||
const findGoodsTotalNumber = findGoods.reduce((prve, cur) => {
|
||||
return prve + cur.num * 1
|
||||
}, 0)
|
||||
const selCoupNumber = selCoupArr.filter(v => v.proId == coup.proId).reduce((prve, cur) => {
|
||||
return prve + cur.num * 1
|
||||
}, 0)
|
||||
if (selCoupNumber >= findGoodsTotalNumber) {
|
||||
return false
|
||||
}
|
||||
console.log(selCoupNumber,findGoodsTotalNumber);
|
||||
return findGoodsTotalNumber < selCoupNumber ? false : true
|
||||
}
|
||||
//查找购物车商品根据购物车商品数据返回商品券信息(抵扣价格以及是否满足可用需求)
|
||||
export function returnProductCoupon(coup, goodsArr, vipUser, selCoupArr = []) {
|
||||
const newGoodsArr = returnNewGoodsList(goodsArr)
|
||||
const item = newGoodsArr.find(v => v.productId == coup.proId);
|
||||
if (!item) {
|
||||
return {
|
||||
...coup,
|
||||
discountAmount: 0,
|
||||
use: false
|
||||
}
|
||||
}
|
||||
const memberPrice = item.memberPrice ? item.memberPrice : item.price;
|
||||
const price = item ? (isUseVipPrice(vipUser,item) ? memberPrice : item.price) : 0;
|
||||
const discountAmount = (price * coup.num).toFixed(2)
|
||||
console.log(discountAmount);
|
||||
|
||||
// const canUse = !coup.use ? false : (discountAmount > 0 && returnCoupCanUse(goodsArr, coup, selCoupArr))
|
||||
// const canUse=discountAmount>0
|
||||
const canUse=coup.use
|
||||
return {
|
||||
...coup,
|
||||
discountAmount: discountAmount,
|
||||
use: canUse
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 根据购物车商品计算商品券抵扣价格以及是否满足可用需求
|
||||
* 1.商品券对应商品数量大于购物车对应商品数量不可用
|
||||
* 2.未在购物车找到相关商品不可用
|
||||
* @param {*} coupArr
|
||||
* @param {*} goodsArr
|
||||
* @param {*} vipUser
|
||||
* @returns
|
||||
*/
|
||||
export function returnProductAllCoup(coupArr, goodsArr, vipUser) {
|
||||
return coupArr.map((v) => {
|
||||
return returnProductCoupon(v, goodsArr, vipUser)
|
||||
})
|
||||
|
||||
}
|
||||
//返回商品实际支付价格
|
||||
export function returnProductPayPrice(goods,vipUser){
|
||||
const memberPrice = goods.memberPrice ? goods.memberPrice : goods.price;
|
||||
const price = isUseVipPrice(vipUser,goods) ? memberPrice : goods.price;
|
||||
return price
|
||||
}
|
||||
//返回商品券抵扣的商品价格
|
||||
export function returnProductCoupAllPrice(productPriceArr,startIndex,num,isMember=true){
|
||||
console.log(productPriceArr);
|
||||
return productPriceArr.slice(startIndex,startIndex+num).reduce((prve,cur)=>{
|
||||
let curPrice=0
|
||||
if(typeof cur==='object'){
|
||||
curPrice=isMember?cur.memberPrice*1:cur.price
|
||||
}else{
|
||||
curPrice=cur*1
|
||||
}
|
||||
return prve+curPrice
|
||||
},0)
|
||||
}
|
||||
|
||||
//返回商品券可抵扣的商品数量
|
||||
export function returnProductCanUseNum(productPriceArr,startIndex,num){
|
||||
console.log(productPriceArr);
|
||||
console.log(num);
|
||||
let n=0;
|
||||
for(let i=0;i<num;i++){
|
||||
if(productPriceArr[startIndex*1+i]){
|
||||
n+=1
|
||||
console.log(n);
|
||||
}else{
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
//返回同类商品券在同类商品价格数组里的开始位置
|
||||
export function returnProCoupStartIndex(coupArr,index){
|
||||
return coupArr.slice(0,index).reduce((prve,cur)=>{
|
||||
return prve+cur.num*1
|
||||
},0)
|
||||
}
|
||||
//返回商品数量从0到n每一个对应的价格对照表
|
||||
export function returnGoodsPayPriceMap(goodsArr){
|
||||
return goodsArr.reduce((prve,cur)=>{
|
||||
if(!prve.hasOwnProperty(cur.productId)){
|
||||
prve[cur.productId]=[]
|
||||
}
|
||||
const arr=new Array(cur.num).fill(cur).map(v=>{
|
||||
return {
|
||||
memberPrice:v.memberPrice?v.memberPrice:v.price,
|
||||
price:v.price
|
||||
}
|
||||
})
|
||||
prve[cur.productId].push(...arr)
|
||||
return prve
|
||||
},{})
|
||||
}
|
||||
//计算商品券总优惠价格
|
||||
export function returnProductCouponAllPrice(coupArr, goodsArr, vipUser) {
|
||||
if (coupArr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
//商品分组
|
||||
const goodsMap={}
|
||||
//商品数量从0到n每一个对应的价格
|
||||
const goodsPayPriceMap={}
|
||||
//商品券分组
|
||||
let coupMap={}
|
||||
for(let i in coupArr){
|
||||
const coup=coupArr[i]
|
||||
if(coupMap.hasOwnProperty(coup.proId)){
|
||||
coupMap[coup.proId].push(coup)
|
||||
}else{
|
||||
coupMap[coup.proId]=[coup]
|
||||
}
|
||||
}
|
||||
let total=0
|
||||
for(let key in coupMap){
|
||||
const arr=coupMap[key]
|
||||
for(let i in arr){
|
||||
const coup=arr[i]
|
||||
if(!goodsMap.hasOwnProperty(coup.proId)){
|
||||
goodsMap[coup.proId]=goodsArr.filter(v=>v.productId==coup.proId).map(v=>{
|
||||
return {
|
||||
...v,
|
||||
payPrice:returnProductPayPrice(v,vipUser)
|
||||
}
|
||||
}).sort((a,b)=>{
|
||||
const aPrice=a.payPrice
|
||||
const bPrice=b.payPrice
|
||||
return aPrice-bPrice
|
||||
})
|
||||
goodsPayPriceMap[coup.proId]=goodsMap[coup.proId].reduce((prve,cur)=>{
|
||||
const arr=new Array(cur.num).fill(cur.payPrice)
|
||||
console.log(arr);
|
||||
prve.push(...arr)
|
||||
return prve
|
||||
},[])
|
||||
}
|
||||
const proCoupStartIndex=returnProCoupStartIndex(arr,i)
|
||||
console.log(proCoupStartIndex);
|
||||
const coupNum=Math.min(goodsPayPriceMap[coup.proId].length,coup.num)
|
||||
console.log(coupNum);
|
||||
total+=returnProductCoupAllPrice(goodsPayPriceMap[coup.proId],proCoupStartIndex,coupNum)
|
||||
}
|
||||
}
|
||||
|
||||
return total.toFixed(2);
|
||||
|
||||
}
|
||||
//计算满减券总优惠价格
|
||||
export function returnFullReductionCouponAllPrice(coupArr) {
|
||||
if (coupArr.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return coupArr.filter(v => v.type == 1).reduce((a, b) => {
|
||||
const price = b.discountAmount
|
||||
return a + price;
|
||||
}, 0).toFixed(2);
|
||||
|
||||
}
|
||||
//计算优惠券总价格
|
||||
export function returnCouponAllPrice(coupArr, goodsArr, vipUser) {
|
||||
const poductAllprice = returnProductCouponAllPrice(coupArr, goodsArr, vipUser)
|
||||
const pointAllPrice = returnFullReductionCouponAllPrice(coupArr)
|
||||
return (poductAllprice * 1 + pointAllPrice * 1).toFixed(2);
|
||||
}
|
||||
|
||||
//返回当前满减券列表可用状态
|
||||
export function returnCanUseFullReductionCoupon(coupArr, payPrice, selCoup) {
|
||||
return coupArr.map(v => {
|
||||
if (v.id == selCoup.id) {
|
||||
return v
|
||||
}
|
||||
const isfullAmount = payPrice >= v.fullAmount * 1
|
||||
if(payPrice<=0){
|
||||
return {
|
||||
...v,
|
||||
use: false
|
||||
}
|
||||
}
|
||||
return {
|
||||
...v,
|
||||
use: v.use && isfullAmount
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//根据商品数量还有商品券数量返回优惠券可以使用的数量数组
|
||||
export function returnCanUseNumProductCoup(coupArr,){
|
||||
let productCoup = coupArr.filter(v => v.type == 2)
|
||||
//商品券分组
|
||||
let coupMap={}
|
||||
for(let i in productCoup){
|
||||
const coup=productCoup[i]
|
||||
if(coupMap.hasOwnProperty(coup.proId)){
|
||||
coupMap[coup.proId].push(coup)
|
||||
}else{
|
||||
coupMap[coup.proId]=[coup]
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
1
pagesOrder/static/image/icon-search.svg
Normal file
1
pagesOrder/static/image/icon-search.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="19.091" height="15" viewBox="0 0 19.091 15"><defs><style>.a{fill:#318afe;}</style></defs><path class="a" d="M64.682,160H82.409a.682.682,0,1,1,0,1.364H64.682a.682.682,0,1,1,0-1.364Zm0,13.636H76.955a.682.682,0,0,1,0,1.364H64.682a.682.682,0,0,1,0-1.364ZM80.773,170.5l2.045,3.136a.682.682,0,1,1-1.091.818l-2.045-3.136a10.526,10.526,0,0,1-2.045.273,4.773,4.773,0,1,1,4.773-4.773A5.15,5.15,0,0,1,80.773,170.5Zm-3.136-.273a3.409,3.409,0,1,0-3.409-3.409A3.376,3.376,0,0,0,77.636,170.227Zm-12.955-3.409h5.455a.682.682,0,1,1,0,1.364H64.682a.682.682,0,0,1,0-1.364Z" transform="translate(-64 -160)"/></svg>
|
||||
|
After Width: | Height: | Size: 641 B |
1
pagesOrder/static/image/no-use.svg
Normal file
1
pagesOrder/static/image/no-use.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.4 KiB |
254
pagesOrder/tuikuan/tuikuan.vue
Normal file
254
pagesOrder/tuikuan/tuikuan.vue
Normal file
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<view class="min-page bg-gray u-p-30">
|
||||
<view class="bg-fff u-p-24 border-r-12 u-flex u-row-between">
|
||||
<view>全退</view>
|
||||
<view>
|
||||
<my-radio v-model="allTui" :disabled="option.productId=='-999'"></my-radio>
|
||||
</view>
|
||||
</view>
|
||||
<view class="u-m-t-24 u-font-24 u-font-24">
|
||||
<text class="color-red">*</text>
|
||||
<text>客座费只能全退</text>
|
||||
</view>
|
||||
<view 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.productSkuName||""}}</view>
|
||||
<view class="u-m-t-10 color-999 u-font-24">最多可退×{{item.num}}</view>
|
||||
</view>
|
||||
<template v-if="option.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="!option.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="color.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(totalPrice)}}元
|
||||
</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(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="color.ColorMain"></up-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import color from '@/commons/color.js';
|
||||
import infoBox from '@/commons/utils/infoBox.js';
|
||||
import * as orderApi from '@/http/yskApi/order.js'
|
||||
import {hasPermission} from '@/commons/utils/hasPermission.js'
|
||||
import {
|
||||
$returnOrder
|
||||
} from '@/http/yskApi/Instead.js'
|
||||
import {
|
||||
onLoad,
|
||||
onShow,
|
||||
onHide
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
computed,
|
||||
reactive,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
let allTui = ref(false)
|
||||
let note = ref('')
|
||||
const tuikuan = reactive({
|
||||
list: ['点错', '数量点错', '客人要求', '协商退费'],
|
||||
sel: -1
|
||||
})
|
||||
|
||||
function changeTuiKuanSel(i) {
|
||||
tuikuan.sel = i
|
||||
}
|
||||
const orderDetail = reactive({
|
||||
goodsList: [],
|
||||
info: {},
|
||||
seatFee: {
|
||||
totalAmount: 0
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => allTui.value, (newval) => {
|
||||
orderDetail.goodsList.map(v => {
|
||||
v.number = newval ? v.num : 0
|
||||
})
|
||||
})
|
||||
|
||||
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 totalPrice = computed(() => {
|
||||
return orderDetail.goodsList.reduce((prve, cur) => {
|
||||
return prve + cur.priceAmount * 1
|
||||
}, 0)
|
||||
})
|
||||
const tuikuanPrice = computed(() => {
|
||||
return orderDetail.goodsList.reduce((prve, cur) => {
|
||||
const n=(cur.number/cur.num*100) * cur.priceAmount
|
||||
return prve + (n/100).toFixed(2)
|
||||
}, 0)
|
||||
})
|
||||
|
||||
|
||||
function to2(n) {
|
||||
return Number(n).toFixed(2);
|
||||
}
|
||||
|
||||
function changeItem(item, step) {
|
||||
if(item.productId=='-999'){
|
||||
return
|
||||
}
|
||||
console.log(item);
|
||||
let newval = item.number * 1 + step * 1;
|
||||
if (newval <= 0) {
|
||||
newval = 0;
|
||||
}
|
||||
if (newval >= item.num) {
|
||||
newval = item.num;
|
||||
}
|
||||
item.number = newval;
|
||||
allTui.value = totalNumber.value == tuikuanNumber.value ? true : false;
|
||||
}
|
||||
|
||||
async function tuikuanConfirm() {
|
||||
const canTuikuan=await hasPermission('允许退款')
|
||||
if(!canTuikuan){
|
||||
return infoBox.showToast('您没有退款权限')
|
||||
}
|
||||
if (tuikuanNumber.value <= 0) {
|
||||
return infoBox.showToast('退款商品数量不能为0!')
|
||||
}
|
||||
const selTag=tuikuan.list[tuikuan.sel]
|
||||
const noteResult=`${selTag?selTag:''}${note.value?(','+note.value):''}`
|
||||
if (!noteResult) {
|
||||
return infoBox.showToast('请输入或选择退款原因!')
|
||||
}
|
||||
await $returnOrder({
|
||||
"orderId": option.orderId,
|
||||
"note":noteResult,
|
||||
"orderDetails":orderDetail.goodsList.filter(v=>v.number*1).map(v=>{
|
||||
return {
|
||||
id:v.id,
|
||||
num:v.number*1
|
||||
}
|
||||
})
|
||||
})
|
||||
infoBox.showToast('退款请求提交成功')
|
||||
setTimeout(()=>{
|
||||
uni.navigateBack({delta:1})
|
||||
},500)
|
||||
}
|
||||
const option=reactive({
|
||||
productId:'-999'
|
||||
})
|
||||
onLoad((opt) => {
|
||||
Object.assign(option,opt)
|
||||
if(opt.productId=='-999'){
|
||||
allTui.value=true
|
||||
}
|
||||
if (Array.isArray(opt)) {
|
||||
orderDetail.goodsList = opt
|
||||
} else {
|
||||
orderDetail.goodsList = [opt]
|
||||
}
|
||||
console.log(opt);
|
||||
})
|
||||
</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>
|
||||
Reference in New Issue
Block a user