Files
cashier_desktop/src/views/home/components/settleAccount.vue

463 lines
12 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>
<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>