增加代客下单页面

This commit is contained in:
2025-02-21 14:42:38 +08:00
parent e08a2eb4b7
commit f961bf7d92
24 changed files with 2780 additions and 199 deletions

View File

@@ -0,0 +1,403 @@
<template>
<div class="box">
<div class="content">
<div class="top">
<div class="left u-flex u-col-center">
<span class="title">代客下单</span>
<div class="u-m-l-20 flex">
<el-button type="primary">选择用户</el-button>
<el-button>选择桌号</el-button>
<el-button type="warning">扫码验券</el-button>
</div>
</div>
<div class="right">
<el-input placeholder="请输入商品名称" v-model="keywords" clearable>
<template #suffix>
<el-icon class="el-input__icon"><search /></el-icon>
</template>
</el-input>
</div>
</div>
<div class="diancan">
<div class="left">
<div class="diners">
<el-button-group v-model="diners.sel" style="width: 100%; display: flex">
<el-button
:class="{ active: index == diners.sel }"
v-for="(item, index) in diners.list"
:key="index"
>
{{ item.label }}
</el-button>
</el-button-group>
</div>
<div class="u-flex u-font-14 clear u-m-t-10 perpoles">
<div
class="u-flex u-p-r-14 u-m-r-14"
style="border-right: 1px solid #ebebeb; line-height: 1"
>
<span>就餐人数-</span>
<el-icon><ArrowRight /></el-icon>
</div>
<a @click="clearCarts" style="color: #1890ff">清空</a>
</div>
<cartsList
:goodsMapisFinish="goodsMapisFinish"
:goodsList="goods.list"
ref="refCart"
></cartsList>
</div>
<div class="center">
<Controls @noteClick="showNote" @packClick="showPack" />
</div>
<div class="right">
<div class="flex categoty u-col-center">
<div
class="show_more_btn"
:class="{ showAll: category.showAll }"
@click="toggleShowAll"
>
<div class="flex">
<div class="flex showmore">
<el-icon color="#fff"><ArrowDown /></el-icon>
</div>
<span>{{ category.showAll ? "收起" : "展开" }}</span>
</div>
</div>
<div class="flex categorys" :class="{ 'flex-wrap': category.showAll }">
<div
v-for="(item, index) in category.list"
:key="index"
@click="changeCategoryId(item)"
>
<el-tag
size="large"
type="primary"
effect="dark"
v-if="goods.query.categoryId === item.id"
>
{{ item.name }}
</el-tag>
<el-tag size="large" type="info" v-else effect="plain">{{ item.name }}</el-tag>
</div>
</div>
</div>
<div class="goods-list">
<GoodsItem
:item="item"
@click="goodsClick(item)"
v-for="item in goods.list"
:key="item.id"
></GoodsItem>
</div>
</div>
</div>
</div>
<dialogGoodsSel ref="refSelSku"></dialogGoodsSel>
<note ref="refNote" @confirm="noteConfirm"></note>
<pack ref="refPack" @confirm="packConfirm"></pack>
</div>
</template>
<script setup>
import Controls from "./components/control.vue";
import note from "./components/note.vue";
import pack from "./components/pack.vue";
import GoodsItem from "./components/goods-item.vue";
import dialogGoodsSel from "./components/dialog-goods-sel.vue";
import cartsList from "./components/carts/list.vue";
import categoryApi from "@/api/product/productclassification";
import productApi from "@/api/product/index";
//打包
const refPack = ref();
function showPack(packNumber, max) {
refPack.value.open(packNumber * 1, max * 1);
}
function packConfirm(packNumber) {
refCart.value.carts.updateTag("pack_number", packNumber);
}
//备注
const refNote = ref(null);
function showNote(isOneNote) {
const remark = isOneNote ? refCart.value.carts.selCart.remark : "";
console.log(remark);
refNote.value.open(remark, isOneNote);
}
function noteConfirm(note, isOneNote) {
if (isOneNote) {
refCart.value.carts.updateTag("remark", note);
return;
}
}
// 搜索
const keywords = ref("");
// 就餐类型
const diners = reactive({
list: [
{ label: "堂食", value: 1 },
{ label: "自取", value: 2 },
],
sel: 0,
});
// 商品分类
const category = reactive({
list: [],
showAll: false,
});
function toggleShowAll() {
category.showAll = !category.showAll;
}
function changeCategoryId() {}
function getCategoryList() {
categoryApi
.getList({
page: 1,
size: 200,
})
.then((res) => {
category.list = res;
});
}
//商品
const refSelSku = ref(null);
const goods = reactive({
list: [],
query: {
categoryId: "",
keywords: "",
},
});
let goodsMapisFinish = ref(false);
function getGoods() {
productApi
.getPage({
page: 1,
size: 200,
...goods.query,
})
.then((res) => {
goods.list = res.records;
goodsMapisFinish.value = true;
});
}
function goodsClick(item) {
//单规格
if (item.type == "single") {
addCarts({
product_id: item.id,
sku_id: item.skuList[0].id,
number: 1,
is_pack: 0,
is_gift: 0,
is_temporary: 0,
discount_sale_amount: 0,
discount_sale_note: "",
is_print: 0,
is_wait_call: 0,
product_name: "",
remark: "",
});
}
// 多规格
if (item.type == "sku") {
refSelSku.value.open(item);
}
}
//购物车
const refCart = ref(null);
function clearCarts() {
ElMessageBox.alert("确定要清空点餐列表吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
refCart.value.carts.clear();
});
}
function addCarts(item) {
const hasCart = refCart.value.carts.list.find((cartItem) => {
return cartItem.product_id == item.product_id && cartItem.sku_id == item.sku_id;
});
console.log(hasCart);
if (hasCart) {
refCart.value.carts.update({ ...item, id: hasCart.id });
} else {
refCart.value.carts.add(item);
}
}
function init() {
getCategoryList();
getGoods();
}
init();
</script>
<style lang="scss" scoped>
$pl: 30px;
.box {
padding: 20px 20px 10px 20px;
height: 100%;
.content {
background-color: #fff;
height: 100%;
box-sizing: border-box;
padding: 20px 20px 20px 0;
.top {
display: flex;
justify-content: space-between;
padding-bottom: 20px;
border-bottom: 1px solid #ebebeb;
margin-left: $pl;
.left {
flex: 1;
.title {
font-size: 16px;
color: #333;
font-weight: 700;
white-space: nowrap;
}
}
.right {
flex: 1;
}
}
.diancan {
padding-top: 10px;
display: flex;
max-height: calc(100vh - 256px);
.left {
width: 350px;
padding-right: 14px;
box-sizing: border-box;
display: flex;
flex-direction: column;
.diners {
padding-left: $pl;
}
.perpoles {
padding-left: $pl;
}
}
.right {
flex: 1;
overflow-x: hidden;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 4px;
}
}
.center {
overflow-x: hidden;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 4px;
}
}
}
}
}
:deep(.diners .el-button-group .active) {
border: 1px solid #409eff !important;
color: #409eff !important;
background: rgba(24, 144, 255, 0.1) !important;
z-index: 10;
}
:deep(.diners .el-button-group) {
width: 100%;
display: flex;
}
:deep(.diners .el-button-group .el-button) {
flex: 1;
}
:deep(.categorys .el-tag--plain.el-tag--info) {
border: 1px solid #dcdfe6;
color: #000;
font-weight: 600;
}
:deep(.categorys .el-tag) {
min-width: 80px;
height: 38px;
line-height: 38px;
text-align: center;
box-sizing: border-box;
text-align: center;
padding: 0 14px;
font-size: 14px;
font-weight: 600;
border-radius: 2px;
user-select: none;
margin: 0 10px 10px 0;
cursor: pointer;
}
.categoty {
position: sticky;
top: 0;
background-color: #f7f7fa;
z-index: 1;
padding-top: 14px;
.show_more_btn {
padding: 0 10px;
color: #333;
font-size: 16px;
display: flex;
align-items: center;
user-select: none;
min-width: 80px;
background: #f7f7fa;
position: absolute;
right: 0;
top: 14px;
height: 38px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
.showmore {
transition: all 0.2s;
margin-right: 8px;
width: 21px;
height: 21px;
border-radius: 50%;
background: #3f9eff;
display: flex;
justify-content: center;
align-items: center;
}
&.showAll {
.showmore {
transform: rotate(180deg);
}
}
}
}
.goods-list {
display: flex;
flex-wrap: wrap;
gap: 15px;
flex: 1;
}
:deep(.carts) {
padding-left: $pl;
}
:deep(.left) {
.bottom {
padding-left: $pl;
}
}
</style>