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

树形结构-CRUD接口

先看一下效果:整体的效果
   

新增效果 --默认值是 default

 修改效果 -

大致效果如上

---------------------------------------------------------------------------------------------------------------------------------
下面讲解代码如何实现的
 根据你使用的UI的框架中的树结构---形成相应的数据结构(递归形式)-如果后端给你分好了(感谢他)
这个是给我的是一个  数组包裹的对象形式 进行递归
这个我写在--一个通用的 js 导出形式  这边我需要是的是两种类型 所以分了一下(效果图上的是第一个)  
解释一下:data:后端给你的数据
                  parentId是 从0 或者 -1 开始 看你的需求 我这边是 -1

                   show:我这是区分我要的是那种类型         

递归形式走的

export function buildTree(data, parentId, show) {const result = [];data?.filter(item => item.parentId === parentId).forEach(items => {const children = buildTree(data, items.id, show);let node = ''if (!show) {node = {value: `${items.categoryName}`,key: `${items.id}`,defaultValue: `${items.categoryName}`,isEditable: false,parentId: `${items.parentId}`,children: children.length ? children : undefined,};} else {node = {value: `${items.id}`,title: `${items.categoryName}`,children: children.length ? children : undefined,};}result.push(node);});return result;
}

 这边都是实现的代码了-------可以详细看下  ---谢谢  -如果不懂-请评论


