Spring Cloud Alibaba 商城项目(2)
1.后端分类列表树展示
- 在分类实体类CategoryEntity添加childrenList
@TableField(exist = false)
private List<CategoryEntity> childrenList;
- 业务代码
//对查询结果封装
@Override
public List<CategoryEntity> queryListByTree() {
//查出全部信息
List<CategoryEntity> categoryEntities = this.baseMapper.selectList(null);
//排序
List<CategoryEntity> collect = categoryEntities.stream().filter(data -> data.getParentCid() == 0).map(
data -> {
data.setChildrenList(convertList(data, categoryEntities));
return data;
}
).sorted((data1, data2) -> {
return data1.getSort() - data2.getSort();
}).collect(Collectors.toList());
return collect;
}
// 递归组合子元素
public List<CategoryEntity> convertList(CategoryEntity currentList, List<CategoryEntity> allList) {
List<CategoryEntity> collect = allList.stream().filter(data -> {
return data.getParentCid() == currentList.getCatId();
}).map(data -> {
data.setChildrenList(convertList(data, allList));
return data;
}).sorted((data1, data2) -> {
return data1.getSort() - data2.getSort();
}).collect(Collectors.toList());
return collect;
}
2.前端分类列表树展示
- 启动人人fast项目 创建一级分类
- 创建二级分类
- 创建商品管理分类管理目录结构
- 修改人人代码前端请求路径改成http://localhost:88/renren-fast,默认都请求到网关,并将人人后台配置到注册中心
为了节约时间我就剔除掉了配置中心的配置 不从配置中心读取renren fast的依赖了
- 修改网关配置
spring:
application:
name: shop-gateway
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yml
namespace: f176f0a9-ee0b-4de6-bf0c-545be48a780d
group: dev
gateway:
routes:
- id: renre_id
#均匀的负载到shop-renren的服务器上面
uri: lb://shop-renren
#包含配置请求规则
predicates:
- Path=/renren-fast/**
- 网关配置允许跨域
package com.fyx.shop.shopgateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class MyCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.配置跨域
//允许哪种请求头跨域
corsConfiguration.addAllowedHeader("*");
//允许哪种方法类型跨域 get post delete put
corsConfiguration.addAllowedMethod("*");
// 允许哪些请求源跨域
corsConfiguration.addAllowedOrigin("*");
// 是否携带cookie跨域
corsConfiguration.setAllowCredentials(true);
//允许跨域的路径
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
- 注释掉人人开源代码跨域请求代码 io.renren.config.CorsConfig.CorsConfig
- 配置goods服务的路由规则
注:如果id_goods的顺序没 id_renren 顺序高,那么id_goods的拦截会优先进入id_renren服务中,就会被id_renren得到拦截器抢先一步拦截从而走不到id_goods 的代码中
spring:
application:
name: shop-gateway
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yml
namespace: f176f0a9-ee0b-4de6-bf0c-545be48a780d
group: dev
gateway:
routes:
- id: id_goods
uri: lb://shop-goods
predicates:
- Path=/renren-fast/goods/**
filters:
#意思是将http://localhost:88/renren-fast/goods/test/list 转为 http://shop-goods/test/list
- RewritePath=/renren-fast/goods/(?<segment>.*),/$\{segment}
- id: id_renren
uri: lb://shop-renren
predicates:
- Path=/renren-fast/**
- 前端分类代码
<template>
<el-tree :data="menus"
:props="defaultProps"></el-tree>
</template>
<script>
export default {
components: {},
props: {},
data () {
return {
menus: [],
defaultProps: {
children: 'childrenList',
label: 'name'
}
}
},
watch: {},
computed: {},
methods: {
getTreeList () {
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/list/tree'),
method: 'get'
}).then(({ data }) => {
console.log(data)
this.menus = data.page
})
}
},
created () { this.getTreeList() },
mounted () { }
}
</script>
<style lang="scss" scoped>
.wrapper {
}
</style>
- 访问成功
3.前端分类列表树展示
完成复选框,增加添加删除按钮,有子节点的不显示删除,第三季的不显示添加按钮
<template>
<el-tree :data="menus"
:props="defaultProps"
:expand-on-click-node="false"
show-checkbox
node-key="catId">
<span class="custom-tree-node"
slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button v-if="node.level <=2"
type="text"
size="mini"
@click="() => append(data)">
添加
</el-button>
<el-button v-if="node.childNodes.length==0"
type="text"
size="mini"
@click="() => remove(node, data)">
删除
</el-button>
</span>
</span>
</el-tree>
</template>
<script>
export default {
components: {},
props: {},
data () {
return {
menus: [],
defaultProps: {
children: 'childrenList',
label: 'name'
}
}
},
watch: {},
computed: {},
methods: {
append (data) {
console.log(data)
},
remove (node, data) {
console.log(data)
},
getTreeList () {
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/list/tree'),
method: 'get'
}).then(({ data }) => {
console.log(data)
this.menus = data.page
})
}
},
created () { this.getTreeList() },
mounted () { }
}
</script>
<style lang="scss" scoped>
.wrapper {
}
</style>
4.后端分类列表树删除
- 配置Mybatis-plus 整合项目的逻辑删除代码(逻辑删除是为了解决物理删除有的数据有关联而返回的Null数据)
mybatis-plus:
global-config:
db-config:
#1 代表删除 0 代表未删除
logic-delete-value: 1
logic-not-delete-value: 0
- 给需要逻辑删除的实体类字段加入
//如果数据库字段的删除标识不对应则可以通过 @TableLogic(value = "0",delval = "1") 指定逻辑删除对应的值
@TableLogic
private Integer showStatus;
- 调用Mybatis-plus 封装的删除代码
@Override
public void removeListByIds(List<Long> asList) {
return baseMapper.deleteBatchIds(asList);
}
5.前端分类列表树删除
<template>
<el-tree :data="menus"
:props="defaultProps"
:expand-on-click-node="false"
show-checkbox
node-key="catId"
:default-expanded-keys="expandedkey">
<span class="custom-tree-node"
slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button v-if="node.level <=2"
type="text"
size="mini"
@click="() => append(data)">
添加
</el-button>
<el-button v-if="node.childNodes.length==0"
type="text"
size="mini"
@click="() => remove(node, data)">
删除
</el-button>
</span>
</span>
</el-tree>
</template>
<script>
export default {
components: {},
props: {},
data () {
return {
expandedkey: [],
menus: [],
defaultProps: {
children: 'childrenList',
label: 'name'
}
}
},
watch: {},
computed: {},
methods: {
open () {
},
append (data) {
console.log(data)
},
// 删除节点
remove (node, data) {
this.$confirm(`是否要删除${data.name}, 是否继续 ? `, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var ids = [data.catId]
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({ data }) => {
this.$message({
type: 'success',
message: '删除成功'
})
this.getTreeList()
// 设置默认展开的节点
this.expandedkey = [node.parent.data.catId]
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
getTreeList () {
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/list/tree'),
method: 'get'
}).then(({ data }) => {
console.log(data)
this.menus = data.page
})
}
},
created () { this.getTreeList() },
mounted () { }
}
</script>
<style lang="scss" scoped>
.wrapper {
}
</style>
6.前端分类列表树添加
<template>
<div>
<el-tree :data="menus"
:props="defaultProps"
:expand-on-click-node="false"
show-checkbox
node-key="catId"
:default-expanded-keys="expandedkey">
<span class="custom-tree-node"
slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<el-button v-if="node.level <=2"
type="text"
size="mini"
@click="() => append(data)">
添加
</el-button>
<el-button v-if="node.childNodes.length==0"
type="text"
size="mini"
@click="() => remove(node, data)">
删除
</el-button>
</span>
</span>
</el-tree>
<el-dialog title="提示"
:visible.sync="flag"
width="30%">
<el-form :model="category">
<el-form-item label="分类名称">
<el-input v-model="category.name"></el-input>
</el-form-item>
</el-form>
<span slot="footer"
class="dialog-footer">
<el-button @click="flag=false">取 消</el-button>
<el-button type="primary"
@click="addcategory">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
components: {},
props: {},
data () {
return {
category: {
name: '',
parentCid: 0,
catLevel: 0,
showStatus: 1,
sort: 0
},
flag: false,
expandedkey: [],
menus: [],
defaultProps: {
children: 'childrenList',
label: 'name'
}
}
},
watch: {},
computed: {},
methods: {
append (data) {
console.log(data)
this.flag = true
this.category.parentCid = data.catId
this.category.catLevel = data.catLevel * 1 + 1
},
addcategory () {
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/save'),
method: 'post',
data: this.$http.adornData(this.category, false)
}).then(({ data }) => {
this.$message({
type: 'success',
message: '保存成功'
})
this.flag = false
this.getTreeList()
// 设置默认展开的节点
this.expandedkey = [this.category.parentCid]
})
},
// 删除节点
remove (node, data) {
this.$confirm(`是否要删除${data.name}, 是否继续 ? `, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var ids = [data.catId]
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({ data }) => {
this.$message({
type: 'success',
message: '删除成功'
})
this.getTreeList()
// 设置默认展开的节点
this.expandedkey = [node.parent.data.catId]
})
})
},
getTreeList () {
this.$http({
url: this.$http.adornUrl('/goods/shopgoods/category/list/tree'),
method: 'get'
}).then(({ data }) => {
console.log(data)
this.menus = data.page
})
}
},
created () { this.getTreeList() },
mounted () { }
}
</script>
<style lang="scss" scoped>
.wrapper {
}
</style>
标签:
SpringCloud Alibaba
, Vue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端