当前位置: 首页 > article >正文

014 属性分组

文章目录

    • 后端
      • AttrGroupEntity.java
      • CategoryEntity.java
      • AttrGroupController.java
      • CategoryServiceImpl.java
    • 前端
      • attrgroup-add-or-update.vue

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

后端

AttrGroupEntity.java

package com.xd.cubemall.product.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;
import lombok.Data;

/**
 * 属性分组表
 * 
 * @author xuedong
 * @email email@gmail.com
 * @date 2024-08-13 01:36:04
 */
@Data
@TableName("tb_attr_group")
public class AttrGroupEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 自增ID
	 */
	@TableId
	private Long id;
	/**
	 * 名称
	 */
	private String name;
	/**
	 * 排序
	 */
	private Integer sort;
	/**
	 * 描述
	 */
	private String descript;
	/**
	 * 图表
	 */
	private String icon;
	/**
	 * 分类ID
	 */
	private Integer categoryId;

	/**
	 * 完整的categoryID的路径
	 */
	@TableField(exist = false)
	private Long[] categoryPath;
}

CategoryEntity.java

package com.xd.cubemall.product.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

/**
 * 商品类目
 * 
 * @author xuedong
 * @email email@gmail.com
 * @date 2024-08-13 01:36:04
 */
@Data
@TableName("tb_category")
public class CategoryEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 子分类
	 */
	@JsonInclude(JsonInclude.Include.NON_EMPTY)
	@TableField(exist = false)
	private List<CategoryEntity> childrens;

	/**
	 * 分类ID
	 */
	@TableId
	private Integer id;
	/**
	 * 分类名称
	 */
	private String name;
	/**
	 * 商品数量
	 */
	private Integer goodsNum;
	/**
	 * 是否显示
	 */
	@TableLogic(value = "1",delval = "0")
	private String isShow;
	/**
	 * 是否导航
	 */
	private String isMenu;
	/**
	 * 排序
	 */
	private Integer seq;
	/**
	 * 上级ID
	 */
	private Integer parentId;
	/**
	 * 模板ID
	 */
	private Integer templateId;

}

AttrGroupController.java

package com.xd.cubemall.product.controller;

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


import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.product.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.xd.cubemall.product.entity.AttrGroupEntity;
import com.xd.cubemall.product.service.AttrGroupService;




