463 lines
12 KiB
Vue
463 lines
12 KiB
Vue
<!-- 结算订单 -->
|
||
<template>
|
||
<el-drawer size="100%" :with-header="false" direction="btt" v-model="dialogVisible">
|
||
<div class="drawer_wrap">
|
||
<div class="cart_list">
|
||
<div class="nav_wrap card">
|
||
<div class="return" @click="returnHandle">
|
||
<el-icon class="icon">
|
||
<ArrowLeftBold />
|
||
</el-icon>
|
||
</div>
|
||
<div class="info">
|
||
<div class="master_id">
|
||
<span>{{ goodsStore.orderListInfo.tableCode || store.shopInfo.shopName }}</span>
|
||
<div class="member_info" v-if="goodsStore.vipUserInfo.id">
|
||
<span>用户昵称:{{ formatPhoneNumber(goodsStore.vipUserInfo.phone) }}</span>
|
||
<span class="vip" v-if="goodsStore.vipUserInfo.memberLevelName">{{
|
||
goodsStore.vipUserInfo.memberLevelName }}</span>
|
||
</div>
|
||
<div class="member_info s" v-if="goodsStore.vipUserInfo.id">当前积分:
|
||
{{ goodsStore.vipUserInfo.accountPoints }}
|
||
</div>
|
||
<div class="member_info s between" v-if="goodsStore.vipUserInfo.id">
|
||
<span>当前余额:{{ goodsStore.vipUserInfo.amount }}</span>
|
||
<el-button size="small" @click="userChangeRef.show()">去充值</el-button>
|
||
</div>
|
||
</div>
|
||
<div class="btm">
|
||
<span class="p">服务员:{{ store.userInfo.name || store.shopInfo.shopName }}</span>
|
||
<span class="t">{{ dayjs().format("M月D日 HH:mm") }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="list_wrap card" style="margin-top: var(--el-font-size-base)">
|
||
<!-- <SettleItem :list="cartList" /> -->
|
||
<SettleItem :list="orderList" />
|
||
<SettleItem
|
||
:list="[{ id: 'tableFee', product_name: '客座费', number: goodsStore.tableInfo.num, salePrice: store.shopInfo.tableFee, memberPrice: store.shopInfo.tableFee }]"
|
||
v-if="!store.shopInfo.isTableFee && goodsStore.tableInfo.name && (goodsStore.cartList.length || goodsStore.orderList.length) && !goodsStore.allSelected" />
|
||
</div>
|
||
<div class="footer">
|
||
<!-- <el-button icon="Edit"></el-button> -->
|
||
<div class="button">
|
||
<el-checkbox v-model="isPrint" :true-value="1" :false-value="0" border label="打印结算小票" style="width: 100%" />
|
||
</div>
|
||
<!-- <div class="print">
|
||
<el-button type="warning" :loading="discountLoading" @click="showStaffDiscountHandle">添加折扣</el-button>
|
||
</div> -->
|
||
<div class="print">
|
||
<el-button type="primary" :loading="printLoading" @click="printHandle">打印预结单</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="pay_wrap">
|
||
<payCard ref="payCardRef" :orderList="orderList" :amount="cartInfo.totalAmount"
|
||
:orderId="goodsStore.orderListInfo.id" @paySuccess="paySuccess" @orderExpired="orderExpiredHnadle"
|
||
:isPrint="0" @reset="show" />
|
||
</div>
|
||
</div>
|
||
<!-- <el-dialog v-model="showStaffDiscount" title="员工折扣" @close="global.updateData(true)">
|
||
<el-form>
|
||
<el-form-item label="折扣比例">
|
||
<div>
|
||
<el-input-number v-model="discount" :min="staffDiscount" :max="0.99" :step="0.1"
|
||
:disabled="staffDiscount == 0" />
|
||
<div class="tips">最低折扣比例:{{ staffDiscount }}</div>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="优惠金额">
|
||
<div>
|
||
<el-input-number v-model="discount" :min="staffDiscount" :max="0.99" :step="0.1"
|
||
:disabled="staffDiscount == 0" />
|
||
<div class="tips">最低折扣比例:{{ staffDiscount }}</div>
|
||
</div>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div class="footer_wrap">
|
||
<div class="btn">
|
||
<el-button style="width: 100%;" @click="showStaffDiscount = false">取消</el-button>
|
||
</div>
|
||
<div class="btn">
|
||
<el-button type="primary" style="width: 100%;" @click="discountConfirm">确认</el-button>
|
||
</div>
|
||
</div>
|
||
</el-dialog> -->
|
||
</el-drawer>
|
||
<user-charge ref="userChangeRef" :userInfo="goodsStore.vipUserInfo" @pay-success="chargeSuccess" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import _ from 'lodash'
|
||
import { ref, nextTick } from "vue";
|
||
import { useUser } from "@/store/user.js";
|
||
import payCard from "@/components/payCard/payCard.vue";
|
||
import SettleItem from './settleItem.vue'
|
||
import { print } from "@/api/pay";
|
||
import { shopStaffInfo, shopUserDetail } from '@/api/account.js'
|
||
import { dayjs, ElMessage } from "element-plus";
|
||
import { formatPhoneNumber, getOrderByIdAjax, commOrderPrintData } from '@/utils/index.js'
|
||
import useStorage from '@/utils/useStorage.js'
|
||
import { useGlobal } from '@/store/global.js'
|
||
import { usePrint } from '@/store/print.js'
|
||
import { useGoods } from '@/store/goods.js'
|
||
import { useSocket } from '@/store/socket.js'
|
||
import { orderPrint } from '@/api/order.js'
|
||
import { } from '@/utils/coupon-utils.js'
|
||
|
||
import { staffPermission } from '@/api/user.js'
|
||
import UserCharge from "@/views/member/components/userCharge.vue";
|
||
|
||
const userChangeRef = ref(null);
|
||
|
||
const goodsStore = useGoods()
|
||
|
||
const global = useGlobal()
|
||
const printStore = usePrint()
|
||
|
||
const store = useUser();
|
||
const socket = useSocket()
|
||
|
||
const emits = defineEmits(['success']);
|
||
|
||
const cartInfo = ref('')
|
||
|
||
const printLoading = ref(false);
|
||
const showStaffDiscount = ref(false)
|
||
const staffDiscount = ref('')
|
||
const discount = ref(0)
|
||
|
||
const dialogVisible = ref(false);
|
||
const props = defineProps({
|
||
amount: {
|
||
type: [Number, String],
|
||
default: 0,
|
||
},
|
||
remark: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
masterId: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
member: {
|
||
type: Object,
|
||
default: {}
|
||
}
|
||
});
|
||
|
||
const orderList = ref([])
|
||
const isPrint = ref(1);
|
||
const discountLoading = ref(false)
|
||
|
||
// 支付失败,订单已过期
|
||
function orderExpiredHnadle() {
|
||
dialogVisible.value = false
|
||
useStorage.del('tableCode')
|
||
socket.cartInit()
|
||
goodsStore.successClearCart()
|
||
}
|
||
|
||
// 显示员工折扣
|
||
async function showStaffDiscountHandle() {
|
||
try {
|
||
discountLoading.value = true
|
||
// await staffPermission('yun_xu_da_zhe')
|
||
await getStaffDiscountAjax()
|
||
discountLoading.value = false
|
||
if (staffDiscount.value <= 0) {
|
||
ElMessage.error('暂无折扣,请稍后再试')
|
||
} else {
|
||
showStaffDiscount.value = true
|
||
discountLoading.value = false
|
||
// global.updateData(false)
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
discountLoading.value = false
|
||
}
|
||
|
||
// 获取员工折扣
|
||
async function getStaffDiscountAjax() {
|
||
try {
|
||
const res = await shopStaffInfo()
|
||
if (res.data) {
|
||
staffDiscount.value = res
|
||
discount.value = res
|
||
} else {
|
||
Promise.reject()
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
// 预打印操作
|
||
const printHandle = _.throttle(async function () {
|
||
printLoading.value = true
|
||
await printOrderLable(true)
|
||
}, 1500, { leading: true, trailing: false })
|
||
|
||
// 打印订单标签
|
||
async function printOrderLable(isBefore = false) {
|
||
try {
|
||
let orderId = goodsStore.orderListInfo.id
|
||
const data = await getOrderByIdAjax(orderId);
|
||
|
||
let printList = useStorage.get("printList") || [];
|
||
|
||
// 防止重复打印
|
||
if (!printList.some((el) => el == orderId)) {
|
||
if (!isBefore) {
|
||
printList.push(orderId);
|
||
useStorage.set("printList", _.uniq(printList));
|
||
}
|
||
|
||
if (printStore.deviceLableList.length) {
|
||
if (!isBefore) {
|
||
// 预结算不打印标签
|
||
printStore.labelPrint(commOrderPrintData(data))
|
||
}
|
||
}
|
||
|
||
if (printStore.deviceNoteList.length) {
|
||
// 使用本地打印机打印
|
||
printStore.pushReceiptData(commOrderPrintData({ ...data, isBefore: isBefore }));
|
||
} else {
|
||
// 本地没有可用打印机使用云打印机
|
||
// await orderPrint({
|
||
// type: isBefore ? 1 : 0,
|
||
// id: orderId,
|
||
// });
|
||
// ElMessage.success(`云打印${isBefore ? '预' : ''}结算单成功`);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
setTimeout(() => {
|
||
printLoading.value = false
|
||
}, 2500)
|
||
}
|
||
|
||
// 订单已支付
|
||
function paySuccess() {
|
||
if (isPrint.value) printOrderLable()
|
||
emits('success')
|
||
dialogVisible.value = false;
|
||
ElMessage.success('支付成功')
|
||
goodsStore.clearCart()
|
||
useStorage.del('tableCode')
|
||
socket.cartInit()
|
||
goodsStore.successClearCart()
|
||
goodsStore.clearVipUserInfo()
|
||
payCardRef.value.resetCouponFormHandle()
|
||
}
|
||
|
||
const payCardRef = ref(null)
|
||
function show(t) {
|
||
dialogVisible.value = true;
|
||
cartInfo.value = { ...goodsStore.cartInfo }
|
||
orderList.value = [...goodsStore.cartList, ...goodsStore.orderList.map(item => item.goods).flat()]
|
||
|
||
console.log('orderListInfo===================', { ...goodsStore.orderListInfo });
|
||
|
||
// 每次初始化paycard
|
||
nextTick(() => {
|
||
payCardRef.value.payCardInit()
|
||
})
|
||
|
||
console.log('vipUserInfo===', goodsStore.vipUserInfo)
|
||
}
|
||
|
||
// 会员充值成功
|
||
async function chargeSuccess() {
|
||
try {
|
||
const res = await shopUserDetail({
|
||
id: goodsStore.vipUserInfo.id,
|
||
})
|
||
|
||
console.log(res)
|
||
goodsStore.vipUserInfo = res
|
||
} catch (e) {
|
||
console.log(e)
|
||
}
|
||
}
|
||
|
||
// 不支付返回清楚所有优惠
|
||
function returnHandle() {
|
||
dialogVisible.value = false
|
||
goodsStore.calcCartInfo({
|
||
pointsPerYuan: '',
|
||
maxDeductionAmount: '',
|
||
userPoints: '',
|
||
backendCoupons: [],
|
||
fixedAmount: ''
|
||
})
|
||
|
||
payCardRef.value.resetCouponFormHandle()
|
||
}
|
||
|
||
defineExpose({
|
||
show,
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
.el-drawer {
|
||
background-color: #efefef !important;
|
||
}
|
||
</style>
|
||
|
||
<style scoped lang="scss">
|
||
.footer_wrap {
|
||
display: flex;
|
||
gap: 10px;
|
||
|
||
.btn {
|
||
flex: 1;
|
||
}
|
||
}
|
||
|
||
.drawer_wrap {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
padding: var(--el-font-size-base) 0;
|
||
|
||
.cart_list {
|
||
flex: 1;
|
||
|
||
.nav_wrap {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 var(--el-font-size-base);
|
||
|
||
.return {
|
||
$size: 50px;
|
||
width: $size;
|
||
height: $size;
|
||
border-radius: 50%;
|
||
border: 2px solid #333;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.icon {
|
||
color: #333;
|
||
font-size: var(--el-font-size-base);
|
||
}
|
||
}
|
||
|
||
.info {
|
||
flex: 1;
|
||
padding-left: var(--el-font-size-base);
|
||
$padding: 10px;
|
||
|
||
.master_id {
|
||
height: 127px;
|
||
font-size: calc(var(--el-font-size-base) + 10px);
|
||
border-bottom: 1px solid #ececec;
|
||
padding: $padding 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
|
||
.member_info {
|
||
font-size: 16px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
|
||
&.s {
|
||
color: #999;
|
||
font-size: 14px;
|
||
}
|
||
|
||
&.between {
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.vip {
|
||
background-color: #F8F8F8;
|
||
border-radius: 6px;
|
||
color: #333;
|
||
font-size: 12px;
|
||
padding: 4px 8px;
|
||
color: #333;
|
||
}
|
||
}
|
||
}
|
||
|
||
.btm {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: $padding 0;
|
||
|
||
.p {
|
||
color: #999;
|
||
width: 160px;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.list_wrap {
|
||
padding: 0 var(--el-font-size-base);
|
||
height: calc(100vh - 270px);
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.footer {
|
||
display: flex;
|
||
padding-top: var(--el-font-size-base);
|
||
gap: var(--el-font-size-base);
|
||
|
||
.editor {
|
||
border: 1px solid #ececec;
|
||
border-radius: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #555;
|
||
}
|
||
|
||
.button {
|
||
flex: 1;
|
||
|
||
:deep(.el-checkbox.el-checkbox--large) {
|
||
height: var(--el-component-size-large);
|
||
background-color: #fff;
|
||
}
|
||
|
||
:deep(.el-checkbox__inner) {
|
||
width: 20px;
|
||
height: 20px;
|
||
|
||
&::after {
|
||
border-width: 2px;
|
||
top: 3px;
|
||
left: 7px;
|
||
}
|
||
}
|
||
|
||
:deep(.el-checkbox__label) {
|
||
font-size: var(--el-font-size-base) !important;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.pay_wrap {
|
||
flex: 1.5;
|
||
padding-left: 20px;
|
||
}
|
||
}
|
||
</style>
|