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

529 lines
13 KiB
Vue

<!-- 结算订单 -->
<template>
<el-drawer size="100%" :with-header="false" direction="btt" v-model="dialogVisible" @closed="drawerClose">
<div class="drawer_wrap">
<div class="cart_list">
<div class="nav_wrap card">
<div class="return" @click="dialogVisible = false">
<el-icon class="icon">
<ArrowLeftBold />
</el-icon>
</div>
<div class="info">
<div class="master_id">
<span>{{ props.masterId }}</span>
<span class="member_info" v-if="global.orderMemberInfo.telephone">
会员:{{ global.orderMemberInfo.telephone }}
</span>
</div>
<div class="btm">
<span class="p">服务员:{{ store.userInfo.loginAccount || "暂无" }}</span>
<span class="t">{{
props.orderInfo.createdAt &&
dayjs(props.orderInfo.createdAt).format("MM-DD HH:mm")
}}</span>
</div>
</div>
</div>
<div class="list_wrap card" style="margin-top: var(--el-font-size-base)">
<div class="item" v-for="item in cartList" :key="item.id">
<div class="top">
<span class="name">{{ item.name }}</span>
<span class="n">x{{ item.number }}</span>
<span class="p">¥{{ item.salePrice }}</span>
</div>
<div class="gift_wrap" v-if="item.isGift == 'true'">
<span>[赠送]</span>
<span>¥-{{ item.salePrice }}</span>
</div>
<div class="tag_wrap" v-if="item.skuName">
<div class="tag" v-for="item in item.skuName.split(',')">
{{ item }}
</div>
</div>
<div class="packge_Wrap" v-if="item.isPack == 'true'">
<div class="icon_item" v-if="item.isPack == 'true'" @click="giftPackHandle('isPack', item)">
<el-icon class="icon" style="color: var(--primary-color)">
<Box />
</el-icon>
</div>
</div>
</div>
</div>
<div class="footer">
<!-- <el-button icon="Edit"></el-button> -->
<div class="button">
<el-checkbox v-model="isPrint" 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 :amount="props.amount" :discount="propsDiscount" :orderId="props.orderInfo.id" @paySuccess="paySuccess"
@cancelDiscount="propsDiscount = 0" />
</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>
<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>
</template>
<script setup>
import _ from 'lodash'
import { onMounted, ref } from "vue";
import { useUser } from "@/store/user.js";
import payCard from "@/components/payCard/payCard.vue";
import { print } from "@/api/pay";
import { orderfindOrder, getStaffDiscount } from '@/api/order/index.js'
import { ElMessage } from "element-plus";
import dayjs from "dayjs";
import useStorage from '@/utils/useStorage'
import { ipcRenderer } from "electron";
import { formatDecimal } from '@/utils/index.js'
import receiptPrint from "@/components/lodop/receiptPrint.js";
import { useGlobal } from '@/store/global.js'
import { usePrint } from '@/store/print.js'
import { staffPermission } from '@/api/user.js'
const global = useGlobal()
const printStore = usePrint()
const store = useUser();
const emit = defineEmits("paySuccess");
const printLoading = ref(false);
const showStaffDiscount = ref(false)
const staffDiscount = ref(0)
const discount = ref(0)
const propsDiscount = ref(0)
const dialogVisible = ref(false);
const props = defineProps({
cart: {
type: Array,
default: [],
},
amount: {
type: [Number, String],
default: 0,
},
remark: {
type: String,
default: "",
},
orderInfo: {
type: Object,
default: "",
},
masterId: {
type: String,
default: "",
},
member: {
type: Object,
default: {}
}
});
const cartList = ref([])
const isPrint = ref(true);
const discountLoading = ref(false)
// 显示员工折扣
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) {
discountLoading.value = false
console.log(error);
}
}
// 获取员工折扣
async function getStaffDiscountAjax() {
try {
const res = await getStaffDiscount({
orderId: props.orderInfo.id,
staffId: store.userInfo.staffId
})
staffDiscount.value = res
discount.value = res
} catch (error) {
console.log(error);
}
}
// 确认折扣
function discountConfirm() {
if (discount.value >= staffDiscount.value) {
propsDiscount.value = discount.value
}
showStaffDiscount.value = false
}
// 关闭结算弹窗
function drawerClose() {
propsDiscount.value = 0
}
// 预打印操作
const printHandle = _.throttle(async function () {
try {
if (!isPrint.value) return;
printLoading.value = true;
const data = {
shop_name: store.userInfo.shopName,
loginAccount: store.userInfo.loginAccount,
isBefore: true,
carts: cartList.value,
amount: formatDecimal(props.amount),
discountAmount: propsDiscount.value > 0 ? formatDecimal(props.amount * propsDiscount.value) : formatDecimal(props.amount),
discount: formatDecimal(propsDiscount.value * 10, 1, true),
remark: props.remark,
orderInfo: props.orderInfo,
createdAt: dayjs(props.orderInfo.createdAt).format("YYYY-MM-DD HH:mm:ss"),
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
};
printStore.labelPrint(data)
setTimeout(() => {
printLoading.value = false;
}, 1500)
if (printStore.deviceNoteList.length) {
printStore.pushReceiptData(data)
} else {
await print({
type: "normal",
ispre: true,
orderId: props.orderInfo.id,
});
printLoading.value = false;
ElMessage.success("打印成功");
}
} catch (error) {
console.log(error);
}
}, 1500, { leading: true, trailing: false })
// 打印订单标签
async function printOrderLable() {
try {
if (!isPrint.value) return
const res = await orderfindOrder({
shopId: store.userInfo.shopId,
status: '',
size: 10,
page: 1,
orderNo: props.orderInfo.orderNo
})
const printLabelOrder = res.list[0]
const data = {
shop_name: store.userInfo.shopName,
loginAccount: store.userInfo.loginAccount,
carts: [],
amount: formatDecimal(printLabelOrder.orderAmount),
discountAmount: printLabelOrder.discountRatio > 0 ? formatDecimal(printLabelOrder.orderAmount - printLabelOrder.discountAmount) : formatDecimal(printLabelOrder.orderAmount),
discount: formatDecimal(printLabelOrder.discountRatio * 10, 1, true) || 0,
remark: printLabelOrder.remark,
orderInfo: printLabelOrder,
outNumber: printLabelOrder.outNumber,
createdAt: dayjs(printLabelOrder.createdAt).format(
"YYYY-MM-DD HH:mm:ss"
),
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
}
printLabelOrder.skuInfos.map(item => {
data.carts.push(
{
categoryId: item.categoryId,
name: item.productName,
number: item.num,
skuName: item.productSkuName,
salePrice: formatDecimal(item.price),
totalAmount: formatDecimal(item.num * item.price)
}
)
})
// 打印标签
printStore.labelPrint(data)
if (printStore.deviceNoteList.length) {
// 打印小票
printStore.pushReceiptData(data)
} else {
await print({
type: "normal",
ispre: true,
orderId: props.orderInfo.id,
});
printLoading.value = false;
ElMessage.success("打印成功");
}
} catch (error) {
console.log(error);
}
}
// 订单已支付
function paySuccess() {
propsDiscount.value = 0
dialogVisible.value = false;
global.setOrderMember({})
global.setOrderTable({})
printOrderLable()
emit("paySuccess");
}
function show() {
dialogVisible.value = true;
cartList.value = []
props.cart.map(item => {
if (item.info && item.info.length) {
item.info.map(item => {
cartList.value.push({ ...item })
})
} else {
cartList.value.push({ ...item })
}
})
}
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 {
font-size: calc(var(--el-font-size-base) + 10px);
border-bottom: 1px solid #ececec;
padding: $padding 0;
display: flex;
align-items: center;
justify-content: space-between;
.member_info {
color: #999;
font-size: 16px;
}
}
.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 - 200px);
overflow-y: auto;
.item {
padding: var(--el-font-size-base) 0;
border-bottom: 1px solid #ececec;
.top {
display: flex;
padding-bottom: 6px;
.name {
flex: 1;
}
.n {
width: 50px;
color: #555;
}
.p {
width: 50px;
color: #555;
}
}
.gift_wrap {
display: flex;
justify-content: space-between;
color: #999;
font-size: 16px;
}
.tag_wrap {
display: flex;
flex-wrap: wrap;
.tag {
padding: 2px 6px;
background-color: var(--el-color-danger);
color: #fff;
margin-right: 10px;
margin-bottom: 10px;
}
}
.packge_Wrap {
display: flex;
align-items: center;
.icon_item {
$size: 40px;
width: $size;
height: $size;
background-color: #e2e2e2;
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
}
}
}
.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>