/**
 * 属性分组表
 *
 * @author xuedong
 * @email email@gmail.com
 * @date 2024-08-13 07:57:20
 */
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {
    @Autowired
    private AttrGroupService attrGroupService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 列表
     */
    @RequestMapping("/list/{categoryId}")
    //@RequiresPermissions("product:attrgroup:list")
    public R list(@RequestParam Map<String, Object> params, @PathVariable("categoryId") Long categoryId){
        //PageUtils page = attrGroupService.queryPage(params);
        PageUtils page = attrGroupService.queryPage(params, categoryId);
        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    //@RequiresPermissions("product:attrgroup:info")
    public R info(@PathVariable("id") Long id){
		AttrGroupEntity attrGroup = attrGroupService.getById(id);
        //查询出categoryPath的路径
        //当前分类ID
        Integer categoryId = attrGroup.getCategoryId();
        //查询出当前分类ID的 祖宗ID
        Long[] path = categoryService.findCategoryPath(categoryId);
        attrGroup.setCategoryPath(path);
        return R.ok().put("attrGroup", attrGroup);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:attrgroup:save")
    public R save(@RequestBody AttrGroupEntity attrGroup){
		attrGroupService.save(attrGroup);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //@RequiresPermissions("product:attrgroup:update")
    public R update(@RequestBody AttrGroupEntity attrGroup){
		attrGroupService.updateById(attrGroup);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    //@RequiresPermissions("product:attrgroup:delete")
    public R delete(@RequestBody Long[] ids){
		attrGroupService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}

CategoryServiceImpl.java

package com.xd.cubemall.product.service.impl;

import com.xd.cubemall.common.utils.PageUtils;
import com.xd.cubemall.common.utils.Query;
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;

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.xd.cubemall.product.dao.CategoryDao;
import com.xd.cubemall.product.entity.CategoryEntity;
import com.xd.cubemall.product.service.CategoryService;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @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);
    }


    /**
     * 查询所有分类
     * @return
     */
    @Override
    public List<CategoryEntity> listWithTree() {
        //1.查询所有分类
        List<CategoryEntity> entities = baseMapper.selectList(null);

        //2.组装成父子的树形结构
        //2.1 找到所有的一级分类
        List<CategoryEntity> levelOneMenus = entities.stream().filter(
            //过滤出一级分类,parentId==0,根据这个条件构建出所有一级分类的数据
                categoryEntity -> categoryEntity.getParentId() == 0

        ).map((menu)->{
            //出现递归操作,关联出子分类(2,3级分类)
            menu.setChildrens(getChildrens(menu,entities));
            return menu;
        }).collect(Collectors.toList());
        return levelOneMenus;
    }

    /**
     * 递归查找指定分类的所有子分类(所有菜单的子菜单)
     * @param currentMenu
     * @param entities
     * @return
     */
    private List<CategoryEntity> getChildrens(CategoryEntity currentMenu, List<CategoryEntity> entities) {
        List<CategoryEntity> childrens = entities.stream().filter(
            //过滤出 当前菜单的所有匹配的子菜单 currentMenu.id == categoryEntity.parentId
                categoryEntity -> currentMenu.getId().equals(categoryEntity.getParentId())

        ).map((menu)->{
            //找到子分类
            menu.setChildrens(getChildrens(menu,entities));
            return menu;
        }).collect(Collectors.toList());

        return childrens;
    }

    /**
     * 逻辑删除菜单
     * @param asList
     */
    @Override
    public void removeMenuByIds(List<Integer> asList) {
        //TODO 检查当前要删除的菜单是否被别的地方引用
        //逻辑删除
        baseMapper.deleteBatchIds(asList);
    }

    /**
     * 收集三级菜单id
     * @param categoryId
     * @return [558, 559, 560]
     */
    @Override
    public Long[] findCategoryPath(Integer categoryId) {
        List<Long> paths = new ArrayList<>();
        //通过递归查询到 把当前分类id与父分类id 添加到paths集合中
        List<Long> parentPath = findParentPath(categoryId, paths);

        Collections.reverse(parentPath);
        return parentPath.toArray(new Long[parentPath.size()]);
    }


    /**
     * 递归收集菜单id
     * @param categoryId
     * @param paths
     * @return [560, 559, 558]
     */
    private List<Long> findParentPath(Integer categoryId, List<Long> paths) {
        //收集当前分类id到集合中
        paths.add(categoryId.longValue());
        CategoryEntity categoryEntity = this.getById(categoryId);
        if (categoryEntity.getParentId() != 0){
            findParentPath(categoryEntity.getParentId(), paths);
        }
        return paths;
    }
}

前端

attrgroup-add-or-update.vue


<template>
  <el-dialog
    :title="!dataForm.id ? '新增' : '修改'"
    :close-on-click-modal="false"
    :visible.sync="visible"
  >
    <el-form
      :model="dataForm"
      :rules="dataRule"
      ref="dataForm"
      @keyup.enter.native="dataFormSubmit()"
      label-width="130px"
    >
      <el-form-item label="名称" prop="name">
        <el-input v-model="dataForm.name" placeholder="名称"></el-input>
      </el-form-item>
      <el-form-item label="排序" prop="sort">
        <el-input v-model="dataForm.sort" placeholder="排序"></el-input>
      </el-form-item>
      <el-form-item label="描述" prop="descript">
        <el-input v-model="dataForm.descript" placeholder="描述"></el-input>
      </el-form-item>
      <el-form-item label="图表" prop="icon">
        <el-input v-model="dataForm.icon" placeholder="图表"></el-input>
      </el-form-item>
      <el-form-item label="分类ID" prop="categoryId">
        <!-- <el-input v-model="dataForm.categoryId" placeholder="分类ID"></el-input> -->
        <el-cascader
          v-model="dataForm.categoryPath"
          :options="categorys"
          :props="props"
        ></el-cascader>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="visible = false">取消</el-button>
      <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      props:{
        value: "id",
        label: "name",
        children: "childrens"
      },
      categorys: [],
      visible: false,
      dataForm: {
        id: 0,
        name: "",
        sort: "",
        descript: "",
        icon: "",
        categoryPath: [],
        categoryId: 0,
      },
      dataRule: {
        name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
        sort: [{ required: true, message: "排序不能为空", trigger: "blur" }],
        descript: [
          { required: true, message: "描述不能为空", trigger: "blur" },
        ],
        icon: [{ required: true, message: "图表不能为空", trigger: "blur" }],
        categoryId: [
          { required: true, message: "分类ID不能为空", trigger: "blur" },
        ],
      },
    };
  },
  created(){
    this.getCategorys()
  },
  methods: {
    // 查询分类菜单
    getCategorys() {
      this.$http({
        url: this.$http.adornUrl("/product/category/list/tree"),
        method: "get",
      }).then(({ data }) => {
        console.log("成功获取到了菜单数据...", data);
        this.categorys = data.data;
      });
    },

    init(id) {
      this.dataForm.id = id || 0;
      this.visible = true;
      this.$nextTick(() => {
        this.$refs["dataForm"].resetFields();
        if (this.dataForm.id) {
          this.$http({
            url: this.$http.adornUrl(
              `/product/attrgroup/info/${this.dataForm.id}`
            ),
            method: "get",
            params: this.$http.adornParams(),
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.dataForm.name = data.attrGroup.name;
              this.dataForm.sort = data.attrGroup.sort;
              this.dataForm.descript = data.attrGroup.descript;
              this.dataForm.icon = data.attrGroup.icon;
              this.dataForm.categoryId = data.attrGroup.categoryId;
              //查询categoryID的完整菜单
              this.dataForm.categoryPath = data.attrGroup.categoryPath

            }
          });
        }
      });
    },
    // 表单提交
    dataFormSubmit() {
      this.$refs["dataForm"].validate((valid) => {
        if (valid) {
          this.$http({
            url: this.$http.adornUrl(
              `/product/attrgroup/${!this.dataForm.id ? "save" : "update"}`
            ),
            method: "post",
            data: this.$http.adornData({
              id: this.dataForm.id || undefined,
              name: this.dataForm.name,
              sort: this.dataForm.sort,
              descript: this.dataForm.descript,
              icon: this.dataForm.icon,
              categoryId: this.dataForm.categoryPath[this.dataForm.categoryPath.length-1],
            }),
          }).then(({ data }) => {
            if (data && data.code === 0) {
              this.$message({
                message: "操作成功",
                type: "success",
                duration: 1500,
                onClose: () => {
                  this.visible = false;
                  this.$emit("refreshDataList");
                },
              });
            } else {
              this.$message.error(data.msg);
            }
          });
        }
      });
    },
  },
};
</script>



http://www.kler.cn/news/342865.html

相关文章:

  • 牛客SQL29详解 计算用户的平均次日留存率
  • MySQL数据库表分区
  • DBO-BP回归预测 | MATLAB实现DBO-BP蜣螂优化算法优化神经网络多输入单输出回归预测
  • 20241011给荣品RD-RK3588-AHD开发板刷荣品预编译的Buildroot之后打开AP6275P的BT【命令行】
  • 单通道 LVDS 差分线路接收器MS21112S
  • 10.10 工作笔记
  • go 的 timer reset
  • 报错笔记
  • 基于模型的强化学习方法4大类灌水范式
  • 分布式常见面试题总结
  • 视频如何转换mp4模式?格式转换软件带你高清无损一秒转换
  • 猫头虎分享:Python库 Django 的简介、安装、用法详解入门教程
  • CANoe_调用C#控件的方法_DEMO方法演示
  • R知识图谱1—tidyverse玩转数据处理120题
  • 在 Linux 上使用 GPG 加解密文件
  • html渲染优先级
  • MySQL(B站CodeWithMosh)——2024.10.4(7)
  • Vue组件库Element-ui
  • vscode显示.vscode文件
  • 【linux开发-Qt】-信号与槽机制