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…...
网站线上模板建设的优缺点
优点: 1.搭建的时间短,在线建站,只需要登录注册然后选择网站模板创建网站即可管理自己的网站后台,就几步操作就可以实现。 2.网站出错率少,因为有很多用户在使用,前期所报出来的问题就已经一一…...
哲学家进餐问题
1.最多允许四个哲学家同时进餐,保证有一个筷子是空闲的,从而保证能有有一个哲学家成功进餐,而不导致死锁 semaphore chopstick[5] {1, 1, 1, 1, 1}, mutex4; Pi(){do{think...P(mutex);P(chopstick[i]);P(chopstick[(i1)%5);eat...V(mutex)…...
无人机遥感在农林信息提取中的实现方法与GIS融合应用
在新一轮互联网信息技术大发展的现今,无人机、大数据、人工智能、物联网等新兴技术在各行各业都处于大爆发的前夜。为了将人工智能方法引入农业生产领域。首先在种植、养护等生产作业环节,逐步摆脱人力依赖;在施肥灌溉环节构建智慧节能系统&a…...
联想测开一面(电话面试)笔试60%
联想测开一面(电话面试)笔试60% 3.21 无自我介绍 基本问项目,问实习 对python自动化测试了解多少 讲一下python中打包和解包的概念 学校无测试相关课程,平时用什么平台去学习的 计算机底层实现原理简要说说(软硬结合&…...
【python】tkinter GUI开发: Button和Entry的应用实战探索
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
sm2证书生成(openssl3.0)
1、下载安装包 https://www.openssl.org/source/openssl-3.0.14.tar.gz 2、解压到指定位置 /appserver/openssl-3.0.14 3、安装依赖包 yum -y install gcc perl make zlib-devel perl-CPAN 4、编译 ./config shared --prefix/appserver/SM make depend make make install 5…...
java计算年化利率
接了业务需求需要计算年化利率, 公式定义: IRR计算 在计算 IRR 时,我们希望找到一个折现率r,使得净现值(NPV)为零。NPV 函数定义如下: NPV ∑ t 0 n C t ( 1 r ) t \text{NPV} \sum_{t0}…...
深入理解ChatGPT工作原理
在人工智能领域,自然语言处理(NLP)技术的飞速发展让机器能够更加自然和人类进行交流。OpenAI的ChatGPT作为当前最受关注的NLP模型之一,其出色的对话能力引起了业界和学术界的广泛关注。本文将深入探讨ChatGPT的工作原理࿰…...
在 Wed 中应用 MyBatis(同时使用MVC架构模式,以及ThreadLocal 事务控制)
1. 在 Wed 中应用 MyBatis(同时使用MVC架构模式,以及ThreadLocal 事务控制) 文章目录 1. 在 Wed 中应用 MyBatis(同时使用MVC架构模式,以及ThreadLocal 事务控制)2. 实现步骤:1. 第一步…...
Elasticsearch index 设置 false,为什么还可以被检索到?
在 Elasticsearch 中,mapping 定义了索引中的字段类型及其处理方式。 近期有球友提问,为什么设置了 index: false 的字段仍能被检索。 本文将详细探讨这个问题,并引入列式存储的概念,帮助大家更好地理解 Elasticsearch 的存储和查…...
权威网站发布平台/优化关键词软件
这个夏天,如果你还不了解网络安全大赛,你就out了。“现男友”李现在《亲爱的,热爱的》剧中扮演的韩商言是CTF(可译为“夺旗赛”)职业选手,让这个原本在大众眼里比较陌生的职业一下子就火了。同时带火的还有…...
手机网站怎么做优化/温州网站优化推广方案
简单介绍 串口是一种非常通用的设备通信的协议(不要与通用串行总线Universal Serial Bus(USB)混淆)。大多数计算机包括两个基于RS232的串口。串口同一时候也是仪器仪表设备通用的通信协议;非常多GPIB兼容的设备也带有RS-232口。同一时候&…...
毕业设计做网站有什么好处/怎样优化网络
参与者列表: (1) Third-party application:第三方应用程序,又称客户端(client),如:"云冲印"、社交应用。 (2)HTTP service:…...
湖南网站建设磐石网络口碑好/登封网络推广
原标题:Python面试宝典之基础篇-08题目36:如何使用random模块生成随机数、实现随机乱序和随机抽样?点评:送人头的题目,因为Python标准库中的常用模块应该是Python开发者都比较熟悉的内容,这个问题回如果答不…...
wordpress 获取页面列表/营销软件网站
做了一款编程面试题小程序,本小程序旨在帮助大家面试刷题使用,小程序中的面试题,大部分来源于编程群内广大程序员朋友上传的真实面试题,答案并经由自己及参考一些资料整理得来,如果使用中遇到问题,请及时反馈。面试题部…...
个人网站备案名字重要吗/互联网网络推广公司
团队项目第三周总结 经过了三周的努力我们的项目已经基本完成啦,团队付出的努力也得到了回报。这一周主要的工作相对前一周来讲比较轻松,但比较繁琐。在技术方面,我们这一周主要是完善了小的技术功能,主要是在做非功能性需求。在界…...