当前位置: 首页 > news >正文

谷粒商城第六天-商品服务之分类管理下的获取三级分类树形列表

目录

一、总述

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接口自动化测试从入门到精通&#xff0c;超详细的进阶教程&#xff0c;看完…...

【限时优惠】红帽openstack管理课程(CL210) 即将开课

课程介绍 通过实验室操作练习&#xff0c;学员将能够深入学习红帽企业 Linux OpenStack 平台各服务的手动安装方法&#xff0c;还将了解 OpenStack 开发社区的未来发展计划。 培训地点&#xff1a; 线下面授&#xff1a;苏州市姑苏区干将东路666号401室&#xff1b; 远程…...

Golang之路---02 基础语法——函数

函数 函数定义 func function_name( [parameter list] ) [return_types] {函数体 }参数解释&#xff1a; func&#xff1a;函数由 func 开始声明function_name&#xff1a;函数名称&#xff0c;函数名和参数列表一起构成了函数签名。[parameter list]&#xff1a;参数列表&a…...

数据结构和算法入门(时间/空间复杂度介绍--java版)

数据结构和算法入门&#xff08;时间/空间复杂度介绍–java版&#xff09; write in front 作者&#xff1a; 向大佬学习 专栏&#xff1a; 数据结构&#xff08;java版&#xff09; 作者简介&#xff1a;大二学生 希望能学习其同学和大佬的经验&#xff01; 本篇博客简介&…...

Spring Mvc 文件上传(MultipartFile )—官方原版

一、创建应用程序类 要启动Spring Boot MVC应用程序&#xff0c;首先需要一个启动器。在这个示例中&#xff0c;已经添加了spring-boot-starter thymelaf和spring-boot-starter web作为依赖项。要使用Servlet容器上传文件&#xff0c;您需要注册一个MultipartConfigElement类&…...

【E题】2023年电赛运动目标控制与自动追踪系统方案

系统的设计和制作可以按照以下步骤进行&#xff1a; 设计红色光斑位置控制系统&#xff1a; 选择合适的红色激光笔&#xff0c;并将其固定在一个二维电控云台上。 使用电机和编码器来控制电控云台的水平和垂直运动。 设计一个控制电路&#xff0c;可以通过输入控制信号来控制…...

企业网络安全之零信任和身份认证

零信任并不是一种技术&#xff0c;而是一个安全概念&#xff0c;是一种建立安全战略的理念、方法和框架。 零信任提供了一系列概念和思想&#xff0c;其中心思想是怀疑一切&#xff0c;否定一切&#xff0c;不再以网络边界为限&#xff0c;不能再将内部网络定义为可信任的&…...

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 5

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

[运维|中间件] 东方通TongWeb使用笔记

参考文献 东方通tongweb部署服务 东方通tongweb部署服务 使用笔记 默认访问地址 http://ip:9060/console/默认用户名密码 TongWeb7.0默认用户名密码&#xff1a;thanos&#xff0c;thanos123.com...

WIZnet W6100-EVB-Pico DHCP 配置教程(三)

前言 在上一章节中我们讲了网络信息配置&#xff0c;那些网络信息的配置都是用户手动的去配置的&#xff0c;为了能跟电脑处于同一网段&#xff0c;且电脑能成功ping通板子&#xff0c;我们不仅要注意子网掩码&#xff0c;对于IP地址主机位和网络位的划分&#xff0c;而且还要注…...

【Linux】Ansible 脚本 playbook 剧本

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Ansible 脚本 playbook 剧本 playbook 剧本Templates 模块tags 模块Roles 模块在一个 playbook 中使用 roles 的步骤 playbook 剧本 playbooks 本身由以下各部分组成 &#…...

解决 tensorflow 出现的 ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘. 问题

在安装完tensorflow库后出现 问题详述&#xff1a; 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:历史、投资和监管

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

Kafka3.0.0版本——Broker(Zookeeper服务端存储的Kafka相关信息)

目录 一、启动zookeeper集群及kafka集群服务启动1.1、先启动三台zookeeper集群服务&#xff0c;再启动三台kafka集群服务1.2、使用PrettyZoo连接zookeeper客户端工具 二、在zookeeper服务端存储的Kafka相关信息 一、启动zookeeper集群及kafka集群服务启动 1.1、先启动三台zook…...

【图论】无向图连通性(tarjan算法)

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

Docker安装

Docker实践 yum安装 YUM源可以使用官方YUM源、清华大学开源镜像站配置YUM源&#xff0c;也可以使用阿里云开源镜像站提供的YUM源&#xff0c;建议选择使用阿里云开源镜像站提供的YUM源&#xff0c;原因速度快。 地址: https://developer.aliyun.com/mirror/ 我们安装ce版 …...

06. 计数原理

6. 计数原理 6.1 分类加法计数原理与分步乘法计数原理 分类加法计数原理定义 完成一件事&#xff0c;有 n n n 类办法&#xff0c;在第1类办法中有 m 1 m_1 m1​ 种不同的方法&#xff0c;在第2类办法中有 m 2 m_2 m2​ 种不同的方法&#xff0c;…&#xff0c;在第 n n…...

计算机网络基础(静态路由,动态路由,公网IP,私网IP,NAT技术)

文章目录 一&#xff1a;静态路由和动态路由二&#xff1a;静态路由的配置路由信息的方式演示三&#xff1a;默认路由四&#xff1a;公网IP和私网IP和NAT技术的基本理解 一&#xff1a;静态路由和动态路由 在说静态路由和动态路由前&#xff0c;我们需要来了解一下&#xff0…...

CGAL 点云Alpha-Shape曲面重建算法

文章目录 一、简介二、相关参数三、实现代码四、实现效果参考资料一、简介 在数学上, a l p h a − s h a p e alpha-shape a...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...