Vue使用el-table给每一行数据上面增加一行自定义合并行

// template
<template><el-table:data="flattenedData":span-method="objectSpanMethod"borderclass="custom-header-table"style="width: 100%"ref="myTable":height="'60vh'"><!-- 订单详情列 --><el-table-column label="订单详情" width="300"><template #default="{ row }"><!-- 额外行 --><div v-if="row.isExtraRow" class="extra-row"><div class="content"><span class="row_text">订单号:{{ row.orderNo }}</span><el-buttontype="text"size="mini"@click="copyOrderNo(row.orderNo, '订单号')"class="copy-btn">复制</el-button><span class="row_text">下单时间:{{ row.createTime }}</span><span class="row_text">企业名称:{{ row.contact }}</span><span class="row_text">报告单位:{{ row.reportUnitAddress }}</span></div><span class="statistic"><el-statisticv-if="row.tradeStatus == 11"format="HH:mm:ss":value="row.remainingTime"time-indices><template slot="suffix"><span class="color">后自动关闭</span></template></el-statistic></span></div><!-- 商品行 --><div v-else class="cell_box"><div class="flex"><el-imageclass="avatar":src="row.serveImageUrl":preview-src-list="[row.serveImageUrl]"></el-image><div class="name"><div class="flex"><el-tagtype="danger"size="small"v-if="row.isUrgent == 1">加急</el-tag><el-tooltipeffect="dark":content="row.serveName"placement="top"><spanclass="name-text":class="row.isUrgent == 1? 'title': 'title2'">{{ row.serveName }}</span></el-tooltip></div><div class="name-desc title2">检测用途:{{ row.testUse }}</div></div></div></div></template></el-table-column><!-- 下单数量列 --><el-table-column label="下单数量" width="200"><template #default="{ row }"><div class="cell_box txt" v-if="!row.isExtraRow">{{ row.orderNumber || '-' }}</div></template></el-table-column><!-- 实付金额列 --><el-table-column label="实付金额" width="200"><template #default="{ row }"><div class="cell_box txt" v-if="!row.isExtraRow">¥{{ row.totalPrice || '0.00' }}</div></template></el-table-column><!-- 订单状态列 --><el-table-column label="订单状态"><template #default="{ row }"><div class="cell_box" v-if="!row.isExtraRow"><!-- 待付款 --><template v-if="row.tradeStatus == 11"><el-tag size="small" type="danger">待付款</el-tag></template><templatev-if="row.tradeStatus == 20 &&row.acceptStatus == 0"><el-tag size="small" type="warning">受理中</el-tag></template><templatev-if="row.tradeStatus == 20 &&row.acceptStatus == 1"><el-tag size="small" type="success">服务中</el-tag></template><template v-if="row.tradeStatus == 40"><el-tag size="small"> 已完成 </el-tag></template><templatev-if="row.tradeStatus == -1 ||row.tradeStatus == -2"><el-tag size="small" type="info">已关闭</el-tag></template></div></template></el-table-column><!-- 操作列 --><el-table-column label="操作" width="150px"><template #default="{ row }"><divclass="cell_box operations"v-if="!row.isExtraRow"><el-button@click="handlePayment(row)"type="text"size="small"class="payBtn"v-if="row.tradeStatus == 11">扫码付款</el-button><el-buttonclass="btns"type="text"size="small"@click="handleDetails(row)">订单详情</el-button><el-buttonclass="btns"type="text"size="small"@click="handleClose(row)"v-if="row.tradeStatus == 11">关闭订单</el-button></div></template></el-table-column></el-table></template>
// datadata() {return {// 原始数据tableData: [],showCheckboxes: false}
}
// computed
computed: {// 实际数据flattenedData() {let result = []this.tableData.forEach((order) => {// 计算剩余时间const remainingTime = (() => {const currentTime = new Date(order.systemTime).getTime()const deadline = new Date(order.deadlineCloseTime).getTime()return currentTime >= deadline? 0: deadline - currentTime + new Date().getTime() // 加上当前时间})()// 1. 额外行(订单信息)result.push({isExtraRow: true,orderNo: order.orderNo, // 使用实际订单号createTime: order.createTime,contact: order.contact,tradeStatus: order.tradeStatus,reportUnitAddress: order.reportUnitAddress,remainingTime: remainingTime// orderData: order,      // 存储完整订单数据(可选)})// 2. 商品行(从 orderServeList 解析)try {const serveList = JSON.parse(order.orderServeList || '[]')serveList.forEach((serveItem) => {result.push({...serveItem, // 商品信息isExtraRow: false,orderId: order.id, // 关联订单IDtradeStatus: order.tradeStatus,acceptStatus: order.acceptStatus// orderData: order // 关联订单数据(可选)})})} catch (e) {console.error('解析 orderServeList 失败:', e)}})console.log(result, 'result')return result}
}
// methods
methods: {objectSpanMethod({ row, column, rowIndex, columnIndex }) {if (row.isExtraRow) {// 动态计算列数(需确保 el-table 已渲染)const columns = this.$refs.myTable?.columns?.lengthif (columnIndex === 0) {return {rowspan: 1,colspan: columns // 动态跨所有列}} else {return {rowspan: 0,colspan: 0}}}return { rowspan: 1, colspan: 1 }},copyOrderNo(content, title) {const textArea = document.createElement('textarea')textArea.value = content// 隐藏 textarea,并防止它影响页面布局textArea.style.position = 'fixed'textArea.style.opacity = '0'textArea.style.left = '-9999px'textArea.style.top = '0'document.body.appendChild(textArea)textArea.select()try {const successful = document.execCommand('copy')if (successful) {this.$message.success(title + '已复制!')} else {this.$message.error('复制失败,请手动复制')}} catch (err) {this.$message.error('复制失败,请手动复制')}document.body.removeChild(textArea)}}
// style
<style lang="scss" scoped>/deep/ .custom-header-table {.el-table__header {th {background: #f6f6f6 !important;height: 20px;font-family: PingFangSC, PingFang SC;font-weight: 500;font-size: 14px;color: #515a6e;line-height: 20px;text-align: left;font-style: normal;padding-left: 10px !important;}}}/* 额外行样式 */.extra-row {background-color: #e2ebfe;padding: 10px;font-weight: bold;display: flex;justify-content: space-between;align-items: center;gap: 20px;.content {flex: 1;white-space: nowrap; // 使文本不换行显示overflow: hidden;text-overflow: ellipsis; // 显示省略号}.statistic {width: 170px;/deep/ .number {color: #ff4131 !important;}}}/* 不影响正常行 *//deep/ .el-table__body tr:not(.extra-row) td {padding: 0; /* 正常行的 padding 保持不变 */}/deep/ .el-table .cell {padding: 0; /* 正常行的 padding 保持不变 */}/deep/ .cell {padding-left: 0 !important;}.copy-btn {font-size: 14px;margin-left: 10px;margin-left: -5px;color: #1464df;}.btns {color: #1464df;}.cell_box {padding: 10px;}.flex {display: flex;.avatar {width: 92px;height: 91px;margin-left: 10px;}/deep/ .el-tag {margin-right: 5px;}.name {display: flex;flex-direction: column;justify-content: space-around;margin-left: 10px;&-text {height: 22px;font-family: PingFangSC, PingFang SC;font-weight: 500;font-size: 16px;color: #262626;line-height: 22px;text-align: left;font-style: normal;}&-desc {height: 20px;font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 14px;color: #999999;line-height: 20px;text-align: left;font-style: normal;}}}.title {max-width: 150px;white-space: nowrap; // 使文本不换行显示overflow: hidden;text-overflow: ellipsis; // 显示省略号}.title2 {max-width: 180px;white-space: nowrap; // 使文本不换行显示overflow: hidden;text-overflow: ellipsis; // 显示省略号}.row_text {margin: 0 8px;}.color {color: #ff4131;}.payBtn {color: orange;}.txt {font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 14px;color: #3c3c3c;text-align: left;font-style: normal;}.operations {display: flex;flex-direction: column;/deep/ .el-button + .el-button,.el-checkbox.is-bordered + .el-checkbox.is-bordered {margin-left: 0 !important;}}
</style>

如何需要合并同一个订单下的数据的操作列

methods: {objectSpanMethod({ row, column, rowIndex, columnIndex }) {if (row.isExtraRow) {// 处理额外行(订单信息行)const columns = this.$refs.myTable?.columns?.length;if (columnIndex === 0) {return {rowspan: 1,colspan: columns // 动态跨所有列};} else {return {rowspan: 0,colspan: 0};}} else {// 处理商品行if (columnIndex === 4) { // 操作列是第5列(从0开始计数)// 找到当前订单的所有商品行const orderRows = this.getOrderRows(row.orderId);const firstRowIndex = this.findFirstRowIndex(row.orderId);// 如果是当前订单的第一个商品行,则合并行数if (rowIndex === firstRowIndex) {return {rowspan: orderRows.length,colspan: 1};} else {return {rowspan: 0,colspan: 0};}}}return { rowspan: 1, colspan: 1 };},// 获取指定订单的所有商品行getOrderRows(orderId) {return this.flattenedData.filter(item => !item.isExtraRow && item.orderId === orderId);},// 找到指定订单的第一个商品行的索引findFirstRowIndex(orderId) {return this.flattenedData.findIndex(item => !item.isExtraRow && item.orderId === orderId);}
}

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

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

相关文章

vue项目使用html2canvas和jspdf将页面导出成PDF文件

一、需求&#xff1a; 页面上某一部分内容需要生成pdf并下载 二、技术方案&#xff1a; 使用html2canvas和jsPDF插件 三、js代码 // 页面导出为pdf格式 import html2Canvas from "html2canvas"; import jsPDF from "jspdf"; import { uploadImg } f…

大模型LLM表格报表分析:markitdown文件转markdown,大模型markdown统计分析

整体流程&#xff1a;用markitdown工具文件转markdown&#xff0c;然后大模型markdown统计分析 markitdown https://github.com/microsoft/markitdown 在线体验&#xff1a;https://huggingface.co/spaces/AlirezaF138/Markitdown 安装&#xff1a; pip install markitdown…

Linux 第二讲 --- 基础指令(二)

前言 这是基础指令的第二部分&#xff0c;但是该部分的讲解会大量使用到基础指令&#xff08;一&#xff09;的内容&#xff0c;为了大家的观感&#xff0c;如果对Linux的一些基本指令不了解的话&#xff0c;可以先看基础指令&#xff08;一&#xff09;&#xff0c;同样的本文…

python格式化字符串漏洞

什么是python格式化字符串漏洞 python中&#xff0c;存在几种格式化字符串的方式&#xff0c;然而当我们使用的方式不正确的时候&#xff0c;即格式化的字符串能够被我们控制时&#xff0c;就会导致一些严重的问题&#xff0c;比如获取敏感信息 python常见的格式化字符串 百…

LLaMA-Factory双卡4090微调DeepSeek-R1-Distill-Qwen-14B医学领域

unsloth单卡4090微调DeepSeek-R1-Distill-Qwen-14B医学领域后&#xff0c;跑通一下多卡微调。 1&#xff0c;准备2卡RTX 4090 2&#xff0c;准备数据集 医学领域 pip install -U huggingface_hub export HF_ENDPOINThttps://hf-mirror.com huggingface-cli download --resum…

React Hooks: useRef,useCallback,useMemo用法详解

1. useRef&#xff08;保存引用值&#xff09; useRef 通常用于保存“不会参与 UI 渲染&#xff0c;但生命周期要长”的对象引用&#xff0c;比如获取 DOM、保存定时器 ID、WebSocket等。 新建useRef.js组件&#xff0c;写入代码&#xff1a; import React, { useRef, useSt…

Spring AI 结构化输出详解

一、Spring AI 结构化输出的定义与核心概念 Spring AI 提供了一种强大的功能&#xff0c;允许开发者将大型语言模型&#xff08;LLM&#xff09;的输出从字符串转换为结构化格式&#xff0c;如 JSON、XML 或 Java 对象。这种结构化输出能力对于依赖可靠解析输出值的下游应用程…

THM Billing

1. 信息收集 (1) Nmap 扫描 bashnmap -T4 -sC -sV -p- 10.10.189.216 输出关键信息&#xff1a; PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 8.4p1 Debian 5deb11u380/tcp open http Apache 2.4.56 (Debian) # MagnusBilling 应用3306/tcp open …

布局决定终局:基于开源AI大模型、AI智能名片与S2B2C商城小程序的战略反推思维

摘要&#xff1a;在商业竞争日益激烈的当下&#xff0c;布局与终局预判成为企业成功的关键要素。本文探讨了布局与终局预判的智慧性&#xff0c;强调其虽无法做到百分之百准确&#xff0c;但能显著提升思考能力。终局思维作为重要战略工具&#xff0c;并非一步到位的战略部署&a…

贪心算法 day08(加油站+单调递增的数字+坏了的计算机)

目录 1.加油站 2.单调递增的数字 3.坏了的计算器 1.加油站 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; gas[index] - cost[index]&#xff0c;ret 表示的是在i位置开始循环时剩余的油量 a到达的最大路径假设是f那么我们可以得出 a b …

【技术派部署篇】云服务器部署技术派

1 环境搭建 1.1 JDK安装 # ubuntu sudo apt update # 更新apt apt install openjdk-8-jdk # 安装JDK安装完毕之后&#xff0c;执行 java -version 命令进行验证&#xff1a; 1.2 Maven安装 cd ~ mkdir soft cd soft wget https://dlcdn.apache.org/maven/maven-3/3.8.8/bina…

Linux:35.其他IPC和IPC原理+信号量入门

通过命名管道队共享内存的数据发送进行保护的bug&#xff1a; 命名管道挂掉后&#xff0c;进程也挂掉了。 6.systemV消息队列 原理:进程间IPC:原理->看到同一份资源->维护成为一个队列。 过程&#xff1a; 进程A,进程B进行通信。 让操作系统提供一个队列结构&#xff0c;…

【数据结构】红黑树超详解 ---一篇通关红黑树原理(含源码解析+动态构建红黑树)

一.什么是红黑树 红黑树是一种自平衡的二叉查找树&#xff0c;是计算机科学中用到的一种数据结构。1972年出现&#xff0c;最初被称为平衡二叉B树。1978年更名为“红黑树”。是一种特殊的二叉查找树&#xff0c;红黑树的每一个节点上都有存储表示节点的颜色。每一个节点可以是…

2024年第十五届蓝桥杯CC++大学A组--成绩统计

2024年第十五届蓝桥杯C&C大学A组--成绩统计 题目&#xff1a; 动态规划&#xff0c; 对于该题&#xff0c;考虑动态规划解法&#xff0c;先取前k个人的成绩计算其方差&#xff0c;并将成绩记录在数组中&#xff0c;记录当前均值&#xff0c;设小蓝已检查前i-1个人的成绩&…

vue2使用ezuikit-js播放萤石视频

需求&#xff1a;需要在大屏上播放萤石视频&#xff0c;用到官方的ezuikit-js插件实现&#xff0c;并实现视频播放切换功能。有个问题至今没有解决&#xff0c;就是萤石视频的宽高是固定的&#xff0c;不会根据大屏缩放进行自适应。我这边做了简单的刷新自适应。 1.下载ezuikit…

爱普生TG-5510CA和TG-5510CB晶振成为服务器中的理想之选

在数字化时代&#xff0c;服务器作为数据存储、处理与传输的核心枢纽&#xff0c;其性能的优劣直接影响着整个信息系统的运行效率与稳定性。从企业内部的数据中心到云计算服务提供商的大规模集群&#xff0c;服务器需要应对海量数据的高速处理与频繁交互。而在服务器复杂精密的…

使用opentelemetry 可观测监控springboot应用的指标、链路实践,使用zipkin展示链路追踪数据,使用grafana展示指标

1.安装docker&#xff0c;docker-compose &#xff08;1&#xff09;安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm22.2、部署dockertar xvf docker-20.10.19.tgz cp docker/* /usr/bin/vim /usr/lib/systemd/system/docker.service[Unit] Descript…

5. 蓝桥公园

题目描述 小明喜欢观景&#xff0c;于是今天他来到了蓝桥公园。 已知公园有 N 个景点&#xff0c;景点和景点之间一共有 M 条道路。小明有 Q 个观景计划&#xff0c;每个计划包含一个起点 stst 和一个终点 eded&#xff0c;表示他想从 stst 去到 eded。但是小明的体力有限&am…

虚幻基础:碰撞帧运算

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 碰撞碰撞盒线段检测 帧运算&#xff1a;每个程序流就是一帧的计算结果速度过快时(10000)&#xff0c;导致每帧移动过大(83)&#xff0c;从而导致碰撞盒错过而没有碰撞速度快的碰撞要用线段检测 碰撞 碰撞盒 线段检…

Qt 入门 3 之对话框 QDialog

Qt 入门 3 之对话框 QDialog 本文从以下几点分开讲述&#xff1a; - 对话框的基本原理介绍 - 两种不同类型的对话框 - 一个由多个窗口组成并且窗口间可以相互切换的程序 1.模态和非模态对话框 QDialog 类是所有对话框窗口类的基类。对话框窗口是一个经常用来完成短小任务或者…