商城项目11_商品SPUSKU详解表结构属性分组列表展示修改新增分类级联更新

Posted 所得皆惊喜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了商城项目11_商品SPUSKU详解表结构属性分组列表展示修改新增分类级联更新相关的知识,希望对你有一定的参考价值。

文章目录

①. 商品SPU和SKU管理

  • ①. SPU:standard product unit(标准化产品单元):是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性
    如iphoneX是SPU(相当于面向对象的类)

  • ②. SKU:stock keeping unit(库存量单位):库存进出计量的基本单元,可以是件/盒/托盘等单位。SKU是对于大型连锁超市DC配送中心物流管理的一个必要的方法。现在已经被引申为产品统一编号的简称,每种产品对应有唯一的SKU号
    如iphoneX 64G黑色是SKU,iphoneX 32G白色是SKU(相当于面向对象的具体实现)

  • ③. 基础属性:同一个SPU拥有的特性叫基本属性。如机身长度,这个是手机共用的属性。而每款手机的属性值不同,也可以叫规格参数

  • ④. 销售属性:能决定库存量的叫销售属性。如颜色

  • ⑤. 基本属性(规格参数)与销售属性
    每个分类下的商品共享规格参数,与销售属性。只是有些商品不一定要用这个分类下全部的属性

  1. 属性是以三级分类组织起来的
  2. 规格参数中有些是可以提供检索的
  3. 规格参数也是基本属性,他们具有自己的分组
  4. 属性的分组也是以三级分类组织起来的
  5. 属性名确定的,但是值是每一个商品不同来决定的

②. 详解SPU、SKU表结构

  • ①. 数据库表结构大概情况如下图所示:

  • ②. pms_attr:属性表,这个表里面有attr_name(属性名)、attr_type(属性类型)、catelog_id(分类ID)、search_type(代表这个属性是否可以被检索)
    比如在基本信息(分组)里面有一个叫机身颜色,那么这个机身颜色就是属性名,它是和分组关联起来的,这个机身颜色属性属于哪一组?

  • ③. psm_attr_group:属性分组表,attr_group_id、attr_group_name、category_id 在手机类下,我们就可以查询到所有的手机类下的分组,分组和属性怎么关联起来的?

  • ④. pms_attr_attrgroup_relation:分组和属性的关联关系表,attr_id、attr_group_id 比如说主体分组关联了入网型号、上市年份等信息
    (这些属性的值是什么,我们要根据选择的哪个商品来的,我们有一张叫商品属性值表来维护)

  • ⑤. pms_product_attr_value:商品属性值表,spu_id、attr_id(属性ID)、attr_value(属性ID对应的具体值) 具体的spu的详细信息在pms_spu_info里面

  • ⑥. pms_sku_info:sku的详细信息,有主副标题、商品的图片信息(图片可能有很多个)等

  • ⑦. pms_sku_images:很多个图片都存在图片表中

  • ⑧. pms_sku_sale_attr_value:比如我们要选择白色+128G或者黑色+64G这些信息属性名确定的,但是值是每一个商品不同来决定的


③. 属性分组 - 列表展示

  • ①. 需求:
    后台:商品系统/平台属性/属性分组
    现在想要实现点击菜单的左边,能够实现在右边展示数据
  • ②. 树状结构代码抽取
<template>
  <div>
    <!--
	(1). 过滤:在需要对节点进行过滤时,调用 Tree 实例的filter方法,参数为关键字。
	需要注意的是,此时需要设置filter-node-method,值为过滤函数。
	:filter-node-method="filterNode"
	(2). node-key:每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
	(3). @node-click:当我们点击树的事件时触发的函数
	(4). :highlight-current:是否高亮当前选中节点,默认值是false。
	(5). 向父组件发送事件: this.$emit("tree-node-click", data, node, component);
	-->
    <el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input>
    <el-tree
      :data="menus"
      :props="defaultProps"
      node-key="catId"
      ref="menuTree"
      @node-click="nodeclick"
      :filter-node-method="filterNode"
      :highlight-current = "true"
    ></el-tree>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';

export default 
  //import引入的组件需要注入到对象中才能使用
  components: ,
  props: ,
  data() 
    //这里存放数据
    return 
      filterText: "",
      menus: [],
      expandedKey: [],
      defaultProps: 
        children: "children",
        label: "name"
      
    ;
  ,
  //计算属性 类似于data概念
  computed: ,
  //监控data中的数据变化
  watch: 
    filterText(val) 
      this.$refs.menuTree.filter(val);
    
  ,
  //方法集合
  methods: 
    //树节点过滤
    filterNode(value, data) 
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    ,
    getMenus() 
      this.$http(
        url: this.$http.adornUrl("/product/category/list/tree"),
        method: "get"
      ).then(( data ) => 
        this.menus = data.data;
      );
    ,
    nodeclick(data, node, component) 
      console.log("子组件category的节点被点击", data, node, component);
      //向父组件发送事件;
      this.$emit("tree-node-click", data, node, component);
    
  ,
  //生命周期 - 创建完成(可以访问当前this实例)
  created() 
    this.getMenus();
  ,
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() ,
  beforeCreate() , //生命周期 - 创建之前
  beforeMount() , //生命周期 - 挂载之前
  beforeUpdate() , //生命周期 - 更新之前
  updated() , //生命周期 - 更新之后
  beforeDestroy() , //生命周期 - 销毁之前
  destroyed() , //生命周期 - 销毁完成
  activated()  //如果页面有keep-alive缓存功能,这个函数会触发
;
</script>
<style scoped>

</style>
  • ③. 属性分组前台代码展示
    先要el-row进行布局处理,左边是树状结构,右边是表格
