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

antd table合并复杂单元格、分组合并行、分组合并列、动态渲染列、嵌套表头

项目里遇到个需求,涉及到比较复杂的单元格合并 、嵌套表头、分组合并行、合并列等,并且数据列还是动态的,效果图如下:
在这里插入图片描述

在这里插入图片描述

可以分组设置【显示列】例如:当前组为【合同约定】,显示列为【合同节点】和【节点金额】

我们按【数据源】进行分组后,把第一组编号为【0001】的单元行合并 ,然后再插入一行【小计】,根据显示的【列数】决定合并几个【单元格】,比如我们的需求可以设置为当【合同节点】与【金额】全部显示时,显示【小计】的信息,再进行单元格合并

我们的数据源如下:

动态列数据

const mockRowData = [// {//     name: '合同约定',//     key: 'agree',//     handle: 'lt',//     handleValue: 2312313,//     color: '#FF811A',//     enable: true,//     checked: true,//     // disabled: true,//     checkable: false,//     hidden: true,//     children: [{name: '合同节点',key: 'contractNodes',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: true,checked: true,type: 1,},{name: '金额',key: 'Money',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: true,checked: true,type: 1,},{name: '节点比例',key: 'NodeRatio',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,type: 1,},{name: '付款条件',key: 'paymentTerms',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: true,checked: true,type: 1,},//     ],// },// {//     name: '确认收入',//     key: 'confirmIncome',//     handle: 'lt',//     handleValue: 2312313,//     color: '#FF811A',//     enable: false,//     checked: true,//     // disabled: true,//     checkable: false,//     hidden: true,//     children: [{name: '成果提交日期',key: 'submissionDate',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,type: 2,},{name: '证明文件日期',key: 'fileDate',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: true,checked: true,type: 2,},{name: '确认收入',key: 'Income',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,type: 2,},{name: '确认比例',key: 'confirmationRatio',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,type: 2,},//     ],// },// {//     name: '收款',//     key: 'receivePayment',//     handle: 'lt',//     handleValue: 2312313,//     color: '#FF811A',//     enable: false,//     checked: true,//     // disabled: true,//     checkable: false,//     hidden: true,//     children: [{name: '到账日期',key: 'DateofReceipt',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,type: 3,},{name: '金额',key: 'Money1',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: true,checked: true,type: 3,},{name: '确认比例',key: 'confirmationRatio1',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,type: 3,},//     ],// },{name: '应收款',key: 'receivables',handle: 'lt',handleValue: 2312313,color: '#FF811A',enable: false,checked: true,children: [],type: 4,},
];

数据源:

