table中表格合并 el-table纵向合并单元格
https://blog.csdn.net/u013558749/article/details/82257168 (element-ui 实现行合并)
https://www.cnblogs.com/guwufeiyang/p/12850088.html (合并后样式的处理)
合并后样式
来源数据- 获取到后台返回的数据再经过前端处理
- 注意 [processId] [dimensionTag] 是参与合并的关键字段
[
{
"processId": "1499255834195238914",
"currentProcessInfoId": "1499255834245570561",
"flowType": "01",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "01",
"dimensionName": "重点-测试",
"dimensionTag": "1499255834195238914重点-测试",
"nature": "01",
"name": "1212",
"statusRemark": "1212",
"scoreStand": "1212",
"source": "1212",
"weight": 0.3,
"status": "Y",
"remark": "-",
"index": 1,
"rowIndex": 0
},
{
"processId": "1499255834195238914",
"currentProcessInfoId": "1499255834245570561",
"flowType": "01",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "01",
"dimensionName": "日常-测试",
"dimensionTag": "1499255834195238914日常-测试",
"nature": "01",
"name": "TEST",
"statusRemark": "100",
"scoreStand": "100",
"source": "100",
"weight": 0.3,
"status": "Y",
"remark": "-",
"index": 1,
"rowIndex": 1
},
{
"processId": "1499255834195238914",
"currentProcessInfoId": "1499255834245570561",
"flowType": "01",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "01",
"dimensionName": "日常-测试",
"dimensionTag": "1499255834195238914日常-测试",
"nature": "01",
"name": "12",
"statusRemark": "12",
"scoreStand": "12",
"source": "12",
"weight": 0.3,
"status": "Y",
"remark": "-",
"index": 1,
"rowIndex": 2
},
{
"processId": "1499255834195238914",
"currentProcessInfoId": "1499255834245570561",
"flowType": "01",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "01",
"dimensionName": "管理指标",
"dimensionTag": "1499255834195238914管理指标",
"nature": "02",
"name": "12",
"statusRemark": "12",
"scoreStand": "12",
"source": "12",
"weight": 0.1,
"status": "Y",
"remark": "-",
"index": 1,
"rowIndex": 3
},
{
"processId": "1499255834996350977",
"currentProcessInfoId": null,
"flowType": "02",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "00",
"dimensionName": "重点-测试",
"dimensionTag": "1499255834996350977重点-测试",
"nature": "01",
"name": "1212",
"statusRemark": "1212",
"scoreStand": "1212",
"source": "1212",
"weight": 0.3,
"status": "-",
"remark": "-",
"index": 2,
"rowIndex": 4
},
{
"processId": "1499255834996350977",
"currentProcessInfoId": null,
"flowType": "02",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "00",
"dimensionName": "日常-测试",
"dimensionTag": "1499255834996350977日常-测试",
"nature": "01",
"name": "TEST",
"statusRemark": "100",
"scoreStand": "100",
"source": "100",
"weight": 0.3,
"status": "-",
"remark": "-",
"index": 2,
"rowIndex": 5
},
{
"processId": "1499255834996350977",
"currentProcessInfoId": null,
"flowType": "02",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "00",
"dimensionName": "日常-测试",
"dimensionTag": "1499255834996350977日常-测试",
"nature": "01",
"name": "12",
"statusRemark": "12",
"scoreStand": "12",
"source": "12",
"weight": 0.3,
"status": "-",
"remark": "-",
"index": 2,
"rowIndex": 6
},
{
"processId": "1499255834996350977",
"currentProcessInfoId": null,
"flowType": "02",
"userName": "xxx",
"itcode": "xxx",
"pernr": "xxx",
"approveStatus": "00",
"dimensionName": "管理指标",
"dimensionTag": "1499255834996350977管理指标",
"nature": "02",
"name": "12",
"statusRemark": "12",
"scoreStand": "12",
"source": "12",
"weight": 0.1,
"status": "-",
"remark": "-",
"index": 2,
"rowIndex": 7
}
]
// 按照dimensionTag合并行
getDimensionNumber() {
this.dimensionIndexArr = []
let DimensionObj = {}
this.dataList.forEach((element, index) => {
element.rowIndex = index
if (DimensionObj[element.dimensionTag]) {
DimensionObj[element.dimensionTag].push(index)
} else {
DimensionObj[element.dimensionTag] = []
DimensionObj[element.dimensionTag].push(index)
}
})
for (let k in DimensionObj) {
if (DimensionObj[k].length > 1) {
this.dimensionIndexArr.push(DimensionObj[k])
}
}
},
// 按照processId合并行
getRecordNumber() {
this.recordIndexArr=[]
let OrderObj = {}
this.dataList.forEach((element, index) => {
element.rowIndex = index
if (OrderObj[element.processId]) {
OrderObj[element.processId].push(index)
} else {
OrderObj[element.processId] = []
OrderObj[element.processId].push(index)
}
})
for (let k in OrderObj) {
if (OrderObj[k].length > 1) {
this.recordIndexArr.push(OrderObj[k])
}
}
},
objectSpanMethod({row, column, rowIndex, columnIndex}) {
if (columnIndex === 0 || columnIndex === 1 || columnIndex >= 9) {
for (let i = 0; i < this.recordIndexArr.length; i ) {
let element = this.recordIndexArr[i]
for (let j = 0; j < element.length; j ) {
let item = element[j]
if (rowIndex == item) {
if (j == 0) {
return {
rowspan: element.length,
colspan: 1
}
} else if (j != 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
if (columnIndex === 2) {
for (let i = 0; i < this.dimensionIndexArr.length; i ) {
let element = this.dimensionIndexArr[i]
for (let j = 0; j < element.length; j ) {
let item = element[j]
if (rowIndex == item) {
if (j == 0) {
return {
rowspan: element.length,
colspan: 1
}
} else if (j != 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
},
- 完成合并后会改变框架的样式,需要修复
样式错乱
- 在el-table上添加 [row-class-name] [@cell-mouse-enter] [@cell-mouse-leave]并实现对应方法
<el-table
ref="table"
v-loading="dataListLoading"
:data="dataList"
border
:span-method="objectSpanMethod"
:row-class-name="tableRowClassName"
@cell-mouse-enter="cellMouseEnter"
@cell-mouse-leave="cellMouseLeave"
style="width: 100%;margin-top: 16px"
>
.......
</el-table>
tableRowClassName({row, rowIndex}) {
let arr = this.hoverOrderArr
for (let i = 0; i < arr.length; i ) {
if (rowIndex === arr[i]) {
return 'success-row'
}
}
},
cellMouseEnter(row, column, cell, event) {
this.rowIndex = row.rowIndex
this.hoverOrderArr = []
this.recordIndexArr.forEach((element) => {
if (element.indexOf(this.rowIndex) >= 0) {
this.hoverOrderArr = element
}
})
},
cellMouseLeave(row, column, cell, event) {
this.rowIndex = '-1'
this.hoverOrderArr = []
},
<style scoped>
/deep/ .el-table .success-row {
background: #ecf4fe;
}
</style>
<template>
<el-card>
<div class="app-container">
<!--工具栏-->
<div class="head-container">
<div>
<!-- 搜索 -->
<el-input
v-model="queryParams.name"
size="small"
clearable
placeholder="输入名称或者描述搜索"
style="width: 200px;"
class="filter-item"
/>
<span>
<el-button
class="filter-item"
size="mini"
type="success"
icon="el-icon-search"
@click="searchHandler"
>搜索</el-button>
<el-button
class="filter-item"
size="mini"
type="warning"
icon="el-icon-refresh-left"
@click="resetHandler"
>重置</el-button>
<el-button
class="filter-item"
size="mini"
icon="el-icon-plus"
@click="addHandler"
>新增</el-button>
</span>
</div>
</div>
<!-- 列表数据 -->
<el-table
ref="table"
v-loading="dataListLoading"
:data="dataList"
border
:span-method="objectSpanMethod"
:row-class-name="tableRowClassName"
@cell-mouse-enter="cellMouseEnter"
@cell-mouse-leave="cellMouseLeave"
style="width: 100%;margin-top: 16px"
>
<el-table-column
label="序号"
prop="index"
width="50"
align="center"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="userName"
header-align="center"
align="center"
label="人员"
>
<template slot-scope="scope">
<span v-if="scope.row.status!=='-'" style="color: #67c23a;font-weight: bold">{{scope.row.userName}}({{scope.row.pernr}})</span>
<span v-if="scope.row.status==='N'" style="color: red;font-weight: bold">{{scope.row.userName}}({{scope.row.pernr}})</span>
<span v-if="scope.row.status ==='-'"style="color: black;font-weight: bold">{{scope.row.userName}}({{scope.row.pernr}})</span>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="dimensionName"
header-align="center"
align="center"
label="维度名称"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="nature"
header-align="center"
align="center"
label="指标性质"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.nature === '01'" type="success">定性</el-tag>
<el-tag v-else type="warning">定量</el-tag>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="name"
header-align="center"
align="center"
label="指标名称"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="statusRemark"
header-align="center"
align="center"
label="目标值/状态描述"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="scoreStand"
header-align="center"
align="center"
label="评分标准"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="source"
header-align="center"
align="center"
label="数据来源"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="weight"
header-align="center"
align="center"
label="权重"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="status"
header-align="center"
align="center"
label="是否同意"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="remark"
header-align="center"
align="center"
label="审批意见"
>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="flowType"
header-align="center"
align="center"
label="流程类型"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.flowType === '01'" type="success">目标流程</el-tag>
<el-tag v-else type="warning">结果流程</el-tag>
</template>
</el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="approveStatus"
header-align="center"
align="center"
label="全局审批状态"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.approveStatus === '00'" type="info">待审批</el-tag>
<el-tag v-if="scope.row.approveStatus === '01'" type="warning">审批流转中</el-tag>
<el-tag v-if="scope.row.approveStatus === '02'" type="success">已完成(同意)</el-tag>
<el-tag v-if="scope.row.approveStatus === '03'" type="danger">已完成(驳回)</el-tag>
</template>
</el-table-column>
<el-table-column
fixed="right"
align="center"
width="150"
label="操作"
>
<template slot-scope="scope">
<span v-if="scope.row.status==='-'">
<el-button type="text" @click="changeStatus(scope.row.processId,'Y')">同意</el-button>
<el-button type="text" @click="changeStatus(scope.row.processId,'N')">不同意</el-button>
</span>
<el-button type="text" @click="fillInOpen(scope.row.currentProcessInfoId)">填写意见</el-button>
<el-button type="text" @click="approveRecord(scope.row.processId)">审批记录</el-button>
</template>
</el-table-column>
</el-table>
<pagetool
v-show="total>0"
:total="total"
:page.sync="queryParams.current"
:limit.sync="queryParams.size"
@pagination="searchHandler"
/>
<eForm ref="eForm" @finish="searchHandler"/>
</div>
</el-card>
</template>
<script>
import eForm from './form'
import kpi from "../../../../api/kpi/kpi";
export default {
name: 'index',
components: {eForm},
data() {
return {
visible: false,
queryParams: {
name: '',
current: 1,
size: 10
},
total: 0,
dataList: [],
recordIndexArr: [],
dimensionIndexArr: [],
hoverOrderArr: [],
dataListLoading: false
}
},
created() {
this.searchHandler()
},
mounted() {
this.searchHandler()
},
methods: {
searchHandler() {
kpi.flowEmployeeApproveRecordPage(this.queryParams).then(({data}) => {
let dataList = []
let index = 0
data.data.records.forEach(record => {
let userName = record.userName // 用户名
let itcode = record.itcode // itcode
let pernr = record.pernr // 员工编号
let status = record.status ? record.status : '-' // 审批状态-是否同意
let remark = record.remark ? record.remark : '-' // 审批意见
let processId = record.id // 流程ID
let currentProcessInfoId = record.currentProcessInfoId // 当前激活的子流程ID
let flowType = record.flowType // 流程类型 01:目标流程02:结果流程
let approveStatus = record.approveStatus // 全局审批状态
index = 1
/** 维度 **/
let dimensionList = record.dimensionList
if (dimensionList && dimensionList.length) {
dimensionList.forEach(dimension => {
let dimensionName = dimension.name // 维度名称
let dimensionTag = processId dimensionName
let userTargetList = dimension.userTargetList
if (userTargetList && userTargetList.length) {
userTargetList.forEach(userTarget => {
// 指标性质
let nature = userTarget.nature
// 指标名称
let name = userTarget.name
// 目标值/状态描述
let statusRemark = userTarget.statusRemark
// 评分标准
let scoreStand = userTarget.scoreStand
// 数据来源
let source = userTarget.source
// 权重
let weight = userTarget.weight
let data = {
processId,
currentProcessInfoId,
flowType,
userName,
itcode,
pernr,
approveStatus,
dimensionName,
dimensionTag,
nature,
name,
statusRemark,
scoreStand,
source,
weight,
status,
remark,
index
}
dataList.push(data)
})
}
})
}
})
this.dataList = dataList
this.total = data.data.total
this.getRecordNumber()
this.getDimensionNumber()
console.log(this.dataList)
})
},
resetHandler() {
},
addHandler() {
},
fillInOpen(currentProcessInfoId){
this.$refs.eForm.init(currentProcessInfoId)
},
changeStatus(id, status) {
console.log(id, status)
this.$confirm(`确定[${status === 'Y' ? '同意' : '拒绝'}]该流程?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
kpi.flowEmployeeChangeApproveRecordStatus(id, status).then(({data}) => {
this.$message.success('操作成功')
this.searchHandler()
})
}).catch(() => {
this.$message.info('已取消')
})
},
delHandler(id) {
},
getDimensionNumber() {
let DimensionObj = {}
this.dataList.forEach((element, index) => {
element.rowIndex = index
if (DimensionObj[element.dimensionTag]) {
DimensionObj[element.dimensionTag].push(index)
} else {
DimensionObj[element.dimensionTag] = []
DimensionObj[element.dimensionTag].push(index)
}
})
for (let k in DimensionObj) {
if (DimensionObj[k].length > 1) {
this.dimensionIndexArr.push(DimensionObj[k])
}
}
},
getRecordNumber() {
let OrderObj = {}
this.dataList.forEach((element, index) => {
element.rowIndex = index
if (OrderObj[element.processId]) {
OrderObj[element.processId].push(index)
} else {
OrderObj[element.processId] = []
OrderObj[element.processId].push(index)
}
})
for (let k in OrderObj) {
if (OrderObj[k].length > 1) {
this.recordIndexArr.push(OrderObj[k])
}
}
},
// 合并单元格
/** https://blog.csdn.net/u013558749/article/details/82257168 **/
objectSpanMethod({row, column, rowIndex, columnIndex}) {
if (columnIndex === 0 || columnIndex === 1 || columnIndex >= 9) {
for (let i = 0; i < this.recordIndexArr.length; i ) {
let element = this.recordIndexArr[i]
for (let j = 0; j < element.length; j ) {
let item = element[j]
if (rowIndex == item) {
if (j == 0) {
return {
rowspan: element.length,
colspan: 1
}
} else if (j != 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
if (columnIndex === 2) {
for (let i = 0; i < this.dimensionIndexArr.length; i ) {
let element = this.dimensionIndexArr[i]
for (let j = 0; j < element.length; j ) {
let item = element[j]
if (rowIndex == item) {
if (j == 0) {
return {
rowspan: element.length,
colspan: 1
}
} else if (j != 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
},
tableRowClassName({row, rowIndex}) {
let arr = this.hoverOrderArr
for (let i = 0; i < arr.length; i ) {
if (rowIndex === arr[i]) {
return 'success-row'
}
}
},
cellMouseEnter(row, column, cell, event) {
this.rowIndex = row.rowIndex
this.hoverOrderArr = []
this.recordIndexArr.forEach((element) => {
if (element.indexOf(this.rowIndex) >= 0) {
this.hoverOrderArr = element
}
})
},
cellMouseLeave(row, column, cell, event) {
this.rowIndex = '-1'
this.hoverOrderArr = []
},
}
}
</script>
<style scoped>
/deep/ .el-table .success-row {
background: #ecf4fe;
}
</style>
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com