手把手教你搭建一个完整的电商系统之品牌管理

猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是问题。想要一起实战吗?,关注公主号猿人工厂获取基础代码,手把手带你开发一个完整的电商系统。

前后端框架已经搭建起来了,接下来的很长一段日子里,猿人君就带着大家撸一个电商系统出来玩耍。实战阶段的目的,是为了让你从需求梳理落地到实现有一个完整的认知,熟练掌握撸码的一些套路,让你具备设计和实现一个完整系统的能力。废话不多说,我们今天开始首战——品牌管理的设计和实现。

需求整理

根据之前的猿设计系列文章猿设计2——电商后台全逻辑需求挖掘,品牌数据是需要维护的,根据对设计文档的梳理,我们需要做的功能如下图所示:

 

 

品牌管理的功能包括,品牌列表——支持根据品牌名称模糊查询并分页展示,新增品牌、编辑品牌、删除品牌、停用/启用品牌,以及为了方便运营人员批量操作而提供的勾选记录批量停用/启用/删除功能。

数据库设计

由于之前的设计文章中,我们已经提及过品牌实体的一些属性了,而这些属性背后承载的信息,将为我们的电商系统提供数据支撑,毫无疑问,这些数据是需要持久的,为此我们自然需要建立相应的数据表来支持。

前端主要组件

由于我们使用了vue-element-admin.git作为基础的后天管理前端开发框架,前端中使用的主要组件,主要是element-ui,关于组件的具体使用办法,大家可以参考官方网站:

https://element.eleme.cn/#/zh-CN

在品牌管理这一功能中,我们主要使用了el-card、el-input、el-button、el-table(列表)、el-pagination(分页)、el-upload(上传组件),考虑到你可能是第一次编写前端代码,很多东西都还不熟悉,这次就把前端的UI代码送给你了。

<template>
  <divid="brandManagementDiv">
    <el-cardclass="filter-container" shadow="never">
      <div>
        <el-formref="listQuery" :model="listQuery" :inline="true">
          <el-form-itemlabel="品牌名称:"prop="brandName">
            <el-inputv-model="listQuery.brandName" placeholder="请输入品牌名称" clearable />
         </el-form-item>
         <el-form-item>
            <el-buttontype="primary" icon="el-icon-edit"@click="addBrand()">新增</el-button>
            <el-buttontype="primary" icon="el-icon-search"@click="fetchData()">查询</el-button>
            <el-buttonicon="el-icon-s-tools" @click="resetForm('listQuery')">重置</el-button>
            <el-buttontype="primary" @click="enbleDataList()">全部启用</el-button>
            <el-buttontype="primary" @click="disableDataList()">全部停用</el-button>
            <el-buttontype="danger" @click="deleteDataList()">全部删除</el-button>
         </el-form-item>
        </el-form>
      </div>
    </el-card>
    <divstyle="height:20px;" />
    <divclass="table-container">
      <el-table
       ref="multipleTable"
       v-loading="listLoading"
       :data="list"
        style="width:100%"
        border
        @selection-change="handleSelectionChange"
      >
       <el-table-column type="selection" min-width="10%"/>
       <el-table-column label="编号" min-width="10%">
          <templateslot-scope="scope">{
  { scope.row.id }}</template>
       </el-table-column>
       <el-table-column label="品牌名称">
          <templateslot-scope="scope">{
  { scope.row.brandName }}</template>
       </el-table-column>
       <el-table-column label="品牌首字母" min-width="10%">
          <templateslot-scope="scope">{
  { scope.row.firstChar }}</template>
       </el-table-column>
        <el-table-columnlabel="品牌logo"align="center">
          <templateslot-scope="scope"><img style="width: 200px; height:200px" :src="scope.row.logo"alt=""></template>
       </el-table-column>
       <el-table-column label="状态" min-width="10%">
          <templateslot-scope="scope">{
  { scope.row.status == 1 ? "启用" : "停用"}}</template>
       </el-table-column>
       <el-table-column label="操作" width="220">

          <templateslot-scope="scope">
            <el-button
              type="primary"
             size="mini"
             @click="handleUpdate(scope.row)"
            >编辑
           </el-button>
            <el-button
             v-if="scope.row.status==1"
             type="primary"
             size="mini"
              @click="handleDisable(scope.$index,scope.row)"
            >停用
           </el-button>
            <el-button
             v-if="scope.row.status==0"
             type="primary"
             size="mini"
             @click="handleEnable(scope.$index, scope.row)"
            >启用
           </el-button>
            <el-button
             size="mini"
             type="danger"
             @click="handleDelete(scope.$index, scope.row)"
            >删除
           </el-button>
          </template>
       </el-table-column>
      </el-table>
    </div>
    <paginationv-show="total>0" :total="total":page.sync="listQuery.page":limit.sync="listQuery.pageSize" @pagination="getList"/>

    <!-- 新增/编辑弹框 -->
    <el-dialog:title="textMap[dialogStatus]":visible.sync="dialogFormVisible">
      <el-formref="dataForm" :rules="rules" :model="temp"label-position="right" label-width="100px"style="width: 500px; margin-left:50px;">
        <el-form-itemlabel="品牌名称:"prop="brandName">
          <el-inputv-model="temp.brandName" />
       </el-form-item>
        <el-form-itemlabel="品牌首字母:"prop="firstChar">
          <el-inputv-model="temp.firstChar" maxlength="1"oninput="value=value.replace(/[^A-Z]/g,'');" alt="英文大写" />
       </el-form-item>
        <el-form-itemv-show="dialogVisible" label="品牌logo:" prop="logo"style="margin-top:15px;">
          <imgstyle="width: 200px; height: 200px" :src="temp.logo"alt="">
       </el-form-item>
       <el-form-item>
          <el-upload
            ref="upload"
           :file-list="imgList"
           action="http://127.0.0.1:9201//upload/uploadFile?moudle=brand"
           list-type="picture-card"
           :on-preview="handlePictureCardPreview"
           :on-success="handleSuccess"
            :limit="1"
           accept="image/jpeg,image/gif,image/png,image/bmp"
          >
            <iclass="el-icon-plus" />
         </el-upload>
       </el-form-item>
      </el-form>
      <divslot="footer">
        <el-button@click="dialogFormVisible = false">
          取消
        </el-button>
        <el-buttontype="primary"@click="dialogStatus==='create'?createData():updateData()">
          确定
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<style scoped>
#brandManagementDiv /deep/ .el-form-item--mini.el-form-item__label {
 width: 100px !important;
}
</style>

