前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >猿实战12——类目属性之动态绑定

猿实战12——类目属性之动态绑定

作者头像
山旮旯的胖子
发布2020-09-14 10:18:26
6750
发布2020-09-14 10:18:26
举报
文章被收录于专栏:猿人工厂

猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是问题。更多精彩内容,敬请大家关注公主号猿人工厂,点击猿人养成获取!

上一个章节,猿人君教会了你如何去用树状的办法去展示属性值,今天我们就一起来完成新增类目属性这个方法。

功能概览

在新增类目属性这个功能中,我们可以在输入需要增加的属性后,点击查询,检索需要新增的属性。然后通过勾选的方式,将需要需要新增的属性,勾选到右边列表,点击保存后,完成新增类目属性的功能。

新增类目属性整体前端

新增类目属性,从本质上讲是一个子组件,通过我们上一章节中展示属性库的数据(猿实战11——类目属性绑定之el-tree的使用),然后通过通过动态表单的方式,提供类目属性的动态新增和删除功能。现在将页面整体都给到你。

代码语言:javascript
复制
<template>
  <div id="evaluateSearchDiv">
    <!-- <el-card shadow="never">
      <div> -->
    <el-form v-if="!showFlag" ref="listQuery" :model="listQuery" :inline="true">
      <el-form-item prop="attributeName">
        <el-input v-model="listQuery.propertyNameLike" placeholder="快捷查询属性组/属性名" clearable />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="fetchData()">查询</el-button>
        <el-button icon="el-icon-s-tools" @click="resetForm('listQuery')">重置</el-button>
      </el-form-item>
    </el-form>
    <!-- </div>
    </el-card> -->
    <el-row>
      <el-col v-if="!showFlag" :span="6">
        <el-card shadow="never">
          <div>
            <el-tree
              ref="tree"
              :data="data"
              show-checkbox
              node-key="id"
              :default-expanded-keys="[1]"
              :props="defaultProps"
              :render-content="renderContent"
              @check-change="updateKeyChildren"
            />
          </div>
        </el-card>
      </el-col>
      <el-col v-if="!showFlag" :span="1"> </el-col>
      <el-col v-if="!showFlag" :span="17">
        <el-card shadow="never">
          <div>
            <div>
              <el-table
                ref="table"
                :data="list"
                style="width: 100%;"
                border
              >
                <el-table-column label="已选属性">
                  <template slot-scope="scope">
                    {{ scope.row.propertyName }}
                  </template>
                </el-table-column>
                <el-table-column label="排序">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.sortOrder" clearable />
                  </template>
                </el-table-column>
                <el-table-column label="状态">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.status" clearable placeholder="请选择">
                      <el-option
                        v-for="item in statusList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="类型" width="170px">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.propertyType" clearable placeholder="请选择">
                      <el-option
                        v-for="item in propertyTypeList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="其他">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.inputType" clearable placeholder="请选择">
                      <el-option
                        v-for="item in inputTypeList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                    <el-select v-model="scope.row.required" clearable placeholder="请选择">
                      <el-option
                        v-for="item in requiredList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                    <el-select v-model="scope.row.nav" clearable placeholder="请选择">
                      <el-option
                        v-for="item in navList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col v-if="showFlag">
        <el-card shadow="never">
          <div>
            <div>
              <el-table
                ref="table"
                :data="list"
                style="width: 100%;"
                max-height="300"
                border
              >
                <el-table-column label="已选属性">
                  <template slot-scope="scope">
                    {{ scope.row.propertyName }}
                  </template>
                </el-table-column>
                <el-table-column label="排序">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.sortOrder" clearable />
                  </template>
                </el-table-column>
                <el-table-column label="状态">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.status" clearable placeholder="请选择">
                      <el-option
                        v-for="item in statusList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="类型" width="170px">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.propertyType" clearable placeholder="请选择">
                      <el-option
                        v-for="item in propertyTypeList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column label="其他">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.inputType" clearable placeholder="请选择">
                      <el-option
                        v-for="item in inputTypeList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                    <el-select v-model="scope.row.required" clearable placeholder="请选择">
                      <el-option
                        v-for="item in requiredList"
                        :key="item.value + '^-^'"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                    </el-select>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
    <div style="text-align: center;margin-top:20px;">
      <el-button type="primary" @click="addClick">
        {{ bottonName }}
      </el-button>
      <el-button type="info" @click="closeClick">
        关闭
      </el-button>
    </div>
  </div>
</template>
 
