文章目录
- 1.前端展示分类管理信息
- 1.目前项目架构
- 2.启动前后端项目
- 1.启动mysql容器
- 2.启动后端 renren-fast
- 3.启动前端
- 1.界面
- 2.用户名密码都是admin
- 3.创建分类管理菜单
- 1.菜单管理 -> 新增 -> 新增目录
- 2.刷新
- 3.能够新增菜单的原因是前端脚手架与renren-fast后端脚手架通信,这个菜单的表是 sys_menu
- 4.新增分类管理菜单
- 5.关于这个分类管理的路由解析
- 1.由于设置的菜单路由是commodity/category,所以点击这个菜单就会查找前端项目的renren-fast-vue\src\views\modules\commodity\category.vue
- 2.一般这个菜单路由是对应于后端的一个controller的前缀
- 3.而后端controller的前缀是根据表来自动生成的
- 4.总结:代码生成器会根据一个表来生成一个controller,一个前端菜单界面
- 6.将生成的commodity文件夹下面的两个文件放到前端项目的modules下
- 7.分析category.vue
- 1.找到向后端发送请求的位置
- 2.进入adornUrl
- 3.进入baseUrl
- 4.浏览器测试请求一下
- 5.注销掉这个url,自己写一个
- 6.启动后端的sunliving-commodity模块
- 7.再次点击分类管理菜单,发现出现跨域错误
- 8.跨域问题解决
- 1.复制renren-fast模块的src/main/java/io/renren/config/CorsConfig.java
- 2.粘贴到sunliving-commodity模块下
- 3.重启后端sunliving-commodity
- 4.再次点击分类管理
- 2.使用树形菜单展示分类(初级)
- 1.思路分析
- 2.首先返回所有记录(没有层级)
- 1.com/sun/sunliving/commodity/service/CategoryService.java 新增方法
- 2.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java 新增方法和属性
- 3.com/sun/sunliving/commodity/controller/CategoryController.java 新增方法
- 4.postman测试 http://localhost:9091/commodity/category/list/tree
- 3.关于com/sun/common/utils/R.java 工具类的解析
- 4.com/sun/sunliving/commodity/entity/CategoryEntity.java 新增字段
- 3.流式计算streamAPI
- 1.基本介绍
- 2.环境搭建
- 3.filter 过滤
- 1.过滤,只要集合中id大于2的
- 2.结果
- 3.分析
- 4.map 映射
- 1.映射,将person过滤出的节点的cat属性赋值
- 2.结果
- 3.分析
- 5.sorted 排序
- 1.排序,按照person节点的id降序排列
- 2.结果
- 3.分析
- 6.常用api
- 1.limt 过滤前两个节点然后遍历输出
- 2.count 统计节点个数
- 4.完成后端返回带层级的记录
- 1.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java 修改listTree方法
- 2.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java 新增方法,获取节点的所有子节点
- 3.启动项目完成测试
- 1.启动mysql容器
- 2.启动前端
- 3.启动后端renren-fast和sunliving-commodity
- 4.启动renren-fast报错数据库连接失败
- 5.由于代码根本没改,所以判断是数据库的问题,查了一下ip原来是101,结果变成100了
- 6.修改一下连接url即可
- 7.postman测试 http://localhost:9091/commodity/category/list/tree
- 8.提交代码
- 5.前端展示分类信息
- 1.集成树形控件
- 1.进入 Element-ui [树形控件](https://element.eleme.cn/#/zh-CN/component/tree)
- 2.首先将category.vue备份,然后新创建一个
- 3.将第一行复制到模板位置
- 4.将其余的复制到script位置
- 5.打开前端页面查看
- 2.根据返回数据修改category.vue
- 3.前端查看效果
1.前端展示分类管理信息
1.目前项目架构
2.启动前后端项目
1.启动mysql容器
2.启动后端 renren-fast
3.启动前端
1.界面
2.用户名密码都是admin
3.创建分类管理菜单
1.菜单管理 -> 新增 -> 新增目录
2.刷新
3.能够新增菜单的原因是前端脚手架与renren-fast后端脚手架通信,这个菜单的表是 sys_menu
4.新增分类管理菜单
5.关于这个分类管理的路由解析
1.由于设置的菜单路由是commodity/category,所以点击这个菜单就会查找前端项目的renren-fast-vue\src\views\modules\commodity\category.vue
2.一般这个菜单路由是对应于后端的一个controller的前缀
3.而后端controller的前缀是根据表来自动生成的
比如表是commodity_category就会生成commodity/category
4.总结:代码生成器会根据一个表来生成一个controller,一个前端菜单界面
6.将生成的commodity文件夹下面的两个文件放到前端项目的modules下
7.分析category.vue
1.找到向后端发送请求的位置
2.进入adornUrl
- 目前肯定是开发环境,经过全局搜索,发现没有开启代理,所以走的是window.SITE_CONFIG.baseUrl
3.进入baseUrl
- 可以查看到baseUrl是http://localhost:8080/renren-fast
4.浏览器测试请求一下
- 完全匹配
5.注销掉这个url,自己写一个
- 请求sunliving-commodity的服务端口在9091,来展示数据
6.启动后端的sunliving-commodity模块
7.再次点击分类管理菜单,发现出现跨域错误
8.跨域问题解决
1.复制renren-fast模块的src/main/java/io/renren/config/CorsConfig.java
2.粘贴到sunliving-commodity模块下
3.重启后端sunliving-commodity
4.再次点击分类管理
2.使用树形菜单展示分类(初级)
1.思路分析
2.首先返回所有记录(没有层级)
1.com/sun/sunliving/commodity/service/CategoryService.java 新增方法
/**
* 查询所有分类及其子分类,以树形结构组装
*
* @return
*/
List<CategoryEntity> listTree();
2.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java 新增方法和属性
@Resource
private CategoryDao categoryDao; // 注入 CategoryDao的代理对象
@Override
public List<CategoryEntity> listTree() {
// 先查询所有记录
List<CategoryEntity> categoryEntities = categoryDao.selectList(null);
return categoryEntities;
}
3.com/sun/sunliving/commodity/controller/CategoryController.java 新增方法
/**
* 查询所有分类及其子分类,以树形结构组装
*
* @return
*/
@RequestMapping("/list/tree")
public R listTree(){
return R.ok().put("data", categoryService.listTree());
}
4.postman测试 http://localhost:9091/commodity/category/list/tree
3.关于com/sun/common/utils/R.java 工具类的解析
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有,侵权必究!
*/
package com.sun.common.utils;
import org.apache.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据
*
* @author Mark sunlightcs@gmail.com
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* 无参构造方法,初始化 code 为 0,msg 为 success
*/
public R() {
put("code", 0);
put("msg", "success");
}
/**
* 返回一个错误的 R 对象
* @return 返回一个code:500, msg:未知异常,请联系管理员的R对象
*/
public static R error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
/**
* 返回一个错误的 R 对象
* @param msg
* @return 返回一个code:500, msg:msg的R对象
*/
public static R error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
/**
* 返回一个错误的 R 对象
* @param code 错误码
* @param msg 错误信息
* @return 返回一个code:code, msg:msg的R对象
*/
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
/**
* 返回一个正确的 R 对象
* @param msg 错误信息
* @return 返回一个code:code, msg:msg的R对象
*/
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
/**
* 返回一个正确的 R 对象
* @param map
* @return 返回一个code:0, msg:success的R对象
*/
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
/**
* 返回一个正确的 R 对象
* @return 返回一个code:0, msg:success的R对象
*/
public static R ok() {
return new R();
}
/**
* 重写 put 方法,给父类的HashMap来赋值,然后返回自身对象,方便链式调用,
* 简称父类key-value赋值,return this
* @param key
* @param value
* @return
*/
@Override
public R put(String key, Object value) {
super.put(key, value);
return this;
}
}
4.com/sun/sunliving/commodity/entity/CategoryEntity.java 新增字段
- 新增一个字段,表示每条记录后面都跟着多条子记录
/**
* 每一条记录后都有一些子记录
*/
@TableField(exist = false) // 表示数据库中没有这个字段
private List<CategoryEntity> childrenCategories;
3.流式计算streamAPI
1.基本介绍
2.环境搭建
package com.sun.streamAPI;
import java.util.Arrays;
import java.util.List;
/**
* Description:
*
* @Author sun
* @Create 2024/4/10 15:27
* @Version 1.0
*/
public class testStream {
public static void main(String[] args) {
// 创建几个person对象
Person person1 = new Person(1, "张三", 18);
Person person2 = new Person(2, "李四", 19);
Person person3 = new Person(3, "王五", 20);
Person person4 = new Person(4, "赵六", 21);
Person person5 = new Person(5, "孙七", 22);
// 将其放到集合中
List<Person> personList = Arrays.asList(person1, person2, person3, person4, person5);
// 输出
for (Person person : personList) {
System.out.println(person);
}
}
}
class Cat {
private Integer id;
private String name;
private String color;
public Cat(Integer id, String name, String color) {
this.id = id;
this.name = name;
this.color = color;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Cat{" +
"id=" + id +
", name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}
class Person {
private Integer id;
private String name;
private Integer age;
private Cat cat;
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", cat=" + cat +
'}';
}
}
3.filter 过滤
1.过滤,只要集合中id大于2的
// 过滤,只要集合中id大于2的节点
List<Person> collect = personList.stream().filter(person -> {
return person.getId() > 2;
}).collect(Collectors.toList());
System.out.println(collect);
2.结果
3.分析
- 首先使用personList.stream()将list转换成流对象
- 然后调用filter()方法进行过滤
- 使用person -> {过滤条件},其中person为需要过滤的节点
- 使用return person.getId() > 2 作为过滤条件,意为只要person节点大于2的
- 最后调用collect(Collectors.toList())方法,将过滤后的结果收集到一个新的集合中
- 注意:只有过滤操作时原来的list不发生变化
4.map 映射
1.映射,将person过滤出的节点的cat属性赋值
// 过滤,只要集合中id大于2的节点
List<Person> collect = personList.stream().filter(person -> {
return person.getId() > 2;
}).map(person -> {
// 映射一下,将person过滤出的节点的cat属性赋值
// 1.创建cat节点
Cat cat = new Cat(person.getId() + 100, "cat", "red");
// 2.为person节点设置cat属性
person.setCat(cat);
// 3.返回处理后的person节点
return person;
}).collect(Collectors.toList());
System.out.println("处理后的:list => " + collect);
System.out.println("处理前的:list => " + personList);
2.结果
3.分析
- 在过滤的基础上调用map(person -> {映射逻辑})方法对过滤后的person节点进行处理
- 首先创建了一个Cat节点Cat cat = new Cat(person.getId() + 100, “cat”, “red”)
- 然后为person节点设置cat属性person.setCat(cat)
- 最后将映射后的person节点返回return person
- 继续调用collect(Collectors.toList())将结果收集到一个新的集合中
- 注意:映射操作后原来的list也会发生变化
5.sorted 排序
1.排序,按照person节点的id降序排列
// 过滤,只要集合中id大于2的节点
List<Person> collect = personList.stream().filter(person -> {
return person.getId() > 2;
}).map(person -> {
// 映射一下,将person过滤出的节点的cat属性赋值
// 1.创建cat节点
Cat cat = new Cat(person.getId() + 100, "cat", "red");
// 2.为person节点设置cat属性
person.setCat(cat);
// 3.返回处理后的person节点
return person;
}).sorted((p1, p2) -> {
// 按照person节点的id降序排列
return p2.getId() - p1.getId();
}).collect(Collectors.toList());
System.out.println("处理后的:list => " + collect);
System.out.println("处理前的:list => " + personList);
2.结果
3.分析
- 调用 sorted((p1, p2) -> {排序方式}) 进行排序操作
- return p2.getId() - p1.getId() 表示对节点进行降序排列
- return p1.getId() - p2.getId() 表示对节点进行升序排列
6.常用api
1.limt 过滤前两个节点然后遍历输出
// 过滤前两个节点然后遍历输出
personList.stream().limit(2).forEach(person -> {
System.out.println(person);
});
2.count 统计节点个数
- 注意:如果是filter或者是limit后使用的count,那么统计的就是filter或者是limit后的数量
// 统计集合的节点个数
long count = personList.stream().count();
System.out.println("count=" + count);
4.完成后端返回带层级的记录
1.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java 修改listTree方法
@Override
public List<CategoryEntity> listTree() {
// 先查询所有记录,放到list中
List<CategoryEntity> categoryEntities = categoryDao.selectList(null);
// 使用streamapi + 递归处理分级菜单
List<CategoryEntity> collect = categoryEntities.stream().filter(categoryEntity -> {
// 过滤一级菜单
return categoryEntity.getParentId() == 0;
}).map(categoryEntity -> {
// 递归处理分级菜单
categoryEntity.setChildrenCategories(getChildrenCategories(categoryEntity, categoryEntities));
return categoryEntity;
}).sorted((category1, category2) -> {
// 按照sort字段进行升序排列
return (category1.getSort() == null ? 0 : category1.getSort()) -
(category2.getSort() == null ? 0 : category2.getSort());
}).collect(Collectors.toList());
return collect;
}
2.com/sun/sunliving/commodity/service/impl/CategoryServiceImpl.java 新增方法,获取节点的所有子节点
// 递归获取一个节点的所有子节点
public List<CategoryEntity> getChildrenCategories(CategoryEntity root, List<CategoryEntity> all) {
List<CategoryEntity> collect = all.stream().filter(categoryEntity -> {
// 过滤出一级节点的所有子节点
return categoryEntity.getParentId() == root.getId();
}).map(categoryEntity -> {
// 递归设置每个子节点的子节点
categoryEntity.setChildrenCategories(getChildrenCategories(categoryEntity, all));
return categoryEntity;
}).sorted((category1, category2) -> {
// 按照sort字段进行升序排列
return (category1.getSort() == null ? 0 : category1.getSort()) -
(category2.getSort() == null ? 0 : category2.getSort());
}).collect(Collectors.toList());
return collect;
}
3.启动项目完成测试
1.启动mysql容器
2.启动前端
3.启动后端renren-fast和sunliving-commodity
4.启动renren-fast报错数据库连接失败
5.由于代码根本没改,所以判断是数据库的问题,查了一下ip原来是101,结果变成100了
6.修改一下连接url即可
7.postman测试 http://localhost:9091/commodity/category/list/tree
8.提交代码
5.前端展示分类信息
1.集成树形控件
1.进入 Element-ui 树形控件
2.首先将category.vue备份,然后新创建一个
3.将第一行复制到模板位置
4.将其余的复制到script位置
5.打开前端页面查看
2.根据返回数据修改category.vue
<template>
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>
<script>
export default {
data() {
return {
data: '',
defaultProps: {
children: 'childrenCategories',
label: 'name'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
// 获取分类列表(带层级)
getCategories() {
this.$http({
url: 'http://localhost:9091/commodity/category/list/tree',
method: 'get'
}).then(({data}) => { // 解构了data
this.data = data.data;
})
}
},
created() { // 生命周期钩子,初始化时调用
this.getCategories()
}
};
</script>
<style scoped>
</style>