后端代码之实体层

前端页面的初步代码有了,我们开始后端数据访问层的设计。根据数据库表结构,我们可以迅速的得到我们所需要的实体MallBrand和QueryMallBrand.为什么是两个实体?因为数据查询和持久是两回事情,在查询实体中,可能为了匹配页面的查询条件而增加一些不需要持久的条件,所以我们需要分开。实体层的代码编写在哪里?自然是我们的pzmall-basic-domain模块了。

/**
 * Copyright(c) 2004-2020pangzi
 *com.pz.basic.mall.domain.sys.MallCity.java
 */
package com.pz.basic.mall.domain.base;

import org.apache.commons.lang3.builder.ToStringBuilder;

import java.io.Serializable;

/**
 *
 * @author pangzi
 * @date 2020-06-2211:28:19
 *
 *
 */
public class BaseDO implements Serializable {

  private static final longserialVersionUID = 1L;


  /**
   * 如果字段值为null将不包含在toString中
   */
  @Override
  public String toString(){
     returnToStringBuilder.reflectionToString(this);
  }
}


 


package com.pz.basic.mall.domain.sys;

import com.pz.basic.mall.domain.base.BaseDO;

import java.util.Date;


/**
 *
 * @author pangzi
 * @date 2020-06-2718:09:41
 *
 */
public class MallBrand extends BaseDO {

    /**主键**/
  private Long id;

    /**品牌名**/
  private String brandName;

    /**logo图片地址**/
  private String logo;

    /**品牌首字母**/
  private String firstChar;

    /**状态1可用0不可用**/
  private Integer status;

    /**记录状态1有效0删除**/
  private Integer active;

    /**创建人**/
  private StringcreateUser;

    /**修改人**/
  private StringmodifyUser;

    /**创建时间**/
  private Date created;

    /**修改时间**/
  private Date modified;
    //g
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值