Commit a53f99b0 authored by xieyishang's avatar xieyishang

~~

parent c0fd900e
......@@ -35,7 +35,11 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"autoprefixer": "^10.0.0",
"postcss": "^8.0.0",
"rollup-plugin-postcss": "^4.0.2",
"sass": "1.77.2",
"tailwindcss": "^3.0.0",
"terser": "^5.31.0",
"vite": "^5.2.0"
}
......
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
\ No newline at end of file
@tailwind base;
@tailwind components;
@tailwind utilities;
\ No newline at end of file
......@@ -4,3 +4,6 @@
@import 'media.scss';
@import 'dark.scss';
@import 'diy.scss';
......@@ -8,6 +8,7 @@ import router from './router'
import store from './store'
import App from './App.vue'
import './assets/style/main.css'; // 假设 main.css 在 src/assets 目录下
import BarcodeScanner from '@/utils/barcode-scanner';
......
.sku_card {
.sku_card_title {
font-size: 15px;
line-height: 40px;
color: #222;
font-weight: bold;
}
.sku_card_main {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.sku_card_item {
font-size: 12px;
line-height: 24px;
background-color: #f1f2f2;
color: #373737;
margin-right: 10px;
margin-bottom: 10px;
padding: 0 10px;
flex-shrink: 0;
border-radius: 3px;
cursor: pointer;
}
.sku_card_item_active {
background-color: #409eff !important;
color: #fff !important;
}
}
}
.card {
margin: 18px auto 0;
background-color: #fff;
.top {
display: flex;
justify-content: flex-start;
align-items: center;
height: 50px;
font-size: 16px;
line-height: 1;
.shop_name {
margin-left: 5px;
font-size: 15px;
font-weight: normal;
font-stretch: normal;
color: #222222;
}
}
.select_box {
width: 40px;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
font-size: 16px;
.circle {
color: #666;
}
.checked {
color: #f64f15;
}
}
.main {
padding-bottom: 23px;
.card_wrap {
margin-top: 15px;
&:first-child {
margin-top: 0;
}
}
.card_item {
width: 100%;
box-sizing: border-box;
}
.card_item_wrap {
display: flex;
justify-content: flex-start;
align-items: center;
}
.img_wrap {
width: 70px;
height: 70px;
border-radius: 10px;
overflow: hidden;
flex-shrink: 0;
img {
display: block;
width: 70px;
height:70px;
}
}
.info {
margin-left: 20px;
padding-right: 20px;
width: calc(100% - 40px - 100px - 15px);
// height: 70px;
display: flex;
flex-direction: column;
justify-content: space-between;
.it {
.goods_title {
display: block;
width: 100%;
font-size: 12px;
font-weight: bold;
font-stretch: normal;
color: #222222;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.deleteicon{
margin: 6px 0;
display: flex;
justify-content: flex-end;
}
.delete{
cursor: pointer;
color: red;
}
.sku {
height: 26px;
border-radius: 5px;
margin-top: 11px;
font-size: 12px;
line-height: 26px;
font-stretch: normal;
color: #838383;
display: flex;
justify-content: flex-start;
align-items: center;
.text {
padding: 0 10px;
background-color: #f6f6f6;
}
.sku_arr {
display: block;
padding-left: 10px;
padding-right: 10px;
background-color: #f6f6f6;
}
}
}
.ib {
display: flex;
justify-content: space-between;
.pricebox{
display: flex;
align-items: center;
}
.jfprice{
margin-left: 8px;
.price_icon,.price_main{
font-size: 12px !important;
color: #a5a5a5 !important;
}
}
.price {
display: flex;
justify-content: flex-start;
align-items: baseline;
.price_icon {
font-size: 13px;
font-weight: bold;
font-stretch: normal;
color: #f64f15;
}
.price_main {
font-size: 16px;
font-weight: bold;
font-stretch: normal;
color: #f64f15;
.mini {
font-size: 15px;
}
}
.ori {
font-size: 12px;
font-stretch: normal;
color: #8a8a8a;
}
}
.num {
flex-shrink: 0;
--stepper-input-disabled-text-color: #323233;
}
}
}
}
}
.qrcodepup{
text-align: center;
}
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="min-h-screen bg-white">
<header @click="gtehomepage" class="h-20 px-8 flex items-center justify-between bg-primary">
<div class="flex items-center gap-3 baselogs">
<img src="@/assets/img/120x120.png" alt="超市logo" class="h-14 w-14 object-contain">
<h1 class="text-2xl font-bold text-white">鹿马生活超市 [收银管理系统]</h1>
</div>
<div class="flex items-center gap-4">
<span class="text-white">{{ currentTime }}</span>
<!-- <div class="flex items-center gap-2 text-white">
<i class="fas fa-user"></i>
<span>收银员:admin</span>
</div> -->
</div>
</header>
<div class="flex h-[calc(100vh-5rem)]">
<!-- 左侧商品区域 -->
<div class="w-2/3 p-6 flex flex-col">
<div class="flex items-center gap-4 mb-6">
<div class="relative max-w-md w-full flex">
<input v-model="keyword" type="text" placeholder="搜索商品"
class="w-full px-5 py-3 pl-12 border rounded-lg focus:outline-none focus:border-primary text-lg">
<!-- <i class="fas fa-search absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 text-xl"></i> -->
<button @click="tosearchfun" class="p-4 !rounded-button bg-gray-100 hover:bg-gray-200 whitespace-nowrap text-lg">搜索</button>
</div>
</div>
<!-- 分类标签 -->
<div class="flex flex-col gap-2 mb-6">
<!-- 一级分类 -->
<div class="flex gap-2 overflow-x-auto pb-2">
<button @click="selectCategory(0)" :class="[
'px-6 py-3 !rounded-button whitespace-nowrap text-lg',
currentCategory === 0 ? 'bg-primary text-white' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
]">
全部
</button>
<button v-for="category in categories" :key="category.id" @click="selectCategory(category.id)" :class="[
'px-6 py-3 !rounded-button whitespace-nowrap text-lg',
currentCategory === category.id ? 'bg-primary text-white' : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
]">
{{ category.title }}
</button>
</div>
<!-- 二级分类 -->
<div v-if="currentCategoryData.children && currentCategoryData.children.length"
class="flex gap-2 overflow-x-auto pb-2">
<button v-for="subCategory in currentCategoryData.children" :key="subCategory.id"
@click="selectSubCategory(subCategory.id)" :class="[
'px-5 py-2 !rounded-button whitespace-nowrap text-base',
currentSubCategory === subCategory.id ? 'bg-blue-100 text-primary' : 'bg-gray-50 text-gray-500 hover:bg-gray-100'
]">
{{ subCategory.title }}
</button>
</div>
</div>
<!-- 商品列表 -->
<div class="grid grid-cols-4 gap-6 overflow-y-auto flex-1" @scroll.passive="handleScroll" ref="productList">
<div v-for="product in products" :key="product.id" @click="addOrderList(product,0)"
class="bg-white rounded-lg shadow-sm border p-4 cursor-pointer hover:shadow-md transition-shadow">
<div class="aspect-square mb-3 overflow-hidden rounded-lg">
<img :src="product.cover" :alt="product.title"
class="w-full h-full object-cover hover:scale-105 transition-transform">
</div>
<h3 class="font-medium text-gray-800 mb-2 text-xl">{{ product.title }}</h3>
<div class="flex items-center justify-between">
<span class="text-red-600 font-medium text-2xl ">{{ product.price }}</span>
<span class="text-gray-500 text-lg">库存: {{ product.stock }}</span>
</div>
</div>
</div>
</div>
<!-- 右侧购物车 -->
<div class="w-1/3 border-l flex flex-col">
<div class="p-6 border-b">
<h2 class="text-2xl font-bold mb-2">购物车</h2>
<p class="text-gray-600 text-lg">{{ totalItems }} 件商品</p>
</div>
<!-- 购物车列表 -->
<div class="flex-1 overflow-y-auto p-6">
<div v-if="listdata.length === 0" class="text-center text-gray-500 mt-10">
购物车是空的
</div>
<template v-else>
<div>
<div v-for="(item, index) in listdata" :key="index">
<div v-for="(cc, inner) in item.content" :key="inner" class="flex items-center gap-4 mb-4 pb-4 border-b last:border-b-0">
<img :src="cc.goods.cover" :alt="item.name" class="w-20 h-20 rounded object-cover">
<div class="flex-1">
<h3 class="font-medium mb-1 text-lg">{{ cc.goods.title }}</h3>
<div class="text-red-600 text-lg ">{{ cc.formatBig }}{{ cc.formatMini }}</div>
</div>
<div class="flex items-center gap-2">
<button @click.stop="stepMinusHandle('minus',cc)"
class="w-10 h-10 !rounded-button flex items-center justify-center bg-gray-100 hover:bg-gray-200">
-
<!-- <i class="fas fa-minus"></i> -->
</button>
<span class="w-10 text-center text-lg">{{ cc.num }}</span>
<button @click.stop="stepMinusHandle('add',cc)"
class="w-10 h-10 !rounded-button flex items-center justify-center bg-gray-100 hover:bg-gray-200">
<!-- <i class="fas fa-plus"></i> -->
+
</button>
</div>
</div>
</div>
</div>
</template>
</div>
<!-- 结算区域 -->
<div class="p-6 border-t bg-gray-50">
<div class="flex justify-between mb-6">
<span class="text-gray-600 text-lg">总计</span>
<span class="text-2xl font-bold text-red-600">¥{{ totalMoney }}</span>
</div>
<div class="grid grid-cols-2 gap-6 mb-6">
<button @click="delAllGoods" class="p-4 !rounded-button bg-gray-100 hover:bg-gray-200 whitespace-nowrap text-lg">清空</button>
<button @click="delAllGoods" class="p-4 !rounded-button bg-gray-100 hover:bg-gray-200 whitespace-nowrap text-lg">清空</button>
</div>
<button @click="checkoutfun()"
class="w-full p-5 !rounded-button bg-primary text-white hover:bg-primary/90 whitespace-nowrap text-xl">
结算
</button>
</div>
</div>
</div>
<!-- Message -->
<div v-if="message.show" :class="[
'message',
message.type === 'success' ? 'success' : 'warning'
]">
{{ message.text }}
</div>
<!-- 弹窗选择规格 -->
<el-dialog
v-model="dialogVisible"
title="选择规格"
width="500"
:before-close="handleClose"
>
<div>
<div class="sku_card" v-for="(item, outer) in childgoods.spec_list" :key="outer">
<div class="sku_card_title">{{ item.name }}</div>
<div class="sku_card_main">
<div :class="{
sku_card_item: true,
sku_card_item_active: item.value[inner] === item.selected,
}" v-for="(cc, inner) in item.value" :key="inner" @click="skuTapHandle(item, outer, cc)">
{{ cc }}
</div>
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="addCartHandle()">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="dialogVisibletwo"
title="支付订单"
width="500"
:before-close="handleClosetwo"
>
<div class="qrcodepup">
<!-- v-model="qrcodeurl" :value="qrcodeurl" -->
<qrcode ref="qrcodecomp" :value="qrcodeurl" v-model="qrcodeurl" ></qrcode>
<div class="qrcodepup_foot">
<svg data-v-5c5419a9="" width="137" height="21" viewBox="0 0 137 21" fill="none" xmlns="http://www.w3.org/2000/svg"><path data-v-5c5419a9="" d="M17.9988 0H2.5712C1.15701 0 0 1.15701 0 2.5712V17.9988C0 19.413 1.15701 20.57 2.5712 20.57H17.9988C19.413 20.57 20.57 19.413 20.57 17.9988V2.5712C20.57 1.15701 19.413 0 17.9988 0ZM10.2851 15.8133C9.38512 15.8133 8.61368 15.6847 7.84232 15.4275C7.32807 15.6847 6.5567 16.3274 6.29954 16.456C5.78526 16.7132 5.91387 16.1989 5.91387 16.1989L6.17103 14.6562C4.62823 13.6276 3.72829 11.9563 3.72829 10.1565C3.72829 6.9424 6.68518 4.37109 10.285 4.37109C12.4706 4.37109 14.5275 5.39962 15.6847 6.81381L9.25654 9.77079C9.25654 9.77079 8.74226 10.0279 8.22801 9.64221L7.19948 8.87084C7.19948 8.87084 6.42812 8.22801 6.81379 9.25654L7.84232 11.5707C7.84232 11.5707 7.9709 12.2134 8.74226 11.8278C9.38512 11.5707 14.1419 8.6137 16.1989 7.45667C16.5846 8.22804 16.8417 9.12796 16.8417 10.0279C16.8417 13.1134 13.8848 15.8133 10.2851 15.8133Z" fill="#09BB07"></path><path data-v-5c5419a9="" d="M34.648 2.88H36.104V3.808H39.944V5.04H36.104V5.824H39.384V7.024H36.104V7.824H40.344V9.088H30.456V7.824H34.648V7.024H31.576V5.824H34.648V5.04H30.904V3.808H34.648V2.88ZM33.032 13.12V14.016H37.784V13.12H33.032ZM37.784 11.968V11.056H33.032V11.968H37.784ZM33.032 15.168V17.648H31.592V9.824H39.24V16.064C39.24 17.056 38.7333 17.552 37.72 17.552H36.392L36.04 16.208L37.288 16.288C37.6187 16.288 37.784 16.112 37.784 15.76V15.168H33.032ZM27.784 3.008C28.84 3.81867 29.7093 4.60267 30.392 5.36L29.352 6.416C28.7013 5.648 27.8213 4.85867 26.712 4.048L27.784 3.008ZM25.608 7.648H29.24V14.336C29.5067 14.08 29.9333 13.648 30.52 13.04L30.92 14.64C30.0027 15.5893 29.016 16.4373 27.96 17.184L27.384 15.808C27.6507 15.5733 27.784 15.2907 27.784 14.96V9.104H25.608V7.648ZM46.472 4.384H50.488V2.88H52.008V4.384H56.312V5.84H52.008V7.104H55.704V11.856H51.944C51.816 13.1893 51.5707 14.224 51.208 14.96C52.7333 15.7387 54.4773 16.176 56.44 16.272L56.072 17.728C53.896 17.5787 51.9867 17.0453 50.344 16.128C49.4907 16.9387 48.1467 17.472 46.312 17.728L45.656 16.352C47.16 16.224 48.2747 15.8613 49 15.264C48.1467 14.624 47.3573 13.8613 46.632 12.976L47.8 12.176C48.4187 12.944 49.1067 13.5947 49.864 14.128C50.1307 13.488 50.312 12.7307 50.408 11.856H46.92V7.104H50.488V5.84H46.472V4.384ZM54.28 10.496V8.448H52.008V10.496H54.28ZM50.488 10.496V8.448H48.344V10.496H50.488ZM43.336 9.264C42.9093 9.808 42.4507 10.3467 41.96 10.88L41.464 9.248C43.032 7.392 44.184 5.22667 44.92 2.752L46.36 3.424C45.9867 4.61867 45.4907 5.78133 44.872 6.912V17.68H43.336V9.264ZM60.616 8.688V11.136H64.296V8.688H60.616ZM60.536 12.544C60.344 14.56 59.752 16.224 58.76 17.536L57.592 16.496C58.552 15.12 59.048 13.376 59.08 11.264V3.424H71.352V15.472C71.352 16.6773 70.7387 17.28 69.512 17.28H67.672L67.272 15.792C67.9653 15.8453 68.5467 15.872 69.016 15.872C69.5387 15.872 69.8 15.5573 69.8 14.928V12.544H65.832V17.104H64.296V12.544H60.536ZM69.8 11.136V8.688H65.832V11.136H69.8ZM69.8 7.296V4.896H65.832V7.296H69.8ZM64.296 4.896H60.616V7.296H64.296V4.896ZM85.144 6.704L84.872 7.808C85.096 9.184 85.3947 10.448 85.768 11.6C86.1627 10.1493 86.3813 8.51733 86.424 6.704H85.144ZM85.176 13.28C84.792 12.224 84.472 11.056 84.216 9.776C83.9707 10.384 83.7147 10.9227 83.448 11.392L82.616 10.336L82.696 10.16H77.72V8.816H82.808V9.904C83.5973 8.08 84.136 5.728 84.424 2.848L85.752 3.072C85.6347 4.032 85.528 4.768 85.432 5.28H88.264V6.704H87.704C87.64 9.33867 87.2453 11.6 86.52 13.488C87.0747 14.6613 87.736 15.584 88.504 16.256L87.64 17.552C86.968 16.88 86.376 16.0053 85.864 14.928C85.2987 15.9733 84.5947 16.8747 83.752 17.632L82.952 16.352C83.8693 15.5733 84.6107 14.5493 85.176 13.28ZM80.616 15.488C80.808 15.3813 80.9253 15.216 80.968 14.992V12.48H79.592V13.2C79.56 15.152 79.064 16.608 78.104 17.568L76.984 16.592C77.7627 15.8133 78.1627 14.6827 78.184 13.2V11.104H82.296V14.432C82.808 13.9627 83.2027 13.584 83.48 13.296L83.784 14.56C82.9627 15.4453 82.1147 16.1707 81.24 16.736L80.616 15.488ZM79.736 2.88H81V6.416H81.784V3.744H83.016V7.696H77.688V3.744H78.936V6.416H79.736V2.88ZM77.32 3.504C76.648 5.22133 75.528 6.768 73.96 8.144L73.496 6.672C74.648 5.57333 75.4907 4.31467 76.024 2.896L77.32 3.504ZM77.384 7.792C77.192 8.32533 76.9413 8.86933 76.632 9.424V17.68H75.208V11.424C74.8667 11.808 74.4667 12.2133 74.008 12.64L73.56 11.184C74.712 10.032 75.56 8.69867 76.104 7.184L77.384 7.792ZM91.288 9.216C90.808 9.84533 90.3653 10.3893 89.96 10.848L89.464 9.216C90.936 7.36 92.0347 5.19467 92.76 2.72L94.184 3.392C93.8 4.61867 93.3307 5.76533 92.776 6.832V17.68H91.288V9.216ZM93.896 4.816H98.584C98.3813 4.272 98.1413 3.744 97.864 3.232L99.32 2.832C99.6613 3.55733 99.9173 4.21867 100.088 4.816H104.408V6.24H93.896V4.816ZM95.352 7.216H103.048V8.576H95.352V7.216ZM95.352 9.472H103.048V10.848H95.352V9.472ZM103.384 11.856V17.648H101.912V16.816H96.472V17.648H95V11.856H103.384ZM96.472 15.392H101.912V13.264H96.472V15.392ZM112.2 2.88H113.768V4.848H119.896V6.32H113.768V8.416H118.024V9.76C117.181 11.4773 115.955 12.9547 114.344 14.192C115.133 14.608 115.917 14.9653 116.696 15.264C117.944 15.712 119.155 16.0693 120.328 16.336L119.448 17.68C118.072 17.3173 116.755 16.8693 115.496 16.336C114.621 15.952 113.805 15.536 113.048 15.088C111.288 16.176 109.149 17.0613 106.632 17.744L105.752 16.384C108.077 15.8613 110.072 15.1307 111.736 14.192C110.936 13.5627 110.237 12.864 109.64 12.096C109.085 11.392 108.685 10.64 108.44 9.84H107.32V8.416H112.2V6.32H106.104V4.848H112.2V2.88ZM113.016 13.392C114.445 12.368 115.539 11.184 116.296 9.84H109.944C110.232 10.5867 110.648 11.248 111.192 11.824C111.747 12.4107 112.355 12.9333 113.016 13.392ZM126.52 3.408C126.179 4.464 125.725 5.51467 125.16 6.56V17.68H123.64V8.912C123.128 9.584 122.568 10.24 121.96 10.88L121.48 9.296C123.123 7.408 124.328 5.22133 125.096 2.736L126.52 3.408ZM126.696 6.224H132.552V2.944H134.072V6.224H136.28V7.696H134.072V15.824C134.072 16.9867 133.512 17.568 132.392 17.568H130.008L129.672 16.08C130.429 16.144 131.16 16.176 131.864 16.176C132.323 16.176 132.552 15.9307 132.552 15.44V7.696H126.696V6.224ZM128.344 9.2C129.539 10.608 130.451 11.8293 131.08 12.864L129.784 13.76C129.112 12.6187 128.216 11.3547 127.096 9.968L128.344 9.2Z" fill="#232323"></path></svg>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<!-- <el-button @click="dialogVisibletwo = false">取消</el-button> -->
<el-button type="primary" @click="cleardialog">
关闭
</el-button>
</div>
</template>
</el-dialog>
<save v-if="dialog.save" ref="saveBox" @success="upsearch" @closed="dialog.save=false" />
<!-- 修改产品 -->
<jfsave v-if="dialog.save1" ref="saveBox1" @success="upsearch1" @closed="dialog.save1=false" />
<!-- 修改积分 -->
</div>
</template>
<script>
import { ElLoading, ElMessage } from "element-plus";
import { ElMessageBox } from 'element-plus'
import qrcode from "@/components/qrcode/qrcode.vue";//二维码
import save from '../goods/lists/save.vue'; //编辑产品
import jfsave from "../member/score/save.vue"; //扣积分
export default {
components: {
qrcode,
save,
jfsave,
},
data() {
return {
logo: 'https://ai-public.mastergo.com/ai/img_res/18f0763466be01b5ffd3e0df086be63d.jpg',
currentTime: '',
keyword: '',
currentCategory: "",//选中的分类id
currentSubCategory: null,
cart: [],
message: { show: false, text: '', type: 'success' },
categories: [
],
products: [
],
//cope code
childgoods:{spec_list:[]},
dialogVisible:false,
scrollbarheight:0,
dialogVisibletwo:false,
dialog: {search: false, import: false, print: false},
selection: [],
search: {},
totalMoney: 0,
totalCount: 0,
loading:null,
scannedCode: '', // 存储扫码后的结果 结果
port:null,
// 原始数据 购物车
odata: [],
listdata: [],
mirror: [],
total: 0,
totaljifen:0,//总共所需积分
Userprice:0,//不使用积分的价格
qrcodeurl:"",
listeningtype:1,//1 扫产品 2扫会员码 状态
page:0,
// 已有代码...
isLoading: false,
hasMore: true
};
},
computed: {
//计算二级分类列表内容
currentCategoryData() {
// return this.categories.find(c => c.id === this.currentCategory);
let list = [];
for (let i = 0; i < this.categories.length; i++) {
let itemss = this.categories[i];
if (itemss.id == this.currentCategory) {
// list.push(itemss);
list = itemss;
}
}
return list;
},
totalItems() {
return this.cart.reduce((sum, item) => sum + item.quantity, 0);
},
totalAmount() {
return this.cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
},
methods: {
gtehomepage(){
console.log('gtehomepage')
this.$router.push({
path: '/cashierhome/cashierhome'
})
},
//瀑布流
handleScroll(e) {
const listEl = this.$refs.productList
// 计算是否滚动到底部(距离底部50px时触发)
if (listEl.scrollHeight - listEl.scrollTop - listEl.clientHeight < 50) {
this.loadMore()
}
},
//瀑布流
async loadMore() {
if (this.isLoading || !this.hasMore) return
this.isLoading = true
try {
await this.getProducts()
} finally {
this.isLoading = false
}
},
//获取产品列表
getProducts() {
this.page++;
let params = { page: this.page, limit: 30 };
//一级分类id
if(this.currentCategory){
params.category_id = this.currentCategory
}
//二级分类id
if(this.currentSubCategory){
params.category_id = this.currentSubCategory
}
//关键词搜索
if(this.keyword){
params.keyword = this.keyword
}
this.$API.goods.lists.list.get(params).then(res=>{
if (res.code == 1) {
// this.products = res.data.data;
this.products = [...this.products, ...res.data.data];
this.hasMore = res.data.data.length >= params.limit;
}else{
}
}).catch((err) => {
console.log("🚀 ~ getProducts ~ err:", err);
});
},
//获取分类列表
getCatetList(){
this.$API.goods.category.list.get({
is_tree: 1
}).then(res=>{
console.log("🚀 ~ getCatetList ~ res:", res);
if (res.code == 1) {
this.categories = res.data;
}else{
}
}).catch((err) => {
console.log("🚀 ~ getCatetList ~ err:", err);
});
},
updateTime() {
// this.currentTime = new Date().toLocaleTimeString('zh-CN');
let now = new Date();
let options = { year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false };
// console.log();
this.currentTime = now.toLocaleString('zh-CN', options)
},
//搜索事件
tosearchfun(){
this.page = 0;
this.products = [];
this.getProducts();
},
//一级分类点击
selectCategory(categoryId) {
this.currentCategory = categoryId;
this.currentSubCategory = null;
this.page = 0;
this.products = [];
this.getProducts();
},
//二级分类点击
selectSubCategory(subCategoryId) {
this.currentSubCategory = subCategoryId;
this.page = 0;
this.products = [];
this.getProducts();
},
showMessage(text, type) {
this.message = { show: true, text, type };
setTimeout(() => {
this.message.show = false;
}, 2000);
},
//---cope------------------------------------------------------------------
add(){
this.dialog.save = true
this.$nextTick(() => {
this.$refs.saveBox.open().setData({})
})
},
table_edit(row){
this.dialog.save = true
this.$nextTick(() => {
this.$refs.saveBox.open('edit').setData(row)
})
},
//---规格加入购物车-------------------------------------------------------------------------
//规格提交
addCartHandle() {
this.dialogVisible = false;
let skuId = this.childgoods.skuId;
let number = this.childgoods.popNumber;
// this.$emit("popAddCart", skuId, number);
this.addCart("multiple", skuId, number);
},
//提交加入购物车
addCart(type, skuId, number) {
let that = this;
let req = {};
if (type === "single") {//没有规格
req = {
goods_sn:that.childgoods.goods_sn,//商品编号
goods_id: that.childgoods.id,
goods_sku_id: 0,
num: 1,
store_id: that.childgoods.store_id,
};
} else {//有规格
req = {
goods_sn:that.childgoods.popSkuGoods_sn,//商品编号
goods_id: that.childgoods.id,
goods_sku_id: skuId,
num: number,
store_id: that.childgoods.store_id,
};
}
console.info('req',req);
this.$API.cashier.cart.add.post(req).then(res=>{
if (res.code == 1) {
this.$message({
message: "添加成功~",
type: "success"
});
this.getCartList();//获取购物清单
this.scannedCode = "";
this.childgoods={spec_list:[]};
}else{
this.scannedCode = "";
this.childgoods={spec_list:[]};
this.$message.error(res.message);
}
}).catch((err) => {
this.scannedCode = "";
this.childgoods={spec_list:[]};
console.log("🚀 ~ cart ~ err:", err);
});
},
//购物车产品数量加减
stepMinusHandle(type,cc) {
let num = cc.num
if(type=="add"){
num = num+1;
}else{
if(num>1){
num = num-1;
}else{
num = 0;
//不能再减了
// this.$message.error('不能再减了');
// return;
}
}
console.info('stepMinusHandle',num,cc);
let that = this;
let goods_id = cc.goods_id;
let goods_sku_id = cc.goods_sku_id;
let cart_id = cc.cart_id;
let obj = that.odata.find((v) => v.id == cart_id);
console.log("🚀 ~ stepMinusHandle ~ obj:", obj);
// let num = obj.num - 1;
if (num != 0) {
let req = {
id: cart_id,
goods_id: goods_id,
goods_sku_id: goods_sku_id,
num: num,
};
this.$API.cashier.cart.edit.post(req)
.then((res) => {
console.log("🚀 ~ editCart ~ res:", res);
if (res.code == 1) {
that.getCartList();
}else{
this.$message.error(res.message);
}
})
.catch((err) => {
console.log("🚀 ~ editCart ~ err:", err);
});
} else {
//删除
let req = {
id: cart_id,
};
this.$API.cashier.cart.delete.post(req)
.then((res) => {
console.log("🚀 ~ delCart ~ res:", res);
if (res.code == 1) {
that.getCartList();
}else{
this.$message.error(res.message);
}
})
.catch((err) => {
console.log("🚀 ~ delCart ~ err:", err);
});
}
},
//数量加减
numberChangeHandle(e) {
console.log(e.detail);
console.log(this.childgoods.popStock.match(/\d+/)[0]);
if (Number(e.detail) > Number(this.childgoods.popStock.match(/\d+/)[0])) {
this.$message.error("库存不足~");
} else {
this.childgoods.popNumber = e.detail;
}
},
//规格被选择
skuTapHandle(item, outer, cc) {
this.childgoods.spec_list[outer]["selected"] = cc;
this.changeSku();
},
//修改规格
changeSku() {
let arr = this.childgoods.spec_list;
if (arr.every((item) => item.selected)) {
console.log("所有规格已选择");
// 取出item的name和selected,组成{name:selected}格式
let sku = arr.reduce((acc, cur) => {
acc[cur.name] = cur.selected;
return acc;
}, {});
let skuObj = this.childgoods.sku.find(
(item) => JSON.stringify(item.sku_value) === JSON.stringify(sku)
);
console.log("🚀 ~ changeSku ~ skuObj:", skuObj);
let parts = skuObj.price.split(".");
this.childgoods.popFormatBig = parts[0];
this.childgoods.popFormatMini = parts[1] ? "." + parts[1] : ".00";
this.childgoods.popStock = "库存 " + skuObj.stock;
this.childgoods.popNumber = 1;
this.childgoods.popSkuGoods_sn = skuObj.goods_sn;
this.childgoods["skuId"] = skuObj.id;
} else {
console.log("还有规格未选择");
}
},
//删除产品
goodsDeleteHandle(gid, sid) {
let that = this;
let cid = that.odata
.filter((v) => v.goods_id == gid && v.goods_sku_id == sid)
.map((v) => v.id);
let req = {
ids: cid,
};
this.$API.cashier.cart.delete.post(req)
.then((res) => {
console.log("🚀 ~ delCart ~ res:", res);
if (res.code == 1) {
that.getCartList();
}else{
this.$message.error(res.message);
}
})
.catch((err) => {
console.log("🚀 ~ delCart ~ err:", err);
});
},
//获取购物车列表
getCartList(){
let that = this;
this.$API.cashier.cart.list.get({page:1,limit:100}).then((res) => {
console.log("🚀 ~ getCartList ~ res:", res);
if (res.code == 1) {
let data = res.data;
that.odata = data;
const groupedData = data.reduce((acc, item) => {
const storeId = item.store_id;
if (!acc[storeId]) {
acc[storeId] = {
id: storeId,
title: item.store.title,
cover: item.store.cover,
content: [],
selected: 0,
};
}
acc[storeId].content.push({
cart_id: item.id,
member_id: item.member_id,
goods_id: item.goods_id,
goods_sku_id: item.goods_sku_id,
num: item.num,
created_at: item.created_at,
updated_at: item.updated_at,
goods: item.goods,
sku: item.sku,
});
return acc;
}, {});
const result = Object.values(groupedData);
result.forEach((store) => {
store.content.forEach((item) => {
if (item.sku && item.sku.price) {
const priceParts = item.sku.price.split(".");
const formatBig = priceParts[0];
const formatMini =
priceParts.length > 1 ? `.${priceParts[1]}` : ".00";
item.formatBig = formatBig;
item.formatMini = formatMini;
item.readyPrice = item.sku.price;
item.selected = 0;
item.ready_integral = item.sku.integral;//积分
} else {
const priceParts = item.goods.price.split(".");
const formatBig = priceParts[0];
const formatMini =
priceParts.length > 1 ? `.${priceParts[1]}` : ".00";
item.formatBig = formatBig;
item.formatMini = formatMini;
item.readyPrice = item.goods.price;
item.selected = 0;
item.ready_integral = item.goods.integral;////积分
}
});
const mergedData = Object.values(
that.mergeObjects(store.content)
);
console.log("🚀 ~ result.forEach ~ mergedData:", mergedData);
store.content = mergedData;
});
console.log("🚀 ~ result.forEach ~ result:", result);
that.listdata = result;
}else{
this.$message.error(res.message);
}
})
.catch((err) => {
console.log("🚀 ~ getCartList ~ err:", err);
});
},
// 合并购物车相同规格的商品
mergeObjects(arr) {
return arr.reduce((acc, curr) => {
const key = curr.sku ?
`${curr.goods.id}-${curr.sku.id}` :
`${curr.goods.id}`;
if (acc[key]) {
acc[key].num += curr.num;
} else {
acc[key] = {
...curr,
goods: {
...curr.goods
},
sku: curr.sku ? {
...curr.sku
} : null,
};
delete acc[key].id;
}
return acc;
}, {});
},
//关闭 支付订单 弹窗
cleardialog(){
this.dialogVisibletwo = false;
this.getCartList();
},
//关闭 支付订单 弹窗
handleClosetwo(done) {
ElMessageBox.confirm('确定要关闭弹窗吗?')
.then(() => {
done()
this.getCartList();
})
.catch(() => {
// catch error
})
},
//---规格加入购物车-------------------------------------------------------------------------
//关闭 选择规格 弹窗
handleClose(done) {
ElMessageBox.confirm('确定要关闭弹窗吗?')
.then(() => {
done()
})
.catch(() => {
// catch error
})
},
//监听扫码枪识别 和 会员扣积分
focusfun(types){
// 自动聚焦到输入框,方便直接扫描
if(types==2 && this.totaljifen==0){
this.$message.error("店员,没有可抵积分的东西,怎么扣积分呀~");
return false;
}
this.listeningtype = types;
// this.loading = ElLoading.service({
// lock: true,
// text: "请开始扫码识别",
// background: "rgba(255, 255, 255, 0.7)",
// });
},
// 扫码识别
handleScan(event){
console.info('handleScan',event);
console.log('扫描结果:', event.detail);
// this.$emit('scan', event.detail);
this.scannedCode = event.detail;
if(this.listeningtype==1){
//扫产品
if(this.scannedCode && this.scannedCode.length>5){
this.childgoods.goods_sn = this.scannedCode;
this.childgoods.store_id = 0;
this.addCart("single", "", 1);
}
}else if(this.listeningtype==2){
//扫会员码
console.info("this.scannedCode 扫会员码",this.scannedCode);
var idPattern = /^\d+$/;
if(this.scannedCode && idPattern.test(this.scannedCode) && this.scannedCode.length<8){
this.addjf(this.scannedCode);
}
}
},
//会员扣积分 事件
addjf(user_id){
console.info("addjf");
this.dialog.save1 = true
this.$nextTick(() => {
this.$refs.saveBox1.open().setData({
amount:this.totaljifen,//积分额度
member_id:user_id,//用户
type:'pay',//积分类型
remark:"到店消费",//积分描述
})
})
},
// 添加和计算商品价格 添加数量
addOrderList(goods,index) {
// 商品是否已经存在于订单列表中
if(goods.sku.length){
//规格
this.dialogVisible = true;
this.childgoods = goods;
return false;
}else{
//非规格
this.childgoods = goods;
this.addCart("single", 0, 1);
return false;
}
},
// 全部删除商品 清空购物车
delAllGoods() {
// this.odata = [];
this.listdata = [];
this.totalMoney = 0;
this.totalCount = 0;
this.totaljifen = 0;
this.childgoods = {spec_list:[]};
let req = {
ids: this.odata.map(product => product.id),
};
this.$API.cashier.cart.delete.post(req)
.then((res) => {
console.log("🚀 ~ delCart ~ res:", res);
if (res.code == 1) {
that.getCartList();
}else{
this.$message.error(res.message);
}
})
.catch((err) => {
console.log("🚀 ~ delCart ~ err:", err);
});
},
// 模拟结账 用户结算
checkoutfun() {
console.info("模拟结账 用户结算");
// this.$message.error("程序猿小哥正在开发中~");
if(this.odata.length){
this.$API.cashier.cart.simple.post({
carts:this.odata.map(item=>{return item.id}),
})
.then((res) => {
console.log("🚀 ~ simple ~ res:", res);
if(res.code==1){
this.$API.cashier.cart.nativepc.post({order_id:res.data.id}).then(restwo=>{
console.log("🚀 ~ simple ~ restwo:", restwo);
if(restwo.code==1){
let packagestr = restwo.data.package;
let match = packagestr.match(/prepay_id=([^&]+)/);
if (match) {
let qrcodeurl = match[1];
console.log(qrcodeurl); // 输出: weixin://wxpay/bizpayurl?pr=g5bMCytz3
this.qrcodeurl = qrcodeurl;
this.dialogVisibletwo = true;
this.$nextTick(()=>{
setTimeout(()=>{
this.$refs.qrcodecomp.updateQRCode(this.qrcodeurl);
},100)
})
}
}else{
this.$message.error(restwo.message);
}
})
}else{
this.$message.error(res.message);
}
})
.catch((err) => {
console.log("🚀 ~ simple ~ err:", err);
});
}else{
this.$message.error("店员,没有东西,怎么结账呀~");
}
},
upsearch(){
this.$refs.table.reload(this.search);
},
upsearch1(){
},
moreUpsearch(search){
this.search = search;
this.upsearch();
},
moreSearch(){
this.dialog.search = true
this.$nextTick(() => {
this.$refs.searchBox.open().setData(this.search)
})
},
//表格选择后回调事件
selectionChange(selection){
this.selection = selection;
},
//---------------------------------------------------------------------
},
mounted() {
this.updateTime();
setInterval(this.updateTime, 1000);
var orderHeight = document.body.clientHeight;
// document.getElementById("order_list").style.height = (orderHeight - 100) + "px";
this.scrollbarheight = orderHeight - 330;
//扫码枪监听事件
this.$barcodeScanner.init({
endChar: 'Enter',
minLength: 4
});
document.addEventListener('barcodeScanned', this.handleScan);
},
beforeUnmount() {
this.$barcodeScanner.destroy();
document.removeEventListener('barcodeScanned', this.handleScan);
// 如果使用被动监听则不需要手动移除
const listEl = this.$refs.productList
listEl?.removeEventListener('scroll', this.handleScroll)
},
created: function() {
this.getCartList();//获取购物清单
//获取产品列表
this.getProducts();
//获取分类列表
this.getCatetList();
},
watch:{
//计算价格
listdata:{
handler(newValue) {
let total = 0;
let totalCount = 0;
let totaljifen = 0;
newValue.forEach((item) => {
item.content.forEach((cc) => {
total += parseFloat(cc.readyPrice) * Number(cc.num);
totalCount = totalCount + cc.num;
totaljifen += parseFloat(cc.ready_integral) * Number(cc.num)
});
});
total = total.toFixed(2);
totaljifen = totaljifen.toFixed(2);
const priceParts = total.split(".");
const formatBig = priceParts[0];
const formatMini = priceParts.length > 1 ? `.${priceParts[1]}` : ".00";
this.totalMoney = total;
this.totalCount = totalCount;
this.totaljifen = totaljifen;//积分
this.Userprice = parseFloat(parseFloat(total) - parseFloat(this.totaljifen)).toFixed(2);
},
deep: true,
}
},
};
</script>
<style scoped>
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.message {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
padding: 10px 20px;
border-radius: 4px;
z-index: 9999;
color: white;
}
.message.success {
background-color: #67C23A;
}
.message.warning {
background-color: #E6A23C;
}
@import url('./cashier.scss');
</style>
\ No newline at end of file
......@@ -315,4 +315,7 @@ text-align: center;
.qrcodepup{
text-align: center;
}
\ No newline at end of file
}
......@@ -53,12 +53,7 @@
</div>
</div>
<div class="price jfprice">
<div class="price_icon">积分可抵扣:</div>
<div class="price_main din">
{{ cc.goods.integral }}
</div>
</div>
</div>
......@@ -74,12 +69,7 @@
<!-- 会员 -->
<div class="pricebox">
<div class="price">
<div class="price_icon">使用积分 ¥</div>
<div class="price_main din">
{{ parseFloat(parseFloat(cc.goods.price) - parseFloat(cc.goods.integral)).toFixed(2) }}
</div>
</div>
</div>
</div>
......@@ -94,23 +84,19 @@
<div class="total">
<small>数量:</small>{{ totalCount }}
<!-- <small>金额:</small>{{ totalMoney }} -->
<small>积分可抵扣:</small>{{ totaljifen }}
</div>
<div class="total">
<small>使用积分需付:</small>{{Userprice }}
</div>
<div class="total">
<small>不使用积分需付:</small>{{totalMoney }}
<small>需付:</small>{{totalMoney }}
</div>
<div class="pos_btn">
<el-button size="large" type="primary" @click="focusfun(1)" >监听扫码枪识别</el-button>
<!-- <el-button size="large" type="primary" @click="focusfun(1)" >监听扫码枪识别</el-button> -->
<el-button size="large" type="danger" @click="delAllGoods()">清空购物单</el-button>
<!-- <el-button size="large" type="success" @click="focusfun(2)">会员扣积分</el-button> -->
<el-button size="large" type="success" @click="checkOut()">用户结算</el-button>
......@@ -378,10 +364,16 @@ export default {
type: "success"
});
this.getCartList();//获取购物清单
this.scannedCode = "";
this.childgoods={spec_list:[]};
}else{
this.$message.error(res.message);
this.scannedCode = "";
this.childgoods={spec_list:[]};
}
}).catch((err) => {
this.scannedCode = "";
this.childgoods={spec_list:[]};
console.log("🚀 ~ cart ~ err:", err);
});
},
......
module.exports = {
content: [
'./src/**/*.{html,js,vue}', // 根据你的项目结构调整路径
],
theme: {
extend: {
colors: {
primary: '#3490dc', // 这里替换为你想要的颜色代码
pricecolar:"#f64f15",
},
},
},
plugins: [],
}
\ No newline at end of file
......@@ -2,6 +2,9 @@ import { defineConfig } from 'vite'
import path from 'path'
import vue from '@vitejs/plugin-vue'
import tailwindcss from 'tailwindcss'
import autoprefixer from 'autoprefixer'
export default defineConfig({
base:'./',
plugins: [vue()],
......@@ -35,6 +38,8 @@ export default defineConfig({
css: {
postcss: {
plugins: [
tailwindcss(),
autoprefixer(),
{
postcssPlugin: 'internal:charset-removal',
AtRule: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment