三十四.增加品牌分类关联

一.增加品牌分类关联的前端

prodect文件夹中的brand.vue文件详情如下:

<template>
  <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:brand:save')"
          type="primary"
          @click="addOrUpdateHandle()"
        >新增</el-button>
        <el-button
          v-if="isAuth('product:brand: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="brandId" header-align="center" align="center" label="品牌id"></el-table-column>
      <el-table-column prop="name" header-align="center" align="center" label="品牌名"></el-table-column>
      <el-table-column prop="logo" header-align="center" align="center" label="品牌logo地址">
        <template slot-scope="scope">
          <!-- <el-image
              style="width: 100px; height: 80px"
              :src="scope.row.logo"
          fit="fill"></el-image>-->
          <img :src="scope.row.logo" style="width: 100px; height: 80px" />
        </template>
      </el-table-column>
      <el-table-column prop="descript" header-align="center" align="center" label="介绍"></el-table-column>
      <el-table-column prop="showStatus" header-align="center" align="center" label="显示状态">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.showStatus"
            active-color="#13ce66"
            inactive-color="#ff4949"
            :active-value="1"
            :inactive-value="0"
            @change="updateBrandStatus(scope.row)"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column prop="firstLetter" 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 fixed="right" header-align="center" align="center" width="250" label="操作">
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="updateCatelogHandle(scope.row.brandId)">关联分类</el-button>
          <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.brandId)">修改</el-button>
          <el-button type="text" size="small" @click="deleteHandle(scope.row.brandId,scope.row.name)">删除</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>

    <el-dialog title="关联分类" :visible.sync="cateRelationDialogVisible" width="30%">
      <el-popover placement="right-end" v-model="popCatelogSelectVisible">
        <category-cascader :catelogPath.sync="catelogPath"></category-cascader>
        <div style="text-align: right; margin: 0">
          <el-button size="mini" type="text" @click="popCatelogSelectVisible = false">取消</el-button>
          <el-button type="primary" size="mini" @click="addCatelogSelect">确定</el-button>
        </div>
        <el-button slot="reference">新增关联</el-button>
      </el-popover>
      <el-table :data="cateRelationTableData" style="width: 100%">
        <el-table-column prop="id" label="#"></el-table-column>
        <el-table-column prop="brandName" label="品牌名"></el-table-column>
        <el-table-column prop="catelogName" label="分类名"></el-table-column>
        <el-table-column fixed="right" header-align="center" align="center" label="操作">
          <template slot-scope="scope">
            <el-button
              type="text"
              size="small"
              @click="deleteCateRelationHandle(scope.row.id,scope.row.brandId)"
            >移除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cateRelationDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="cateRelationDialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import AddOrUpdate from "./brand-add-or-update";
import CategoryCascader from "../common/category-cascader";
export default {
  data() {
    return {
      dataForm: {
        key: ""
      },
      brandId: 0,
      catelogPath: [],
      dataList: [],
      cateRelationTableData: [],
      pageIndex: 1,
      pageSize: 10,
      totalPage: 0,
      dataListLoading: false,
      dataListSelections: [],
      addOrUpdateVisible: false,
      cateRelationDialogVisible: false,
      popCatelogSelectVisible: false
    };
  },
  components: {
    AddOrUpdate,
    CategoryCascader
  },
  activated() {
    this.getDataList();
  },
  methods: {
    addCatelogSelect() {
      //{"brandId":1,"catelogId":2}
      this.popCatelogSelectVisible =false;
      this.$http({
        url: this.$http.adornUrl("/prodect/categorybrandrelation/save"),
        method: "post",
        data: this.$http.adornData({brandId:this.brandId,catelogId:this.catelogPath[this.catelogPath.length-1]}, false)
      }).then(({ data }) => {
        this.getCateRelation();
      });
    },
    deleteCateRelationHandle(id, brandId) {
      this.$http({
        url: this.$http.adornUrl("/prodect/categorybrandrelation/delete"),
        method: "post",
        data: this.$http.adornData([id], false)
      }).then(({ data }) => {
        this.getCateRelation();
      });
    },
    updateCatelogHandle(brandId) {
      this.cateRelationDialogVisible = true;
      this.brandId = brandId;
      this.getCateRelation();
    },
    getCateRelation() {
      this.$http({
        url: this.$http.adornUrl("/prodect/categorybrandrelation/catelog/list"),
        method: "get",
        params: this.$http.adornParams({
          brandId: this.brandId
        })
      }).then(({ data }) => {
        this.cateRelationTableData = data.data;
      });
    },
    // 获取数据列表
    getDataList() {
      this.dataListLoading = true;
      this.$http({
        url: this.$http.adornUrl("/prodect/brand/list"),
        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;
      });
    },
    updateBrandStatus(data) {
      console.log("最新信息", data);
      let { brandId, showStatus } = data;
      //发送请求修改状态
      this.$http({
        url: this.$http.adornUrl("/prodect/brand/update/status"),
        method: "post",
        data: this.$http.adornData({ brandId, showStatus }, false)
      }).then(({ data }) => {
        this.$message({
          type: "success",
          message: "状态更新成功"
        });
      });
    },
    // 每页数
    sizeChangeHandle(val) {
      this.pageSize = val;
      this.pageIndex = 1;
      this.getDataList();
    },
    // 当前页
    currentChangeHandle(val) {
      this.pageIndex = val;
      this.getDataList();
    },
    // 多选
    selectionChangeHandle(val) {
      this.dataListSelections = val;
    },
    // 新增 / 修改
    addOrUpdateHandle(id) {
      this.addOrUpdateVisible = true;
      this.$nextTick(() => {
        this.$refs.addOrUpdate.init(id);
      });
    },
    // 删除
    deleteHandle(id,name) {
      var ids = id
        ? [id]
        : this.dataListSelections.map(item => {
            return item.brandId;
          });
      var names = name
        ? [name]
        : this.dataListSelections.map(item => {
            return item.name;
          });
      this.$confirm(
        `确定对品牌=[${names.join(",")}]进行[${
          name ? "删除" : "批量删除"
        }]操作?`,
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }
      ).then(() => {
        this.$http({
          url: this.$http.adornUrl("/prodect/brand/delete"),
          method: "post",
          data: this.$http.adornData(ids, false)
        }).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message({
              message: "操作成功",
              type: "success",
              duration: 1500,
              onClose: () => {
                this.getDataList();
              }
            });
          } else {
            this.$message.error(data.msg);
          }
        });
      });
    }
  }
};
</script>

common文件夹增加category-cascader.vue文件,详情如下:

<template>
<!-- 
使用说明:
1)、引入category-cascader.vue
2)、语法:<category-cascader :catelogPath.sync="catelogPath"></category-cascader>
    解释:
      catelogPath:指定的值是cascader初始化需要显示的值,应该和父组件的catelogPath绑定;
          由于有sync修饰符,所以cascader路径变化以后自动会修改父的catelogPath,这是结合子组件this.$emit("update:catelogPath",v);做的
      -->
  <div>
    <el-cascader
      filterable
      clearable 
      placeholder="试试搜索:手机"
      v-model="paths"
      :options="categorys"
      :props="setting"
    ></el-cascader>
  </div>
</template>

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

export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  //接受父组件传来的值
  props: {
    catelogPath: {
      type: Array,
      default(){
        return [];
      }
    }
  },
  data() {
    //这里存放数据
    return {
      setting: {
        value: "catId",
        label: "name",
        children: "children"
      },
      categorys: [],
      paths: this.catelogPath
    };
  },
  watch:{
    catelogPath(v){
      this.paths = this.catelogPath;
    },
    paths(v){
      this.$emit("update:catelogPath",v);
      //还可以使用pubsub-js进行传值
      this.PubSub.publish("catPath",v);
    }
  },
  //方法集合
  methods: {
    getCategorys() {
      this.$http({
        url: this.$http.adornUrl("/prodect/category/list/tree"),
        method: "get"
      }).then(({ data }) => {
        this.categorys = data.data;
      });
    }
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {
    this.getCategorys();
  }
};
</script>
<style scoped>
</style>

