java+vue3+el-tree实现树形结构操作
基于springboot + vue3 elementPlus实现树形结构数据的添加、删除和页面展示
效果如下
代码如下,业务部分可以自行修改
- java后台代码
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.daztk.mes.common.annotation.LogOperation;
import com.daztk.mes.common.utils.Result;
import com.daztk.mes.module.cad.dto.CadPartDto;
import com.daztk.mes.module.cad.entity.CadPart;
import com.daztk.mes.module.cad.entity.CadRelation;
import com.daztk.mes.module.cad.service.ICadPartService;
import com.daztk.mes.module.cad.service.ICadRelationService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.*;
import java.util.stream.Collectors;/*** <p>* 零部件 * </p>** @since 2024-05-30*/
@RestController
@RequestMapping("cad/part")
public class CadPartController {@AutowiredICadPartService service;@AutowiredICadRelationService relationService;/*** 获取所有零部件* @param dto* @return*/@GetMapping("listAll")public Result listAll(CadPartDto dto){List<CadPart> list = new ArrayList<>();try {list = service.getList(dto);if(CollectionUtils.isNotEmpty(list)){list = getTree(list);}} catch (Exception e) {e.printStackTrace();return new Result().err();}return new Result().ok().setData(list);}@PostMapping("add")@LogOperation(tags = "CAD管理-零部件",serviceClass = ICadPartService.class,entityClass = CadPart.class)public Result add(@RequestBody CadPart cadPart){try {service.saveData(cadPart);} catch (Exception e) {e.printStackTrace();return new Result().err();}return new Result().ok().setData(cadPart);}@DeleteMapping("delete")@LogOperation(tags = "CAD管理-零部件",serviceClass = ICadPartService.class,entityClass = CadPart.class)public Result delete(@RequestBody Long[] ids){try {List<Long> idList = Arrays.asList(ids);List<Long> list = recurveIdList(idList);service.removeByIds(list);} catch (Exception e) {e.printStackTrace();return new Result().err();}return new Result().ok();}/*** 递归获取id树** @param ids* @return*/public List<Long> recurveIdList(List<Long> ids){List<Long> list = new ArrayList<>();for(Long id: ids){list.add(id);//关系表查子集List<CadRelation> cadRelations = relationService.list(new QueryWrapper<CadRelation>().eq("parent_id", id));if(CollectionUtils.isNotEmpty(cadRelations)){List<Long> partIds = cadRelations.stream().map(CadRelation::getPartId).collect(Collectors.toList());List<Long> list1 = recurveIdList(partIds);list.addAll(list1);}}return list;}public List<CadPart> getTree(List<CadPart> treeList){List<CadPart> collect = treeList.stream().filter(item -> item.getParentId() == 0)//构造最外层节点,即id=0的节点.map(item -> {item.setChildren(getChildren(item, treeList));//id=0的节点就为他设置子节点return item;}).collect(Collectors.toList());return collect;}private static List<CadPart> getChildren(CadPart treeEntity, List<CadPart> treeEntityList) {List<CadPart> collect = treeEntityList.stream().filter(item -> item.getParentId().equals(treeEntity.getId()))//判断当前节点的父id是不是要设置节点的id.map(item -> {item.setChildren(getChildren(item, treeEntityList));//如果是 为其设置子节点 通过递归 为每个除了最外层节点的节点设置子节点return item;}).collect(Collectors.toList());return collect;}
- 前端代码
<template><div class="custom-tree-container"><!-- <p>Using render-content</p><el-tree style="max-width: 600px" :data="dataSource" show-checkbox node-key="id" default-expand-all:expand-on-click-node="false" :render-content="renderContent" /> --><el-button type="primary" class="add-btn" icon="el-icon-circle-plus-outline" @click="addEdit">新增零部件</el-button><div style="padding-top: 20px;"><el-tree style="max-width: 600px; " :data="dataSource" show-checkbox node-key="id" default-expand-all:expand-on-click-node="false" ref="treeRef" :props="mapProps"><template #default="{ node, data }"><span class="custom-tree-node"><span>{{ node.label }}</span><span><a @click="append(data)"> 增加子节点 </a><a style="margin-left: 8px" @click="removeNode(node, data)"> 删除 </a></span></span></template></el-tree></div><el-dialog :title="title" v-model="drawer" width="600px"><el-form :model="partForm" :rules="rules" ref="ruleFormsss" label-width="120px" class="demo-partForm"><el-form-item label="数模号:" prop="partNo"><el-input v-model="partForm.partNo" clearable></el-input></el-form-item><el-form-item label="版本号:" prop="partRev"><el-input v-model="partForm.partRev" clearable></el-input></el-form-item><el-form-item label="名称:" prop="name"><el-input v-model="partForm.name" clearable></el-input></el-form-item><el-form-item label="中文名称:" prop="cName"><el-input v-model="partForm.cName" clearable></el-input></el-form-item><el-form-item label="材料:" prop="material"><el-input v-model="partForm.material" clearable></el-input></el-form-item><el-form-item label="规格:" prop="gauge"><el-input v-model="partForm.gauge" clearable></el-input></el-form-item><el-form-item label="重量:" prop="massqty"><el-input v-model="partForm.massqty" clearable></el-input></el-form-item><el-form-item label="数据类型:" prop="partType"><el-input v-model="partForm.partType" clearable></el-input></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="cancelEdit">取 消</el-button><el-button type="primary" @click="saveEdit">确 定</el-button></span></template></el-dialog></div>
</template><script>
import { reactive, ref, toRefs, unref, onMounted } from 'vue'
import { add, remove, listAll } from '@api/cad/part'
import { ElMessage } from 'element-plus'export default {name: 'part',setup() {const state = reactive({drawer: false,title: '',query: {partName: ''},dataSource: [// {// id: 1,// label: 'Level one 1',// children: []// // children: [// // {// // id: 4,// // label: 'Level two 1-1',// // children: [// // {// // id: 9,// // label: 'Level three 1-1-1'// // }// // ]// // }// // ]// }],mapProps: {id: 'id',label: 'name',children: 'children'}})const treeRef = ref(null)const append = (data) => {state.drawer = truestate.title = '添加子节点'partForm.parentId = data.idpartForm.partNo = ''partForm.partRev = ''partForm.name = ''partForm.cName = ''partForm.material = ''partForm.gauge = ''partForm.massqty = ''partForm.partType = ''// debugger// 获取当前节点// const currentNode = treeRef.value.getNode(data.id)// // 获取当前节点在树中的索引// // const currentIndex = getNod(data.id)// // // 如果索引大于 0,获取前一个节点// // if (currentIndex > 0) {// // const prevNode = getNodeAt(currentIndex - 1);// // const prevId = prevNode.id; // // // 处理前一个节点的 id// // }// let treeNodeId = data.$treeNodeId //节点id// console.info(data)// // alert('当前id'+data.id)// // alert(data.$treeNodeId)// let id = null// if (!data.children || data.children.length == 0) {// //没有子节点// id = data.id * 100 + 1// } else {// id = data.id * 100 + 1 + data.children.length// }// const newChild = { id: id, label: data.label + '-' + id, children: [] }// const child = [{ id: id, label: data.label + '-' + id, children: [] }]// data.children = child// data.push()// state.dataSource = [data];}const removeNode = (node, data) => {const ids = []ids.push(data.id)remove(ids).then(res => {if (res.code == 200) {ElMessage({type: 'success',message: '删除成功'})getPartTableData(state.query)} else {ElMessage({type: 'error',message: res.msg})}})// dataSource.value = [...dataSource.value];}const partForm = reactive({partNo: '',partRev: '',name: '',cName: '',material: '',gauge: '',massqty: '',partType: '',parentId: ''})const ruleFormsss = ref(null)const addEdit = () => {state.drawer = truestate.title = '添加零部件'partForm.parentId = ''partForm.partNo = ''partForm.partRev = ''partForm.name = ''partForm.cName = ''partForm.material = ''partForm.gauge = ''partForm.massqty = ''partForm.partType = ''}// 取消const cancelEdit = () => {state.drawer = falsesetTimeout(() => {const form = unref(partFormsss)form.resetFields()}, 100)}// 新建/编辑零部件const saveEdit = async () => {const form = unref(ruleFormsss)if (!form) returntry {await form.validate()if (state.title == '添加零部件' || state.title == '添加子节点') {addSavePart()}if (state.title == '编辑零部件') {updateSavePart()}state.drawer = false} catch (error) {console.error(error)ElMessage.error('抱歉,您有必填项未填!')}}const addSavePart = () => {// let quantity = partForm.quantity + partForm.iQuantityconst data = {partNo: partForm.partNo,partRev: partForm.partRev,name: partForm.name,cName: partForm.cName,material: partForm.material,gauge: partForm.gauge,massqty: partForm.massqty,partType: partForm.partType,parentId: partForm.parentId}add(data).then(res => {state.drawer = false// const treeData = {// id: res.data.id,// label: res.data.name,// children: []// }// state.dataSource = res.datagetPartTableData(state.query)ElMessage.success('恭喜您,添加成功!')})}const updateSavePart = () => {const data = {id: state.handleId,name: partForm.name,manager: partForm.manager,startDate: partForm.startDate,endDate: partForm.endDate}update(data).then(res => {state.drawer = falsegetPartTableData(state.query)ElMessage.success('恭喜您,保存成功!')})}const rules = {name: [{ required: true, message: '此处为必填项', trigger: 'blur' }]}function getPartTableData() {listAll(state.query).then(res => {state.dataSource = res.data})}onMounted(() => {getPartTableData()})return {...toRefs(state),append,removeNode,addEdit,cancelEdit,treeRef,partForm,ruleFormsss,saveEdit,rules}}
}</script><style lang="scss" >
.el-tree-node {margin-top: 8px;
}
.custom-tree-node {flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 18px;padding-right: 8px;
}</style>
相关文章:

java+vue3+el-tree实现树形结构操作
基于springboot vue3 elementPlus实现树形结构数据的添加、删除和页面展示 效果如下 代码如下,业务部分可以自行修改 java后台代码 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.daztk.mes.common.annotation.LogOperation…...
Oracle创建索引的LOGGING | NOLOGGING区别
在Oracle中,创建索引时的LOGGING和NOLOGGING选项主要影响索引创建过程中产生的重做日志(redo log)的数量。这两个选项对于性能和数据恢复能力有着显著的影响。以下是关于这两个选项的详细解释和区别: LOGGING 定义:当…...

GoogleDeepMind联合发布医学领域大语言模型论文技术讲解
Towards Expert-Level Medical Question Answering with Large Language Mod 这是一篇由Google Research和DeepMind合作发表的论文,题为"Towards Expert-Level Medical Question Answering with Large Language Models"。 我先整体介绍下这篇论文的主要内容&#x…...

Spark安装、解压、配置环境变量、WordCount
Spark 小白的spark学习笔记 2024/5/30 10:14 文章目录 Spark安装解压改名配置spark-env.sh重命名,配置slaves启动查看配置环境变量 工作流程maven创建maven项目配置maven更改pom.xml WordCount按照用户求消费额上传到spark集群上运行 安装 上传,直接拖拽…...
DeepSeek-V2-Chat多卡推理(不考虑性能)
TOC 本文演示了如何使用accelerate推理DeepSeek-V2-Chat(裁剪以后的模型,仅演示如何将权值拆到多卡) 代码 import torch from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig from accelerate import init_empty_weights import sys from acce…...
算法题day42(补5.28日卡:动态规划02)
今天的动态规划都是二维的,与昨日不同。 一、刷题: 1.leetcode题目 62. 不同路径 - 力扣(LeetCode)(medium,) 解决: class Solution:def uniquePaths(self, m: int, n: int) -> int:dp …...
分治与递归
实验一:分治与递归 【实验目的】 深入理解分治法的算法思想,应用分治法解决实际的算法问题。 【实验性质】 验证性实验(学时数:2H) 【实验内容与要求】 1、设有n2k个运动员要进行网球循环赛。现要设计一个满足以…...

Spring中IOC容器
IoC IOC容器 IoC是一种设计思想,面向对象编程 Spring通过IoC管理所有Java对象的实例化和初始化,控制对象之间依赖关系 将IoC容器管理的Java对象称为Spring Bean,与new创建的对象没有区别 控制反转(IoC Inversion of Controle&a…...

php redis分布式锁
一,概念 在PHP中实现分布式锁通常可以使用数据库、缓存系统(如Redis)或者其他中央存储系统来保证在分布式系统中的数据一致性与同步。秒杀下单、抢红包等等业务场景,都需要用到分布式锁。 常规方案大概有七中 方案一:…...
kotlin 中的布尔
1、kotlin中内置的Boolean类型,可以有true与false两个值的布尔对象。 布尔值的内置运算有(跟很多语言如java、js一摸一样): ||——逻辑或&&——逻辑与!——逻辑非 fun main() {val a: Boolean trueval b: Boolean fa…...

有哪些ai聊天推荐?简单分享三款
有哪些ai聊天推荐?在当今数字化时代,人工智能(AI)聊天软件已经成为我们日常生活中不可或缺的一部分。无论是与朋友、家人还是同事交流,这些智能聊天软件都能为我们提供极大的便利。那么,市面上有哪些值得推…...

Python第二语言(十、Python面向对象(上))
目录 1. 标记变量的基础类型 2. 初识对象 2.1 使用对象组织数据 3. 成员变量 3.1 类和类成员的定义 3.2 成员变量和成员方法使用 3.3 成员方法的定义语句 4. 类和对象class Clock: def ring(self): 4.1 创建类对象的语法:对象名 类名称() 4.2 用生活中的…...

SolidWorks 2016 SP5安装教程
软件介绍 Solidworks软件功能强大,组件繁多。 Solidworks有功能强大、易学易用和技术创新三大特点,这使得SolidWorks 成为领先的、主流的三维CAD解决方案。 SolidWorks 能够提供不同的设计方案、减少设计过程中的错误以及提高产品质量。SolidWorks 不仅…...

为什么高考志愿只选计算机专业?
刚刚高考结束,不知道各位学弟学妹考的怎么样啊? 高考毕竟是对十二年寒窗苦读的评判,也是很多人改变命运的机会。很多同学每天等待出分的过程很煎熬,既吃不好也玩不好(os:这种同学还挺多的)。 但…...
GPT大模型微调-提高垂直领域回答质量
微调一个大模型并测试微调后的效果是一个很好的学习实践。下面是一个逐步指导,帮助你使用一个较小的预训练大模型进行微调,并测试其效果。我们将使用 Hugging Face 的 Transformers 库和一个较小的预训练模型,如 DistilBERT。这个库非常流行且易于使用。 实现步骤 步骤 1:…...

全网首发-Docker被封后的代理设置教程
最近上交、科大以及阿里的一些docker镜像,好像都因为不可控力导致无法访问。 所以,之前好多正常的一些镜像的打包都会报错: 比如: #1 [internall load build definition from Dockerfile#1transferring dockerfile:972B done#1 D…...
代码随想录算法训练营第五十七天|1143.最长公共子序列、1035.不相交的线、53. 最大子序和、392.判断子序列
代码随想录算法训练营第五十七天 1143.最长公共子序列 题目链接:1143.最长公共子序列 确定dp数组以及下标的含义:dp[i][j] :以下标i - 1为结尾的text1,和以下标j - 1为结尾的text2,最长重复子数组长度为dp[i][j]确…...

RocketMQ事务性消息
RocketMQ事务性消息是一定能保证消息发送成功的 事务消息发送步骤: (1)发送方将半事务消息发送至RocketMQ服务端。 (2)RocketMQ服务端将消息持久化之后,向发送方返回ack确认消息已经发送成功。由于消息为…...

mysql (事物)
一.什么是事物 事物是一组操作的集合,不可分割的工作单位,事物会把所有的操作当作一个整体一起向系统提交或撤销操作请求,就是这些操作要么一起成功要么一起失败。 二.事物操作 (这个就是一个理解) 1.事务特性 原子性…...

kotlin 中的字符串
一、字符类访问 1、字符串的访问跟js一样,可以使用索引来访问或者直接循环。 fun main() {val a: String "2024"// 方式一:for (item in a) {println(item) // 输出每一个字符}// 方式二:println("${a[0]}, ${a[1]}, ${a[2…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...