638 lines
16 KiB
Vue
638 lines
16 KiB
Vue
<template>
|
|
<div class="content">
|
|
<div class="cart_wrap card">
|
|
<div class="menu_top">
|
|
<div class="menu" @click="pendingCartModalRef.show()">
|
|
<el-icon class="icon">
|
|
<TakeawayBox />
|
|
</el-icon>
|
|
<el-text class="t">({{ pendingCartNum }})</el-text>
|
|
</div>
|
|
<div class="number" @click="takeFoodCodeRef.show()">
|
|
<el-text class="t">{{ masterId }}</el-text>
|
|
</div>
|
|
<div class="select_user" @click="fastCashierRef.show()" v-if="!memberInfo.telephone">
|
|
<div class="left">
|
|
<el-icon class="icon">
|
|
<WalletFilled />
|
|
</el-icon>
|
|
<el-text class="t">快捷收银</el-text>
|
|
</div>
|
|
<el-icon class="arrow">
|
|
<ArrowRight />
|
|
</el-icon>
|
|
</div>
|
|
<div class="select_user" v-else @click="clearMember">
|
|
<div class="left">
|
|
<el-icon class="icon">
|
|
<UserFilled />
|
|
</el-icon>
|
|
<el-text class="t">{{ memberInfo.telephone }}</el-text>
|
|
</div>
|
|
<el-icon class="arrow">
|
|
<Close />
|
|
</el-icon>
|
|
</div>
|
|
</div>
|
|
<div class="shop_operation" v-loading="cartLoading">
|
|
<div class="shop_list">
|
|
<div class="item" :class="{ active: cartListActive == index }" v-for="(item, index) in cartList"
|
|
:key="item.id" @click="selectCartItemHandle(item, index)">
|
|
<div class="name_wrap">
|
|
<span>{{ item.name }}</span>
|
|
<span>¥{{ item.salePrice }}</span>
|
|
</div>
|
|
<div class="sku_list" v-if="item.skuName">
|
|
<div class="tag" v-for="item in item.skuName.split(',')">
|
|
{{ item }}
|
|
</div>
|
|
</div>
|
|
<div class="num">
|
|
<div class="left">
|
|
<div class="icon_item" v-if="item.isGift == 'true'" @click="giftPackHandle('isGift', item)">
|
|
<el-icon class="icon">
|
|
<ShoppingBag />
|
|
</el-icon>
|
|
</div>
|
|
<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>
|
|
<el-text class="t">X{{ item.number }}</el-text>
|
|
</div>
|
|
</div>
|
|
<div class="empty">
|
|
<el-empty description="请选择商品" v-if="!cartList.length" />
|
|
</div>
|
|
</div>
|
|
<!-- 购物车操作栏 -->
|
|
<cartOperation :item="cartList[cartListActive]" @confirm="(res) => addCart(res, 'edit')" @delete="delCartHandle"
|
|
@pending="pendingCart" @clearCart="clearCartHandle" />
|
|
</div>
|
|
<div class="footer">
|
|
<div class="top">
|
|
<div class="left" @click="allSelectedHandle">
|
|
<div class="selected">
|
|
<div class="selected_round" v-if="!allSelected"></div>
|
|
<el-icon class="icon" v-else>
|
|
<CircleCheckFilled />
|
|
</el-icon>
|
|
</div>
|
|
<el-text class="t">打包(¥{{ cartInfo.packAmount || 0 }})</el-text>
|
|
</div>
|
|
<div class="num-wrap">
|
|
<el-text>共{{ cartInfo.productNum || 0 }}种商品,{{
|
|
cartInfo.productSum || 0
|
|
}}件</el-text>
|
|
</div>
|
|
</div>
|
|
<div class="btm">
|
|
<el-button icon="Edit" @click="remarkRef.show()"></el-button>
|
|
<div class="button">
|
|
<el-button type="primary" style="width: 100%" :disabled="!cartList.length" v-loading="createOrderLoading"
|
|
@click="createOrderHandle">
|
|
<span v-if="!createOrderLoading">结算(¥{{ cartInfo.totalAmount || 0 }})</span>
|
|
<span v-else>下单中...</span>
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="shop_manage card">
|
|
<!-- 分类/商品列表 -->
|
|
<goods ref="goodsRef" :masterId="masterId" @success="addCart" />
|
|
<!-- ©银收客 v{{ packageData.version }} -->
|
|
</div>
|
|
</div>
|
|
<!-- 备注 -->
|
|
<remarkModal ref="remarkRef" @success="(e) => (remark = e)" />
|
|
<!-- 修改取餐号 -->
|
|
<takeFoodCode />
|
|
<el-drawer v-model="membershow" :with-header="true" size="90%" title="选择会员">
|
|
<member :membershow="'1'"></member>
|
|
</el-drawer>
|
|
<takeFoodCode ref="takeFoodCodeRef" title="修改取餐号" placeholder="请输入取餐号" @success="takeFoodCodeSuccess" />
|
|
<!-- 结算订单 -->
|
|
<settleAccount ref="settleAccountRef" :cart="cartList" :amount="cartInfo.totalAmount" :remark="remark"
|
|
:masterId="masterId" :orderInfo="orderInfo" :member="memberInfo" @paySuccess="createCodeAjax(1)" />
|
|
<!-- 快捷收银 -->
|
|
<fastCashier ref="fastCashierRef" type="0" />
|
|
<!-- 挂起订单 -->
|
|
<pendingCartModal ref="pendingCartModalRef" @select="pendingCartHandle" />
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "home",
|
|
};
|
|
</script>
|
|
<script setup>
|
|
import { onMounted, ref } from "vue";
|
|
import { useRoute } from 'vue-router'
|
|
import { useUser } from "@/store/user.js";
|
|
import remarkModal from "@/components/remarkModal.vue";
|
|
import takeFoodCode from "@/components/takeFoodCode.vue";
|
|
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 useStorage from '@/utils/useStorage'
|
|
|
|
import {
|
|
createCart,
|
|
queryCart,
|
|
createCode,
|
|
packall,
|
|
delCart,
|
|
cartStatus,
|
|
clearCart,
|
|
createOrder,
|
|
} from "@/api/product";
|
|
|
|
// 商品列表
|
|
import goods from "@/views/home/components/goods.vue";
|
|
import member from "@/views/member/index.vue";
|
|
|
|
const route = useRoute()
|
|
|
|
const membershow = ref(false);
|
|
const store = useUser();
|
|
const remarkRef = ref(null);
|
|
const takeFoodCodeRef = ref(null);
|
|
const goodsRef = ref(null);
|
|
const pendingCartModalRef = ref(null);
|
|
const settleAccountRef = ref(null);
|
|
const fastCashierRef = ref(null);
|
|
|
|
const allSelected = ref(false);
|
|
|
|
const remark = ref("");
|
|
const cartListActive = ref(0);
|
|
const cartList = ref([]);
|
|
const cartInfo = ref({});
|
|
const cartLoading = ref(false);
|
|
|
|
const orderInfo = ref({});
|
|
const createOrderLoading = ref(false);
|
|
|
|
const memberInfo = ref({})
|
|
|
|
// 取餐码
|
|
const masterId = ref("");
|
|
|
|
// 挂单量
|
|
const pendingCartNum = ref(0);
|
|
|
|
// 生成订单
|
|
async function createOrderHandle() {
|
|
try {
|
|
createOrderLoading.value = true;
|
|
const res = await createOrder({
|
|
masterId: masterId.value,
|
|
shopId: store.userInfo.shopId,
|
|
remark: remark.value,
|
|
});
|
|
orderInfo.value = res;
|
|
settleAccountRef.value.show();
|
|
createOrderLoading.value = false;
|
|
} catch (error) {
|
|
console.log(error);
|
|
createOrderLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// 清空购物车
|
|
async function clearCartHandle() {
|
|
try {
|
|
await clearCart({
|
|
shopId: store.userInfo.shopId,
|
|
masterId: masterId.value,
|
|
});
|
|
queryCartAjax();
|
|
|
|
// 清除商品所有红点
|
|
goodsRef.value.clearDot()
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
|
|
// 恢复挂单
|
|
async function pendingCartHandle(item) {
|
|
const nItem = { ...item };
|
|
if (cartList.value.length) {
|
|
// 当购物车有数据时,先挂起当前购物车
|
|
await pendingCart({ masterId: masterId.value });
|
|
}
|
|
masterId.value = nItem.masterId;
|
|
await pendingCart(nItem, false);
|
|
await queryCartAjax();
|
|
}
|
|
|
|
// 挂单
|
|
async function pendingCart(params, status = true) {
|
|
try {
|
|
cartLoading.value = true;
|
|
await cartStatus({
|
|
shopId: store.userInfo.shopId,
|
|
masterId: params.masterId,
|
|
status: status,
|
|
uuid: params.uuid,
|
|
});
|
|
if (status && cartList.value.length) {
|
|
await createCodeAjax();
|
|
cartLoading.value = false;
|
|
} else {
|
|
cartLoading.value = false;
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
|
|
// 删除购物车
|
|
async function delCartHandle(params) {
|
|
try {
|
|
cartLoading.value = true;
|
|
await delCart({
|
|
masterId: params.masterId,
|
|
cartId: params.id,
|
|
});
|
|
await queryCartAjax();
|
|
cartLoading.value = false;
|
|
cartListActive.value = 0;
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
|
|
// 赠送打包操作
|
|
function giftPackHandle(key, item) {
|
|
item[key] = false;
|
|
addCart(item, "edit");
|
|
}
|
|
|
|
// 打包全选
|
|
const allSelectedHandle = async () => {
|
|
if (!cartList.value.length) return;
|
|
allSelected.value = !allSelected.value;
|
|
await packall({
|
|
shopId: store.userInfo.shopId,
|
|
status: allSelected.value,
|
|
masterId: masterId.value,
|
|
});
|
|
queryCartAjax();
|
|
};
|
|
|
|
// 确认取餐号
|
|
async function takeFoodCodeSuccess(code) {
|
|
if (cartList.value.length) {
|
|
await pendingCart({
|
|
masterId: masterId.value,
|
|
uuid: cartList.value[0].uuid,
|
|
});
|
|
}
|
|
masterId.value = `#${code}`;
|
|
queryCartAjax();
|
|
}
|
|
|
|
// 从购物车选择商品
|
|
function selectCartItemHandle(item, index) {
|
|
cartListActive.value = index;
|
|
}
|
|
|
|
// 选择完规格开始添加购物车
|
|
async function addCart(params, type = "add") {
|
|
try {
|
|
cartLoading.value = true;
|
|
const res = await createCart({
|
|
productId: params.productId,
|
|
masterId: masterId.value,
|
|
shopId: store.userInfo.shopId,
|
|
skuId: type == "add" ? params.id : params.skuId,
|
|
number: params.number || 1,
|
|
isPack: params.isPack || "false",
|
|
isGift: params.isGift || "false",
|
|
cartId: type == "add" ? "" : params.id,
|
|
uuid: params.uuid || store.userInfo.uuid,
|
|
type: type,
|
|
});
|
|
cartLoading.value = false;
|
|
masterId.value = res;
|
|
goodsRef.value.updateData();
|
|
queryCartAjax();
|
|
} catch (error) {
|
|
console.log(error);
|
|
cartLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// 获取购物车商品
|
|
async function queryCartAjax() {
|
|
try {
|
|
const res = await queryCart({
|
|
masterId: masterId.value,
|
|
shopId: store.userInfo.shopId,
|
|
});
|
|
cartList.value = res.list;
|
|
cartInfo.value = res.amount;
|
|
pendingCartNum.value = res.num;
|
|
goodsRef.value.updateData();
|
|
|
|
let i = 0;
|
|
res.list.map((item) => {
|
|
if (item.isPack == "true") {
|
|
i++;
|
|
}
|
|
});
|
|
if (i == res.list.length) {
|
|
allSelected.value = true;
|
|
} else {
|
|
allSelected.value = false;
|
|
}
|
|
} catch (error) {
|
|
console.log("获取购物车商品", error);
|
|
}
|
|
}
|
|
|
|
// 获取取餐码
|
|
async function createCodeAjax(type = "0") {
|
|
try {
|
|
// if (!process.env.VITE_DEV_SERVER_URL) {
|
|
// masterId.value = '#20'
|
|
// } else {
|
|
// const res = await createCode({
|
|
// shopId: store.userInfo.shopId
|
|
// })
|
|
// masterId.value = res.code
|
|
// }
|
|
const res = await createCode({
|
|
shopId: store.userInfo.shopId,
|
|
type: type,
|
|
});
|
|
masterId.value = res.code;
|
|
queryCartAjax();
|
|
getLocalMemberInfo()
|
|
|
|
if (type == 1) {
|
|
// 结算订单 清楚商品所有红点
|
|
goodsRef.value.clearDot()
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
|
|
// 从本地获取会员信息
|
|
function getLocalMemberInfo() {
|
|
let localMemberInfo = useStorage.get('memberInfo')
|
|
if (localMemberInfo && localMemberInfo.telephone) {
|
|
memberInfo.value = localMemberInfo
|
|
} else {
|
|
memberInfo.value = {}
|
|
}
|
|
}
|
|
|
|
// 清除本地会员
|
|
function clearMember() {
|
|
useStorage.del('memberInfo')
|
|
getLocalMemberInfo()
|
|
}
|
|
|
|
onMounted(() => {
|
|
createCodeAjax();
|
|
getLocalMemberInfo()
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.cart_wrap {
|
|
flex: 1.5;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.menu_top {
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
height: var(--el-component-size-large);
|
|
|
|
.menu {
|
|
background-color: var(--el-color-warning);
|
|
color: #fff;
|
|
width: 60px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.icon {
|
|
font-size: var(--el-font-size-base);
|
|
position: relative;
|
|
top: 2px;
|
|
}
|
|
|
|
.t {
|
|
color: #fff;
|
|
margin-left: 4px;
|
|
font-size: var(--el-font-size-base);
|
|
}
|
|
}
|
|
|
|
.number {
|
|
width: 50px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background-color: var(--el-color-info-light-7);
|
|
// padding-left: var(--el-font-size-base);
|
|
|
|
.t {
|
|
font-size: var(--el-font-size-base);
|
|
}
|
|
}
|
|
|
|
.select_user {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
background-color: var(--el-color-info-light-8);
|
|
padding: 0 var(--el-font-size-base);
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.icon {
|
|
color: var(--el-color-primary);
|
|
font-size: 20px;
|
|
}
|
|
|
|
.t {
|
|
font-size: var(--el-font-size-base);
|
|
margin-left: 4px;
|
|
}
|
|
}
|
|
|
|
.arrow {
|
|
color: #999;
|
|
font-size: 16px;
|
|
position: relative;
|
|
top: 2px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.shop_operation {
|
|
flex: 1;
|
|
display: flex;
|
|
|
|
.shop_list {
|
|
flex: 1;
|
|
height: calc(100vh - 40px - 60px - 80px);
|
|
overflow-y: auto;
|
|
border-right: 1px solid #ececec;
|
|
|
|
.item {
|
|
padding: var(--el-font-size-base);
|
|
|
|
&.active {
|
|
background-color: var(--primary-color-hover);
|
|
}
|
|
|
|
&:not(:last-child) {
|
|
border-bottom: 1px solid #ececec;
|
|
}
|
|
|
|
.name_wrap {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: var(--el-font-size-base);
|
|
}
|
|
|
|
.sku_list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
padding-top: 10px;
|
|
|
|
.tag {
|
|
padding: 2px 6px;
|
|
background-color: var(--el-color-danger);
|
|
color: #fff;
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
}
|
|
|
|
.num {
|
|
padding-top: var(--el-font-size-base);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.icon_item {
|
|
$size: 30px;
|
|
width: $size;
|
|
height: $size;
|
|
border-radius: 4px;
|
|
background-color: #e2e2e2;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 10px;
|
|
}
|
|
}
|
|
|
|
.t {
|
|
font-size: var(--el-font-size-base);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.footer {
|
|
padding: var(--el-font-size-base);
|
|
border-top: 1px solid #ececec;
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.selected {
|
|
width: 16px;
|
|
height: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
position: relative;
|
|
top: 1px;
|
|
|
|
.icon {
|
|
display: block;
|
|
font-size: var(--el-font-size-base);
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
.selected_round {
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 50%;
|
|
border: 1px solid #ddd;
|
|
}
|
|
}
|
|
|
|
.t {
|
|
margin-left: 6px;
|
|
}
|
|
}
|
|
|
|
.top {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.btm {
|
|
$h: 70px;
|
|
display: flex;
|
|
height: $h;
|
|
padding-top: var(--el-font-size-base);
|
|
gap: var(--el-font-size-base);
|
|
|
|
.editor {
|
|
width: $h;
|
|
border: 1px solid #ececec;
|
|
border-radius: 6px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #555;
|
|
font-size: var(--el-font-size-base);
|
|
}
|
|
|
|
.button {
|
|
flex: 1;
|
|
|
|
.js {
|
|
.t {
|
|
color: #fff;
|
|
font-size: var(--el-font-size-base);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.shop_manage {
|
|
flex: 3;
|
|
margin-left: var(--el-font-size-base);
|
|
height: 100%;
|
|
}
|
|
</style>
|