import { DownOutlined, EditOutlined, PlusOutlined, MinusOutlined, CloseOutlined, CheckOutlined } from '@ant-design/icons';
import { Input, Tree, message } from 'antd';
import React, { useEffect, useState } from 'react';
import moment from 'moment';
import { GetclubGoodsCategoryList, PostclubGoodsCategoryRemove, PostclubGoodsCategorySave, PostclubGoodsCategoryUpdate } from '@/services/commodity';
import { buildTree } from '@/utils/utils';const { TreeNode } = Tree;
// 三张图
import reduce from '@/assets/icon/reduce.png';
import addIng from '@/assets/icon/addIng.png';
import editIng from '@/assets/icon/editIng.png';
function TreeData({ onNodeClick }) {// 佛祖保佑,不会报错const [selectedNode, setSelectedNode] = useState(null);// const treeData = buildTree(data1, 0);const expandedKeyArr = ["0"];const [data, setData] = useState();const [listObj, setListObj] = useState({});let isMounted = true;const getDate = async () => {try {
//获取最初的数据  ------------接口let res = await GetclubGoodsCategoryList();if (isMounted && res && res.code == "200") {const treeData = buildTree(res.data, 0);setData(treeData);}} catch (error) {console.error("Error fetching data: ", error);}};useEffect(() => {getDate();return () => {isMounted = false;};}, []);const [expandedKeys, setExpandedKeys] = useState(expandedKeyArr);// 修改---树结构 有值---接口const onChangeUpdate = async () => {if (Object.keys(listObj).length > 0) {let res = await PostclubGoodsCategoryUpdate({categoryName: listObj.value,// parentId: listObj.key,id: listObj.key,});if (res && res.code == "200") {message.success("修改成功");
//重新获取树形结构getDate();}}}const onExpand = (expandedKeys) => {setExpandedKeys(expandedKeys);};const handleNodeClick = (node) => {setSelectedNode(node);// 进行暴露---作为一个组件调用你所点击的值对象onNodeClick(node);};const renderTreeNodes = (data, depth = 0) => {return data?.map((item) => {const title = item.isEditable ? (<div style={{display: 'flex',justifyContent: 'space-between',alignItems: 'center',}}>{/*  输入框显示 和   一个对号  一个 叉号*/}<Input placeholder="输入名称" defaultValue={item.defaultValue}onChange={(e) => onChange(e, item)} /><CheckOutlined style={{margin: '0 4px',}} onClick={() => onSave(item)} /><CloseOutlined onClick={() => onClose(item.parentKey, item.defaultValue)} /></div>) : (<div onClick={() => handleNodeClick(item)}style={{display: 'flex',justifyContent: 'space-between',alignItems: 'center',}}><divstyle={{whiteSpace: 'nowrap'}}>{item.value}</div><divstyle={{display: 'flex',flexWrap: 'nowrap',alignItems: 'center',}}>{/* <EditOutlined onClick={() => onEdit(item.key)} /><PlusOutlined onClick={() => onAdd(item.key)} />{item.parentKey !== "0" && (<MinusOutlined onClick={() => onDelete(item.key)} />)} */}{/* 两层之上就没有图标l 效果上的左边字 右边图片 */}{item.value &&<><img style={{ margin: '0 4px' }} width='15px' onClick={() => onEdit(item.key)} height='15px' src={editIng} alt="" />{depth < 2 && <img width='15px' onClick={() => onAdd(item.key)} height='15px' src={addIng} alt="" />}<img style={{ margin: '0 4px' }} onClick={() => onDelete(item.key)} width='15px' height='15px' src={reduce} alt="" /></>}</div></div>);if (item.children) {return (<TreeNode title={title} key={item.key}>{renderTreeNodes(item.children, depth + 1)}</TreeNode>);}return <TreeNode title={title} key={item.key} />;});};const onAdd = (key) => {if (expandedKeys.indexOf(key) === -1) {expandedKeys.push(key);}setExpandedKeys(expandedKeys.slice());addNode(key, data);setData([...data]);};const onEdit = (key) => {editNode(key, data);setData([...data]);};const editNode = (key, data) =>data.forEach((item) => {if (item.key === key) {item.isEditable = true;} else {item.isEditable = false;}item.value = item.defaultValue;if (item.children) {editNode(key, item.children);}});const getRandomNumber = (min = 1, max = 10000) => {return Math.floor(Math.random() * (max - min + 1)) + min;};const addNode = (key, data) =>data.forEach((item) => {if (item.key === key) {if (item.children) {item.children.push({value: "default",key: getRandomNumber(),parentKey: key,isEditable: false,showAdd: true});} else {item.children = [{value: "default",key: getRandomNumber(),parentKey: key,isEditable: false,showAdd: true},];}return;}if (item.children) {addNode(key, item.children);}});const onChange = (e, key) => {changeNode(key.parentKey ? key : key, e.target.value, data);setData([...data]);};const changeNode = (key, value, data) =>data.forEach((item) => {if (item.parentKey || item.key == key.key) {item.value = value;}if (item.children) {changeNode(key, value, item.children);}});// 保存---数据新增---接口const onSaveObj = async () => {let res = await PostclubGoodsCategorySave({categoryName: listObj.value,parentId: listObj.parentKey,})if (res && res.code === 200) {message.success('新增成功')getDate();} else {message.error('新增失败')}};useEffect(() => {if (listObj.showAdd) {onSaveObj();} else {onChangeUpdate()}}, [listObj])const onSave = (key) => {if (key.value == undefined) {message.error('请输入分类名称')return}setListObj(key)saveNode(key, data);setData([...data]);};const saveNode = (key, data) =>data.forEach((item) => {if (item.parentKey === key) {item.defaultValue = item.value;}if (item.children) {saveNode(key, item.children);}item.isEditable = false;});const onClose = (key, defaultValue) => {closeNode(key, defaultValue, data);setData([...data]);};const closeNode = (key, defaultValue, data) =>data.forEach((item, index) => {item.isEditable = false;if (item.parentKey === key) {data.splice(index, 1);item.value = defaultValue;}if (item.children) {closeNode(key, defaultValue, item.children);}});const onDelete = (key) => {deleteNode(key, data);setData([...data]);};//删除节点---接口const deleteIds = async (key) => {let data = await PostclubGoodsCategoryRemove({ids: key,})if (data && data.code === 200) {message.success('删除成功')getDate();}}const deleteNode = (key, data) =>data.forEach((item, index) => {if (item.key === key) {if (!item.showAdd) {deleteIds(key);}data.splice(index, 1);return;} else {if (item.children) {deleteNode(key, item.children);}}});return (<div style={{position: 'relative',left: '-14px'}}><Tree onExpand={onExpand} expandedKeys={expandedKeys}>{renderTreeNodes(data)}</Tree></div>);
}export default TreeData;


 

相关文章:

树形结构-CRUD接口

先看一下效果&#xff1a;整体的效果 新增效果 --默认值是 default 修改效果 - 大致效果如上 --------------------------------------------------------------------------------------------------------------------------------- 下面讲解代码如何实现的 根据你使用…...

【Qt知识】Qt窗口坐标系

Qt的窗口坐标体系遵循标准的计算机图形坐标系统规则 Qt窗口坐标体系特点 坐标原点&#xff1a;窗口坐标体系的原点位于窗口的左上角&#xff0c;即坐标(0, 0)位置。 轴方向&#xff1a; X轴&#xff1a;向右为正方向&#xff0c;随着X坐标值的增加&#xff0c;元素在窗口中从…...

SAP Build引言

前言 SAP Build 似乎是一个整合了很多低代码或无代码产品的平台&#xff0c;最早的时候应该都是各自分开的几个产品&#xff0c;近年合并到一块上了SAP Build平台 现在看官网的介绍应该是有三四个产品被集成进来了&#xff0c;分别是SAP IRPA&#xff0c;SAP Workflow&#xf…...

2024上海国际钢丝绳及吊索具展览会

2024上海国际钢丝绳及吊索具展览会 2024 Shanghai International Wire Rope and Hanger Exhibition 时间&#xff1a;2024年12月18日--20日 地点&#xff1a;上海新国际博览中心 详询主办方陆先生 I38&#xff08;前三位&#xff09; I82I&#xff08;中间四位&#xff…...

记一次mysql索引优化

生产日志告警出现一条慢 sql 告警, 通过 sql 监控平台拿到 这条sql 语句是 : SELECTid,report_id,report_detail_id,item_code,report_type,photo FROM**** 表 WHEREdel_flag 0 AND (report_type 1 AND report_detail_id IN ( 1742 )) 之后用 explain 分析这条 sql 的命中…...

【Javascript系列】Terser通过调用API来实现代码的压缩和优化功能

Terser通过调用API来实现代码的压缩和优化功能 起源通过API来调用API调用过程中的一个隐含的技术点 - 异步调用和Promise对象官方文档中的一个有点容易忽略和混淆的地方关于Promise 起源 书接 上回&#xff0c;对Terser的功能做了一个初步的探索。在官方的主页上&#xff0c;有…...

嵌入式期末复习

一、选择题&#xff08;20&#xff09; 二、判断题&#xff08;10&#xff09; 三、填空题&#xff08;10&#xff09; 主机-目标机的文件传输方式主要有串口传输方式、网络传输方式、USB接口传输方式、JTAG接口传输方式、移动存储设备方式。常用的远程调试技术主要有 插桩/st…...

生信算法7 - 核酸序列Fasta和蛋白PDB文件读写与检索

python 3.9实现以下算法。 1. 简单的写文件和读文件 # 写 file1 open(count.txt,w) file1.write(this is a test) file1.close()# 读 file2 open(my_file) print(file2.read())2. 将列表内容写入文本文件 # 生成100-500数字列表 data [i * 100 for i in range(1, 6)] pri…...

【Python】Python异步编程

Python 异步编程 异步编程 异步编程是一种编程范式&#xff0c;通过非阻塞的方式执行任务&#xff0c;允许程序在等待某些操作&#xff08;如I/O操作、网络请求、数据库查询等&#xff09;完成时&#xff0c;继续执行其他任务。这与同步编程&#xff08;或阻塞编程&#xff09…...

pytorch笔记:自动混合精度(AMP)

1 理论部分 1.1 FP16 VS FP32 FP32具有八个指数位和23个小数位&#xff0c;而FP16具有五个指数位和十个小数位Tensor内核支持混合精度数学&#xff0c;即输入为半精度&#xff08;FP16&#xff09;&#xff0c;输出为全精度&#xff08;FP32&#xff09; 1.1.1 使用FP16的优缺…...

R语言ggplot2包绘制世界地图

数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 1. 数据读取与处理 首先&#xff0c;从CSV文件中读取数据&#xff0c;并计算各国每日收入的平均签证成本。 library(tidyverse) ​ df <- read_csv("df.csv") %>% group_…...

【Linux】Linux的权限_1

文章目录 三、权限1. shell外壳2. Linux的用户3. Linux权限管理文件访问者的分类文件类型和访问权限 未完待续 三、权限 1. shell外壳 为什么要使用shell外壳 由于用户不擅长直接与操作系统直接接触和操作系统的易用程度、安全性考虑&#xff0c;用户不能直接访问操作系统。 什…...

日语_远程办公常用日语单词

基本词汇 リモートワーク&#xff08;Rimōto Wāku&#xff09;&#xff1a;远程工作テレワーク&#xff08;Terewāku&#xff09;&#xff1a;远程工作&#xff08;Telework&#xff09;在宅勤務&#xff08;ざいたくきんむ&#xff0c;Zaitaku Kinmu&#xff09;&#xff…...

MTK 平台项目security boot 开启/关闭 及 系统签名流程

以 https://online.mediatek.com/FAQ#/SW/FAQ26691 为基础做如下记录以做备忘&#xff1a; How to Enable/Disable Secure Boot for Security 3.0: 1、 How to Enable Path Enable Preloader /vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/{…...

JDBC连接MySQL

目录 1.数据库编程的必备条件 2.Java的数据库编程JDBC 3.JDBC的工作原理 4.第三方库connector的下载和导包 5.JDBC的使用 使用步骤 &#xff08;1&#xff09;创建数据源对象DataSource &#xff08;2&#xff09;给对象设置必要的属性 &#xff08;3&#xff09;和数据…...

【Qt】【模型视图架构】 在项目视图中启用拖放

文章目录 1. 在便捷类中启用拖放2. 在模型/视图类中启用拖放 模型/视图框架支持Qt的拖放应用。 列表、表格和树中的项目可以在视图中被拖拽&#xff0c;数据作为MIME编码的数据被导入和导出。标准视图可以自动支持内部的拖放。 默认视图的拖放功能并没有被启用&#xff0c;如果…...

B端产品无爆款,说有的都是忽悠和外行!

前言&#xff1a;网上经常有人讲运营&#xff0c;把C端那一套硬搬到B端&#xff0c;讲的自我陶醉&#xff0c;稍微有点常识的人就知道不能这么玩。 一、什么是B端和C端 B端&#xff08;Business-to-Business&#xff09;是指面向企业客户的市场和产品。B端产品或服务主要是为…...

腾讯云的身份证核验,找不到这个类

文件上传功能在许多Web应用程序中是非常常见的需求之一。然而&#xff0c;由于文件上传存在安全风险&#xff0c;保护用户上传的文件的安全性&#xff0c;以及防止黑客利用上传功能进行攻击是非常重要的。在本文中&#xff0c;我们将讨论一些常见的安全漏洞&#xff0c;并提供一…...

vue3 vue-draggable-next 实现拖拽穿梭框效果

一、vue3 vue-draggable-next 实现拖拽穿梭框效果 <template> <div> <h2>列表 1</h2> <draggable v-model"list1" group"items" tag"transition-group" end"onDragEnd"> <div v-for"(item…...

FreeRTOS【16】直达任务通知使用

1.开发背景 直达任务通知&#xff0c;FreeRTOS 的线程任务提供的接口&#xff0c;可以用作线程唤醒&#xff0c;或者是传递数据&#xff0c;因为是基于线程本身的操作&#xff0c;是轻量级&#xff0c;速度响应更快&#xff0c;适合小内存芯片使用。 事实上本人使用得比较少&am…...

关于软件<PDF文档管理系统V1.0>的介绍

<PDF文档管理系统V1.0>&#xff08;下载地址在最下面&#xff09;是我在2023年发布的<知识辅助系统>的改善以及重新开发版本&#xff0c;软件在重新开发提供了<知识辅助系统>的所有功能的基础上&#xff0c;添加了一些新的功能。软件尽量提供简单、实用的功能…...

Java面试题-Tomcat初级面试题

Tomcat是什么&#xff1f;请简述它的主要功能。 Tomcat是一个开源的Web应用服务器&#xff0c;由Apache软件基金会开发。它是一个实现了Java Servlet和JavaServer Pages&#xff08;JSP&#xff09;技术的容器&#xff0c;用于处理客户端的请求并返回响应。Tomcat的主要功能如…...

红队内网攻防渗透:内网渗透之windows内网权限提升技术:数据库篇

红队内网攻防渗透 1. 内网权限提升技术1.1 数据库权限提升技术1.1.1 数据库提权流程1.1.1.1 先获取到数据库用户密码1.1.1.2 利用数据库提权工具进行连接1.1.1.3 利用建立代理解决不支持外联1.1.1.4 利用数据库提权的条件及技术1.1.2 Web到Win-数据库提权-MSSQL1.1.3 Web到Win-…...

rust嵌入式开发之总结

我们用rust开发的新版产品刚刚交付&#xff0c;已经在海上安装测试完毕并顺利投产。终于松了口气&#xff0c;同时也有时间和精力来做个全面的总结了。 这个产品&#xff0c;目前差不多有三版&#xff1a; 第一个版本是用crt-thread写的&#xff0c;投产后出了一个内存泄露的…...

【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言方法一、使用excel配置表excel转txt文本读取txt数据按配置信息生成僵尸 方法二、使用ScriptableObject 配置关卡信息源码结束语 前言 本节主要是推荐两种实现配置关卡信息&#xff0c;并按表生成僵尸和关卡波次 方法一、使用…...

回溯算法指组合总和

题目&#xff1a; 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 思路&#xff1a; 这种问题…...

java-stream转换map key重复报错解决小记

解决key重复问题 在用stream转成map过程中会有key重复的隐患&#xff0c;如果数据没重复还好&#xff0c;如果重复了会提示 java.lang.IllegalStateException: Duplicate key 8753444332651at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)at ja…...

王春城 | 如何解决精益转型过程中的信任问题?

实践证明&#xff0c;精益转型不仅仅是技术和管理方法的更新&#xff0c;更是一场深刻的文化变革。在这个过程中&#xff0c;涉及到多个部门、多个层级的协同合作&#xff0c;需要团队成员之间的深度沟通和高度信任。如果缺乏信任&#xff0c;团队成员之间就会产生隔阂和抵触情…...

Ubuntu Nvidia Docker单机多卡环境配置

ubuntu版本是22.04&#xff0c;现在最新版本是24.xx&#xff0c;截止当前&#xff0c;Nvidia的驱动最高还是22.04版本&#xff0c;不建议更新至最新版本。本部分是从0开始安装Nvidia docker的记录&#xff0c;若已安装Nvdia驱动&#xff0c;请直接跳至3。 1、更新软件软件列表…...

小公司的软件开发IT工具箱

目录 工具链困境 难题的解决 达到的效果 资源要求低 工具箱一览 1、代码管理工具 2、自动化发版&#xff08;测试&#xff09;工具 3、依赖库&#xff08;制品包&#xff09;管理 4、镜像管理 5、授权管理&#xff08;可选&#xff09; 待讨论&#xff1a;为什么不是…...