二.后端添加品牌分类关联代码

以下后端代码完成了两个功能:

  • 品牌分类关联的查看,新增,修改,删除功能
  • 修改品牌或者分类数据,会同步品牌分类关联的冗余数据

CategoryBrandRelationController类详情如下:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
//import org.apache.shiro.authz.annotation.RequiresPermissions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.jiejie.webshop.prodect.entity.CategoryBrandRelationEntity;
import com.jiejie.webshop.prodect.service.CategoryBrandRelationService;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.common.utils.R;


/**
 * 品牌分类关联
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
@RestController
@RequestMapping("prodect/categorybrandrelation")
public class CategoryBrandRelationController {
    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    /**
     * 列表
     */
    @GetMapping("/catelog/list")
    //@RequiresPermissions("prodect:categorybrandrelation:list")
    public R catelogList(@RequestParam("brandId") Long brandId) {
        List<CategoryBrandRelationEntity> categoryBrandRelationEntities = categoryBrandRelationService.list(
                new QueryWrapper<CategoryBrandRelationEntity>().eq("brand_id", brandId));
        return R.ok().put("data", categoryBrandRelationEntities);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    //@RequiresPermissions("prodect:categorybrandrelation:info")
    public R info(@PathVariable("id") Long id) {
        CategoryBrandRelationEntity categoryBrandRelation = categoryBrandRelationService.getById(id);
        return R.ok().put("categoryBrandRelation", categoryBrandRelation);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("prodect:categorybrandrelation:save")
    public R save(@RequestBody CategoryBrandRelationEntity categoryBrandRelation) {
        categoryBrandRelationService.insertCategoryBrandRelationEntity(categoryBrandRelation);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //@RequiresPermissions("prodect:categorybrandrelation:update")
    public R update(@RequestBody CategoryBrandRelationEntity categoryBrandRelation) {
        categoryBrandRelationService.updateById(categoryBrandRelation);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    //@RequiresPermissions("prodect:categorybrandrelation:delete")
    public R delete(@RequestBody Long[] ids) {
        categoryBrandRelationService.removeByIds(Arrays.asList(ids));
        return R.ok();
    }
}

CategoryBrandRelationService类详情如下:

package com.jiejie.webshop.prodect.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.webshop.prodect.entity.CategoryBrandRelationEntity;
import sun.util.resources.ga.LocaleNames_ga;

import java.util.Map;

/**
 * 品牌分类关联
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
public interface CategoryBrandRelationService extends IService<CategoryBrandRelationEntity> {

    PageUtils queryPage(Map<String, Object> params);

    /**
     * 新增品牌分类关联
     *
     * @param categoryBrandRelation
     */
    void insertCategoryBrandRelationEntity(CategoryBrandRelationEntity categoryBrandRelation);

    /**
     * 通过品牌id更新品牌名称
     *
     * @param brandName
     * @param brandId
     */
    void updateBrandNameByBrandId(String brandName, Long brandId);

    /**
     * 通过分类id更新分类名称
     *
     * @param catelogName
     * @param catelogId
     */
    void updateCatelogNameByCatelogId(String catelogName, Long catelogId);
}

CategoryBrandRelationServiceImpl类详情如下:

package com.jiejie.webshop.prodect.service.impl;

import com.jiejie.webshop.prodect.dao.BrandDao;
import com.jiejie.webshop.prodect.dao.CategoryDao;
import com.jiejie.webshop.prodect.entity.BrandEntity;
import com.jiejie.webshop.prodect.entity.CategoryEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.common.utils.Query;

import com.jiejie.webshop.prodect.dao.CategoryBrandRelationDao;
import com.jiejie.webshop.prodect.entity.CategoryBrandRelationEntity;
import com.jiejie.webshop.prodect.service.CategoryBrandRelationService;


@Service("categoryBrandRelationService")
public class CategoryBrandRelationServiceImpl extends ServiceImpl<CategoryBrandRelationDao, CategoryBrandRelationEntity> implements CategoryBrandRelationService {

    @Autowired
    private BrandDao brandDao;
    @Autowired
    private CategoryDao categoryDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryBrandRelationEntity> page = this.page(
                new Query<CategoryBrandRelationEntity>().getPage(params),
                new QueryWrapper<CategoryBrandRelationEntity>()
        );

        return new PageUtils(page);
    }


    @Override
    public void insertCategoryBrandRelationEntity(CategoryBrandRelationEntity categoryBrandRelation) {
        Long brandId = categoryBrandRelation.getBrandId();
        Long catelogId = categoryBrandRelation.getCatelogId();
        BrandEntity brandEntity = brandDao.selectById(brandId);
        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        categoryBrandRelation.setBrandName(brandEntity.getName());
        categoryBrandRelation.setCatelogName(categoryEntity.getName());
        this.save(categoryBrandRelation);
    }

    @Override
    public void updateBrandNameByBrandId(String brandName, Long brandId) {
        this.baseMapper.updateBrandNameByBrandId(brandName, brandId);
    }


    @Override
    public void updateCatelogNameByCatelogId(String catelogName, Long catelogId) {
        this.baseMapper.updateCatelogNameByCatelogId(catelogName, catelogId);
    }
}

CategoryBrandRelationDao类详情如下:

package com.jiejie.webshop.prodect.dao;

import com.jiejie.webshop.prodect.entity.CategoryBrandRelationEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 * 品牌分类关联
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
@Mapper
public interface CategoryBrandRelationDao extends BaseMapper<CategoryBrandRelationEntity> {
    /**
     * 通过品牌id更新品牌名称
     *
     * @param brandName
     * @param brandId
     */
    void updateBrandNameByBrandId(@Param("brandName") String brandName, @Param("brandId") Long brandId);

    /**
     * 通过分类id更新分类名称
     *
     * @param catelogName
     * @param catelogId
     */
    void updateCatelogNameByCatelogId(@Param("catelogName") String catelogName, @Param("catelogId") Long catelogId);
}

CategoryBrandRelationDao.xml文件详情如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.jiejie.webshop.prodect.dao.CategoryBrandRelationDao">

    <!-- 可根据自己的需求,是否要使用 -->
    <resultMap type="com.jiejie.webshop.prodect.entity.CategoryBrandRelationEntity" id="categoryBrandRelationMap">
        <result property="id" column="id"/>
        <result property="brandId" column="brand_id"/>
        <result property="catelogId" column="catelog_id"/>
        <result property="brandName" column="brand_name"/>
        <result property="catelogName" column="catelog_name"/>
    </resultMap>


    <select id="updateBrandNameByBrandId">
       update pms_category_brand_relation set  brand_name=#{brandName} where brand_id=#{brandId}
    </select>

    <select id="updateCatelogNameByCatelogId">
       update pms_category_brand_relation set  catelog_name=#{catelogName} where catelog_id=#{catelogId}
    </select>
</mapper>

BrandController类详情如下:

package com.jiejie.webshop.prodect.controller;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

//import org.apache.shiro.authz.annotation.RequiresPermissions;
import com.jiejie.common.valid.AddGroup;
import com.jiejie.common.valid.UpdateGroup;
import com.jiejie.common.valid.UpdateStatusGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.jiejie.webshop.prodect.entity.BrandEntity;
import com.jiejie.webshop.prodect.service.BrandService;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.common.utils.R;

import javax.validation.Valid;


/**
 * 品牌
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
@RestController
@RequestMapping("prodect/brand")
public class BrandController {
    @Autowired
    private BrandService brandService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    //@RequiresPermissions("prodect:brand:list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = brandService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{brandId}")
    //@RequiresPermissions("prodect:brand:info")
    public R info(@PathVariable("brandId") Long brandId) {
        BrandEntity brand = brandService.getById(brandId);

        return R.ok().put("brand", brand);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    //@RequiresPermissions("prodect:brand:save")
    public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand) {
        brandService.save(brand);
        return R.ok();
    }

    /**
     * 修改
     */
    @PostMapping("/update")
    //@RequiresPermissions("prodect:brand:update")
    public R updateBrandEntity(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand) {
        brandService.updateBrandEntity(brand);
        return R.ok();
    }

    /**
     * 更新品牌状态
     */
    @PostMapping("/update/status")
    //@RequiresPermissions("prodect:brand:update")
    public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody BrandEntity brand) {
        brandService.updateById(brand);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    //@RequiresPermissions("prodect:brand:delete")
    public R delete(@RequestBody Long[] brandIds) {
        brandService.removeByIds(Arrays.asList(brandIds));

        return R.ok();
    }
}

