springboot vue 开源 会员收银系统 (6) 收银台的搭建
前言
完整版演示
前面我们对会员系统 分类和商品的开发 完成了收银所需的基础信息 下面我们开始完成收银台的开发
简单画了一个收银的流程图大家参考下
从这张图我们可以分析一下几点
- 可以选择会员或散客收银
- 选择会员使用相应的会员价结算
- 使用会员卡则在价格基础根据卡折扣结算
根据上述分析我搭建了一个简单的收银台
- 左边显示会员和已选择的商品信息
- 右边显示商品的价格信息
- 商品选择后可以修改数字
- 总金额自动计算
- 后续完成挂单功能便于保证收银连续性
开发中运用的组件
- Tabs 标签页 和 Card 完成右侧的商品选择
- el-autocomplete 完成会员的检索
- InputNumber Table 完成购物车开发
收银台运用过多组件会导致页面很乱 我们后续需要进行组件的封装
<template><div class="app-container" style="border-box:box-sizing;"><!-- left--><el-row :gutter="30" style=""><el-col :span="10"><el-autocompletestyle="width: 100%"popper-class="my-autocomplete"v-model="querySearchStr":fetch-suggestions="querySearch"placeholder="会员检索"@select="handleSelect"><iclass="el-icon-search el-input__icon"slot="suffix"></i><template slot-scope="{ item }"><div v-if="item.errorMsg">{{item.errorMsg}}</div><template v-else><div class="name"><i class="el-icon-user"></i>{{ item.memberName }}</div><span class="addr"><i class="el-icon-phone"></i>{{ item.memberPhone }}</span></template></template></el-autocomplete><el-descriptions border title="用户信息" v-if="member.memberId" style="margin-top: 20px;margin-bottom: 20px;"><el-descriptions-item label="用户名">{{member.memberName}}</el-descriptions-item><el-descriptions-item label="手机号">{{member.memberPhone}}</el-descriptions-item><el-descriptions-item label="备注">{{member.remark}}</el-descriptions-item></el-descriptions><el-descriptions border title="用户信息" v-else style="margin-top: 20px;margin-bottom: 20px;"><el-descriptions-item label="用户名">散客</el-descriptions-item></el-descriptions><div class="grid-content bg-purple"><el-tableborderheight="400"max-height="400":data="shopCart"style="width: 100%;margin-bottom: 20px;"><el-table-columnalign="center"prop="categoryName"label="分类"width="100"></el-table-column><el-table-columnalign="center"prop="productName"label="商品名"></el-table-column><el-table-columnalign="center"prop="productAmount"label="价格"width="100"><template slot-scope="scope"><span v-if="app.isEmpty(member.memberId)" class="price">{{ scope.row.productAmount }}</span><span v-else="member.memberId" class="price">{{ scope.row.productMemberAmount }}</span></template></el-table-column><el-table-columnalign="center"prop="count"label="数量"width="200"><template slot-scope="scope"><el-input-number size="mini" :min="0" :max="100" v-model="scope.row.count" @change="handleChange($event,scope)" ></el-input-number></template></el-table-column><el-table-columnalign="center"prop="totalPrice"label="总金额"width="100"><template slot-scope="scope"><span class="price">{{ scope.row.totalPrice }}</span></template></el-table-column></el-table><el-divider></el-divider>总金额: <span class="price">{{app.getFloatStr(getTotalPrice)}}</span><el-divider></el-divider><el-row><el-button type="success">结算</el-button><el-button type="warning">挂单</el-button><el-button type="primary">取单</el-button></el-row></div></el-col>
<!--right--><el-col :span="14"><div class="grid-content bg-purple"><el-tabs v-model="activeName" @tab-click="handleClick" type="border-card" style="height: calc(100vh - 180px);width: 100%;overflow: scroll;overflow:hidden;"><el-tab-panev-for="(item, index) in categoryList":key="item.categoryId":label="item.categoryName":name="item.categoryId"><div><el-row :gutter="20" style="" v-if="productList.length>0"><el-col @click.native="chooseProduct(item)" :span="6" v-for="item in productList" :key="item.productId" style="margin-top: 20px;cursor: pointer;"><el-card :body-style="{ padding: '0px' }" style="height: 230px;"><div style="height: 150px;display: flex;align-items: center;justify-content: center; box-sizing: border-box;padding-top: 10px;"><img style="width:85%;height: 140px;border-radius: 5px;border: 1px solid #eee;" :src="baseUrl + item.productImageUrl" class="image"/></div><div style="padding:10px 0 0 10px;font-size: 16px;">{{item.productName}}</div><div style="padding:5px 0 0 10px;"><span style="font-size: 14px;"> 散客价 <span class="price">¥ {{item.productAmount}}</span></span><br/><span style="font-size: 14px;"> 会员价 <span class="price">¥ {{item.productMemberAmount}}</span></span></div></el-card></el-col></el-row><div v-else><el-empty description="该分类商品为空"></el-empty></div></div></el-tab-pane></el-tabs></div></el-col></el-row></div>
</template><script>import {accAdd, accMul,isEmpty} from "@/utils";import confirm from "@/utils/confirm";import {getCategoryList} from "@/api/business/category/category";import {getProductList} from "@/api/business/product/product";import {getMemberList} from "@/api/business/member/member";export default {name: "cashierDesk",data(){return{shopCart: [],categoryList: [],productList: [],activeName: "",member: {},querySearchStr: '',}},mounted() {this.getCategoryList()},computed:{getTotalPrice(){let totalPrice = 0;for(let product of this.shopCart){const noMember = isEmpty(this.member.memberId)let productTotalPriceif(noMember){productTotalPrice = accMul(product.productAmount,product.count)}else{productTotalPrice = accMul(product.productMemberAmount,product.count)}this.$set(product, 'totalPrice', productTotalPrice)totalPrice = accAdd(totalPrice,productTotalPrice);}return totalPrice;}},watch:{shopCart(newVal,oldVal){let showCardList = newValconsole.log('这是监听属性新的')}},methods:{querySearch(queryString, cb) {if(queryString){getMemberList({querySearch:queryString}).then(res=>{// 调用 callback 返回建议列表的数据cb(res.data);})}else{cb([{errorMsg:'暂无数据'}])}},getCategoryList(){getCategoryList().then(res=>{this.categoryList = res.dataif(this.categoryList.length>0){this.activeName = this.categoryList[0].categoryIdgetProductList({categoryId:this.activeName }).then(res=>{this.productList = res.data})}})},handleClick(e){//拿到分类idconst categoryId = e.namegetProductList({categoryId:categoryId}).then(res=>{this.productList = res.data})},handleChange(e,scope){console.log(e)console.log(scope.$index)if(e==0){confirm('要删除该条目吗?').then(res=>{if(res){this.shopCart.splice(scope.$index,1)}else{this.shopCart[scope.$index].count = 1}})}},chooseProduct(e){let product = e;let findProductIndex = this.shopCart.findIndex(p => p.productId == product.productId);console.log(findProductIndex)if(findProductIndex == -1){this.$set(product, 'count', 1)this.shopCart.push(product)}else{this.shopCart[findProductIndex].count += 1}console.log(this.shopCart)},handleSelect(e){console.log(e)this.member = e}}}
</script><style scoped>::v-deep .el-tabs--border-card>.el-tabs__header .el-tabs__item{height: 50px;line-height: 50px;font-size: 14px;}.price{font-weight: bold;color: #ff5b57;}
</style>
代码地址
https://gitee.com/ddeatrr/memberShop
然后为了大家预览我把开发板也部署了 大家可以参考
http://store.gbadd.space/
相关文章:

springboot vue 开源 会员收银系统 (6) 收银台的搭建
前言 完整版演示 前面我们对会员系统 分类和商品的开发 完成了收银所需的基础信息 下面我们开始完成收银台的开发 简单画了一个收银的流程图大家参考下 从这张图我们可以分析一下几点 可以选择会员或散客收银选择会员使用相应的会员价结算使用会员卡则在价格基础根据卡折扣…...
重排和重绘的区别,什么情况下会触发这两种情况
重排(Reflow)和重绘(Repaint)是Web前端开发中关于浏览器渲染机制的两个核心概念。它们之间的主要区别以及触发条件如下: 重排(Reflow) 定义: 重排也称为布局(Layout&a…...

亮点回顾|智能汽车芯片创新技术应用与质量研讨会
5月29日,2024汽车软件与通信大会——智能汽车芯片创新技术应用与质量研讨会在江苏苏州狮山国际会议中心举行。本次会议由中国中检所属中国汽车工程研究院股份有限公司(简称:中国汽研)主办,旨在为智能汽车芯片的技术创新…...
特征工程,减小过拟合
目录 特征工程 减小过拟合 图像增强方法 特征工程是机器学习和数据分析中不可或缺的一环,其重要性不言而喻。以下是关于特征工程的详细回答: 一、定义 特征工程是将原始数据转化为更好的表达问题本质的特征的过程,旨在发现对因变量y有明显影响作用的特征(通常称自变量…...

STM32-16-ADC
STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU STM32-14-FSMC_LCD STM32-15-DMA…...
单例模式(C语言)
C语言的设计模式(单例模式) 单例模式(Singleton Pattern)是一种设计模式,目的是确保一个类只有一个实例,并提供一个全局访问点。 #include "stdio.h" #include "stdlib.h"// 定义一个…...
js前端格式化日期函数
开发需求 在前端中我们通常使用new Date()函数获取到的日期时间是下面这种样子:Thu Jun 06 2024 17:29:11 GMT0800 (中国标准时间),我们想要把它转换成常见的指定格式,比如 年-月-日 时:分:秒年/月/日 时:分:秒年-月-日年/月/日 所以就封装…...

五个超实用的 ChatGPT-4o 提示词
GPT-4o 是 OpenAI 最近推出的最新人工智能模型,不仅具备大语言模型的能力,而且拥有多模态模型的看、读、说等能力,而且速度比 GPT-4 更快。下面我们就来介绍几个超实用的 GPT-4o 提示词,帮助大家更好地了解 GPT-4o 的功能和应用场…...

基于51单片机多功能防盗报警proteus仿真( proteus仿真+程序+设计报告+原理图+讲解视频)
基于51单片机多功能防盗报警系统 1. 主要功能:2. 讲解视频:3. 仿真4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接 基于51单片机多功能防盗报警系统( proteus仿真程序设计报告原理图讲解视频) 仿真图proteus8.9及以上…...
gitee和github的协同
假设gitee上zhaodezan有一个开发库,但是从andeyeluguo上拉取最新的(从github上同步过来最新的) git remote add dbgpt_in_gitee https://gitee.com/andeyeluguo/DB-GPT.git remote -v git pull --rebase dbgpt_in_gitee main 有冲突可能需要…...

压力测试-性能指标-Jmeter使用-压力测试报告
文章目录 1.压测目的2.性能指标3.Jmeter3.1Jmeter使用3.1.1 运行Jmeter3.1.2 添加线程组3.1.3设置HTTP请求3.1.4 设置监视器 3.2 查看Jmeter压测结果3.2.1 查看结果树3.2.2 查看汇总报告3.2.3 查看聚合报告3.2.4 查看汇总图 1.压测目的 内存泄漏:OOM,重…...
通过Slf4j中的MDC实现在日志中添加用户IP功能
一、slf4j中MDC是什么 slf4j除了trace、debug、info、warn、error这几个日志接口外,还可以配合MDC将数据写入日志。换句话说MDC也是用来记录日志的,但它的使用方式与使用日志接口不同。 在使用日志接口时我们一般这么做 log.debug("log debug"…...
代码随想录算法训练营第四十九天| 139.单词拆分、背包问题总结
139.单词拆分 题目链接:139.单词拆分 文档讲解:代码随想录/单词拆分 视频讲解:视频讲解-单词拆分 状态:已完成(0遍) 解题过程 这几天博主忙着面试和入职,一晃已经周四了,这个礼拜…...

STM32F103VE和STM32F407VE的引脚布局
STM32F103VE vs STM32F407VE 引脚对比表 引脚 STM32F103VE STM32F407VE 备注 1 VSS VSS 地 2 VDD VDD 电源 3 VSSA VSSA 模拟地 4 VDDA VDDA 模拟电源 5 OSC_IN OSC_IN 外部时钟输入 6 OSC_OUT OSC_OUT 外部时钟输出 7 NRST NRST 复位 8 PC13 (GPIO) PC13 (GPIO) GPIO 9 PC14 (…...
搜维尔科技:使用 Xsens 动作捕捉技术创建栩栩如生的动画
使用Xsens 动作捕捉技术创建栩栩如生的动画 搜维尔科技:使用 Xsens 动作捕捉技术创建栩栩如生的动画...
鸿蒙开发 一 (三)、ArkTS开发实战上
ArkTS 从 TypeScript 优化而来, 但有些用法又不太一样, 在开发中, 经常会出现一些报错提示,下面我们也汇总一些常见错误,捡一些常见的整理一下 Promise 的用法: //TypeScript 写法:private load…...
TensorRT教程(1)初探TensorRT
1. TensorRT简要介绍 TensorRT(NVIDIA TensorRT)是 NVIDIA 开发的一个用于深度学习推理的高性能推理引擎。它可以针对 NVIDIA GPU 进行高效的深度学习推理加速,提供了许多优化技术,使得推理速度更快,并且可以在生产环境…...

多表连接查询和子查询
一、连接查询 连接查询是SQL语言最强大的功能之一,它可以执行查询时动态的将表连接起来,然后从中查询数据。 1.1、连接两表的方法 在SQL中连接两表可以有两种方法,一种是无连接规则连接,另一种是有连接规则连接。 无连接规则连…...

数据挖掘与机器学习——聚类算法
目录 无监督学习 聚类算法 概念: 功能: 应用场景: 评判标准: 划分聚类: K-means聚类 逻辑实现: 聚类方式 问题: 解决: 可能存在的问题: 1.初始值对K-means聚…...

QT快速下载
去QT官网之后,如下图所示 比如要下载qt-opensource-windows-x86-5.14.2.exe,进入5.14对应的文件夹,找到对应的版本 点击Details, 下载对应的种子,然后通过迅雷下载 个人实测,家庭网络平均18M的速率...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...