springboot vue 开源 会员收银系统 (6) 收银台的搭建

前言

完整版演示

前面我们对会员系统 分类和商品的开发 完成了收银所需的基础信息 下面我们开始完成收银台的开发

简单画了一个收银的流程图大家参考下
收银流程图

从这张图我们可以分析一下几点

  • 可以选择会员或散客收银
  • 选择会员使用相应的会员价结算
  • 使用会员卡则在价格基础根据卡折扣结算

根据上述分析我搭建了一个简单的收银台
收银台

  • 左边显示会员和已选择的商品信息
  • 右边显示商品的价格信息
  • 商品选择后可以修改数字
  • 总金额自动计算
  • 后续完成挂单功能便于保证收银连续性

开发中运用的组件

  1. Tabs 标签页 和 Card 完成右侧的商品选择
  2. el-autocomplete 完成会员的检索
  3. InputNumber Table 完成购物车开发

收银台运用过多组件会导致页面很乱 我们后续需要进行组件的封装

<template>
  <div class="app-container"  style="border-box:box-sizing;">

<!--    left-->
    <el-row :gutter="30" style="">
      <el-col :span="10">

        <el-autocomplete
          style="width: 100%"
          popper-class="my-autocomplete"
          v-model="querySearchStr"
          :fetch-suggestions="querySearch"
          placeholder="会员检索"
          @select="handleSelect">
          <i
            class="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-table

            border
            height="400"
            max-height="400"
            :data="shopCart"
            style="width: 100%;margin-bottom: 20px;">

        <el-table-column
          align="center"
          prop="categoryName"
          label="分类"
          width="100">
        </el-table-column>

        <el-table-column
          align="center"
          prop="productName"
          label="商品名"
          >
        </el-table-column>

        <el-table-column
          align="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-column
          align="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-column
           align="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-pane
            v-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 productTotalPrice
            if(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 = newVal
          console.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.data
              if(this.categoryList.length>0){
                this.activeName = this.categoryList[0].categoryId
                getProductList({categoryId:this.activeName }).then(res=>{
                  this.productList = res.data
                })
              }
            })
          },
         handleClick(e){
            //拿到分类id
           const categoryId = e.name
           getProductList({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://120.26.95.195:8889/

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring BootVue.js都是非常流行的开源项目,它们分别用于后端和前端开发。有很多基于这两个项目的开源项目,可以让开发人员快速地搭建起一个全栈应用程序。其中,一些比较受欢迎的开源项目包括: 1. vue-element-admin:这是一个基于Vue.js和Element UI的开源后台管理系统,提供了许多常见的管理功能和布局。 2. spring-boot-vuejs:这是一个使用Spring BootVue.js构建的全栈Web应用程序,提供了一个简单的示例,展示了如何使用这两个项目搭建一个现代化的Web应用程序。 3. mall-admin-web:这是一个基于Spring BootVue.js的电子商务管理系统,提供了管理商品、订单、库存等功能。 这些开源项目可以帮助开发人员学习和掌握如何使用Spring BootVue.js构建现代化的Web应用程序。 ### 回答2: SpringBootVue是现在非常流行的两个开源项目,它们分别是Java后端开发和前端开发中最火热的框架之一。SpringBoot是一款基于Spring框架的快速开发脚手架,它简化了Spring应用程序的配置和部署,这样开发人员可以更加专注于业务逻辑的实现。 Vue是一款轻量级MVVM框架,它可以轻松地构建复杂的单页应用程序。与传统的MVC框架相比,Vue具有更好的性能和更高的开发效率。同时,Vue还支持组件化开发,这意味着开发人员可以将复杂的用户界面分解为更小、更可重用的部分。 将SpringBootVue结合起来,可以构建出一款具有前后端分离的全栈应用程序。 SpringBoot作为后端承担处理业务逻辑和操作数据库等后台处理,Vue作为前端负责展示UI界面和用户交互。使用Vue作为前端框架,可以让开发人员更容易地构建交互式和动态的Web应用程序,同时采用SpringBoot作为后端框架,能够更快地开发出高质量的后台服务,增强Web应用程序的性能和扩展性。 熟悉 SpringBootVueJava 开发人员很容易使用这两个框架来构建成熟的全栈应用程序,尤其适合面向中小型企业开发Web应用程序。当然,将SpringBootVue结合起来开发全栈应用程序也需要熟练的前后端分离技术,这包括熟悉AJAX技术、 XML/JSON 文件的操作、理解前后端代码分离的思想等。在掌握了相关的开发技术后,开发人员可以选择自己感兴趣的业务领域,并用SpringBootVue完美地搭建出一款高质量的全栈应用程序。 ### 回答3: SpringBoot是一个非常流行的Java开发框架,而Vue则是一个轻量级的JavaScript框架,两者都是开源的。综合使用SpringBootVue,可以开发出高效、稳定、易于维护的Web应用程序。下面我将就SpringBoot Vue开源项目(以下简称项目)进行详细介绍。 首先,项目依托于SpringBoot框架,它提供了很多便利的开箱即用的特性,比如自动配置、优化等。SpringBoot的运行时环境也非常简洁,可以大大减少应用程序的启动时间。另外,SpringBoot还提供了自带的Embedded Tomcat服务器,无需繁杂的配置,就能直接运行Web应用程序。 而Vue则是客户端框架,它非常适合构建用户界面Vue提供了一些易于使用的指令和组件,可以将应用程序的视图和状态分离。这对开发人员来说非常方便,大大减少了应用程序的前端开发成本,并且提高了应用程序的响应速度。 在项目中,我们可以使用Vue-CLI帮助我们构建项目,并使用webpack进行构建。Vue-CLI提供了一些方便的特性,比如热加载、自动刷新等。这些特性可以让我们更加高效地进行开发,并且提高开发效率和质量。 总体来说,SpringBoot Vue开源项目是一款优秀的Web应用程序开发框架,它结合了SpringBootVue等流行的框架,提供了一套简洁高效的开发模式和运行环境。开发人员可以快速地开发出高质量、高性能的Web应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值