const mockTableData = {group1: [{group: 'group1',id: 1,name: '第一建筑设计院',order: '0001',type: '外部承包',isConsortium: '是',nameSquare:'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',cstatus: '执行中',money: '60,0000,0000',value1: 12345,contractNodes: 12345,Money: 12345,NodeRatio: 12345,paymentTerms: 12345,confirmIncome: 12345,submissionDate: 12345,fileDate: 12345,Income: 12345,confirmationRatio: 12345,Money1: 879,DateofReceipt: '2024-10-25',confirmationRatio1: '20%',receivables: '',agree: '',receivePayment: '200,0000,0000',},{group: 'group1',id: 2,name: '第二建筑设计院',order: '0001',type: '外部承包',isConsortium: '是',nameSquare:'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',cstatus: '执行中',money: '60,0000,0000',value1: 1234124,contractNodes: 1234124,Money: 1234124,NodeRatio: 1234124,paymentTerms: 1234124,confirmIncome: 1234124,submissionDate: 1234124,fileDate: 1234124,Income: 1234124,confirmationRatio: 1234124,Money1: 879,DateofReceipt: '2024-10-25',confirmationRatio1: '20%',receivables: '',agree: '',receivePayment: '200,0000,0000',},{group: 'group1',id: 3,name: '第三建筑设计院',order: '0001',type: '外部承包',isConsortium: '是',nameSquare:'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',cstatus: '执行中',money: '60,0000,0000',value1: 54321,contractNodes: 54321,Money: 54321,NodeRatio: 54321,paymentTerms: 54321,confirmIncome: 54321,submissionDate: 54321,fileDate: 54321,Income: 54321,confirmationRatio: 54321,Money1: 879,DateofReceipt: '2024-10-25',confirmationRatio1: '20%',receivables: '',agree: '',receivePayment: '200,0000,0000',},],group2: [{group: 'group2',id: 4,name: '第一建筑设计院',order: '0002',type: '外部承包',isConsortium: '是',nameSquare:'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',cstatus: '执行中',money: '60,0000,0000',value1: 12345,contractNodes: 12345,Money: 12345,NodeRatio: 12345,paymentTerms: 12345,confirmIncome: 12345,submissionDate: 12345,fileDate: 12345,Income: 12345,confirmationRatio: 12345,Money1: 879,DateofReceipt: '2024-10-25',confirmationRatio1: '20%',receivables: '',agree: '',receivePayment: '200,0000,0000',},{group: 'group2',id: 5,name: '第二建筑设计院',order: '0002',type: '外部承包',isConsortium: '是',nameSquare:'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',cstatus: '执行中',money: '60,0000,0000',value1: 1234124,contractNodes: 1234124,Money: 1234124,NodeRatio: 1234124,paymentTerms: 1234124,confirmIncome: 1234124,submissionDate: 1234124,fileDate: 1234124,Income: 1234124,confirmationRatio: 1234124,Money1: 879,DateofReceipt: '2024-10-25',confirmationRatio1: '20%',receivables: '',agree: '',receivePayment: '200,0000,0000',},{group: 'group2',id: 6,name: '第三建筑设计院',order: '0002',type: '外部承包',isConsortium: '是',nameSquare:'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',cstatus: '执行中',money: '60,0000,0000',value1: 54321,contractNodes: 54321,Money: 54321,NodeRatio: 54321,paymentTerms: 54321,confirmIncome: 54321,submissionDate: 54321,fileDate: 54321,Income: 54321,confirmationRatio: 54321,Money1: 879,DateofReceipt: '2024-10-25',confirmationRatio1: '20%',receivables: '',agree: '',receivePayment: '200,0000,0000',},],
};

那接下来咱们就先看如何显示【动态列】吧~

1.显示动态列

 const columns = useCallback(() => {if (rowData && rowData.length) {console.log(rowData);const list = [// 先写入非动态列{title: '合同编号',dataIndex: 'order',width: 50,render: (text) => {return (<divclassName="ellipsis-item"title={text}style={{ width: '100px' }}>{text}</div>);},onCell: mergeRow,},// 循环动态列,{title: '收款',className: 'type3Column',children: [...flattenData(rowData, 0).filter((item) => item.checked).filter((item) => item.type === 3).map((item) => {return {title: (<div className="ellipsis-item" title={item.name}>{item.name}</div>),dataIndex: item.key,className: 'type3Column',width: 100,render: (text) => {return (<divstyle={{background: getColumnColor(item.enable,text,item.handle,item.handleValue,item.color,),}}className="value-item">{text}</div>);},};}),],},];console.log('list', list);return list;}}, [rowData]);

2.合并列

思路

我们的列是动态变换的,所以合并的列数也是动态合并的,那我们就需要在每次变化的时候再去判断需要合并几列

1.先将【原始数据源】分组处理,计算每组的【小计】金额 ,然后写入【表格数据源】里
2.循环动态列,将列也分别写入三个数组里
3.判断我们【每组】【动态列】中是否符合我们的需求,是否要显示【小计】信息,设置【要合并的列】为1
4.如果存在,判断本组有无其他列显示,有的话【要合并的列数+1】

处理列数&计算要合并的列数
  const handleColumnData = (row) => {console.log('row=======', row);let type1list = [];// 分组列1let type2list = []; // 分组列2let type3list = []; // 分组列3let haveAgreeTotal = false;  // 分组列1是否有【小计】let haveIncomeTotal = false;  // 分组列1是否有【小计】let haveReciveTotal = false;  // 分组列1是否有【小计】let AgreeColspan = 0;  // 分组列1要合并的列数let IncomeColspan = 0;  // 分组列1要合并的列数let ReciveColspan = 0;  // 分组列1要合并的列数row.forEach((item) => {if (item.type === 1) {type1list.push(item.key);} else if (item.type === 2) {type2list.push(item.key);} else if (item.type === 3) {type3list.push(item.key);}});// console.log('type1', type1list)// console.log('type2', type2list)// console.log('type3', type3list)if (type1list.length > 0) {// 如果同时存在【合同节点】和【金额】字段,显示小计if (type1list.includes('contractNodes') &&type1list.includes('Money')) {haveAgreeTotal = true;AgreeColspan = 1;if (type1list.includes('NodeRatio')) {AgreeColspan += 1;}if (type1list.includes('paymentTerms')) {AgreeColspan += 1;}}}if (type2list.length > 0) {// 如果同时存在【成果提交日期】和【确认收入】字段,显示小计if (type2list.includes('submissionDate') &&type2list.includes('Income')) {haveIncomeTotal = true;IncomeColspan = 1;if (type2list.includes('fileDate')) {IncomeColspan += 1;}if (type2list.includes('confirmationRatio')) {IncomeColspan += 1;}}}if (type3list.length > 0) {// 如果同时存在【到账日期】和【金额】字段,显示小计if (type3list.includes('DateofReceipt') &&type3list.includes('Money1')) {haveReciveTotal = true;ReciveColspan = 1;if (type3list.includes('confirmationRatio1')) {ReciveColspan += 1;}}}// console.log('haveAgreeTotal, haveIncomeTotal, haveReciveTotal', haveAgreeTotal, haveIncomeTotal, haveReciveTotal)// console.log('AgreeColspan, IncomeColspan, ReciveColspan', AgreeColspan, IncomeColspan, ReciveColspan)return {haveAgreeTotal,haveIncomeTotal,haveReciveTotal,AgreeColspan,IncomeColspan,ReciveColspan,};};
  useEffect(() => {// setTableData(mockTableData)let source = formatData(mockTableData, rowData);setDataSource(source);}, []);
根据需求写入【小计】行
 const formatData = (data, rowData) => {let obj = handleColumnData(rowData);let resTableData = [];const {haveAgreeTotal,haveIncomeTotal,haveReciveTotal,AgreeColspan,IncomeColspan,ReciveColspan,} = obj;// 是否有任意一组列存在小计,存在则写入新一行// 循环列表,把数据分组写入// 写入小计行,根据列标识写入要合并的列数// 渲染时判断标识行,写入列数,其余为0if (haveAgreeTotal || haveIncomeTotal || haveReciveTotal) {Object.keys(data).forEach((key) => {let group = data[key];let nodeSum = 0;let IncomeSum = 0;let Money1Sum = 0;group.forEach((item) => {resTableData.push(item);nodeSum += item.NodeRatio;IncomeSum += item.Income;Money1Sum += item.Money1;});let totalRecord = {group: key,id: '',order: '',type: '',isConsortium: '',nameSquare: '',cstatus: '',money: '',value1: '',confirmIncome: '',receivables: '',agree: '',receivePayment: '',};if (haveAgreeTotal) {totalRecord.contractNodes = '小计';totalRecord.Money = nodeSum;totalRecord.NodeRatio = nodeSum;totalRecord.paymentTerms = nodeSum;totalRecord.AgreeColspan = AgreeColspan;}if (haveIncomeTotal) {totalRecord.submissionDate = '小计';totalRecord.Income = IncomeSum;totalRecord.fileDate = IncomeSum;totalRecord.confirmationRatio = IncomeSum;totalRecord.IncomeColspan = IncomeColspan;}if (haveReciveTotal) {totalRecord.DateofReceipt = '小计';totalRecord.Money1 = Money1Sum;totalRecord.confirmationRatio1 = Money1Sum;totalRecord.ReciveColspan = ReciveColspan;}// console.log('recordtotal', totalRecord)resTableData.push(totalRecord);});} else {Object.keys(data).forEach((key) => {let group = data[key];group.forEach((item) => {resTableData.push(item);});});}
return resTableData};
渲染表格

此处我们要注意的是!当前合并单元格行数、列数设置好后,我们要把【被合并的行列】都设置为0!!并且【其他的行和列】的合并数也要都为0!不然表格会出现错位问题!

我们把cloumns列设置

  {title: '合同约定',className: 'type1Column',children: [...flattenData(rowData, 0).filter((item) => item.checked).filter((item) => item.type === 1).map((item) => {return {title: (<div className="ellipsis-item" title={item.name}>{item.name}</div>),dataIndex: item.key,className: 'type1Column',width: 100,render: (text, record, index) => {if (record.AgreeColspan) { // 判断是否是小计行if (item.key === 'Money') {return {children: handleNode(item, text, 'total_back_pink'),props: { colSpan: record.AgreeColspan }, // 合并"小计"行从第二列开始的所有列};} else if (item.key === 'contractNodes') {return {children: handleNode(item, text, 'total_back_pink'),props: { colSpan: 1 }, // "小计"列不合并};} else {return {children: handleNode(item, text, 'total_back_pink'),props: { colSpan: 0 }, // 当前组其他列设置为0,不会出现表格错位情况};}} else {return {children: handleNode(item, text),props: { colSpan: 1 }, // 非"小计"行全部不合并};}},};}),],},

这样就实现了【分组合并列】、【动态渲染列】啦!
在这里插入图片描述

2.合并行

思路

循环【数据源】,从第一行开始判断,如果【当前行】与【下一行】是同一组,那【rowSpan】 + 1,【被合并的行】记得要设置为0哦

const formatData = (data, rowData) => {// 处理要合并的列...// 处理要合并的行let processedData = [...resTableData];let prevFinishNum;let currentIndexForSameProperty;for (let i = 0; i < processedData.length; i++) {const currentItem = processedData[i];if (i === 0 || currentItem.group !== prevFinishNum) {// 新的组开始,重置计数器,并将上一组最后一项的rowSpan设置好if (prevFinishNum !== undefined &&currentIndexForSameProperty !== undefined) {processedData[currentIndexForSameProperty].rowSpan =i - currentIndexForSameProperty;}currentIndexForSameProperty = i;currentItem.rowSpan = 1;currentItem.opcaty = '0'; // 标识是不是被合并的行} else {// 相同组内,累加rowSpanprocessedData[currentIndexForSameProperty].rowSpan += 1;currentItem.opcaty = '1'; // 标识是被合并的行}prevFinishNum = currentItem.group;}// 处理数组的最后一项if (currentIndexForSameProperty !== undefined &&currentIndexForSameProperty < processedData.length - 1) {processedData[currentIndexForSameProperty].rowSpan =processedData.length - currentIndexForSameProperty;}return processedData;}

这样就实现了【合并行】啦!
在这里插入图片描述

3.嵌套表头

这个在 antd官网 都有,就是给columns设置children就行了,咱们在上面【渲染动态列】的代码里也有提到 ~
在这里插入图片描述

在这里插入图片描述

相关文章:

antd table合并复杂单元格、分组合并行、分组合并列、动态渲染列、嵌套表头

项目里遇到个需求&#xff0c;涉及到比较复杂的单元格合并 、嵌套表头、分组合并行、合并列等&#xff0c;并且数据列还是动态的&#xff0c;效果图如下&#xff1a; 可以分组设置【显示列】例如&#xff1a;当前组为【合同约定】&#xff0c;显示列为【合同节点】和【节点金额…...

一键安装与配置Stable Diffusion,轻松实现AI绘画

随着技术的迭代&#xff0c;目前 Stable Diffusion 已经能够生成非常艺术化的图片了&#xff0c;完全有赶超人类的架势&#xff0c;已经有不少工作被这类服务替代&#xff0c;比如制作一个 logo 图片&#xff0c;画一张虚拟老婆照片&#xff0c;画质堪比相机。 最新 Stable Di…...

模板和静态文件

模板和静态文件 1、templates模板2、静态文件2.1、static目录2.2、引用静态文件 1、templates模板 "templates"目录用于存放模板文件&#xff0c;通常是用于动态生成页面的文件。 在app01目录下创建templates文件夹&#xff0c;html文件均保存在templates中 在urls.p…...

Android Studio 打包aar丢失远程依赖问题解决

之前打包&#xff0c;使用的com.kezong.fat-aar&#xff0c;embed&#xff08;‘XXXX’&#xff09;的方式&#xff0c;可以使三方依赖打包在aar包里&#xff0c;在项目里直接使用 升级了Gradle&#xff1a;7.5后&#xff0c;打包就打包不起来了&#xff0c;一直报错&#xff…...

Chromium 搜索引擎功能浅析c++

地址栏输入&#xff1a;chrome://settings/searchEngines 可以看到 有百度等数据源&#xff0c;那么如何调整其顺序呢&#xff0c;此数据又存储在哪里呢&#xff1f; 1、浏览器初始化搜索引擎数据来源在 components\search_engines\prepopulated_engines.json // Copyright …...

DDoS攻击快速增长,如何在抗ddos防护中获得主动?

当下DDoS攻击规模不断突破上限。前段时间&#xff0c;中国首款3A《黑神话&#xff1a;悟空》也在一夜之内遭受到28万次攻击DDoS攻击&#xff0c;严重影响到全球玩家的游戏体验。Gcore发布的数据也显示了 DDoS攻击令人担忧的趋势&#xff0c;尤其是峰值攻击已增加到了令人震惊的…...

MongoDB 死锁 锁定问题

要查看 MongoDB 是否出现“锁死” (也就是所谓的 锁定问题&#xff0c;通常指长时间的锁定导致数据库操作无法正常进行)&#xff0c;可以通过以下几种方法来检测数据库的锁定状态和锁定相关信息。 1. 使用 db.currentOp() 检查活动操作 MongoDB 提供了 db.currentOp() 命令来查…...

鸿蒙--商品列表

这里主要利用的是 List 组件 相关概念 Scroll:可滚动的容器组件,当子组件的布局尺寸超过父组件的视口时,内容可以滚动。List:列表包...

【Fargo】5:根据网络带宽动态调整发送速率

根据网络带宽动态调整发送速率 原理:这个简单实现的原理是 改变包的发送速率就可以改变发送码率了。例如1秒发1000个1KB 的包,带宽8Mbps,如果带宽是4Mbps,那么1秒发500个就够了。D:\XTRANS\thunderbolt\ayame\zhb-bifrost\player-only\worker\src\fargo\zhb_uv_udp_sender.…...

入门C语言:从原码、反码、补码到位运算

入门C语言&#xff1a;从原码、反码、补码到位运算 C语言作为一门底层编程语言&#xff0c;离不开对计算机硬件的深入理解。掌握整数的二进制表示法和位运算是深入学习C语言的基础。对于大一新生来说&#xff0c;理解原码、反码、补码与位运算这几个概念&#xff0c;将帮助你更…...

18770 差值最大

### 思路 为了找到两个数x和y使得x - y的值最大&#xff0c;并且x在y的右侧&#xff0c;我们可以使用以下方法&#xff1a; 1. 从右向左遍历数组&#xff0c;记录当前遍历到的最大值max_right。 2. 对于每个元素a[i]&#xff0c;计算max_right - a[i]&#xff0c;并更新最大差…...

【Flutter】合并多个流Stream

1.说明 无意间发现了一个好用的库rxdart&#xff0c;它为 Dart 的 Stream 添加了额外的功能。 2.功能 &#xff08;1&#xff09;合并多个流Stream 借助Rx.combineLatest2()合并两个流stream1和stream2。 注意&#xff1a;如果dart文件中同时使用了getx&#xff0c;需要隐…...

【SQL学习笔记】

Pycharm社区版的页面中无database选项&#xff1f; 1、进入Setting-Pluggins窗口&#xff0c;输入database navigator 2、安装后&#xff0c;重启即可 MySQL 的架构共分为两层&#xff1a;Server 层和存储引擎层 1、Server 层负责建⽴连接、分析和执⾏ SQL 2、存储引擎层负…...

contact form 7设置方法与详细步骤

Contact Form 7(CF7)是WordPress中非常流行的表单插件&#xff0c;用于创建和管理网站上的联系表单。以下是Contact Form 7的设置方法与详细步骤&#xff1a; 一、安装Contact Form 7插件 从WordPress后台安装&#xff1a; 登录WordPress后台&#xff0c;进入“插件”菜单下…...

第170天:应急响应-战中溯源反制对抗上线CSGoby蚁剑Sqlmap等安全工具

目录 案例一&#xff1a;溯源反制-Webshell工具-Antsword 案例二&#xff1a;溯源反制-SQL注入工具-SQLMAP 案例三&#xff1a;溯源反制-漏洞扫描工具-Goby 案例四&#xff1a;溯源反制-远程控制工具-CobaltStrike 反制Server&#xff0c;爆破密码&#xff08;通用&#x…...

5-容器管理工具Docker

├──5-容器管理工具Docker | ├──1-容器管理工具Docker | | ├──1-应用部署容器化演进之路 | | ├──2-容器技术涉及Linux内核关键技术 | | ├──3-Docker生态架构及部署 | | ├──4-使用容器运行Nginx及docker命令介绍 | | ├──5-容器镜像介…...

OCR+PDF解析配套前端工具开源详解!

目录 一、项目简介 TextIn为相关领域的前端开发提供了优秀的范本。 目前项目已在Github上开源&#xff01; 二、性能特色 三、安装使用 安装依赖启动项目脚本命令项目结构 四、效果展示 面对日常生活和工作中常见的OCR识别、PDF解析、翻译、校对等场景&#xff0c;配套的…...

【操作系统】引导(Boot)电脑的奇妙开机过程

&#x1f339;&#x1f60a;&#x1f339;博客主页&#xff1a;【Hello_shuoCSDN博客】 ✨操作系统详见 【操作系统专项】 ✨C语言知识详见&#xff1a;【C语言专项】 目录 什么是操作系统的引导&#xff1f; 操作系统的引导&#xff08;开机过程&#xff09; Windows操作系…...

国产云桌面迁移对接信创AD域控方案

在前文《替换AD域时&#xff0c;网络准入场景如何迁移对接国产身份域管&#xff1f;》中&#xff0c;根据 AD 在企业中的应用程度&#xff0c;我们将企业分为了轻度、中度及深度三类微软 AD 用户。 轻度AD用户&#xff1a;仅部分应用对接 AD 。替换 AD 时&#xff0c;可能会直接…...

ESP32—C3实现DS18B20(温度传感器)检测温度(Arduino IED )

1源代码&#xff08;DS18B20&#xff09; #include <OneWire.h> // 引入OneWire库&#xff0c;用于与单总线设备通信 #include <DallasTemperature.h> // 引入DallasTemperature库&#xff0c;用于读取DS18B20温度传感器数据// 定义连接到DS18B20数据引脚的GPIO编…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...