<template>
  <el-row :gutter="20">
    <el-col :span="6">
      <Category @tree-node-click="treenodeclick"></Category>
    </el-col>
    <el-col :span="18">
      <div class="mod-config">
        <el-form
          :inline="true"
          :model="dataForm"
          @keyup.enter.native="getDataList()"
        >
          <el-form-item>
            <el-input
              v-model="dataForm.key"
              placeholder="参数名"
              clearable
            ></el-input>
          </el-form-item>
          <el-form-item>
            <el-button @click="getDataList()">查询</el-button>
            <el-button
              v-if="isAuth('product:attrgroup:save')"
              type="primary"
              @click="addOrUpdateHandle()"
              >新增</el-button
            >
            <el-button
              v-if="isAuth('product:attrgroup:delete')"
              type="danger"
              @click="deleteHandle()"
              :disabled="dataListSelections.length <= 0"
              >批量删除</el-button
            >
          </el-form-item>
        </el-form>
        <el-table
          :data="dataList"
          border
          v-loading="dataListLoading"
          @selection-change="selectionChangeHandle"
          style="width: 100%;"
        >
          <el-table-column
            type="selection"
            header-align="center"
            align="center"
            width="50"
          >
          </el-table-column>
          <el-table-column
            prop="attrGroupId"
            header-align="center"
            align="center"
            label="分组id"
          >
          </el-table-column>
          <el-table-column
            prop="attrGroupName"
            header-align="center"
            align="center"
            label="组名"
          >
          </el-table-column>
          <el-table-column
            prop="sort"
            header-align="center"
            align="center"
            label="排序"
          >
          </el-table-column>
          <el-table-column
            prop="descript"
            header-align="center"
            align="center"
            label="描述"
          >
          </el-table-column>
          <el-table-column
            prop="icon"
            header-align="center"
            align="center"
            label="组图标"
          >
          </el-table-column>
          <el-table-column
            prop="catelogId"
            header-align="center"
            align="center"
            label="所属分类id"
          >
          </el-table-column>
          <el-table-column
            fixed="right"
            header-align="center"
            align="center"
            width="150"
            label="操作"
          >
            <template slot-scope="scope">
              <el-button
                type="text"
                size="small"
                @click="addOrUpdateHandle(scope.row.attrGroupId)"
                >修改</el-button
              >
              <el-button
                type="text"
                size="small"
                @click="deleteHandle(scope.row.attrGroupId)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          @size-change="sizeChangeHandle"
          @current-change="currentChangeHandle"
          :current-page="pageIndex"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="pageSize"
          :total="totalPage"
          layout="total, sizes, prev, pager, next, jumper"
        >
        </el-pagination>
        <!-- 弹窗, 新增 / 修改 -->
        <add-or-update
          v-if="addOrUpdateVisible"
          ref="addOrUpdate"
          @refreshDataList="getDataList"
        ></add-or-update>
      </div>
    </el-col>
  </el-row>
</template>

<script>
/**
 * 父子组件传递数据
 * 1)、子组件给父组件传递数据,事件机制;
 *    子组件给父组件发送一个事件,携带上数据。
 * // this.$emit("事件名",携带的数据...)
 */
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import Category from "@/views/modules/common/category";
import AddOrUpdate from "./attrgroup-add-or-update";
export default 
  //import引入的组件需要注入到对象中才能使用
  components:  Category, AddOrUpdate ,
  data() 
    return 
      catId: 0,
      dataForm: 
        key: ""
      ,
      dataList: [],
      pageIndex: 1,
      pageSize: 10,
      totalPage: 0,
      dataListLoading: false,
      dataListSelections: [],
      addOrUpdateVisible: false,
      relationVisible: false
    ;
  ,
  //监听属性 类似于data概念
  computed: ,
  //监控data中的数据变化
  watch: ,
  //方法集合
  methods: 
    //感知树节点被点击
    treenodeclick(data, node, component) 
      //只有点击三级分类的时候才会进行查询
      if (node.level == 3) 
        this.catId = data.catId;
        this.getDataList(); //重新查询
      
    ,
    // 获取数据列表
    getDataList() 
      this.dataListLoading = true;
      this.$http(
        url: this.$http.adornUrl(`/product/attrgroup/list/$this.catId`),
        method: "get",
        params: this.$http.adornParams(
          page: this.pageIndex,
          limit: this.pageSize,
          key: this.dataForm.key //搜索字段
        )
      ).then(( data ) => 
        if (data && data.code === 0) 
          this.dataList = data.page.list;
          this.totalPage = data.page.totalCount;
         else 
          this.dataList = [];
          this.totalPage = 0;
        
        this.dataListLoading = false;
      );
    ,
    // 每页数
    sizeChangeHandle(val) 
      this.pageSize = val;
      this.pageIndex = 1;
      this.getDataList();
    ,
    // 当前页
    currentChangeHandle(val) 
      this.pageIndex = val;
      this.getDataList();
    ,
    // 多选
    selectionChangeHandle(val) 
      this.dataListSelections = val;
    ,
    // 新增 / 修改
    addOrUpdateHandle第195天学习打卡(项目 谷粒商城 37新增商品 获取分类下所有属性及分组)

电商项目---数据库表设计

商城项目13_查询分组关联属性删除新增查询分组未关联的属性调整会员服务获取分类关联的品牌

商城项目13_查询分组关联属性删除新增查询分组未关联的属性调整会员服务获取分类关联的品牌

商城项目07_网关工程初步搭建商品分类树状结构展示网关配置解决跨域问题

商城项目07_网关工程初步搭建商品分类树状结构展示网关配置解决跨域问题