parent
4b54fdaff1
commit
8dfa5b7aac
15849
dist-electron/main.js
15849
dist-electron/main.js
File diff suppressed because one or more lines are too long
|
|
@ -246,3 +246,16 @@ export function orderPrint(data) {
|
|||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 转台/并台
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function orderSwitcht(data) {
|
||||
return request({
|
||||
method: "PUT",
|
||||
url: "/order/switch",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
<el-drawer size="60%" :with-header="false" direction="rtl" v-model="dialogVisible" style="padding: 0">
|
||||
<div class="drawerbox_box">
|
||||
<div class="drawerbox_bo_top">
|
||||
<div class="drawerbox_bo_top_left">
|
||||
<div class="drawerbox_bo_top_left" @click="computeExpired">
|
||||
<div class="drawerbox_bo_top_left_one" style="font-size: 24px;">
|
||||
{{ store.userInfo.shopName }}
|
||||
</div>
|
||||
<div class="tips" style="margin-top: 4px; color: var(--el-color-warning);" v-if="!showTips">注意:您的账号将于{{
|
||||
store.userInfo.expireDate }}后过期,请尽快续期!</div>
|
||||
<div class="drawerbox_bo_top_left_tow" style="margin-top: 10px">
|
||||
收银员:{{ store.userInfo.loginAccount }}
|
||||
</div>
|
||||
|
|
@ -109,8 +111,21 @@ const screenref = ref(null);
|
|||
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
const showTips = ref(false)
|
||||
|
||||
function show() {
|
||||
dialogVisible.value = true;
|
||||
computeExpired()
|
||||
}
|
||||
|
||||
// 计算是否小于过期时间30天
|
||||
function computeExpired() {
|
||||
// 当前日期
|
||||
let now = dayjs()
|
||||
// 到期时间
|
||||
let expired = dayjs(store.userInfo.expireDate).subtract(30, 'day')
|
||||
// 判断当前时间是否大于到期时间30天
|
||||
showTips.value = now.isBefore(expired)
|
||||
}
|
||||
|
||||
// 打开叫号弹窗
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export const useSocket = defineStore({
|
|||
uuid: "", // 长连接唯一id
|
||||
heartbeatTimer: null, // 心跳计时器
|
||||
orderList: [],
|
||||
log: true,
|
||||
}),
|
||||
actions: {
|
||||
// 创建uuid
|
||||
|
|
@ -33,7 +34,7 @@ export const useSocket = defineStore({
|
|||
},
|
||||
// 关闭ws
|
||||
close() {
|
||||
console.log("关闭ws");
|
||||
if (this.log) console.log("关闭ws");
|
||||
this.online = false;
|
||||
this.ws.close(1000);
|
||||
this.ws = null;
|
||||
|
|
@ -57,7 +58,7 @@ export const useSocket = defineStore({
|
|||
printStore.init();
|
||||
|
||||
if (this.ws == null) {
|
||||
console.log("创建新的ws连接");
|
||||
if (this.log) console.log("创建新的ws连接");
|
||||
|
||||
const protocols = []; // 可选的子协议数组
|
||||
const options = {
|
||||
|
|
@ -67,17 +68,17 @@ export const useSocket = defineStore({
|
|||
};
|
||||
this.ws = new ReconnectingWebSocket(wsUrl, protocols, options);
|
||||
} else {
|
||||
console.log("重新连接ws");
|
||||
if (this.log) console.log("重新连接ws");
|
||||
this.wsReconnect();
|
||||
}
|
||||
|
||||
this.ws.addEventListener("open", (event) => {
|
||||
console.log("wss连接成功");
|
||||
if (this.log) console.log("wss连接成功");
|
||||
this.online = true;
|
||||
// 清除心跳
|
||||
this.clearHeartBeat();
|
||||
|
||||
console.log(this);
|
||||
if (this.log) console.log(this);
|
||||
|
||||
this.ws.send(
|
||||
JSON.stringify({
|
||||
|
|
@ -92,7 +93,7 @@ export const useSocket = defineStore({
|
|||
this.ws.addEventListener("message", (e) => {
|
||||
let data = JSON.parse(e.data);
|
||||
if (data.type == "order") {
|
||||
console.log("接收消息", data);
|
||||
if (this.log) console.log("接收消息", data);
|
||||
this.ws.send(
|
||||
JSON.stringify({
|
||||
type: "send",
|
||||
|
|
@ -112,18 +113,18 @@ export const useSocket = defineStore({
|
|||
}
|
||||
}
|
||||
} else if (data.type == "heartbeat") {
|
||||
console.log("接收心跳");
|
||||
if (this.log) console.log("接收心跳");
|
||||
}
|
||||
});
|
||||
|
||||
this.ws.addEventListener("error", () => {
|
||||
console.log("WebSocket连接发生错误");
|
||||
if (this.log) console.log("WebSocket连接发生错误");
|
||||
this.online = false;
|
||||
this.clearHeartBeat();
|
||||
});
|
||||
|
||||
this.ws.addEventListener("error", (e) => {
|
||||
console.log("ws关闭了", e);
|
||||
if (this.log) console.log("ws关闭了", e);
|
||||
this.online = false;
|
||||
this.clearHeartBeat();
|
||||
});
|
||||
|
|
@ -131,7 +132,7 @@ export const useSocket = defineStore({
|
|||
// 启动心跳连接
|
||||
startheartbeat() {
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
console.log("发送心跳");
|
||||
if (this.log) console.log("发送心跳");
|
||||
this.ws.send(JSON.stringify({ type: "heartbeat" }));
|
||||
}, 10000);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -56,6 +56,13 @@
|
|||
</el-icon>
|
||||
<el-text class="t">挂单</el-text>
|
||||
</div>
|
||||
<div class="item" @click="tableMergingHandle" :class="{ disabled: !props.item.id }"
|
||||
v-if="shopStore.info.registerType == 'restaurant' && props.item.tableId">
|
||||
<el-icon class="icon">
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
<el-text class="t">转桌</el-text>
|
||||
</div>
|
||||
<div class="item" @click="props.item.id && emit('clearCart')">
|
||||
<el-icon class="icon">
|
||||
<RefreshRight />
|
||||
|
|
@ -117,7 +124,7 @@ const props = defineProps({
|
|||
default: {}
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['confirm', 'delete', 'pending', 'clearCart'])
|
||||
const emit = defineEmits(['confirm', 'delete', 'pending', 'clearCart', 'merging'])
|
||||
|
||||
const takeFoodCodeRef = ref(null)
|
||||
const skuModalRef = ref([])
|
||||
|
|
@ -280,6 +287,14 @@ async function kitchenPrint() {
|
|||
}
|
||||
}
|
||||
/**免厨打印 end */
|
||||
|
||||
|
||||
// 显示合并转桌
|
||||
function tableMergingHandle() {
|
||||
if (props.item.id) {
|
||||
emit('merging')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
@ -287,7 +302,7 @@ async function kitchenPrint() {
|
|||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
gap: 10px;
|
||||
|
||||
.item {
|
||||
width: 70px;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
</div>
|
||||
<div class="shop_list" :class="{ img: shopListType == 'img' }" v-loading="loading">
|
||||
<!-- <swiper class="swiper_box" direction="vertical" @slideChange="onSlideChange"> -->
|
||||
<swiper class="swiper_box" direction="vertical" @slideChange="onSlideChange">
|
||||
<swiper ref="swiperRef" :loop="false" class="swiper_box" direction="vertical" @slideChange="onSlideChange">
|
||||
<swiper-slide class="slide_item" v-for="(goods, index) in goodsList" :key="index">
|
||||
<div class="item_wrap" v-for="item in goods" :key="item.id" @click="showSkuHandle(item)">
|
||||
<div class="item">
|
||||
|
|
@ -225,7 +225,7 @@
|
|||
<script setup>
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { nextTick, onMounted, ref } from 'vue'
|
||||
import _ from 'lodash'
|
||||
import useStorage from "@/utils/useStorage";
|
||||
import skuModal from '@/components/skuModal.vue'
|
||||
|
|
@ -239,6 +239,8 @@ import { staffPermission } from '@/api/user.js'
|
|||
import { useGlobal } from '@/store/global.js'
|
||||
import { inputFilterFloat } from '@/utils/index.js'
|
||||
|
||||
const swiperRef = ref(null)
|
||||
|
||||
const global = useGlobal()
|
||||
|
||||
const store = useUser()
|
||||
|
|
@ -594,14 +596,14 @@ async function queryCategoryAjax() {
|
|||
}
|
||||
|
||||
// 查询商品信息
|
||||
async function productqueryCommodityInfoAjax() {
|
||||
async function productqueryCommodityInfoAjax(page = goodsPage.value) {
|
||||
try {
|
||||
// loading.value = true
|
||||
const res = await queryNewCommodityInfo({
|
||||
shopId: store.userInfo.shopId,
|
||||
categoryId: categorys.value[categorysActive.value].id,
|
||||
commdityName: commdityName.value,
|
||||
page: goodsPage.value,
|
||||
page: page,
|
||||
pageSize: goodsPageSize.value,
|
||||
masterId: props.masterId,
|
||||
tableId: global.tableInfo.qrcode || '',
|
||||
|
|
@ -657,9 +659,7 @@ async function updataGoods() {
|
|||
}
|
||||
searchLoading.value = false
|
||||
} else {
|
||||
goodsPage.value = currentGoodsIndex.value + 1
|
||||
// console.log('更新第二页数据', goodsPage.value);
|
||||
const res = await productqueryCommodityInfoAjax()
|
||||
const res = await productqueryCommodityInfoAjax(currentGoodsIndex.value + 1)
|
||||
goodsList.value[currentGoodsIndex.value] = res.list
|
||||
searchLoading.value = false
|
||||
}
|
||||
|
|
@ -669,7 +669,6 @@ async function updataGoods() {
|
|||
const onSlideChange = _.debounce(async function (e) {
|
||||
if (e.activeIndex == e.previousIndex) return
|
||||
if (e.activeIndex > e.previousIndex) {
|
||||
// console.log('向下滑动');
|
||||
{
|
||||
goodsPage.value++
|
||||
const res = await productqueryCommodityInfoAjax()
|
||||
|
|
@ -681,24 +680,19 @@ const onSlideChange = _.debounce(async function (e) {
|
|||
const res = await productqueryCommodityInfoAjax()
|
||||
res.list.length && goodsList.value.push(res.list)
|
||||
}
|
||||
// goodsList.value.shift()
|
||||
} else {
|
||||
// console.log('向上滑动');
|
||||
// goodsPage.value--
|
||||
// const res = await productqueryCommodityInfoAjax()
|
||||
// goodsList.value.unshift(res)
|
||||
// goodsList.value.pop()
|
||||
}
|
||||
|
||||
currentGoodsIndex.value = e.activeIndex
|
||||
}, 500)
|
||||
|
||||
// 订单已结算,清楚商品所有数字
|
||||
// 订单已结算,清除商品所有数字
|
||||
function clearDot() {
|
||||
goodsList.value.map(item => {
|
||||
item.map(val => {
|
||||
val.orderCount = 0
|
||||
})
|
||||
})
|
||||
// goodsList.value.map(item => {
|
||||
// item.map(val => {
|
||||
// val.orderCount = 0
|
||||
// })
|
||||
// })
|
||||
updateData()
|
||||
}
|
||||
|
||||
const showEditor = ref(false)
|
||||
|
|
@ -770,6 +764,7 @@ async function showPutawayHandle(item) {
|
|||
}
|
||||
}
|
||||
|
||||
// 确认上架操作
|
||||
async function putawayHandle(item) {
|
||||
try {
|
||||
showPutawayLoading.value = true
|
||||
|
|
@ -875,6 +870,7 @@ onMounted(async () => {
|
|||
getUnitListAjax()
|
||||
await updateCategoryActive()
|
||||
await queryCategoryAjax()
|
||||
updataGoods()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,203 @@
|
|||
<!-- 合并/转桌 -->
|
||||
<template>
|
||||
<el-dialog title="转桌/并桌" width="700px" v-model="visible" @closed="onClose" top="10vh">
|
||||
<div class="scroll_y">
|
||||
<el-form :model="form" ref="formRef" :rules="rules" label-position="top">
|
||||
<el-form-item label="转入台桌" prop="targetTableId">
|
||||
<el-select v-model="form.targetTableId" style="width: 200px;" placeholder="请选择目标台桌">
|
||||
<el-option :label="item.name" :value="item.qrcode" v-for="item in tableList"
|
||||
:key="item.qrcode"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="转入类型">
|
||||
<el-radio-group v-model="form.isFull">
|
||||
<el-radio :value="false" border>转桌(可将部分商品转入)</el-radio>
|
||||
<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-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="number"></el-table-column>
|
||||
<el-table-column label="规格" prop="skuName"></el-table-column>
|
||||
<el-table-column label="价格" prop="salePrice"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="footer" style="display: flex;">
|
||||
<el-button style="width: 100%" @click="visible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button type="primary" style="width: 100%" :loading="loading" @click="confirmHandle">
|
||||
确认
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { queryShopTable } from '@/api/table.js'
|
||||
import { orderSwitcht } from '@/api/product.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: []
|
||||
})
|
||||
|
||||
const emits = defineEmits(['success'])
|
||||
|
||||
const tableRefs = ref([])
|
||||
|
||||
const list = ref([])
|
||||
|
||||
const loading = ref(false)
|
||||
const formRef = ref(null)
|
||||
const resetForm = ref({})
|
||||
const form = ref({
|
||||
shopId: store.userInfo.shopId,
|
||||
masterId: '',
|
||||
orderId: '',
|
||||
cartIds: [],
|
||||
isFull: false,
|
||||
currentTableId: '',
|
||||
targetTableId: '',
|
||||
})
|
||||
|
||||
const rules = ref({
|
||||
targetTableId: [
|
||||
{
|
||||
required: true,
|
||||
message: ' ',
|
||||
trigger: 'change',
|
||||
}
|
||||
],
|
||||
cartIds: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
let arr = []
|
||||
props.data.map((item, index) => {
|
||||
arr.push(...tableRefs.value[index].getSelectionRows())
|
||||
})
|
||||
|
||||
if (!arr.length) {
|
||||
ElMessage.error('至少选择一个商品')
|
||||
callback(new Error('至少选择一个商品'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const tableList = ref([])
|
||||
// 获取台桌列表
|
||||
async function queryShopTableAjax() {
|
||||
try {
|
||||
const res = await queryShopTable({
|
||||
shopId: store.userInfo.shopId,
|
||||
areaId: '',
|
||||
status: '',
|
||||
page: 1,
|
||||
pageSize: 100
|
||||
})
|
||||
tableList.value = res.list.filter(item => item.qrcode != props.data[0].info[0].tableId && item.status == 'using')
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 提交
|
||||
function confirmHandle() {
|
||||
formRef.value.validate(async valid => {
|
||||
try {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
form.value.masterId = props.data[0].info[0].masterId
|
||||
form.value.orderId = props.data[0].info[0].orderId
|
||||
form.value.currentTableId = props.data[0].info[0].tableId
|
||||
|
||||
if (!form.value.isFull) {
|
||||
let arr = []
|
||||
props.data.map((item, index) => {
|
||||
arr.push(...tableRefs.value[index].getSelectionRows())
|
||||
})
|
||||
form.value.cartIds = arr.map(item => item.id)
|
||||
}
|
||||
|
||||
await orderSwitcht(form.value)
|
||||
loading.value = false
|
||||
|
||||
// 更新台桌信息
|
||||
global.setOrderTable(tableList.value.find(item => item.qrcode == form.value.targetTableId))
|
||||
|
||||
visible.value = false
|
||||
|
||||
emits('success', { isTemporary: true })
|
||||
}
|
||||
} catch (error) {
|
||||
loading.value = false
|
||||
console.log(error);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
form.value = { ...resetForm.value }
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
function show(data) {
|
||||
props.data = data
|
||||
visible.value = true
|
||||
queryShopTableAjax()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
resetForm.value = { ...form.value }
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$btmH: 50px;
|
||||
|
||||
.scroll_y {
|
||||
height: 50vh;
|
||||
overflow-y: auto;
|
||||
padding-bottom: $btmH;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
height: $btmH;
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: $btmH*-1;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
</div>
|
||||
<!-- 购物车操作栏 -->
|
||||
<cartOperation :item="cartListActiveItem" @confirm="(res) => addCart(res, 'edit')" @delete="delCartHandle"
|
||||
@pending="pendingCart" @clearCart="clearCartHandle" />
|
||||
@pending="pendingCart" @clearCart="clearCartHandle" @merging="showTableMerging" />
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="top">
|
||||
|
|
@ -165,6 +165,8 @@
|
|||
<pendingCartModal ref="pendingCartModalRef" @select="pendingCartHandle" />
|
||||
<!-- 检查版本升级 -->
|
||||
<updateDialog />
|
||||
<!-- 合并/转桌 -->
|
||||
<tableMerging ref="tableMergingRef" @success="addCart" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -185,6 +187,7 @@ import cartOperation from "@/views/home/components/cartOperation.vue";
|
|||
import settleAccount from "@/views/home/components/settleAccount.vue";
|
||||
import fastCashier from "@/views/home/components/fastCashier.vue";
|
||||
import pendingCartModal from "@/views/home/components/pendingCartModal.vue";
|
||||
import tableMerging from '@/views/home/components/tableMerging.vue'
|
||||
import useStorage from '@/utils/useStorage'
|
||||
import { formatDecimal } from '@/utils/index.js'
|
||||
|
||||
|
|
@ -209,6 +212,7 @@ import member from "@/views/member/index.vue";
|
|||
import { ElMessage } from "element-plus";
|
||||
|
||||
import { useShop } from '@/store/shop.js'
|
||||
import TableMerging from "./components/tableMerging.vue";
|
||||
|
||||
const shopStore = useShop()
|
||||
|
||||
|
|
@ -224,6 +228,7 @@ const goodsRef = ref(null);
|
|||
const pendingCartModalRef = ref(null);
|
||||
const settleAccountRef = ref(null);
|
||||
const fastCashierRef = ref(null);
|
||||
const tableMergingRef = ref(null)
|
||||
|
||||
const allSelected = ref(false);
|
||||
|
||||
|
|
@ -493,7 +498,7 @@ async function queryCartAjax() {
|
|||
|
||||
cartInfo.value = res.amount;
|
||||
pendingCartNum.value = res.num;
|
||||
goodsRef.value.updateData();
|
||||
// goodsRef.value.updateData();
|
||||
|
||||
let i = 0;
|
||||
res.list.map((item) => {
|
||||
|
|
@ -568,6 +573,12 @@ function clearMember() {
|
|||
createCodeAjax()
|
||||
}
|
||||
|
||||
// 显示转桌/并桌
|
||||
function showTableMerging() {
|
||||
let data = cartList.value.filter(item => item.placeNum)
|
||||
tableMergingRef.value.show(data)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
createCodeAjax()
|
||||
shopStore.queryShopInfo()
|
||||
|
|
|
|||
Loading…
Reference in New Issue