谷粒商城第七天-商品服务之分类管理下的分类的拖拽功能的实现

news2024/11/18 18:37:54

目录

一、总述

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);
    },
    //修改子节点的level
    updateChirenLevel(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 即可求得其被拖拽节点的最大层数,有了这个最大层数然后再配合目标那里的层数,按照不同的条件进行相加,最后总的层数不就出来了吗?有了总层数当然是否能拖拽就好判断了。

另外还有就是搬过来之后会导致一些节点的信息发送改变,此时就需要收集起来,发给后端,再后端进行修改,这里关键是想明白到底哪些节点修改了,需要收集哪些属性,其实也是很简单的,想清楚就好了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/813715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CMU15-213 课程笔记 01-课程概览

知识点 这门课的目的&#xff1a;深入理解当你执行代码时&#xff0c;计算机在做什么 LLDB&#xff1a;基于 LLVM 的命令行调试器&#xff0c;类似 GBD 内存引用 Bug typedef struct {int a[2];double d; } struct_t;double fun(int i) {volatile struct_t s;s.d 3.14;s.a…

Flowable-服务-邮件任务

目录 定义图形标记XML内容邮件服务器配置界面操作 定义 Flowable 支持通过自动的邮件服务任务&#xff08;Email Task&#xff09;增强业务流程&#xff0c;它可以向一个或多个收信人发送 邮件&#xff0c;支持 cc&#xff0c;bcc&#xff0c;HTML 内容等。 流程流转到邮件任务…

xshell连接liunx服务器身份验证不能选择password

ssh用户身份验证不能选择password 只能用public key的解决办法 问题现象 使用密码通过Workbench或SSH方式(例如PuTTY、Xshell、SecureCRT等)远程登录ECS实例时&#xff0c;遇到服务器禁用了密码登录方式错误. 可能原因 该问题是由于SSH服务对应配置文件/etc/ssh/sshd_config中…

【软件安装】MATLAB_R2021b for mac 安装

Mac matlab_r2021b 安装 下载链接&#xff1a;百度网盘 下载链接中所有文件备用。 我所使用的电脑配置&#xff1a; Macbook Pro M1 Pro 16512 系统 macOS 13.5 安装步骤 前置准备 无此选项者&#xff0c;自行百度 “mac 任何来源”。 1 下载好「MATLAB R2021b」安装文…

stm32 舵机 cubemx

文章目录 前言一、cubemx配置二、代码1.serve.c2.serve.h3.主函数 总结 前言 stm32对舵机进行控制&#xff0c;很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此&#…

【C语言】扫雷(保姆级教程+内含源码)

C系列文章目录 前言 一&#xff0c;模块化编程 二&#xff0c;游戏思路与逻辑 三&#xff0c;实现游戏步骤/过程 1&#xff0c;菜单界面(menu) 2&#xff0c;实现多行多列扫雷 3&#xff0c; 实现多个雷 4,棋盘初始化 5&#xff0c;棋盘的打印 6&#xff0c;布置雷…

连接器信号完整性仿真教程 六

连接器信号完整性仿真教程五中,讲了波导端口中同轴波导端口及多Pin波导端口的设置。本将继续以实例演示的方式讲解波导端口中的微带(Microstrip Line)波导端口的设置及其在连接器信号完整性仿真中的应用。 一 微带线(Microstrip Line) 由介基材(Dielectric Substrate)及…

正则表达式速通

简介 正则表达式&#xff0c;我们可以看作通配符的增强版&#xff0c;可以帮我们匹配指定规则的字符串&#xff0c;在计算机中应用广泛&#xff0c;比如说爬虫、网站的登录表单等。 原视频&#xff1a;https://www.bilibili.com/video/BV1da4y1p7iZ 学习正则表达式的常用工具…

【LeetCode每日一题】——566.重塑矩阵

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 566.重塑矩阵 四【题目描述】 在 MATLAB 中&…

【C++ 程序设计】实战:C++ 实践练习题(1~10)

目录 01. 二维数组 02. 奇偶性 03. 指针与变量 04. 员工薪资 05. 整型值&#xff08;%4d 进行格式化&#xff09; 06. 求三个数中的最大值和最小值 07. 同一字母次数统计 08. 字符串回文判断 09. 闰年判断 10. 交换两个双精度数 01. 二维数组 #include <stdio.…

系统学习Linux-MySQL主从复制及读写分离(五)

部署MySQL主从异步复制 在MySQL Master上的配置NTP时间同步服务器 [rootlocalhost ~]# rpm -q ntpntp-4.2.6p5-28.el7.centos.x86_64[rootlocalhost ~]# vim /etc/ntp.conf #添加两行server 127.127.1.0fudge 127.127.1.0 stratum 8 启动NTP服务 [rootlocalhost ~]# system…

pytorch(续周报(1))

文章目录 2.1 张量2.1.1 简介2.1.2 创建tensor2.1.3 张量的操作2.1.4 广播机制 2.2 自动求导Autograd简介2.2.1 梯度 2.3 并行计算简介2.3.1 为什么要做并行计算2.3.2 为什么需要CUDA2.3.3 常见的并行的方法&#xff1a;网络结构分布到不同的设备中(Network partitioning)同一层…

C++入门篇2---类和对象(上)

看前须知:何为面向对象&#xff1f; 面向对象&#xff08;Object-oriented&#xff09;是一种计算机编程的方法论和编程范式。面向对象的核心思想是将数据&#xff08;对象&#xff09;和操作&#xff08;方法&#xff09;封装在一起&#xff0c;形成一个相互关联和相互作用的…

Diffusion mdoel: Denoising Diffusion Probabilistic Models论据解读及实现(一)

论文地址&#xff1a;https://arxiv.org/pdf/2006.11239.pdf 1 正向加噪推导 **核心公式1 ** x t α ˉ t ∗ x 0 1 − α ˉ t z t x_t\sqrt{\bar \alpha_t}*x_{0}\sqrt{1-\bar \alpha_t}z_t xt​αˉt​ ​∗x0​1−αˉt​ ​zt​ 证明如下&#xff1a; α t 1 − β…

芯片制造详解.刻蚀原理.学习笔记(五)

本篇笔记是看完原视频后的整理和补充&#xff0c;建议各位观看原视频&#xff0c;这里附上地址。 如何雕刻芯片&#xff1a;刻蚀原理&#xff5c;芯片制造详解05 芯片制造详解.刻蚀原理.学习笔记 五 一、刻蚀技术的分类二、刻蚀中三个关键指标2.1 刻蚀速率2.2 选择比2.3 方向性…

linux配置固定ip

为什么要固定ip&#xff1f; 虚拟机是利用DHCP&#xff08;动态获取ip&#xff09;&#xff0c;ip地址会频繁变化&#xff0c;不利于远程连接linux&#xff0c;同时会改变映射关系。 VMware 第一步&#xff1a;在workstation中配置IP地址网关和网段 1.点击虚拟网络编辑器 …

RISCV - 4 ISA 扩展名命名约定

RISCV - 4 ISA 扩展名命名约定 1 Case Sensitivity2 Base Integer ISA3 Instruction-Set Extension Names4 Version Numbers5 Underscores6 Additional Standard Extension Names7 Supervisor-level Instruction-Set Extensions8 Hypervisor-level Instruction-Set Extensions9…

28_计算机网络(Computer Networks)基础

本篇介绍计算机网络的基础知识。 文章目录 1. 计算机网络历史2. 以太网" (Ethernet)2.1 以太网" (Ethernet)的简单形式及概念2.2 指数退避解决冲突问题2.3 利用交换机减少同一载体中设备2.4 互联网&#xff08;The Internet&#xff09;2.5 路由(routing)2.6 数据包…

【Spring AOP + 自定义注解 + 动态数据源 实现主从库切换读写分离】—— 案例实战

&#x1f4a7; S p r i n g A O P 主从数据源切换 读写分离 自定义注解案例实战&#xff01; \color{#FF1493}{Spring AOP 主从数据源切换 读写分离 自定义注解 案例实战&#xff01;} SpringAOP主从数据源切换读写分离自定义注解案例实战&#xff01;&#x1f4a7; …

第三课:运算符

1.算数运算符 int a 20; int b 10; System.out.println(a b); // 30 System.out.println(a - b); // 10 System.out.println(a * b); // 200 System.out.println(a / b); // 2 System.out.println(a % b); // 0 --->模运算相当于数学中除法的余数 ⚠关于/除法 public s…