Files
cashier_app/pagesOrder/detail/components/list.vue

661 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="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=" font-bold u-p-b-32 border-bottom u-m-b-24" v-if="orderInfo.tableName&&orderInfo.status=='unpaid'">
<view class="block" @tap="rotatingTables"
style="display: flex;align-items: center;justify-content: space-between;">
<view>转桌/并桌</view>
<uni-icons type="right" color="#999" size="16"></uni-icons>
</view>
</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 v-if="item.isTemporary == 0" class="img" :src="item.coverImg||item.productImg" mode=""></image>
<view v-else style="background-color: #3f9eff; width: 152rpx;height: 152rpx;line-height: 152rpx;text-align: center;color: #fff;" >
{{item.name||item.productName||'临时菜'}}
</view>
</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=='part_refund'?'部分已退':'全部已退'}}
</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" style="flex-direction: column;align-items: flex-start;">
<view class="u-flex u-m-b-8">
<view class="u-m-r-20 u-flex" v-if="item.isGift">
<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.packNumber > 0">
<uni-tag
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
size="small" text="打包" inverted type="success" />
</view>
</view>
<view class="u-flex u-m-t-8">
<view class="u-m-r-20 u-font-24 u-flex" v-if="item.refundNum>0">
<view class="color-666">退款金额:</view>
<view class="color-999 u-m-l-6">{{item.refundNum*item.unitPrice}}</view>
</view>
<view class="u-m-r-20 u-font-24 u-flex" v-if="item.returnNum">
<view class="color-666">退菜数量:</view>
<view class="color-999 u-m-l-6">{{item.returnNum}}</view>
</view>
</view>
</view>
<view class="color-999 u-font-24 u-m-t-8">{{item.skuName||''}}</view>
<view class="u-m-t-12 color-666 u-font-24" v-if="item.remark">
备注{{item.remark}}
</view>
</view>
<view class="u-text-right u-m-t-28">
<template v-if="item.refundNum>0||item.returnNum>0">
<view>{{mathFloorPrice( parseFloat(mathFloorPrice(item.num*item.unitPrice,item)) - (parseFloat(mathFloorPrice(item.returnNum*item.unitPrice,item)) + parseFloat(mathFloorPrice(item.refundNum*item.unitPrice,item))))}}</view>
<view class="line-th color-666 ">{{returnTotalMoney(item)}}</view>
</template>
<template v-else-if="item.couponNum > 0">
<view>{{mathFloorPrice((item.num-item.couponNum)*item.unitPrice,item)}}</view>
<view class="line-th color-666 ">{{returnTotalMoney(item)}}</view>
</template>
<template v-else-if="item.discountSaleAmount > 0">
<view>{{mathFloorPrice(item.num*item.discountSaleAmount,item)}}</view>
<view class="line-th color-666 ">{{returnTotalMoney(item)}}</view>
</template>
<template v-else-if="isVip == 1">
<view>{{mathFloorPrice((item.memberPrice?item.num*item.memberPrice:item.num*item.price),item)}}</view>
<view class="line-th color-666 ">{{returnTotalMoney(item)}}</view>
</template>
<template v-else>
<template v-if="returnCanTuiMoney(item)*1!=returnTotalMoney(item)*1">
<view>{{returnTotalMoney(item)}}</view>
<view class=" color-666 line-th">
{{returnCanTuiMoney(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 class=" u-flex u-font-24 color-333" style="gap: 20rpx;">
<text v-if="item.dishOutTime">出菜时间{{item.dishOutTime}}</text>
<text v-if="item.foodServeTime">上菜时间{{item.foodServeTime}}</text>
</view>
</view>
</view>
<template v-if="canTuicai(orderInfo,item)">
<view class="u-flex u-row-right gap-20 u-m-t-24" v-if="item.returnNum*item.unitPrice<item.num*item.unitPrice">
<my-button :width="128" :height="48" plain shape="circle" @tap="tuicai(item,index)"><text
class="no-wrap">退菜</text></my-button>
</view>
</template>
</view>
</view>
</view>
<view class="u-m-t-32">
<template v-if="seatFeePrice&&seatFeePrice>0">
<view class="u-flex u-row-between border-top u-p-t-32 u-p-b-32 u-col-top">
<view class="no-wrap u-m-r-32">桌位费</view>
<view>{{seatFeePrice||'0.00'}}</view>
</view>
</template>
<template v-if="allPpackFee&&allPpackFee>0">
<view class="u-flex u-row-between border-top u-p-t-32 u-p-b-32 u-col-top">
<view class="no-wrap u-m-r-32">打包费</view>
<view>{{allPpackFee||'0.00'}}</view>
</view>
</template>
<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="discountsPrice>0">
<view class="color-red u-m-r-6 ">
已优惠{{discountsPrice}}
</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="">{{$dict.getDiceName(orderInfo.refundType,'refundType')||''}}</text>
</view>
</view>
<view class="u-flex u-row-between u-m-t-32">
<view>退款金额</view>
<view class="color-999">
<text class="">{{mathFloorPrice(orderInfo.refundAmount)}}</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>
<template v-if="canTuiKuan(orderInfo)">
<view class="u-flex u-row-right gap-20 u-m-t-20">
<my-button :width="168" :height="48" plain shape="circle" @tap="tuikuan(data,index)"><text
class="no-wrap">全部退款</text> </my-button>
</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">{{allPrice}}</text>
</view>
</template>
<template v-else>
<view>
<text>总计</text>
<text class="font-bold u-font-32">{{mathFloorPrice(orderInfo.payAmount)}}</text>
</view>
</template>
</view>
<view class="u-m-t-24" v-if="orderInfo.status == 'unpaid'||orderInfo.status == 'done'">
<my-button @tap="printOrder" type="cancel" :color="$utils.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="discountSaleAmount">
<view>单品打折</view>
<view class="color-red">
<text></text>
<text>{{ discountSaleAmount }}</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="orderInfo.productCouponDiscountAmount*1>0">
<view>商品券抵扣</view>
<view class="color-red">
<text></text>
<text> {{to2(orderInfo.productCouponDiscountAmount) }}</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 { hasPermission } from '@/commons/utils/hasPermission.js'
import { isTui, isTuiCai, isGift, canTuiKuan, canTuicai, mathFloorPrice } from '@/commons/utils/goodsUtil.js'
const emits = defineEmits(['tuicai', 'tuikuan', 'printOrder'])
const pop = reactive({
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
}
}
}
})
/**
* 计算菜品数量
*/
const goodsNumber = computed(() => {
let result = 0
result = props.data.reduce((a, b) => {
const bTotal = b.info.length
return a + bTotal
}, 0)
return result.toFixed(0)
})
/**
* 桌位费
*/
const seatFeePrice = computed(() => {
const n = props.orderInfo.seatNum > 0 ? props.orderInfo.seatNum*uni.getStorageSync('shopInfo').tableFee : 0
return n.toFixed(2)
})
/**
* 判断是否是会员
*/
const isVip = computed(() => {
return uni.getStorageSync('shopInfo').isMemberPrice && props.user && props.user.id && props.user.isVip
})
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 (!isVip.value) {
return 0
}
const goodsPrice = props.data.reduce((prve, cur) => {
const curTotal = cur.info.filter(v => v.discountSaleAmount <= 0 && v.isGift != 1 && v.status !== "return" && (v.price != v.unitPrice) && (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 discountSaleAmount = computed(() => {
const goodsPrice = props.data.reduce((prve, cur) => {
const curTotal = cur.info.filter(v => v.discountSaleAmount > 0 && v.isGift != 1 && v.status !== "return" ).reduce(( a, b) => {
return a + (b.num * (b.price - b.discountSaleAmount))
}, 0)
return prve + curTotal
}, 0)
return goodsPrice.toFixed(2)
})
/**
* 打折优惠
*/
const discountAmount = computed(() => {
return props.orderInfo.discountAmount||0
})
/**
* 总优惠金额
*/
const discountsPrice = computed(() => {
// 满减券优惠
let fullCouponDiscountAmount = props.orderInfo.status == 'done' ? props.orderInfo.fullCouponDiscountAmount : 0
// 商品券优惠
let productCouponDiscountAmount = props.orderInfo.status == 'done' ? props.orderInfo.productCouponDiscountAmount : 0
// 积分抵扣优惠
let pointsDiscountAmount = props.orderInfo.status == 'done' ? props.orderInfo.pointsDiscountAmount : 0
return (parseFloat(vipDiscountPrice.value) + parseFloat(discountSaleAmount.value) + discountAmount.value + fullCouponDiscountAmount + productCouponDiscountAmount + pointsDiscountAmount).toFixed(2)
})
// 菜品金额
const productCoupPrice = computed(() => {
if (props.orderInfo.status == 'done') {
return props.orderInfo.productCouponDiscountAmount
}
const goodsPrice = props.data.reduce((a, b) => {
const curTotal = b.info.filter(v => !v.isGift).reduce((prve, cur) => {
let memberPrice = cur.memberPrice ? cur.memberPrice : cur.price
let tPrice = (isVip.value ? memberPrice : cur.price)
tPrice = cur.memberPrice != cur.unitPrice&& cur.price != cur.unitPrice ? cur.unitPrice : tPrice
let Total = Math.floor(tPrice * cur.num * 100) / 100
return prve + Total - (cur.returnNum*tPrice) - (cur.refundNum*cur.unitPrice)
}, 0)
return a + curTotal
}, 0)
// console.log("菜品金额==",goodsPrice)
return goodsPrice.toFixed(2)
})
const allPpackFee = computed(() => {
//不是退菜只要有打包费的都计算,包括赠送
const goodsPrice = props.data.reduce((prve, cur) => {
const curTotal = cur.info.filter(v => v.packNumber > 0).reduce((a,
b) => {
return a + parseFloat(b.packAmount*b.packNumber).toFixed(2)*1
}, 0)
return prve + curTotal
}, 0)
return goodsPrice.toFixed(2)
})
const packFee = computed(() => {
//不是退菜只要有打包费的都计算,包括赠送
const goodsPrice = props.data.reduce((prve, cur) => {
const curTotal = cur.info.filter(v => v.status !== "return" && (v.returnNum+v.refundNum < v.num)).reduce((a,
b) => {
return a + parseFloat((b.packAmount*(b.num-(b.returnNum+b.refundNum)>b.packNumber?b.packNumber:b.num-(b.returnNum+b.refundNum))).toFixed(2))
}, 0)
return prve + curTotal
}, 0)
return goodsPrice.toFixed(2)
})
const allPrice = computed(() => {
let seatAmount = props.orderInfo.seatAmount || 0
const total = productCoupPrice.value*1 + seatAmount*1 + packFee.value*1
return (total <= 0 ? 0 : total).toFixed(2)
})
/**
* 已优惠金额
*/
const youhuiAllPrice = computed(() => {
const n = vipDiscountPrice.value * 1
return (n < 0 ? 0 : n).toFixed(2)
})
function youhuiDetailShow() {
pop.youhui = true
}
function productCouponDikou(item) {
return '商品券抵扣¥' + returnProductCoupPrice(item)
}
function youhuiDetailHide() {
pop.youhui = false
}
/**
* 转桌/并桌
*/
function rotatingTables() {
let arr = []
props.data.forEach(ele => {
ele.info.forEach(res => {
// 头像 coverImg
res.coverImg = res.productImg
// 名字 name
res.name = res.productName
// 金额 salePrice
res.salePrice = res.price
// 数量 number
res.number = res.num
res.masterId = props.orderInfo.masterId
res.useType = props.orderInfo.useType
res.tableId = props.orderInfo.tableId
arr.push(res)
})
})
uni.navigateTo({
url: '/pagesCreateOrder/confirm-order/rotatingTables?item=' + JSON.stringify(arr) + '&tableId=' + props
.orderInfo.tableId
})
}
function returnProductCoupPrice(item) {
if (!item.isMember) {
return item.price * item.num
}
const price = item.memberPrice ? item.memberPrice : item.price
return price * item.num
}
function returnTotalMoney(item) {
return (Math.floor(item.num*item.price*100)/100).toFixed(2)
}
function returnCanTuiMoney(item) {
// if (props.orderInfo.status == 'unpaid') {
// return returnTotalMoney(item)
// } else {
if (props.orderInfo.pointsDiscountAmount > 0 || props.orderInfo.fullCouponDiscountAmount > 0) {
return item.canReturnAmount
} else if (item.price != item.unitPrice) {
return item.price*item.num
} else {
return (Math.floor(item.num*item.unitPrice*100)/100).toFixed(2)
}
// }
}
const canTuiKuanPrice = computed(() => {
const goodsTotal = props.data.reduce((prve, cur) => {
const curTotal = cur.info.filter(v => !isTui(v) && !v.userCouponId)
.reduce((a, b) => {
return a + b.payAmount * 1
}, 0)
return prve + curTotal
}, 0)
return (goodsTotal + seatFeePrice.value * 1).toFixed(2)
})
const TuiKuanPrice = computed(() => {
return props.data.reduce((prve, cur) => {
const curTotal = cur.info.filter(v => isTui(v) && !v.userCouponId)
.reduce((a, b) => {
return a + b.payAmount * 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.payAmount * 1
}, 0)
return prve + curTotal
}, 0)
})
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) {
if (Array.isArray(item)) {
let arr = [];
item.map(v=>{
let infoLit = JSON.parse(JSON.stringify(v.info))
infoLit.map((obj,i)=>{
obj.number = '0.00'
obj.skuName = obj.skuName || ''
obj.unitPrice = obj.unitPrice
obj.num = obj.num - obj.returnNum - obj.refundNum - obj.couponNum
obj.priceAmount = mathFloorPrice(obj.num*obj.unitPrice ,obj)
})
arr = [...arr,...infoLit]
})
arr.map((v,e)=>{
if( v.num <= 0){
// arr.splice(e, 1)
}
})
emits('tuikuan', arr)
} else {
emits('tuikuan', {
...item,
payAmount: item.payAmount
}, index)
}
}
})
}
function printOrder() {
emits('printOrder')
}
</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>