625 lines
15 KiB
Vue
625 lines
15 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="membershow = true">
|
||
<el-icon class="icon">
|
||
<UserFilled />
|
||
</el-icon>
|
||
<el-text class="t">选择会员</el-text>
|
||
<el-icon class="arrow">
|
||
<ArrowRight />
|
||
</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"
|
||
@paySuccess="createCodeAjax(1)"
|
||
/>
|
||
<!-- 挂起订单 -->
|
||
<pendingCartModal ref="pendingCartModalRef" @select="pendingCartHandle" />
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: "home",
|
||
};
|
||
</script>
|
||
<script setup>
|
||
import { onMounted, ref } from "vue";
|
||
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 pendingCartModal from "@/views/home/components/pendingCartModal.vue";
|
||
|
||
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 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 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 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();
|
||
} 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();
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
createCodeAjax();
|
||
});
|
||
</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: 100px;
|
||
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 {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: 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 {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: var(--el-color-info-light-8);
|
||
padding: 0 var(--el-font-size-base);
|
||
|
||
.icon {
|
||
color: var(--el-color-primary);
|
||
font-size: 24px;
|
||
}
|
||
|
||
.t {
|
||
font-size: var(--el-font-size-base);
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.arrow {
|
||
color: #999;
|
||
font-size: 20px;
|
||
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>
|