优化小票打印

This commit is contained in:
gyq
2025-03-13 18:54:10 +08:00
parent cfe9f7bb36
commit 745b8675ea
8 changed files with 207 additions and 167 deletions

View File

@@ -68,12 +68,12 @@
</el-icon>
<el-text class="t">删除</el-text>
</div>
<!-- <div class="item" @click="props.item.id && emit('pending', props.item)">
<div class="item" @click="pendingOrderHandle">
<el-icon class="icon">
<Sell />
</el-icon>
<el-text class="t">挂单</el-text>
</div> -->
</div>
<div class="item" @click="tableMergingRef.show()">
<el-icon class="icon">
<EditPen />
@@ -143,12 +143,12 @@
</el-icon>
<el-text class="t">退菜</el-text>
</div>
<!-- <div class="item" @click="props.item.id && emit('pending', props.item)">
<el-icon class="icon">
<Sell />
</el-icon>
<el-text class="t">挂单</el-text>
</div> -->
<div class="item" @click="pendingOrderHandle">
<el-icon class="icon">
<Sell />
</el-icon>
<el-text class="t">挂单</el-text>
</div>
<div class="item" @click="tableMergingRef.show()">
<el-icon class="icon">
<EditPen />
@@ -254,14 +254,13 @@ import { ElMessage } from 'element-plus'
import takeFoodCode from '@/components/takeFoodCode.vue'
import TableMerging from './tableMerging.vue'
import skuModal from '@/components/skuModal.vue'
import { useShop } from '@/store/shop.js'
import { useGoods } from '@/store/goods.js'
import { inputFilterFloat, formatDecimal } from '@/utils/index.js'
import { updatePrice, orderPrint } from '@/api/product.js'
import { refundOrder } from '@/api/order.js'
import { useSocket } from '@/store/socket.js'
const shopStore = useShop()
const goodsStore = useGoods()
const socket = useSocket()
const tableMergingRef = ref(null)
@@ -282,6 +281,18 @@ const returnForm = ref({
num: 1
})
// 挂单
function pendingOrderHandle() {
let cart = goodsStore.cartList;
let order = goodsStore.orderList;
if (cart.length || order.length) {
goodsStore.pendingCart()
goodsStore.successClearCart();
socket.cartInit();
ElMessage.success('挂单成功')
}
}
// 退菜
async function returnOrderItemHandle() {
@@ -348,18 +359,20 @@ function packHandle() {
// 赠送打包操作
function giftPackHandle(key) {
if (!goodsStore.cartList[goodsStore.cartActiveIndex].id) return
let item = goodsStore.cartList[goodsStore.cartActiveIndex]
if (item && item.id) {
if (key == 'is_gift' && goodsStore.cartList[goodsStore.cartActiveIndex] == 0) {
goodsStore.cartList[goodsStore.cartActiveIndex].discount_sale_amount = 0
}
if (key == 'is_gift' && goodsStore.cartList[goodsStore.cartActiveIndex] == 0) {
goodsStore.cartList[goodsStore.cartActiveIndex].discount_sale_amount = 0
if (goodsStore.cartList[goodsStore.cartActiveIndex][key] == 0) {
goodsStore.cartList[goodsStore.cartActiveIndex][key] = 1
} else {
goodsStore.cartList[goodsStore.cartActiveIndex][key] = 0
}
goodsStore.operateCart({ ...goodsStore.cartList[goodsStore.cartActiveIndex] }, 'edit')
}
if (goodsStore.cartList[goodsStore.cartActiveIndex][key] == 0) {
goodsStore.cartList[goodsStore.cartActiveIndex][key] = 1
} else {
goodsStore.cartList[goodsStore.cartActiveIndex][key] = 0
}
goodsStore.operateCart({ ...goodsStore.cartList[goodsStore.cartActiveIndex] }, 'edit')
}
// 显示直接修改数量
@@ -467,9 +480,10 @@ const noteList = ref([
// 显示
function showDiscountModalHandle() {
let item = goodsStore.cartList[goodsStore.cartActiveIndex]
if ((item && !item.id) || item.is_temporary || item.is_gift) return
// 存在商品并且不能为临时菜
showDiscountModal.value = true
if ((item && item.id) && (!item.is_temporary || !item.is_gift)) {
// 存在商品并且不能为临时菜
showDiscountModal.value = true
}
}
// 过滤价格输入
@@ -519,24 +533,10 @@ function discountFormSubmit() {
}
/**单品打折 end */
/**免厨打印 start */
async function kitchenPrint() {
try {
const res = await orderPrint({
isPrint: props.item.isPrint ? 0 : 1,
shopId: props.item.shopId,
cartId: props.item.id
})
emit('confirm', { isTemporary: true })
} catch (error) {
console.log(error);
}
}
/**免厨打印 end */
// 删除
function deleteHandle() {
if (goodsStore.cartList[goodsStore.cartActiveIndex].id) {
let item = goodsStore.cartList[goodsStore.cartActiveIndex]
if (item && item.id) {
goodsStore.deleteCartItem()
}
}
@@ -605,7 +605,7 @@ function packFormSubmit() {
padding: 10px;
display: flex;
flex-direction: column;
gap: 10px;
gap: 8px;
.item {
width: 70px;

View File

@@ -1,7 +1,7 @@
<template>
<el-dialog title="恢复挂起的订单" width="800" v-model="dialogVisible">
<div class="pending_carts">
<div class="item" v-for="(item, index) in cartList" :key="index" @click="select(item)">
<div class="item" v-for="(item, index) in goodsStore.pendingList" :key="index" @click="select(item)">
<div class="time">
<el-icon class="icon">
<Clock />
@@ -9,12 +9,12 @@
<span>{{ dayjs(item.pendingAt).format('HH:mm') }}</span>
</div>
<div class="info">
<span class="name">{{ item.productName }}</span>
<span class="p">{{ item.totalAmount }}</span>
<span class="name">{{ item.tableCode }}{{ item.productName }}</span>
<span class="p">{{ formatDecimal(item.totalAmount) }}</span>
</div>
</div>
<div class="empty">
<el-empty description="暂无挂单" v-if="!cartList.length" />
<el-empty description="暂无挂单" v-if="!goodsStore.pendingList.length" />
</div>
</div>
</el-dialog>
@@ -23,40 +23,20 @@
<script setup>
import { ref } from 'vue'
import { dayjs } from 'element-plus'
import { getCartList } from "@/api/product";
import { useUser } from "@/store/user"
import { useGoods } from '@/store/goods.js'
import { formatDecimal } from '@/utils/index.js'
const emit = defineEmits(['select'])
const store = useUser()
const goodsStore = useGoods()
const dialogVisible = ref(false)
const loading = ref(false)
const cartList = ref([])
// 恢复挂单
function select(item) {
emit('select', item)
async function select(item) {
await goodsStore.recoverPending(item)
dialogVisible.value = false
}
function show() {
dialogVisible.value = true
getCartListAjax()
}
// 获取挂起购物车列表
async function getCartListAjax() {
try {
loading.value = true
const res = await getCartList({
shopId: store.userInfo.shopId
})
cartList.value = res
loading.value = false
} catch (error) {
console.log(error)
}
}
defineExpose({

View File

@@ -1,6 +1,6 @@
<!-- 合并/转桌 -->
<template>
<el-dialog title="转桌/并桌" width="700px" v-model="visible" @closed="onClose" top="10vh">
<el-dialog title="转桌/并桌" width="700px" v-model="visible" @closed="onClose" top="3vh">
<div class="scroll_y">
<el-form :model="form" ref="formRef" :rules="rules" label-position="top">
<el-form-item label="转入台桌" prop="targetTableId">
@@ -15,15 +15,24 @@
<el-radio :value="true" border>并桌并台会将全部购物车商品转入</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="转入商品" prop="cartIds" v-if="!form.isFull">
<div v-for="item in props.data" style="width: 100%;">
<div>{{ `${item.placeNum}次下单` }}</div>
<el-table ref="tableRefs" :data="item.info" border>
<el-form-item label="购物车商品" v-if="!form.isFull">
<el-table ref="cartTableRefs" :data="goodsStore.cartList" border stripe>
<el-table-column type="selection" align="center" width="50px"></el-table-column>
<el-table-column label="名称" prop="product_name"></el-table-column>
<el-table-column label="数量" prop="number"></el-table-column>
<el-table-column label="规格" prop="sku_name"></el-table-column>
<el-table-column label="价格" prop="lowPrice"></el-table-column>
</el-table>
</el-form-item>
<el-form-item label="已下单商品" prop="cartIds" v-if="!form.isFull">
<div v-for="item in goodsStore.orderList" style="width: 100%;">
<div>{{ `${item.orderNum}次下单` }}</div>
<el-table ref="orderTableRefs" :data="item.goods" border stripe>
<el-table-column type="selection" align="center" width="50px"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="名称" prop="product_name"></el-table-column>
<el-table-column label="数量" prop="number"></el-table-column>
<el-table-column label="规格" prop="skuName"></el-table-column>
<el-table-column label="价格" prop="salePrice"></el-table-column>
<el-table-column label="规格" prop="sku_name"></el-table-column>
<el-table-column label="价格" prop="lowPrice"></el-table-column>
</el-table>
</div>
</el-form-item>
@@ -41,29 +50,20 @@
</template>
<script setup>
import { onMounted, reactive, ref } from 'vue'
import { shopTable } from '@/api/account.js'
import { queryShopTable } from '@/api/table.js'
import { onMounted, ref } from 'vue'
import { orderSwitcht } from '@/api/product.js'
import { useGoods } from '@/store/goods.js'
import { useUser } from "@/store/user.js"
import { useGlobal } from '@/store/global.js'
import { ElMessage } from 'element-plus'
const store = useUser()
const global = useGlobal()
const visible = ref(false)
const props = reactive({
data: []
})
import { shopTable } from "@/api/account.js";
const emits = defineEmits(['success'])
const tableRefs = ref([])
const list = ref([])
const store = useUser()
const goodsStore = useGoods()
const visible = ref(false)
const cartTableRefs = ref(null)
const orderTableRefs = ref(null)
const loading = ref(false)
const formRef = ref(null)
const resetForm = ref({})
@@ -111,10 +111,8 @@ const tableList = ref([])
async function queryShopTableAjax() {
try {
const res = await shopTable({
areaId: store.userInfo.shopId,
tableCode: '',
status: 'using',
name: ''
isBind: true
})
tableList.value = res.records
} catch (error) {
@@ -144,7 +142,7 @@ function confirmHandle() {
loading.value = false
// 更新台桌信息
global.setOrderTable(tableList.value.find(item => item.qrcode == form.value.targetTableId))
// 在这里做点什么
visible.value = false
@@ -162,8 +160,7 @@ function onClose() {
formRef.value.resetFields()
}
function show(data) {
props.data = data
function show() {
visible.value = true
queryShopTableAjax()
}
@@ -181,7 +178,7 @@ onMounted(() => {
$btmH: 50px;
.scroll_y {
height: 50vh;
height: 68vh;
overflow-y: auto;
padding-bottom: $btmH;
}

View File

@@ -6,7 +6,7 @@
<el-icon class="icon">
<TakeawayBox />
</el-icon>
<el-text class="t">({{ pendingCartNum }})</el-text>
<el-text class="t">({{ goodsStore.pendingList.length }})</el-text>
</div>
<div class="number" @click="SelectVipUserRef.show()">
<div class="left">
@@ -106,7 +106,8 @@
<div class="top">
<div class="num-wrap">
<div class="num_wrap_top">
<div class="left" @click="allSelectedHandle" v-if="store.shopInfo.eatModel.includes('take-out')">
<div class="left" @click="allSelectedHandle"
v-if="store.shopInfo && store.shopInfo.eatModel.includes('take-out')">
<div class="selected">
<div class="selected_round" v-if="!goodsStore.allSelected"></div>
<el-icon class="icon" v-else>
@@ -118,7 +119,7 @@
<div class="left" v-else></div>
<div class="right">
<el-text>
{{ goodsStore.cartInfo.total }}
{{ formatDecimal(goodsStore.cartInfo.total, 2, true) }}
</el-text>{{ formatDecimal(goodsStore.cartInfo.totalAmount || 0) }}
</div>
</div>
@@ -167,7 +168,7 @@
<!-- 快捷收银 -->
<fastCashier ref="fastCashierRef" type="0" />
<!-- 挂起订单 -->
<pendingCartModal ref="pendingCartModalRef" @select="pendingCartHandle" />
<pendingCartModal ref="pendingCartModalRef" />
<!-- 检查版本升级 -->
<updateDialog />
<!-- 选择会员 -->
@@ -195,13 +196,12 @@ import { createOrder } from '@/api/order.js'
import goods from "@/views/home/components/goods.vue";
import member from "@/views/member/index.vue";
import { useUser } from '@/store/user.js'
import { useSocket } from '@/store/socket.js'
const SelectVipUserRef = ref(null)
const goodsStore = useGoods()
const global = useGlobal()
const socket = useSocket()
const membershow = ref(false);
const store = useUser();
const remarkRef = ref(null);
@@ -320,18 +320,15 @@ const allSelectedHandle = async () => {
} else {
goodsStore.allSelected = 1
}
if (goodsStore.cartList.length) {
goodsStore.operateCart({
table_code: goodsStore.cartList[0].table_code,
is_pack: goodsStore.allSelected
}, 'batch')
}
};
// 购物车选中
function selectCartItemHandle(index) {
goodsStore.selectCartItemHandle(index)
}
// 清除本地会员/台桌信息
function clearMember() {
global.setOrderMember({})
global.setOrderTable({})
}
// 显示转桌/并桌
function showTableMerging() {

View File

@@ -1,5 +1,5 @@
<template>
<el-drawer v-model="isShow" direction="rtl" size="60%">
<el-drawer v-model="isShow" direction="rtl" size="70%">
<template #header>
<h4>订单号{{ item.orderNo }}</h4>
</template>
@@ -24,9 +24,10 @@
<el-radio-button label="自定义" :value="3" />
</el-radio-group>
<div class="amount">
<el-input v-model="customAmount" v-if="refundType == 3" style="width: 250px;"
<el-input v-model="customAmount" v-if="refundType == 3" style="width: 370px;height: 42px;"
placeholder="请输入退款金额" @input="inputChange">
<template #prepend></template>
<template #append>最多可退{{ formatDecimal(item.payAmount - item.refundAmount, 2) }}</template>
</el-input>
<template v-else>
退款金额{{ formatDecimal(refundType == 1 ? item.originAmount - item.refundAmount : amount) }}
@@ -97,10 +98,10 @@
</el-table>
</template>
<div class="ipt">
<el-input type="textarea" v-model="remark" placeholder="请输入退单原因" />
<el-input type="textarea" rows="4" v-model="remark" placeholder="请输入退单原因" />
</div>
<div class="remark_tag">
<div class="item" v-for="(item, index) in remarkTagList" :key="index" @click="remark = item">
<div class="item" v-for="(item, index) in remarkTagList" :key="index" @click="addRmarkHandle(item)">
{{ item }}
</div>
</div>
@@ -394,13 +395,22 @@ function refundTypeChange(val) {
function inputChange(n) {
setTimeout(() => {
if (n > item.value.payAmount - item.value.refundAmount) {
customAmount.value = formatDecimal(item.value.payAmount - item.value.refundAmount, 2, true)
customAmount.value = formatDecimal(item.value.payAmount - item.value.refundAmount, 2)
} else {
customAmount.value = inputFilterFloat(n)
}
}, 100)
}
// 添加备注
function addRmarkHandle(item) {
if (remark.value.length) {
remark.value += `${item}`
} else {
remark.value = item
}
}
defineExpose({
show
})

View File

@@ -45,10 +45,15 @@
</div>
</div>
</div>
<div class="empty">
<el-empty description="空空如也~" v-if="!tableList.length" />
<div class="empty" v-if="!tableList.length">
<el-empty description="空空如也~" />
</div>
</div>
<div class="pagination">
<el-pagination background v-model:current-page="query.page" :pager-count="5"
layout=" pager, jumper, total" :total="query.total"
@current-change="shopTableAjax"></el-pagination>
</div>
</div>
</div>
<div class="right_card card">
@@ -61,17 +66,11 @@
</template>
<script setup>
import { queryShopArea, queryShopTable } from '@/api/table'
import { shopArea, shopTable } from "@/api/account.js";
import countCard from '@/views/table/components/countCard.vue'
import tableInfo from '@/views/table/components/tableInfo.vue'
import { ref, onMounted } from 'vue'
import { useUser } from "@/store/user.js"
import { dayjs } from 'element-plus'
const store = useUser()
const tabActive = ref(0)
const tabAreas = ref([
@@ -93,6 +92,11 @@ const tabAreas = ref([
// }
])
const query = ref({
page: 1,
size: 12,
total: 0
})
const loading = ref(false)
// 区域列表
const areaList = ref([])
@@ -158,12 +162,15 @@ async function shopTableAjax() {
try {
loading.value = true
const res = await shopTable({
page: query.value.page,
size: query.value.size,
areaId: area.value,
tableCode: '',
name: '',
status: tabAreas.value[tabActive.value].type,
})
tableList.value = res.records
query.value.total = +res.totalRow
setTimeout(() => {
loading.value = false
}, 500)
@@ -180,6 +187,12 @@ onMounted(() => {
</script>
<style scoped lang="scss">
.pagination {
display: flex;
justify-content: flex-end;
padding-top: var(--el-font-size-base);
}
.cart_wrap {
flex: 2;
}
@@ -244,7 +257,7 @@ onMounted(() => {
}
.overflow_y {
height: calc(100vh - 160px);
height: calc(100vh - 220px);
overflow-y: auto;
}
@@ -252,7 +265,7 @@ onMounted(() => {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: auto;
gap: var(--el-font-size-base);
gap: 10px;
.item {
$closedColor: #aeb8c9;
@@ -317,7 +330,7 @@ onMounted(() => {
}
.tab_cont {
height: 120px;
height: 112px;
display: flex;
align-items: center;
justify-content: center;