1 category.vue
批量保存
批量删除
{{ node.label }}
append(data)"
>添加
编辑
remove(node, data)"
>删除
1 gulimall-gateway 配置路由
# 当访问 /api/product/** ,则负载均衡路由到 gulimall-product 服务的 /product 后端管理系统
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
# 过滤器实现路径重写功能:将 /api/** 重写为 /**,即去掉 api 前缀
- RewritePath=/api/(?.*),/$\{segment}
2 guli-product 在bootstrap.properties中配置nacos注册中心地址
spring.application.name=gulimall-product
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=c8294b4e-0f13-496e-98d7-5172ba0db9e2
3 guli-product 的application.yml配置
spring:
datasource:
username: root
password: root
url: jdbc:mysql://192.168.0.110:3306/gulimall_pms
driver-class-name: com.mysql.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # 配置nacos注册中心地址
jackson:
date-format: yyyy-MM-dd HH:mm:ss
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
# 逻辑删除全局配置:1表示删除值
logic-delete-value: 1
# 逻辑删除全局配置:0表示未删除值
logic-not-delete-value: 0
server:
port: 10000
logging:
level:
# 调成debug后,可打印SQL语句
com.atguigu.gulimall: debug
4 CategoryEntity实现
package com.atguigu.gulimall.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 com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @className: CategoryEntity
* @description: 商品三级分类实体类
* @date: 2020/10/25
* @author: cakin
*/
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 分类id
*/
@TableId
private Long catId;
/**
* 分类名称
*/
private String name;
/**
* 父分类id
*/
private Long parentCid;
/**
* 层级
*/
private Integer catLevel;
/**
* 逻辑删除注解,value = "1":表示未删除值,delval = "0":表示删除值,配置这个的目的是覆盖全局配置,因为全局配置和这个相反
* 是否显示[0-不显示,1显示]
*/
@TableLogic(value = "1", delval = "0")
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 图标地址
*/
private String icon;
/**
* 计量单位
*/
private String productUnit;
/**
* 商品数量
*/
private Integer productCount;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false) // 表示该字段在数据库中不存在,存储某个分类的子分类
private List children;
}
5 控制器实现
package com.atguigu.gulimall.product.controller;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.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.RestController;
import java.util.Arrays;
import java.util.List;
/**
* @className: CategoryController
* @description: 商品三级分类
* @date: 2020/10/25
* @author: cakin
*/
@RestController
@RequestMapping("product/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 功能描述:查出所有分类以及子分类,以树形结构组装起来
*
* @return R 返回给前端数据
* @author cakin
* @date 2020/10/25
* @description:
*/
@RequestMapping("/list/tree")
public R list() {
List entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
/**
* 信息
*/
@RequestMapping("/info/{catId}")
public R info(@PathVariable("catId") Long catId) {
CategoryEntity category = categoryService.getById(catId);
return R.ok().put("data", category);
}
/**
* 保存
*/
@RequestMapping("/save")
public R save(@RequestBody CategoryEntity category) {
categoryService.save(category);
return R.ok();
}
/**
* 功能描述:批量更新分类列表
*
* @author cakin
* @date 2020/10/26
* @param category 分类数组
* @return R 返回给前端的数据
*/
@RequestMapping("/update/sort")
public R updateSort(@RequestBody CategoryEntity[] category) {
categoryService.updateBatchById(Arrays.asList(category));
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody CategoryEntity category) {
categoryService.updateCascade(category);
return R.ok();
}
/**
* 功能描述:删除分类
*
* @param catIds 待删除分类id列表
* @return R 返回给前端的数据
* @author cakin
* @date 2020/10/25
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] catIds) {
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok();
}
}
6 实现类实现
package com.atguigu.gulimall.product.service.impl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryBrandRelationService;
import com.atguigu.gulimall.product.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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 implements CategoryService {
@Autowired
CategoryBrandRelationService categoryBrandRelationService;
@Override
public PageUtils queryPage(Map params) {
IPage page = this.page(
new Query().getPage(params),
new QueryWrapper()
);
return new PageUtils(page);
}
/**
* 功能描述:查出所有分类以及子分类,以树形结构组装起来
*
* @author cakin
* @date 2020/10/25
* @return List:树形结构列表返回父子结构
* @description:
*/
@Override
public List listWithTree() {
// 1 查出所有分类
List entities = baseMapper.selectList(null);
// 2 组装成父子的树形结构
// 2.1 找到所有的一级分类
List level1Menus = entities.stream()
.filter(categoryEntity -> categoryEntity.getParentCid() == 0) // 过滤一级分类
.map((menu) -> {
menu.setChildren(getChildrens(menu, entities));
return menu;
}) // 设置一级二类的孩子
.sorted((menu1, menu2) -> {
return (menu1.getSort() == null ? 0 : menu1.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
}) // 给一级分类排序
.collect(Collectors.toList());
// 2.2 返回一级分类列表
return level1Menus;
}
/**
* 功能描述:实现逻辑批量删除
*
* @author cakin
* @date 2020/10/25
* @param asList 批量删除id列表
*/
@Override
public void removeMenuByIds(List asList) {
// TODO 检查当前删除的菜单,是否被别的地方引用
// 逻辑删除
baseMapper.deleteBatchIds(asList);
}
//[2,25,225]
@Override
public Long[] findCatelogPath(Long catelogId) {
List paths = new ArrayList<>();
List parentPath = findParentPath(catelogId, paths);
Collections.reverse(parentPath);
return parentPath.toArray(new Long[parentPath.size()]);
}
/**
* 级联更新所有关联的数据
*
* @param category
*/
@Transactional
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category);
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
}
//225,25,2
private List findParentPath(Long catelogId, List paths) {
//1、收集当前节点id
paths.add(catelogId);
CategoryEntity byId = this.getById(catelogId);
if (byId.getParentCid() != 0) {
findParentPath(byId.getParentCid(), paths);
}
return paths;
}
/**
* 功能描述:递归查找某个菜单的子菜单
*
* @param root 当前菜单
* @param all 所有分类
* @return List 当前菜单的子菜单列表
* @author cakin
* @date 2020/10/23
*/
private List getChildrens(CategoryEntity root, List all) {
// 当前菜单的子菜单列表
List children = all.stream()
.filter(categoryEntity -> {
return categoryEntity.getParentCid() == root.getCatId();
}) // 找出了二级菜单
.map(categoryEntity -> {
// 1 找到子菜单
categoryEntity.setChildren(getChildrens(categoryEntity, all));
return categoryEntity;
}) // 为二级菜单找到它的三级子菜单列表
.sorted((menu1, menu2) -> {
// 2 菜单的排序
return (menu1.getSort() == null ? 0 : menu1.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
}) // 二级菜单排序
.collect(Collectors.toList());
return children;
}
}
1 vue的相关模板
{
"Print to console": {
"prefix": "vue",
"body": [
"",
"",
"$5",
"",
"",
"",
""
],
"description": "Log output to console"
},
"http-get请求": {
"prefix": "httpget",
"body": [
"this.\\$http({",
"url: this.\\$http.adornUrl(''),",
"method: 'get',",
"params: this.\\$http.adornParams({})",
"}).then(({ data }) => {",
"})"
],
"description": "httpGET请求"
},
"http-post请求": {
"prefix": "httppost",
"body": [
"this.\\$http({",
"url: this.\\$http.adornUrl(''),",
"method: 'post',",
"data: this.\\$http.adornData(data, false)",
"}).then(({ data }) => { });"
],
"description": "httpPOST请求"
}
}