<script>
import { fetchForSelect, createMallCategoryProperty, updateMallCategoryProperty } from '@/api/product-manage'
export default {
  props: { attributeFlag: Boolean },
  data() {
    return {
      bottonName: '确定',
      showFlag: false,
      categoryId: undefined,
      updateFlag: false,
      list: [
      ],
      requiredList: [
        {
          value: 1,
          label: '必填'
        }, {
          value: 0,
          label: '选填'
        }
      ],
      navList: [
        {
          value: 1,
          label: '导航属性'
        }, {
          value: 0,
          label: '非导航属性'
        }
      ],
      inputTypeList: [
        {
          value: 0,
          label: '单选'
        }, {
          value: 1,
          label: '多选'
        },
        {
          value: 2,
          label: '输入'
        }
      ],
      // 类型
      statusList: [
        {
          value: 1,
          label: '启用'
        }, {
          value: 0,
          label: '停用'
        }
      ],
      // 状态
      propertyTypeList: [
        {
          value: 1,
          label: '普通属性'
        }, {
          value: 2,
          label: '关键属性'
        },
        {
          value: 3,
          label: '文字销售属性'
        }, {
          value: 4,
          label: '图片销售属性'
        }
      ],
      data: [],
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      listQuery: {
        catOneId: undefined,
        catTwoId: undefined,
        catThreeId: undefined
      }
    }
  },
  created() {
    // 判断一些按钮是否显示
    if (this.attributeFlag !== undefined) {
      this.showFlag = this.attributeFlag
    }
  },
  methods: {
    updateDate(flag, row, categoryId, catOneId, catTwoId, catThreeId) {
      console.log(catOneId + ';' + catTwoId + ';' + catThreeId)
      this.list = []
      if (flag !== undefined) {
        if (row.propertyType !== null && row.propertyType !== undefined && row.propertyType !== '') {
          this.updateFlag = true
          this.list.push(row)
          this.bottonName = '保存'
        } else {
          console.log(categoryId)
          this.categoryId = categoryId
          this.listQuery.catOneId = catOneId
          this.listQuery.catTwoId = catTwoId
          this.listQuery.catThreeId = catThreeId
          this.bottonName = '新增'
        }
      }
    },
    updateKeyChildren(data, key1, key2) {
      // this.list.push(this.atteibute)
      const checkedNodes = this.$refs.tree.getCheckedNodes()
      // const checkedMenuIds = new Set()
      // this.list = []
      if (checkedNodes != null && checkedNodes.length > 0) {
        for (let i = 0; i < checkedNodes.length; i++) {
          if (checkedNodes[i].label === undefined) {
            this.atteibute = {
              categoryId: this.categoryId,
              propertyId: checkedNodes[i].propertyId,
              propertyName: checkedNodes[i].propertyName,
              groupId: checkedNodes[i].groupId,
              sortOrder: 1,
              status: 1,
              propertyType: 1,
              inputType: 1,
              required: 0,
              nav: 0
            }
            const checkedNode = checkedNodes[i]
            var flag = true
            for (let j = 0; j < this.list.length; j++) {
              if (checkedNode.propertyId === this.list[j].propertyId) {
                flag = false
                break
              }
            }
            if (flag) {
              this.list.push(this.atteibute)
            }
          }
        }
      }
    },
    // 新增
    addClick() {
      if (this.updateFlag) {
        updateMallCategoryProperty(this.list[0]).then(() => {
        // const index = this.list.findIndex(v => v.id === data[0].id)
        // this.list.unshift(tempData)
          this.dialogFormVisible = false
          this.$notify({
            title: 'Success',
            message: 'Update Successfully',
            type: 'success',
            duration: 2000
          })
          this.$emit('closeClick')
        })
      } else {
        if (this.list.length < 1) {
          this.$notify({
            title: 'error',
            message: '请选择需要新增的属性',
            type: 'error',
            duration: 2000
          })
          return false
        }
        createMallCategoryProperty(this.list).then(() => {
        // const index = this.list.findIndex(v => v.id === data[0].id)
        // this.list.unshift(tempData)
          this.dialogFormVisible = false
          this.$notify({
            title: 'Success',
            message: 'Update Successfully',
            type: 'success',
            duration: 2000
          })
          this.$emit('closeClick')
        })
      }
    },
    // 关闭
    closeClick() {
      this.$emit('closeClick')
    },
    // 查询方法
    fetchData() {
      fetchForSelect(this.listQuery).then(response => {
        this.data = response.model
 
        // Just to simulate the time of the request
        setTimeout(() => {
          this.listLoading = false
        }, 1.5 * 1000)
      })
    },
    // 重置表单
    resetForm(formName) {
      this.$refs[formName].resetFields()
    },
    renderContent(h, { node, data, store }) {
      if (node.label === undefined) {
        return (
          <span>
            <span>{node.data.propertyName}</span>
          </span>)
      }
 
      return (
        <span>
          <span>{node.label}</span>
        </span>)
    }
 
  }
 
}
</script>
 
<style scoped>
</style>

其中有一些你需要特别注意的东西。比如右侧的已经选择的属性列表,是一个动态列表。一般来说我们使用el-table这样的组件来做到它。

关于如何做到勾选左侧展示的属性,到右侧的动态表单中,需要利用之前在el-tree中定义的回调函数。如何获取已选中的数据节点?使用this.$refs.tree.getCheckedNodes()来获取。

