谷粒商城第七天-商品服务之分类管理下的分类的拖拽功能的实现
目录
一、总述
1.1 前端思路
1.2 后端思路
二、前端实现
2.1 判断是否能进行拖拽
2.2 收集受影响的节点,提交给服务器
三、后端实现
四、总结
一、总述
这个拖拽功能对于这种树形的列表,整体的搬迁是很方便的。但是其实现却并不是那么的简单。
1.1 前端思路
花样主要体现在前端上面,前端有两个大的部分,一个是使用elementUI提供给我们的api判断是否能够进行拖拽,因为并不是能够随意的拖拽的,因为这个树形列表是三级分类,受到了三级的限制。另外一个部分就是拖拽之后,会有一些节点的信息将发生改变,需要进行收集,然后统一发到后端服务器,进行修改
1.2 后端思路
而后端的话没什么,就一个修改接口就行了。
二、前端实现
当然最开始肯定得开启树形控件的可拖拽功能

默认是未开启的,需要我们手动开启

2.1 判断是否能进行拖拽
完成这个功能需要依靠elementUI提供给我们的api,我下面简单的介绍一下这个api

然后在树形控件的参数那里放上这个参数,并给上一个方法

然后根据它提供给我们的这三个信息来进行判断,最终决定是否能拖拽成功。
这个判断的核心逻辑是:
1. 先计算出被拖拽节点的最大层数
计算方法是:使用打擂台的方式计算出子节点的最大深度,并递归的计算其又子节点的最大深度,得到这个目标节点的子节点的最大深度,但这个只是子节点的最大深度,并不是以被拖拽节点为始发层的最大层数,那么如何计算呢?实际上就是求差,现在求得是总的,我们并不需要前面的那一截了,因为等下我要换地方了,前面的那一截就换了,而被拖拽的那一部分是不变的,那前面的那一部分又该怎样得到呢?
其实就是当前拖拽节点的层级,然后使用子节点的最大深度 - 当前拖拽节点的层数 + 1 就得到了当前被拖拽节点的最大层数。
1.1 使用打擂台的方式计算出子节点的最大深度


