<template>
<div>
<el-table
ref="tableData"
:data="tableData"
show-summary
:max-height="520"
:summary-method="summaryMethod"
:default-sort="sortRule"
@sort-change="sortChange"
>
<el-table-column
v-if="analyseType==='5'"
key="provice"
header-align="center"
label="省份"
prop="typeName"
min-width="140"
fixed
/>
<el-table-column
v-else
key="customerType"
header-align="center"
label="客户类型"
prop="typeName"
min-width="140"
fixed
/>
<template v-for="year in yearList">
<el-table-column
v-if="selectedAllColumns.length"
:key="`${year}_all`"
header-align="center"
:label="`${year}`"
>
<el-table-column
v-for="column in selectedAllColumns"
:key="`${column.prop}_${year}`"
:prop="`${column.prop}_${year}`"
:label="column.columnLabel"
:min-width="getHeaderWidth(column.columnLabel)"
sortable="custom"
>
<template slot-scope="{row,column:scopeColumn}">
<span
v-if="column.columnLabel === '业绩(万元)'"
class="link-style"
@click="handleCeilClick(row,scopeColumn,year)"
>
{{ row[`${column.prop}_${year}`] }}
</span>
<span v-else>{{ formatCeilData(column.columnLabel,row[`${column.prop}_${year}`]) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column
v-if="selectedCutoffColumns.length"
:key="`${year}_cutoff`"
header-align="center"
:label="`${year},其中截止${deadline}`"
>
<el-table-column
v-for="column in selectedCutoffColumns"
:key="`${column.prop}_${year}`"
:prop="`${column.prop}_${year}`"
:label="column.columnLabel"
:min-width="getHeaderWidth(column.columnLabel)"
sortable="custom"
>
<template slot-scope="{row,column:scopeColumn}">
<span
v-if="column.columnLabel === '业绩(万元)'"
class="link-style"
@click="handleCeilClick(row,scopeColumn,year)"
>
{{ row[`${column.prop}_${year}`] }}
</span>
<span v-else>{{ formatCeilData(column.columnLabel,row[`${column.prop}_${year}`]) }}</span>
</template>
</el-table-column>
</el-table-column>
</template>
</el-table>
</div>
</template>
<script>
export default {
name: 'DataTable',
props: {
deadline: {
type: String,
default: ''
},
tableLebel: {
type: String,
default: ''
},
analyseType: {
type: String,
default: ''
},
systemDate: {
type: String,
default: ''
}
},
data() {
return {
tableColumns: [], // 列指标
selectedColumns: [], // 已选列指标
tableData: [], // 表格数据
yearList: [], // 年列表
sortRule: { prop: null, order: null },
sortData: [] // 拷贝的表格数据
}
},
computed: {
// 全量数据已选列
selectedAllColumns() {
const { selectedColumns } = this
return selectedColumns.filter(({ cutoff }) => !cutoff)
},
// 限制数据已选列
selectedCutoffColumns() {
const { selectedColumns } = this
return selectedColumns.filter(({ cutoff }) => cutoff)
}
},
methods: {
init(yearList, tableColumns, data) {
this.totalRow = data.pop() || {}
this.yearList = yearList
this.tableColumns = tableColumns
this.selectedColumns = [].concat(tableColumns)
this.tableData = data || []
this.sortData = data || []
this.$nextTick(() => {
const { tableData } = this.$refs
if (tableData) {
tableData && this.setScrollXY() // 解决滚动条不重置问题
tableData && tableData.doLayout() // 解决表格固定列塌陷导致无数据显示
}
})
},
setScrollXY(scrollLeft = 0, scrollTop = 0) {
const { $el } = this.$refs.tableData
const wrapper = $el.querySelector('.el-table__body-wrapper') // 滚动的元素类名
wrapper && Object.assign(wrapper, {
scrollLeft,
scrollTop
})
},
// 表格列点击事件
handleClick(row, column, year) {
console.log(row, column, year)
},
// 表格合计保持在最后
summaryMethod({ columns }) {
const total = ['合计']
for (let i = 1, l = columns.length; i < l; i++) {
const { property } = columns[i]
total[i] = this.formatCeilData(columns[i].label, this.totalRow[property])
}
return total
},
// 针对拼接百分比的单元格显示值格式化
formatCeilData(columnLabel, val) {
if (['业绩占比', '同期业绩增长率'].includes(columnLabel)) {
if (![null, undefined, '', '/'].includes(val)) {
return val + '%'
}
}
return val
},
// 表格排序方法(/排最后)
sortChange(column) {
const { prop, order } = column
if (order != null) {
const data = []
for (let i = 0; i < this.tableData.length; i++) {
//tableData是el-tabel绑定的表格数据
//判断如果是空的push在数字后面,有值的就放在前面,然后把排好的数组再赋值给表格data
const value = this.tableData[i][prop]
if ([null, '', '/', undefined].includes(value)) {
data.push(this.tableData[i])
} else {
data.unshift(this.tableData[i])
}
}
// 自定义排序方法 过滤掉 null undefined '' 等空值
data.sort((a, b) => {
const aValue = a[prop]
const bValue = b[prop]
if (aValue === bValue) {
return 0;
} else if ([null, '', '/', undefined].includes(aValue)) {
return 1;
} else if ([null, '', '/', undefined].includes(bValue)) {
return -1;
} else if (order === "ascending") {
// 升序
return Number(aValue) < Number(bValue) ? -1 : 1
} else {
// 降序
return Number(aValue) < Number(bValue) ? 1 : -1
}
});
this.tableData = data //最后把排序好的表格数据赋值给排序前的表格数据
} else { //如果不排序了,就恢复到最初未排序的状态
this.tableData = this.sortData // 用之前拷贝的数据还原默认排序
}
Object.assign(this.sortRule, {
prop,
order
})
},
clear() {
this.yearList = []
this.tableColumns = []
this.selectedColumns = []
this.tableData = []
},
getHeaderWidth(str) {
let strLength = this.computeStrOccupyLength(str)
strLength = Math.ceil(strLength)
return strLength * 15 + 30
},
// 计算字符串占用长度
computeStrOccupyLength(str) {
let num = 0
str.split('').forEach((s) => {
if (/[0-9a-z]|[.?()-:/\\]|\s/.test(s)) {
num += 0.5
} else if (/[A-Z]/.test(s)) {
num += 0.7
} else {
num += 1
}
})
return num
}
}
}
</script>
<style lang="scss" scoped>
.link-style {
color: #50308d;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
</style>