BrandService类详情如下:

package com.jiejie.webshop.prodect.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.webshop.prodect.entity.BrandEntity;

import java.util.Map;

/**
 * 品牌
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
public interface BrandService extends IService<BrandEntity> {

    PageUtils queryPage(Map<String, Object> params);

    /**
     * 更新品牌信息
     *
     * @param brand
     */
    void updateBrandEntity(BrandEntity brand);
}

BrandServiceImpl类详情如下:

package com.jiejie.webshop.prodect.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.common.utils.Query;
import com.jiejie.webshop.prodect.dao.BrandDao;
import com.jiejie.webshop.prodect.entity.BrandEntity;
import com.jiejie.webshop.prodect.service.BrandService;
import com.jiejie.webshop.prodect.service.CategoryBrandRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;


@Service("brandService")
public class BrandServiceImpl extends ServiceImpl<BrandDao, BrandEntity> implements BrandService {

    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        //获取到key
        String key = (String) params.get("key");
        QueryWrapper<BrandEntity> queryWrapper = new QueryWrapper<>();
        //如果搜索的key不为null,那么就模糊匹配出id相同或者品牌名称相同的数据
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.eq("brand_Id", key).or().like("name", key);
        }
        IPage<BrandEntity> page = this.page(
                new Query<BrandEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }


    @Override
    public void updateBrandEntity(BrandEntity brand) {
        //更新品牌信息
        this.updateById(brand);
        //更新品牌分类关联表信息,因为存了冗余字段,所以得保证冗余字段的数据一致
        categoryBrandRelationService.updateBrandNameByBrandId(brand.getName(), brand.getBrandId());
        //todo 其他关联表
    }
}

