谷粒商城第六天-商品服务之分类管理下的获取三级分类树形列表
目录
一、总述
1.1 前端思路
1.2 后端思路
二、前端部分
2.1 在网页中建好目录及菜单
2.1.1 建好商品目录
2.1.2 建好分类管理菜单
编辑
2.2 编写组件
2.2.1 先完成组件文件的创建
2.2.2 编写组件
2.2.2.1 显示三级分类树形列表
三、后端部分
3.1 编写商品分类的相关接口
3.1.1 获取树形三级分类列表
四、总结
一、总述
就是在前端编写好相应的组件,展示内容,绑定好相关的事件,然后向后端发送请求,在后端编写好想要的接口,执行操作或者是返回前端想要的数据。
具体细节:
1.1 前端思路
前端组件的编写就参考elementUI进行编写,只需稍作修改即可。
前端组件的写法按照那三部分即可,模板、脚本、样式
发的请求依靠请求对象,在api文件夹中写好相应的api对象向后端发好请求,然后在组件中进行引入,发送请求即可
1.2 后端思路
基本上直接使用若依提供好的逆向代码,只需稍作修改即可。
编写好各层代码。
二、前端部分
2.1 在网页中建好目录及菜单
这个比较简单在页面中找到菜单管理新建一个目录即可,首先还不是着急创建菜单,而是创建好目录,一个目录即代表一个一个大的类别,其实也就是对应着后端的一个微服务。比如说商品服务,优惠卷服务啥的,为什么说是一个大的类别,因为商品中就有类别管理,品牌管理啥的,一些细的管理,这就作为前端的一个菜单出现了,而菜单其实就对应后端的一个控制器。一个菜单里面实际上就是对一张表或者是多张表做增删改查的。
说了总体的,其实就是新建一个目录代表商品服务。建的步骤如下:
2.1.1 建好商品目录
不会写的,就参考之前已经存在了的目录,就比如这个路由地址,有点模糊,就参考之前的,比如是之前的系统工具这个目录的路由地址写的就是tool,可以知道其实也就是目录的英文简写,那这个就叫product就行了,其他按钮部分基本上默认就行了。
2.1.2 建好分类管理菜单
同样也是参考之前写好的,创建好分类管理菜单
到目前为止页面的基本框架就有了,但是这个分类菜单缺少实际的内容。接下来就是到前端项目里面按照刚刚的路径创建好组件,并进行编写 1.2 在前端项目中编写前端组件
2.2 编写组件
2.2.1 先完成组件文件的创建
2.2.2 编写组件
2.2.2.1 显示三级分类树形列表
这里直接使用elementUI的树形组件
在elementUI官网中到组件中找到树形控件,在data一栏中可以找到
这里因为不单单的只是展示节点,还涉及到节点的新增以及删除,因此得在节点的后面自定义上内容,定义上新增和删除按钮,所以直接使用上
这个组件,这里我们使用scoped slot这个。
复制下面的样例代码,注意别复制多了,只复制需要的,然后打开运行前端项目就能有官网的那种效果了,当然还是需要作一些优化的,比如说复制下来的某些东西不需要,就比如说这里的
模板就保留这里:
<el-tree:data="data"show-checkboxnode-key="id"default-expand-all:expand-on-click-node="false"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><el-buttontype="text"size="mini"@click="() => append(data)">Append</el-button><el-buttontype="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree>
可能有人会问,为什么不用div盖着,其实这个并不是必要的,只是有个时候可能需要,需要的时候我们在添上即可。
脚本部分:
<script>let id = 1000;export default {data() {const data = [{id: 1,label: '一级 1',children: [{id: 4,label: '二级 1-1',children: [{id: 9,label: '三级 1-1-1'}, {id: 10,label: '三级 1-1-2'}]}]}, {id: 2,label: '一级 2',children: [{id: 5,label: '二级 2-1'}, {id: 6,label: '二级 2-2'}]}, {id: 3,label: '一级 3',children: [{id: 7,label: '二级 3-1'}, {id: 8,label: '二级 3-2'}]}];return {data: JSON.parse(JSON.stringify(data)),data: JSON.parse(JSON.stringify(data))}},methods: {append(data) {const newChild = { id: id++, label: 'testtest', children: [] };if (!data.children) {this.$set(data, 'children', []);}data.children.push(newChild);},remove(node, data) {const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex(d => d.id === data.id);children.splice(index, 1);}}};
</script>
这里的数据先留着,方便初看效果,下面的renderContent方法可以删掉,这是
样式部分一般不要动,保留即可:
<style>.custom-tree-node {flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;}
</style>
注意:这里除了对原有的内容进行删减之后,还需要优化一些内容,就比如说:
1. 就结构而言,我是需要点击箭头才展开子节点。
2. 就内容:append和delete按钮来说,append因为最多只有三级分类,所以如果当前分类的层级已经是三层了,不能添加这个append,对于delete,如果当前分类下面还有子分类的话,也不能添加delete。
具体实现如下:
其实完成这些操作,注意参考element的官方文档,对于它给我的这些数据,有什么可以使用控制台打印查看,对于一些你想要的操作这里比如说想点击箭头再展开这样的特殊操作,就需要查看文档下面的属性配置
所以:
经过上面的两处优化,基本上三级分类也就是这个样子了,现在只是数据不是我们的真实数据罢了。
接下来的工作就是:在前端工程中写好请求对象,用来请求后端获得三级分类的树形列表,然后在组件中引入,然后使用,得到数据,然后再参考文档,将数据正确显示出来即可。
1. 在api文件夹中编写好请求对象
export function treeListCategory() {return request({url: '/product/category/treeList',method: 'get'})
}
2, 在组件中引入并使用
现在是创建了一个方法,调用接口
其实很简单,就是前端写好树形控件基本的架子先搭起来,然后将数据换成经由调用后端接口返回的数据。步骤也是很简单。到这里网页已经是可以显示三级分类的分类列表了。
三、后端部分
3.1 编写商品分类的相关接口
3.1.1 获取树形三级分类列表
无论是前台页面还是后台管理页面都得将分类列表以子父的树形三级列表体现出来。
所以就得写一个接口获取到树形三级分类列表。
树形子父关系如何体现呢?貌似有点抽象,其实很简单,就是一个分类下面有许多的子分类,在面向对象的思想中就是分类的这个类中有一个类型为集合,集合元素为分类的子分类属性。
如下图所示:
注意: 非表的字段一定得加上@TabelField(exist = false)注解,来标明此字段是非表字段,如果不加这个注解,MyBatis字段映射的时候就会出问题,就比如说sql查了记录的所有字段,但是却找不到该字段,就会报错
好,现在字段是有了,最终肯定是需要为这个字段赋上值的,所有的子分类是计算出来的,那到底如何计算呢?其核心业务实现如何写?请看下面我写的:
其实很简单,就两步,其实获取子分类的关键就是 依靠表中的父类别字段。有了这一个就很容易得到一个类别的下的子类别。
第一步:编写获取子分类的方法(不带真正实现)。
遍历所有分类,为每个分类赋上子分类
第二步:编写获取子分类的具体实现
也就是根据当前分类的id,然后遍历所有的分类,找到它的子分类,其实也就是分类的父id为当前分类的id,那么这个分类就为当前分类的子分类
最关键的业务实现思路就有了,最关键最重要的一步其实已经想明白了,接下来就是常规的写好各个层的代码。我现在已经习惯逆向编写了,也就是从控制层开始写,一直写到dao层。话不多说,直接贴代码:
controller:
@ApiOperation("获取商品分类的树形结构")@GetMapping("/treeList")public AjaxResult treeList(){List<Category> treeList = categoryService.treeList();return AjaxResult.success(treeList);}
service:
service接口:
service实现:
@Overridepublic List<Category> treeList() {//获取到所有分类List<Category> list = list();//为每个分类添加上子分类list.stream().forEach(category -> category.setChildren(getChildren(category,list)));//为根父类排序list.stream().sorted((c1,c2)->c1 == null ? 0 : c1.getSort().intValue() - (c2 == null ? 0 : c2.getSort().intValue()));return list;}
private List<Category> getChildren(Category root, List<Category> all) {//从所有类别中找到子分类,并排好序List<Category> childrenCategory = all.stream().filter(c -> c.getParentCid().equals(root.getCatId())).sorted((c1,c2)->c1 == null ? 0 : c1.getSort().intValue() - (c2 == null ? 0 : c2.getSort().intValue())).collect(Collectors.toList());//针对所有的子分类也递归找其对应的子分类childrenCategory.stream().forEach(category -> category.setChildren(getChildren(category,childrenCategory)));return childrenCategory;}
这里由于是直接使用的MP,并且没有复杂查询,也就不需要直接显式的写dao层了
四、总结
其实从后端编写好接口,到前端编写好组件,整个过程还是比较简单的
在这里前端相较于后端而言反而要繁琐一点,后端主要把真正的获取逻辑写明白就好了
而前端就根据elememtUI的组件库选好组件,然后将参数写好,使得能正确的将数据渲染出来,还有一些其他的修改,优化一下就行了。
另外写好api,使得可以正确的访问后端,其实不难,但是繁琐,之后的功能实现大体都是这些步骤,主要就是核心组件不同,后端无非还是CURD。
这次相当于是Vue+Boot的开发,这是比较主流的开发方式,利用若依框架开发也是公司中常用的,因此需要熟练掌握。
相关文章:

谷粒商城第六天-商品服务之分类管理下的获取三级分类树形列表
目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端部分 2.1 在网页中建好目录及菜单 2.1.1 建好商品目录 2.1.2 建好分类管理菜单 编辑 2.2 编写组件 2.2.1 先完成组件文件的创建 2.2.2 编写组件 2.2.2.1 显示三级分类树形列表 三、后端部分 3.1 编写商品分类…...

【UI自动化测试】Appium+Python+Unittest+HTMLRunner
简介 获取AppPackage和AppActivity 定位UI控件的工具 脚本结构 PageObject分层管理 HTMLTestRunner生成测试报告 启动appium server服务 以python文件模式执行脚本生成测试报告 【B站最通俗易懂】Python接口自动化测试从入门到精通,超详细的进阶教程,看完…...

【限时优惠】红帽openstack管理课程(CL210) 即将开课
课程介绍 通过实验室操作练习,学员将能够深入学习红帽企业 Linux OpenStack 平台各服务的手动安装方法,还将了解 OpenStack 开发社区的未来发展计划。 培训地点: 线下面授:苏州市姑苏区干将东路666号401室; 远程…...

Golang之路---02 基础语法——函数
函数 函数定义 func function_name( [parameter list] ) [return_types] {函数体 }参数解释: func:函数由 func 开始声明function_name:函数名称,函数名和参数列表一起构成了函数签名。[parameter list]:参数列表&a…...

数据结构和算法入门(时间/空间复杂度介绍--java版)
数据结构和算法入门(时间/空间复杂度介绍–java版) write in front 作者: 向大佬学习 专栏: 数据结构(java版) 作者简介:大二学生 希望能学习其同学和大佬的经验! 本篇博客简介&…...
Spring Mvc 文件上传(MultipartFile )—官方原版
一、创建应用程序类 要启动Spring Boot MVC应用程序,首先需要一个启动器。在这个示例中,已经添加了spring-boot-starter thymelaf和spring-boot-starter web作为依赖项。要使用Servlet容器上传文件,您需要注册一个MultipartConfigElement类&…...
【E题】2023年电赛运动目标控制与自动追踪系统方案
系统的设计和制作可以按照以下步骤进行: 设计红色光斑位置控制系统: 选择合适的红色激光笔,并将其固定在一个二维电控云台上。 使用电机和编码器来控制电控云台的水平和垂直运动。 设计一个控制电路,可以通过输入控制信号来控制…...
企业网络安全之零信任和身份认证
零信任并不是一种技术,而是一个安全概念,是一种建立安全战略的理念、方法和框架。 零信任提供了一系列概念和思想,其中心思想是怀疑一切,否定一切,不再以网络边界为限,不能再将内部网络定义为可信任的&…...

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 5
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...
[运维|中间件] 东方通TongWeb使用笔记
参考文献 东方通tongweb部署服务 东方通tongweb部署服务 使用笔记 默认访问地址 http://ip:9060/console/默认用户名密码 TongWeb7.0默认用户名密码:thanos,thanos123.com...

WIZnet W6100-EVB-Pico DHCP 配置教程(三)
前言 在上一章节中我们讲了网络信息配置,那些网络信息的配置都是用户手动的去配置的,为了能跟电脑处于同一网段,且电脑能成功ping通板子,我们不仅要注意子网掩码,对于IP地址主机位和网络位的划分,而且还要注…...
【Linux】Ansible 脚本 playbook 剧本
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Ansible 脚本 playbook 剧本 playbook 剧本Templates 模块tags 模块Roles 模块在一个 playbook 中使用 roles 的步骤 playbook 剧本 playbooks 本身由以下各部分组成 &#…...

解决 tensorflow 出现的 ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘. 问题
在安装完tensorflow库后出现 问题详述: ImportError: Could not find the DLL(s) msvcp140_1.dll. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downlo…...

百度与AI:历史、投资和监管
来源:猛兽财经 作者:猛兽财经 百度的人工智能在中国具有先发优势 随着ChatGPT的爆火,人工智能重新引起了投资者的注意,然而人工智能并不是突然爆火的,而是全球众多公司在人工智能技术上进行数十年如一日的研发和积累&a…...

Kafka3.0.0版本——Broker(Zookeeper服务端存储的Kafka相关信息)
目录 一、启动zookeeper集群及kafka集群服务启动1.1、先启动三台zookeeper集群服务,再启动三台kafka集群服务1.2、使用PrettyZoo连接zookeeper客户端工具 二、在zookeeper服务端存储的Kafka相关信息 一、启动zookeeper集群及kafka集群服务启动 1.1、先启动三台zook…...

【图论】无向图连通性(tarjan算法)
割边:dfn[u]<low[v] 割点:dfn[u]<low[v] (若为根节点,要有两个v这样的点) 一.知识点: 1.连通: 在图论中,连通性是指一个无向图中的任意两个顶点之间存在路径。如果对于图中的任意两个顶点 u 和 v&…...

Docker安装
Docker实践 yum安装 YUM源可以使用官方YUM源、清华大学开源镜像站配置YUM源,也可以使用阿里云开源镜像站提供的YUM源,建议选择使用阿里云开源镜像站提供的YUM源,原因速度快。 地址: https://developer.aliyun.com/mirror/ 我们安装ce版 …...
06. 计数原理
6. 计数原理 6.1 分类加法计数原理与分步乘法计数原理 分类加法计数原理定义 完成一件事,有 n n n 类办法,在第1类办法中有 m 1 m_1 m1 种不同的方法,在第2类办法中有 m 2 m_2 m2 种不同的方法,…,在第 n n…...

计算机网络基础(静态路由,动态路由,公网IP,私网IP,NAT技术)
文章目录 一:静态路由和动态路由二:静态路由的配置路由信息的方式演示三:默认路由四:公网IP和私网IP和NAT技术的基本理解 一:静态路由和动态路由 在说静态路由和动态路由前,我们需要来了解一下࿰…...
CGAL 点云Alpha-Shape曲面重建算法
文章目录 一、简介二、相关参数三、实现代码四、实现效果参考资料一、简介 在数学上, a l p h a − s h a p e alpha-shape a...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...