页面API的封装

要完成这样一个功能自然离不开调用后端的数据接口,调用后端的api封装我们可以看一下。

代码语言:javascript
复制
export function createMallCategoryProperty(data) {
  return request({
    url: '/categoryProperty/addMallCategoryPropertyBatch',
    method: 'post',
    data: data
  })
}
 
export function updateMallCategoryProperty(data) {
  return request({
    url: '/categoryProperty/updateMallCategoryProperty',
    method: 'post',
    data: data
  })
}
 
 
// 新增类目属性获取可以选择的属性
export function fetchForSelect(query) {
  return request({
    url: '/categoryProperty/findForSelect',
    method: 'post',
    data: query
  })
}

后端数据接口封装

后端的实现较为复杂的上一章节已经讲述过了,现在把剩余的Controller层代码给到你。

代码语言:javascript
复制
/**
 * Copyright(c) 2004-2020 pangzi
 * com.pz.basic.mall.controller.product.category.MallCategoryPropertyController.java
 */
package com.pz.basic.mall.controller.product.category;
 
import com.pz.basic.mall.domain.base.Result;
import com.pz.basic.mall.domain.product.category.MallCategoryProperty;
import com.pz.basic.mall.domain.product.category.query.QueryMallCategoryProperty;
import com.pz.basic.mall.domain.product.category.vo.MallCategoryPropertyVo;
import com.pz.basic.mall.domain.product.property.query.QueryMallProperty;
import com.pz.basic.mall.domain.product.property.vo.MallGroupVo;
import com.pz.basic.mall.service.product.category.MallCategoryPropertyService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.List;
 
 
/**
 *
 * @author pangzi
 * @date 2020-06-22 20:47:27
 *
 *
 */
@RestController
@RequestMapping("/categoryProperty")
public class MallCategoryPropertyController {
 
 
    private MallCategoryPropertyService mallCategoryPropertyService;
 
    public void setMallCategoryPropertyService(MallCategoryPropertyService MallCategoryPropertyService) {
        this.mallCategoryPropertyService = MallCategoryPropertyService;
    }
 
 
    /**
     * 批量新增类目属性
     * @param mallCategoryPropertyList
     * @return
     */
    @RequestMapping("/addMallCategoryPropertyBatch")
    public Result<List<MallCategoryProperty>> addMallCategoryProperty(@RequestBody List<MallCategoryProperty> mallCategoryPropertyList){
        try{
            return mallCategoryPropertyService.addMallCategoryPropertyBatch(mallCategoryPropertyList);
        }catch(Exception e){
            e.printStackTrace();
            return new Result(false);
        }
    }
 
    /**
     * 修改类目属性
     * @param mallCategoryProperty
     * @return
     */
    @RequestMapping("/updateMallCategoryProperty")
    public Result updateMallCategoryProperty(@RequestBody MallCategoryProperty mallCategoryProperty){
        try{
            return  mallCategoryPropertyService.updateMallCategoryPropertyById(mallCategoryProperty);
        }catch(Exception e){
            e.printStackTrace();
            return new Result(false);
        }
    }
 
 
    /**
     * 分页返回类目属性列表
     * @param queryMallCategoryProperty
     * @return
     */
    @RequestMapping("/findByPage")
    public  Result<List<MallCategoryProperty>> findByPage(@RequestBody QueryMallCategoryProperty queryMallCategoryProperty){
        return mallCategoryPropertyService.getMallCategoryPropertysByPage(queryMallCategoryProperty);
    }
 
    /**
     * 删除类目属性
     * @param mallCategoryProperty
     * @return
     */
    @RequestMapping("/deleteMallCategoryProperty")
    public Result deleteMallCategoryProperty(@RequestBody MallCategoryProperty mallCategoryProperty){
        try{
            MallCategoryProperty updateMallCategoryProperty = new MallCategoryProperty();
            updateMallCategoryProperty.setCategoryPropertyId(mallCategoryProperty.getCategoryPropertyId());
            updateMallCategoryProperty.setStatus(-1);
            return  mallCategoryPropertyService.updateMallCategoryPropertyById(updateMallCategoryProperty);
        }catch(Exception e){
            e.printStackTrace();
            return new Result(false);
        }
    }
 
 
 
    /**
     * 分页返回类目属性列表
     * @param queryMallProperty
     * @return
     */
    @RequestMapping("/findForSelect")
    public  Result<List<MallGroupVo>> findForSelect(@RequestBody QueryMallProperty queryMallProperty){
        return mallCategoryPropertyService.getMallPropertyGroup(queryMallProperty);
    }
 
 
}

还是那句老话,代码要尽量自己去实现,才能有真正的提高,所以猿人君一直会留下一些小尾巴给你,帮助你提升你的技能。相信你已经能够完成新增属性的前提下,修改属性值的事情,应该也难不倒你,就暂且不讲了噢。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 猿人工厂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档