computerMaxLevel(node){var childrenNodeList = node.childNodes;//console.log("childrenNodeList",childrenNodeList);if(childrenNodeList!=null){for(let i = 0;i<childrenNodeList.length;i++){//console.log(1111);if(childrenNodeList[i].level>this.maxLevel){this.maxLevel = childrenNodeList[i].level;}this.computerMaxLevel(childrenNodeList[i]);}}}
2. 计算拖拽后总层数(也就是目标结果)
现在的话拖的一部分已经有了,但是拖到的位置,那里所占据的层数还没有考虑,现在的工作就是加上新地方的层数。
现在的计算得按照不同情况进行计算,因为有两种情况:
2.1 与拖到的目标节点同层级,互为兄弟
那么就是目标节点的父节点的层级 + 刚刚求出的被拖拽节点的最大层数
2.2 是拖到的目标节点的孩子
那么直接就是目标节点的层级 + 刚刚求出的被拖拽节点的最大层数
3. 直接判断
当拖拽后的总层数<=3时,判断方法返回true,拖拽成功
否则拖拽失败

allowDrop(draggingNode, dropNode, type) {this.maxLevel = draggingNode.level;console.log(draggingNode, dropNode, type);this.computerMaxLevel(draggingNode);console.log("maxLevel",this.maxLevel);var deep = this.maxLevel - draggingNode.level +1;console.log("deep",deep);if(type == "before"|| type == "next"){return (deep + dropNode.parent.level)<=3;}else{return (deep + dropNode.level)<=3;}}
2.2 收集受影响的节点,提交给服务器
首先要明白有哪些节点会受到影响。
1. 前序的数据域中数据的定义

一、考虑影响了别人
其实就是影响了兄弟。
如果说被拖拽节点与目标节点经拖拽后互为兄弟关系的话,那么就会影响到其他兄弟的排序顺序,因为现在多加了一个节点,势必这个新增节点之后的节点顺序都要向后推一位。(这些兄弟就需要收集起来)


当然如果被拖拽节点与目标节点经拖拽后互为父子关系的话,那么就改变了目标节点的子节点的那些兄弟。
二、考虑影响了自己
被拖拽节点拖拽后,到其他父节点上面去了,因此被拖拽节点的父节点也发生了改变,另外被拖拽节点的层级也将发生变化,其被拖拽节点的子节点的父节点不会变,还是被拖拽节点,可是其子节点的层级肯定发生了改变,其子节点的字节点的层级也发生了改变,因此需要递归操作
总的来说标红的三处地方就是需要提交到服务器的节点,但是并不是需要提供节点的完整信息,而是提供需要修改的信息即可:
1. 对于那些兄弟节点,提供兄弟节点的 id和 排序值就可以了,根据id主键进行修改
2. 对于那个被拖拽节点,需要提供被拖拽节点的 id、父节点、还有最新的层级
3. 对于其被拖拽节点的字节点,需要提供其节点的id 以及节点最新的层级即可
最后将这三部分的节点,提交给服务器就行了。
思路我说了,最后代码进一步的简洁,我已经说的很明白了,在截图中,这里为什么和我刚刚说了有点不一样,就是那个sort字段为什么任何时候都需要加上这个,是因为其实数据库本来全是0的,正是靠这个算法才赋上值,当然这里也不全面,只涉及到修改了的部分,详细的代码参考如下:

handleDrop(draggingNode, dropNode, dropType){//受影响的数组var nodes = null;if(dropType == "before" || dropType == "next"){nodes = dropNode.parent.childNodes;this.pCid = dropNode.parent.data.catId==undefined?0:dropNode.parent.data.catId;}else{nodes = dropNode.childNodes;this.pCid = dropNode.data.catId;}console.log("nodes",nodes);for(let i=0;i<nodes.length;i++){if(nodes[i].data.catId == draggingNode.data.catId){this.updateNodes.push({catId:nodes[i].data.catId,sort:i,parentCid:this.pCid,level:nodes[i].level})if(nodes[i].data.level != nodes[i].level){//因为被拖拽的节点的层级发生了改变,因此其子节点的层级也会跟着改变this.updateChirenLevel(nodes[i]);} }else{this.updateNodes.push({catId:nodes[i].data.catId,sort:i})}}console.log("updateNodes",this.updateNodes);},//修改子节点的levelupdateChirenLevel(node){if(node.childNodes!=null && node.childNodes.length>0){for(let i=0;i<node.childNodes.length;i++){this.updateNodes.push({catId:node.childNodes[i].data.catId,level:node.childNodes[i].level,sort:i});this.updateChirenLevel(node.childNodes[i]);}}},
最终将需要更新的节点数组作为请求参数提交给后端,在后端修改即可


三、后端实现
后端的话很简单,就一个修改接口,使用MP的方法,根据主键进行批量修改。

/*** 批量修改商品分类信息*/@ApiOperation("批量修改商品分类信息")@Log(title = "批量修改商品分类信息",businessType = BusinessType.UPDATE)@PutMapping("/batchUpdateCategory")public AjaxResult batchEdit(@RequestBody List<Category> categoryList){return toAjax(categoryService.updateBatchById(categoryList));}
四、总结
其实总的来说只要想清楚了,其实还是很简单的。
这里关键是前端的逻辑稍微有那么点复杂,有写算法题的那味了,但是仔细一想还是挺简单的。
主要是关系,还有数量关系等,比如说求被拖拽节点的最大层数,需要用到数量计算表达式
其实就是一个减法,用子节点的最大深度减去被拖拽节点的层数 + 1 即可求得其被拖拽节点的最大层数,有了这个最大层数然后再配合目标那里的层数,按照不同的条件进行相加,最后总的层数不就出来了吗?有了总层数当然是否能拖拽就好判断了。
另外还有就是搬过来之后会导致一些节点的信息发送改变,此时就需要收集起来,发给后端,再后端进行修改,这里关键是想明白到底哪些节点修改了,需要收集哪些属性,其实也是很简单的,想清楚就好了。
相关文章:
谷粒商城第七天-商品服务之分类管理下的分类的拖拽功能的实现
目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端实现 2.1 判断是否能进行拖拽 2.2 收集受影响的节点,提交给服务器 三、后端实现 四、总结 一、总述 这个拖拽功能对于这种树形的列表,整体的搬迁是很方便的。但是其实现却并不是那么的简单。 …...
解决单节点es索引yellow
现象 单节点的es,自动创建索引后,默认副本个数为1,索引状态为yellow 临时解决 修改副本个数为0 永久解决 方法1、修改elasticsearch.yml文件,添加配置并重启es number_of_replicas:副本分片数,默认…...
Java虚拟机在类加载阶段都做了些什么,才使得我们可以运行Java程序
前言: 今天和大家探讨一道Java中经典的面试题,这道面试题经常出现在各个公司的面试中,结合周志明,老师的《深入理解Java虚拟机》书籍,本篇文章主要讲解Java类加载机制的知识。该专栏比较适合刚入坑Java的小白以及准备秋…...
华为认证 | 学HCIE,想培训需要注意啥?
HCIE(华为认证网络专家)是华为技术认证体系中的最高级别认证,对于网络工程师来说考试难度也比较高,一般来说,需要进行培训。 那么HCIE考试培训需要注意啥? 01 充分了解认证要求 在开始准备HCIE认证之前&a…...
这所211考数一英二,学硕降分33分,十分罕见!
一、学校及专业介绍 合肥工业大学(Hefei University of Technology),简称“合工大”,校本部位于安徽省合肥市,是中华人民共和国教育部直属的全国重点大学,是国家“双一流”建设高校, 国家“211工…...
关于BQ27427的配置问题
EVM是TI家做的BQ27427的开发板,这款芯片还挺新的。 大概是这样,一块开发板要一千多块钱,使用的时候还出现了一些奇怪的问题。 配置使用的是买的盗版的EV2400,就是黑色的那个东西,使用的通信方式IIC。 TI手册上写的软件…...
试卷还原成空白卷怎么做?分享个简单的方法
在进行考试时,可能会填错答案或想要重新测试,此时需要正确擦除填写的试卷答案。下面介绍一些需要注意的事项以及正确的擦除方法。 使用橡皮擦或橡皮 正确的擦除方法是使用橡皮擦或橡皮对填写的答案进行擦除。首先,将橡皮擦或橡皮放置在试卷上…...
查看学校名称中含北京的用户
查看学校名称中含北京的用户_牛客题霸_牛客网 1.like select device_id,age,university from user_profile where university like %北京%; 注意虽然按实际需求,北京一般是排在最前面,即北京%,但是严格意义上来说,搜索含有北京…...
快速开发人脸识别系统Java版本
简介: 先说下什么是人脸识别系统:举个例子,公司门口有个人脸识别系统,员工站到门口,看着摄像头,大屏幕上会抓拍到你的人脸,然后和公司的员工照片库里的照片比对,比对成功就提示&…...
Reinforcement Learning with Code 【Code 1. Tabular Q-learning】
Reinforcement Learning with Code 【Code 1. Tabular Q-learning】 This note records how the author begin to learn RL. Both theoretical understanding and code practice are presented. Many material are referenced such as ZhaoShiyu’s Mathematical Foundation o…...
解决:Uncaught (in promise) SyntaxError: “[object Object]“ is not valid JSON 问题的过程
1、问题描述: 其一、报错为: Uncaught (in promise) SyntaxError: "[object Object]" is not valid JSON 中文为: 未捕获(承诺中)语法错误:“[object Object]”不是有效的 JSON 其二、问题描…...
机器学习-New Optimization
机器学习(New Optimization) 前言: 学习资料 videopptblog 下面的PPT里面有一些符号错误,但是我还是按照PPT的内容编写公式,自己直到符号表示什么含义就好了 Notation 符号解释 θ t \theta_t θt第 t 步时,模型的参数 Δ L …...
3d虚拟vr汽车实景展厅吸引更多潜在消费者
随着人们对生活品质的追求,越来越多的消费者开始关注汽车的外观设计、内饰配置等方面。传统的展示方式已经不能满足消费者的需求,车辆VR虚拟漫游展示应运而生。借助VR虚拟现实和web3d开发建模技术,对汽车的外观、造型及信息数据进行数字化处理…...
Java里的static import使用小结
Java里的static import使用小结 换了工作要把Java重新捡起来了,这个在大学里用过的语言,虽然不复杂,还是有一些奇怪的地方的。比如static Slgluimport。 Static import是JDK 1.5中引进的特性,不过读大学那会还真没注意到。它的作…...
go程序使用tcp短连接报:only one usage of each socket address
环境及现象 Win10上位机(C#,WPF)后台使用go作为服务。 连接情况 C#连接大概60个TCP长连接(设备)。 后台go服务连接60个UDP短连接(设备附属硬件), 10个TCP短连接(PLC,modbus通讯&a…...
十分钟配置好Neovim go开发环境(其他语言一样)
文章目录 前言仓库地址用法快捷键问题反馈 前言 这篇文章的目的是为了分享下我自己的Neovim配置。 本人是Golang程序员,最开始使用的IDE是JetBrains Goland。有一说一这个ide适配度很高,认识的很多人都使用这个。但是它也有几个对我来说的缺点…...
Linux第八章之进程概念
一、冯诺依曼体系结构 关于冯诺依曼,必须强调几点: 这里的存储器指的是内存不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)外设(输入或输出设备)要输入或者输出数据,也只能写入内存或…...
怎么学习Java并发编程相关技术? - 易智编译EaseEditing
学习Java并发编程可以通过多种方式进行,包括但不限于以下几种: 在线教程和学习平台: 网上有许多免费和付费的Java并发编程教程和学习平台,如Coursera、Udemy、edX、Codecademy等。这些平台提供结构化的课程和练习,适…...
vue3 +element动态表单实现
可以直接复制,接口看后端 父页面 <schedulesref"schedulesRef":dxbz"props.dxbz":jdlx"props.jdlx":woId"myWoId":addendumList"formInline.addendumList"v-if"addendumShow"addendum"addendu…...
Linux部署jar包,隐藏命令行参数
Linux部署jar包,隐藏命令行参数 一、背景需求二、查阅资料三、实现隐藏库3.1、测试test.c3.2、设置隐藏库3.3、验证 四、应用jar启动命令五、直接应用结果 最新项目安全检测,发现配置文件中数据库密码,redis密码仍处理明文状态 于是整理了一篇…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