CategoryController类详情如下:

package com.jiejie.webshop.prodect.controller;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

//import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.jiejie.webshop.prodect.entity.CategoryEntity;
import com.jiejie.webshop.prodect.service.CategoryService;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.common.utils.R;


/**
 * 商品三级分类
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
@RestController
@RequestMapping("prodect/category")
public class CategoryController {
    @Autowired
    private CategoryService categoryService;

    /**
     * 获取树形结构商品分类
     */
    @GetMapping("/list/tree")
    //@RequiresPermissions("prodect:category:list")
    public R getCategoryforTree() {
        List<CategoryEntity> categoryEntities = categoryService.getListToTree();
        return R.ok().put("data", categoryEntities);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{catId}")
    //@RequiresPermissions("prodect:category:info")
    public R info(@PathVariable("catId") Long catId) {
        CategoryEntity category = categoryService.getById(catId);
        return R.ok().put("data", category);
    }

    /**
     * 新增
     */
    @RequestMapping("/save")
    //@RequiresPermissions("prodect:category:save")
    public R save(@RequestBody CategoryEntity category) {
        categoryService.save(category);
        return R.ok();
    }

    /**
     * 拖拽功能,批量修改分类排序
     */
    @RequestMapping("/update/sort")
    //@RequiresPermissions("prodect:category:update")
    public R updateSort(@RequestBody CategoryEntity[] categories) {
        categoryService.updateBatchById(Arrays.asList(categories));
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //@RequiresPermissions("prodect:category:update")
    public R updateCategoryEntity(@RequestBody CategoryEntity category) {
        categoryService.updateCategoryEntity(category);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")

    //@RequiresPermissions("prodect:category:delete")
    public R delete(@RequestBody Long[] catIds) {
        categoryService.removeMenusByIds(Arrays.asList(catIds));
        return R.ok();
    }
}

CategoryService类详情如下:

package com.jiejie.webshop.prodect.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.webshop.prodect.entity.CategoryEntity;

import java.util.List;
import java.util.Map;

/**
 * 商品三级分类
 *
 * @author ${author}
 * @email jiejie@gmail.com
 * @date 2020-06-02 23:44:05
 */
public interface CategoryService extends IService<CategoryEntity> {

    PageUtils queryPage(Map<String, Object> params);

    /**
     * 获取树形结构商品分类
     *
     * @return
     */
    List<CategoryEntity> getListToTree();

    /**
     * 删除商品分类
     *
     * @param catIds
     */
    void removeMenusByIds(List<Long> catIds);

    /**
     * 获取所属分类的完整路径
     *
     * @param catelogId
     * @return
     */
    Long[] findCatelogPath(Long catelogId);

    /**
     * 更新分类信息
     *
     * @param category
     */
    void updateCategoryEntity(CategoryEntity category);
}

CategoryServiceImpl类详情如下:

package com.jiejie.webshop.prodect.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiejie.common.utils.PageUtils;
import com.jiejie.common.utils.Query;
import com.jiejie.webshop.prodect.dao.CategoryDao;
import com.jiejie.webshop.prodect.entity.CategoryEntity;
import com.jiejie.webshop.prodect.service.CategoryBrandRelationService;
import com.jiejie.webshop.prodect.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> getListToTree() {
        //1.获取所有分类数据
        List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
        //2.组装成树形结构
        //2.1).先找到所有的一级分类,然后继续设置分类下的子分类,最后排序,归约
        List<CategoryEntity> firstLevelMenu = categoryEntities.stream()
                .filter(categoryEntity -> categoryEntity.getParentCid() == 0)
                .map((menu) -> {
                    menu.setChildren(getChildrens(categoryEntities, menu));
                    return menu;
                })
                .sorted((menu1, menu2) -> {
                    return (menu1.getSort() == null ? 0 : menu1.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
                })
                .collect(Collectors.toList());
        return firstLevelMenu;
    }

    /**
     * 递归设置各级子菜单
     *
     * @param all  所有的分类数据
     * @param root 一级菜单
     * @return
     */
    private List<CategoryEntity> getChildrens(List<CategoryEntity> all, CategoryEntity root) {
        List<CategoryEntity> children = all.stream()
                .filter(categoryEntity -> categoryEntity.getParentCid().equals(root.getCatId()))
                .map(categoryEntity -> {
                    //递归设置子菜单
                    categoryEntity.setChildren(getChildrens(all, categoryEntity));
                    return categoryEntity;
                })
                .sorted((menu1, menu2) -> {
                    return (menu1.getSort() == null ? 0 : menu1.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
                })
                .collect(Collectors.toList());
        return children;
    }

    @Override
    public void removeMenusByIds(List<Long> catIds) {
        //todo 如果被删除的分类菜单有被引用,则给出阻拦
        //逻辑删除商品分类
        baseMapper.deleteBatchIds(catIds);
    }

    private List<Long> findParentPath(Long catelogId, List<Long> paths) {
        //收集当前节点id
        paths.add(catelogId);
        CategoryEntity byId = this.getById(catelogId);
        if (byId.getParentCid() != 0) {
            //递归调用,添加节点
            findParentPath(byId.getParentCid(), paths);
        }
        return paths;
    }

    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> paths = new ArrayList<>();
        //调用findParentPath方法添加各级节点
        List<Long> parentPath = findParentPath(catelogId, paths);
        //反转数据,才是正确的顺序
        Collections.reverse(parentPath);
        //转为数组返回
        return parentPath.toArray(new Long[parentPath.size()]);
    }

    @Override
    public void updateCategoryEntity(CategoryEntity category) {
        //更新分类信息
        this.updateById(category);
        //更新品牌分类关联表信息,因为存了冗余字段,所以得保证冗余字段的数据一致
        categoryBrandRelationService.updateCatelogNameByCatelogId(category.getName(), category.getCatId());
        //todo 其他关联表
    }
}

三.测试效果

修改前品牌分类关联列表展示:
在这里插入图片描述
修改手机分类名称改为手机1,品牌名称华为改为华为1:
在这里插入图片描述

增加品牌分类关联成功。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值