电商项目——初识电商——第一章——上篇
电商项目——分布式基础概念和电商项目微服务架构图,划分图的详解——第二章——上篇
电商项目——电商项目的虚拟机环境搭建_VirtualBox,Vagrant——第三章——上篇
电商项目——Linux虚拟机中安装docker,mysql,redis_VirtualBox——第四章——上篇
电商项目——电商项目的环境搭建_开发工具&环境搭建——第五章——上篇
电商项目——快速开发人人开源搭建后台管理系统&代码生成器逆向工程搭建——第六章——上篇
电商项目——分布式组件(SpringCloud Alibaba,SpringCloud)——第七章——上篇
电商项目——前端基础——第八章——上篇
电商项目——商品服务-API-三级分类——第九章——上篇
电商项目——商品服务-API-品牌管理——第十章——上篇
电商项目——商品服务-API-属性分组——第十一章——上篇
电商项目——商品服务-API-品牌管理——第十二章——上篇
电商项目——商品服务-API-平台属性——第十三章——上篇
电商项目——商品服务-API-新增商品——第十四章——上篇
电商项目——商品服务-API-商品管理——第十五章——上篇
电商项目——商品服务-API-仓库管理——第十六章——上篇
文章目录
讲完了前面几章的内容,现在我们就可以对后台管理系统,和微服务项目进行开发了,我们先从三级分类说起
默认mall-product的环境已经全部配置好了
1:查询-递归树形结构获取数据
三级分类(电商里面经常用到的功能):所有的数据都是来源于数据库,我们要对三级分类进行维护,进行增删改查,我们首先就必须要后台管理系统来可以维护我们的整个数据。所以我们引出了下面的问题,解决了下面问题,我们就可以在搭建前端界面进行前后端连接
问题:如何查出所有三级分类以及子分类,并以树形结构组装起来?,我们看这篇的思路分析
电商项目——如何查出所有三级分类,并以树形结构组装起来?
2:配置网关路由与路径重写
接下来我们来编写后台管理系统的前端项目,来维护三级分类的增删改查
我们先进行测试看是否后台管理系统可以成功启动
启动renren-fast和renren-fast-vue
第一步:我们要写商品系统的相关内容,看如下操作
跟商品系统有关的项目都放在我自己新增的商品系统目录下,然后我们在商品系统的目录下,增加一个菜单
最终的效果如下
搭建分类维护功能,我们期望展示出整个三级分类,然后可以对三级分类进行增删改查,而我们想要做这个功能,就要先了解脚手架工程的一些基本规范
脚手架工程的基本规范1:
脚手架工程的基本规范2:
第二步:在renren-fast-vue中搭建分类维护路径的对应目录如下,并进行前端显示三级分类数据的搭建
我们就可以在category中使用ElementUI进行前端显示三级分类数据的搭建
第三步:在renren-fast-vue中的src/views/modules/product/路径下搭建category.vue
我们使用ElementUI组件中的Tree树形控件来完成我们的功能,并且还要向后端发送请求在返回数据给前端
代码如下
<template>
<!--label 指定节点标签为节点对象的某个属性值,,children 指定子树为节点对象的某个属性值,,,data 展示数据-->
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>
<script>
export default {
// import引入的组件需要注入到对象中才能使用",
components: {},
data () {
// 这里存放数据",
return {
data: [],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
// 方法集合",
methods: {
// 获取数据列表
getDataList () {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then(({data}) => {
console.log("成功获取到菜单数据:"+data)
})
}
},
// 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
created () {
this.getDataList();
}
}
</script>
我们进行测试
解决办法:我们要改变基本路径http://localhost:8080/renren-fast的值把它变成网关的基本路径(我们以后要上线很多微服务项目,我们不肯能一直去renren-fast-vue中一直修改基本路径的端口,所以我们把所有的请求发送给网关,网关在分配到指定的路径的微服务中)
在进行测试,发现下面问题
解决办法:把renren-fast注册到注册中心中,并且配置网关的routes
renren-fast
- 引入mall-common依赖
<dependency>
<groupId>com.atstudying.mall</groupId>
<artifactId>mall-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
- 编译application.yml配置
spring:
application:
name: renren-fast
cloud:
nacos:
discovery:
server-addr: localhost:8848
- 导入@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class RenrenApplication {
public static void main(String[] args) {
SpringApplication.run(RenrenApplication.class, args);
}
}
- mall-gateway中
配置网关的routes
在进行测试,发现下面问题
解决办法:重新配置好网关的路由,新增一个路径重写功能
mall-gateway
在进行测试:发现如下问题
从8001访问到88出现了跨域问题,默认拒绝跨域请求
我们下一章就来介绍如何解决跨域问题
3:网关统一配置跨域
上一小节,我们配置了网关路由和路径重写(renren-fast),我们的验证码也刷新出来了,但是我们在登录测试的时候,发现报了一个跨域的问题
什么是跨域呢?怎么解决跨域问题呢?下面这篇文章为大家一一解答
HTTP访问控制(CORS)——预检请求问题的解决
上面这篇文章的第四节就是解决网关统一配置跨域的一个案例演示
我们根据上面这篇文章成功解决跨域问题后,再次登录,发现登录,发现还是登录不了,进行检查,发现下面问题
解决办法:renren-fast中注释掉有关跨域的代码
重新启动renren-fast,并重新登录,发现登录成功
4:查询-树形展示三级分类数据
上节我们解决了跨域,我们现在来继续编写商品系统目录下分类维护菜单的代码
我么刷新上面界面,并检查元素发现,跨域问题解决了,可是请求却找不到
解决办法,我么以前配置网关路由默认是全部转到renren-fast的,所以我们的请求找不到,我们现在去网关配置一个mall-product的网关路由,让请求跳转到该路由下。
我们进行如下测试,发现数据成功获取
http://localhost:88/api/product/category/list/tree
如上的地址经过网关会变成如下地址
http://localhost:30000/product/category/list/tree
因为,我们配置的网关路由在起作用,如上两个地址的访问都会得到下面的图的效果
- id: mall-product
uri: lb://mall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{
segment}
我们看见数据已经成功返回给了前端界面,可是我们要怎么展示呢?
category.vue
methods: {
handleNodeClick(data){
console.log(data)
},
// 获取数据列表
getDataList () {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then( data => {
console.log("成功获取到菜单数据:"+data)
})
}
created () {
// <!--在组件创建的时候就已经调用了,就相当于请求已经发送出去了,我们上面的方法就会有成功获取到的菜单数据-->
this.getDataList();
},
我们发现data中有很多属性,可是我们要的数据是在data.data中,所以我们可以在前端的category.vue中进行项目解构
如下category.vue中部分代码演示片段({data})(解构)
// 获取数据列表
getDataList () {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then( ({data}) => {
console.log("成功获取到菜单数据:"+data.data)
})
}
完整的代码如下
category.vue
<template>
<!--label 指定节点标签为节点对象的某个属性值,,children 指定子树为节点对象的某个属性值,,,data 展示数据-->
<el-tree :data="menus" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>
<script>
export default {
// import引入的组件需要注入到对象中才能使用",
components: {},
data () {
// 这里存放数据",
return {
menus: [],
defaultProps: {
children: 'children',
label: 'name'
}
}
},
// 监听属性 类似于data概念",
computed: {},
// 监控data中的数据变化",
watch: {},
// 方法集合",
methods: {
handleNodeClick(data){
console.log(data)
},
// 获取数据列表
getDataList () {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then( ({data}) => {
console.log("成功获取到菜单数据:"+data.data)
this.menus=data.data;
})
}
},
// 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
created () {
// <!--在组件创建的时候就已经调用了,就相当于请求已经发送出去了,我们上面的方法就会有成功获取到的菜单数据-->
this.getDataList();
}
}
</script>
我们的商品系统下的分类维护中成功显示出三级分类数据
5:删除-页面效果
我们先来编写菜单删除功能,哪些菜单可以被删除呢?那就是没有子菜单,并且没有被别的地方引用的菜单,操作如下
第一步:我们先来展示前端界面的删除效果,我们去eliment中找到Tree树形控件下的自定义节点内容,把它的代码引入,如下代码演示
<template>
<!-- 使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据-->
<!--label 指定节点标签为节点对象的某个属性值,,children 指定子树为节点对象的某个属性值,,,data 展示数据-->
<el-tree
:data="menus"
show-checkbox
node-key="id"
:props="defaultProps"
default-expand-all
:expand-on-click-node="false">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{
{ node.label }}</span>
<span>
<el-button
type="text"
size="mini"
@click="() => append(data)">
Append
</el-button>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)">
Delete
</el-button>
</span>
</span>
</el-tree>
</template>
<script>
export default {
// import引入的组件需要注入到对象中才能使用",
components: {},
data () {
// 这里存放数据",
return {
menus: [],
defaultProps: {
children: 'children',
label: 'name'
}
}
},
// 监听属性 类似于data概念",
computed: {},
// 监控data中的数据变化",
watch: {},
// 方法集合",
methods: {
append(data) {
},
remove(node, data) {
},
// 获取数据列表
getDataList () {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then( ({data}) => {
console.log("成功获取到菜单数据:"+data.data)
this.menus=data.data;
})
}
},
// 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
created () {
// <!--在组件创建的时候就已经调用了,就相当于请求已经发送出去了,我们上面的方法就会有成功获取到的菜单数据-->
this.getDataList();
},
}
</script>
就会变成如下效果
第二步:只有我们这个菜单是一级菜单或者是二级菜单的时候才显示append按钮(三级分类不可以追加元素);无论是一级分类还是二级分类,只要我们没子节点就可以删除;所以我们进行修改按钮,在合适的时机显示出来,添加如下v-if语句,v-if里面的判断值怎么得出呢?
我们要进行检查界面,观察点击按钮后,在控制台上打印值的变化,如下
<el-button
type="text"
size="mini"
@cl