<template>
<div :class="['md-table', noPadding ? 'no-padding' : '']" :style="tableStyle" ref="refTable" v-resize="handleResize">
<!-- {{ defultSelectRadioIndex }}
{{ clickRowIndex }} -->
<action-bar
v-if="action"
v-bind="$attrs"
:tableName="tableName"
:getRowIndex="getRowIndex"
:selectionItemsInfo="multipleSelection"
:isReportTable="isReportTable"
:topBtnPosition="topBtnPosition"
:isExport="isExport"
:exportCode="exportCode"
:listManageCode="listManageCode"
:menuCodePrifixListManage="menuCodePrifixListManage"
@handlerChange="handlerChange"
@handlerExport="handlerExport"
ref="actionBar"
>
<slot name="after"></slot>
<slot name="btn"></slot>
<slot name="right"></slot>
</action-bar>
<div class="table-container">
<el-table
ref="elTable"
class="tableClass"
border
v-bind="$attrs"
v-on="$listeners"
v-loading="loading || innerLoading"
:row-key="rowKey"
:lazy="lazy"
:load="loadFunction"
:tree-props="treeProps"
:data="data"
:row-class-name="tableRowClassName"
:cell-style="cellStyle"
:element-loading-text="loadingText"
:span-method="this.merge ? this.mergeMethod : this.spanMethod"
:height="customHeight || height"
@row-click="handleRowClick"
@cell-click="handleCellClick"
@select="tableSelect"
@select-all="tableSelectAll"
@selection-change="handleSelectionChange"
@header-dragend="headerDragend"
@sort-change="handleSortChange"
@expand-change="expandChange"
>
<!-- 多选框配置 -->
<el-table-column
v-if="isSelection"
:reserve-selection="reserveSelection"
type="selection"
width="35"
:selectable="typeof selectable === 'function' ? selectable : renderSelectable"
>
</el-table-column>
<!-- 单选配置 -->
<el-table-column v-if="isSelectRadio" width="35" show-overflow-tooltip="false">
<template slot-scope="scope">
<el-radio v-if="clickRowIndex === scope.$index"></el-radio>
<el-radio v-else :value="false" :disabled="selectDisabled || scope.row.selectRadioDisabled"></el-radio>
</template>
</el-table-column>
<!-- 索引配置:从 1 开始计算 -->
<el-table-column
:label="isCustomizeNoLable ? customizeNoLable : $t('basic.NoH')"
v-if="showIndex"
type="index"
:index="indexMethod"
:width="column.length > 0 ? customizeNoLableWidth : fullTableWidth"
>
<template slot-scope="scope">
{{ (customIndexMethod && customIndexMethod(scope)) || scope.$index + 1 }}
</template>
</el-table-column>
<!-- 自定义 el-table-column -->
<template v-for="(item, index) in filterColumn">
<el-table-column
v-bind="item"
v-if="item.childrenHeader"
:label="$t(item.customLabel) || $t(item.label) || item.label"
>
<el-table-column
v-for="(cItem, cIndex) in item.childrenHeader"
v-bind="cItem"
:key="cIndex"
:label="$t(cItem.customLabel) || $t(cItem.label) || cItem.label"
>
</el-table-column>
</el-table-column>
<el-table-column
v-bind="item"
v-else
:key="item.prop + '##' + index"
:label="$t(item.customLabel) || $t(item.label) || item.label"
:show-overflow-tooltip="setShowOverFlow(item)"
>
<template slot-scope="scope">
<template
v-if="
!item.formViewDisabled &&
(item.viewAlways || formViewMethod(scope, index) || scope.$index === editTableRowIndex) &&
!(typeof item.hidden === 'function' ? item.hidden(scope.row) : item.hidden)
"
>
<slot
v-if="item.slotName"
:name="item.slotName"
:row="scope.row"
:column="item"
:$index="scope.$index"
></slot>
<div v-else-if="item.html" v-html="renderHtml(item, scope)"></div>
<component
:is="typeof item.render === 'function' ? handleRendel(item.render, scope) : item.render"
:scope="scope"
v-else-if="item.render"
></component>
<mingdu-form
v-else-if="item.formView && Object.keys(item.formView).length > 0"
:form-view="cloneDeep(item.formView)"
class="tableForm"
form-table
ref="mdform"
:key="index + '#' + scope.$index"
:form-data="scope.row"
:editTableRowIndex="editTableRowIndex"
:table-row-index="scope.$index"
:table-col-index="index"
label-width="0"
:form-item-min-width="(item.formViewConfig && item.formViewConfig.formItemMinWidth) || 40"
v-bind="item.formViewConfig"
:columns="12"
></mingdu-form>
<span
style="white-space: break-spaces !important"
v-else
v-html="renderCellHtml(item, scope)"
v-tableTooltip
></span>
</template>
<component
:is="
typeof item.formatterRender === 'function'
? handleRendel(item.formatterRender, scope)
: item.formatterRender
"
:scope="scope"
v-else-if="item.formatterRender"
></component>
<span
style="white-space: break-spaces !important"
v-else
v-html="renderCellHtml(item, scope)"
v-tableTooltip
></span>
<component
:is="typeof item.renderRight === 'function' ? handleRendel(item.renderRight, scope) : item.renderRight"
:scope="scope"
></component>
</template>
</el-table-column>
</template>
<!-- data数据为空时的插槽配置 -->
<template slot="empty">
<template v-if="!loading">
<template v-if="Number(emptyImageSize) > 0">
<el-empty :description="emptyText" :image-size="Number(emptyImageSize)"></el-empty>
</template>
<template v-else>
<span>{{ emptyText }}</span>
</template>
</template>
</template>
<!-- 操作列配置 -->
<el-table-column
v-if="isOperation && column.length > 0"
class-name="class-name"
:fixed="fixed"
:label="$t('操作')"
:showOverflowTooltip="false"
:resizable="false"
:width="operationWidth"
>
<slot name="operation" slot-scope="scope" :value="scope"></slot>
</el-table-column>
</el-table>
</div>
<!-- 分页配置 -->
<pages
v-model="page.page"
v-if="pagination && isPageNum === 1"
:page="currentPage"
:pageSize.sync="page.limit"
:total="totalNumber || data.length"
v-bind="$attrs"
v-on="$listeners"
/>
<!-- 拖拽组 -->
<customColumn
ref="customColumn"
:column="keyList"
:tableName="tableName"
:customListGlobalMenuCode="customListGlobalMenuCode"
></customColumn>
</div>
</template>
<script>
/**
* 基于element ui table二次封装,几乎支持原table所有的功能
* 文档地址:https://github.liubing.me/lb-element-table/zh/
*/
import { cloneDeep } from 'lodash'
import draggable from 'vuedraggable'
import pages from '@/components/page/pages'
import { getSelectData, optionsConfigs } from '@/common/getBasicDate.js'
import page from './page'
import actionBar from './action-bar'
import customColumn from './customColumn'
import i18n from '@/lang'
export default {
mixins: [page],
props: {
rowKey: {
type: String,
default: 'id'
},
lazy: {
type: Boolean,
default: false
},
loadFunction: {
type: Function,
default: () => ({})
},
indexMethod: {
type: Function
},
customIndexMethod: {
type: Function
},
treeProps: {
typa: Object,
default: () => ({})
},
selectable: {
type: Function | String,
default: () => ({})
},
fixed: {
type: String | Boolean,
default: 'right'
},
selectionItems: {
type: Array,
default: () => []
},
column: {
type: Array,
default: (_) => []
},
data: Array,
spanMethod: Function,
expandChange: Function,
exportCode: '', // 导出按钮 权限编码
listManageCode: '', // 列表管理按钮 权限编码
menuCodePrifixListManage: '', // 列表管理权限自定义前缀, 有了该值不取路由名
cellStyle: {
type: Object | Function,
default: () => {
'color: inherit'
}
},
//自定义行class
setTableRowClassName: {
type: Function
},
pagination: {
// 是否分页
type: Boolean,
default: true
},
total: {
type: Number,
default: 0
},
showIndex: {
// 是否显示序号列
type: Boolean,
default: true
},
action: {
// 是否操作菜单
type: Boolean,
default: true
},
paginationTop: {
type: String,
default: '15px'
},
paginationAlign: {
type: String,
default: 'right'
},
merge: Array,
isHeight: {
// 是否自动设置表格高度
type: Boolean,
default: true
},
reserveSelection: {
// 是否缓存选中数据
type: Boolean,
default: false
},
needClearSelection: {
// 是否需要清空多选数据
type: Boolean,
default: true
},
isOperation: {
// 是否操作列
type: Boolean,
default: false
},
operationWidth: {
// 操作列宽度
type: String | Number,
default: 100
},
isSelection: {
// 是否选择
type: Boolean,
default: true
},
isRowclick: {
// 是否可以选中单行
type: Boolean,
default: true
},
height: {
// 表格高度
type: Number / String,
default: '100%'
},
isPageNum: {
type: Number,
default: 1
},
tableName: String,
highlightCurrentRow: {
type: Boolean,
default: true
},
isSelectStyle: {
type: Boolean,
default: true
},
isSelectOnlyOne: {
// 是否单选
type: Boolean,
default: false
},
selectForm: {
// 查询条件
type: Object,
default: () => {
return {}
}
},
isReportTable: {
// 是否打表格
type: Boolean,
default: false
},
topBtnPosition: {
// 表格上方button的位置,left/right,默认展示在右边
type: String,
default: 'right'
},
// 行内编辑时正在编辑的行
editTableRowIndex: {
type: Number,
default: -1
},
/**
* 控制自定义表单类单元格的方法,返回true显示当前单元格
*@param {paraName}
*/
formViewShowMethod: {
type: Function
// default: () => {
// return () => {
// return true
// }
// }
},
loading: {
// 是否加载中
type: Boolean,
default: false
},
isCustomizeNoLable: {
// 是否自定义序号lable
type: Boolean,
default: false
},
loadingText: {
// 加载中的文案
type: String,
default: i18n.t('拼命加载中') + '...'
},
emptyText: {
// 数据为空时的文案
type: String,
default: i18n.t('暂无数据')
},
emptyTextColor: {
type: String,
default: ''
},
customizeNoLable: {
type: String,
default: ''
},
customizeNoLableWidth: {
type: String,
default: '55'
},
emptyImageSize: {
type: [Number, String],
default: 80
},
// 是否设置padding样式为0px,默认不设置
noPadding: {
type: Boolean,
default: false
},
// 是否显示单选列
isSelectRadio: {
type: Boolean,
default: false
},
//单选radio是否能点击取消选中
canSelectRadioCancel: {
type: Boolean,
default: false
},
defultSelectRadioIndex: {
// 默认选择的单选行
type: Number,
default: 0
},
// 单选是否禁止选择
selectDisabled: {
type: Boolean,
default: false
},
isExport: {
type: Boolean,
default: false
},
pageParams: {
type: Object,
default: () => ({})
},
// 是否选中第一行数据
defaultSelectedFirstRow: {
type: Boolean,
default: true
},
// 表格来源于哪个组件页面
from: {
type: String,
default: ''
},
// 单元格默认显示的文字
defaultText: {
type: String,
default: 'N/A'
},
clickRowToSelect: {
//是否可以在点击行的时候选中行
type: Boolean,
default: true
},
autoRowClick: {
//是否data变化时默认执行选中首行rowClick方法
type: Boolean,
default: true
}
},
model: {
prop: 'selectionItems',
event: 'changeSelection'
},
components: {
actionBar,
pages,
draggable,
customColumn
},
data() {
return {
customHeight: 0,
mergeLine: {},
mergeIndex: {},
targetRow: {},
selectRow: {},
getRowIndex: '',
enabled: true,
totalNumber: this.total,
multipleSelection: [],
innerLoading: false,
groupCodeData: {},
clickRowIndex: -1,
fullTableWidth: '100%',
timer: null
}
},
beforeDestroy() {
if (this.timer) {
clearTimeout(this.timer)
}
},
// async created() {
// await this.setTableMaxWidth()
// },
async created() {
await this.handelTableColumngGroupCode()
this.getMergeArr(this.data, this.merge)
this.clickRowIndex = this.$props.defaultSelectedFirstRow ? 0 : -1
},
activated() {
this.doLayout()
this.handelTableColumngGroupCode()
},
deactivated() {
if (this.selectionItems && this.selectionItems.length > 1) {
this.clearSelection()
}
},
watch: {
total: {
handler(nVal) {
this.totalNumber = nVal
},
immediate: true
},
merge() {
this.getMergeArr(this.data, this.merge)
},
dataLength() {
this.getMergeArr(this.data, this.merge)
this.doLayout()
},
column() {
this.doLayout()
},
defultSelectRadioIndex: {
handler(nVal) {
if (this.data) {
this.clickRowIndex = nVal
}
},
deep: true,
immediate: true
},
clickRowIndex: {
handler(nVal) {
// console.log('watch =>', nVal, this.selectionItems, this.data[nVal])
// 设置单选时的默认选中数据
if (this.isSelectRadio && nVal === 0 && this.data.length > 0) {
// this.selectionItems.push(this.data[nVal])
this.chooseSingleItem(this.data, this.data[nVal])
}
},
deep: true,
immediate: true
},
// 监听 data 数据,设置已选中数据的状态
data: {
handler(nVal) {
// console.log('watch data =>', this.from, nVal, this.selectionItems)
if (this.$refs.elTable) {
this.$nextTick(() => {
const selected = cloneDeep(this.selectionItems)
if (Array.isArray(nVal) && Array.isArray(selected) && selected.length > 0) {
const selectedKeys = selected.map((e) => e[this.rowKey])
nVal.forEach((item) => {
// 判断列表数据是否能被选中,如果被选中了但是这条数据已被设置为不可选中,则将此数据取消选中
const key = item[this.rowKey]
if (selectedKeys.includes(key) && item.selectable !== false) {
this.$refs.elTable.toggleRowSelection(item, true)
} else {
this.$refs.elTable.toggleRowSelection(item, false)
}
})
}
// 设置单选时的选中数据
if (this.autoRowClick && this.isSelectRadio && nVal.length > 0) {
this.chooseSingleItem(this.data, this.data[this.clickRowIndex])
this.$emit('rowClick', cloneDeep(this.data[this.clickRowIndex]))
}
})
}
},
deep: true,
immediate: true
},
// 监听 selectionItems 数据,设置已选中数据的状态
selectionItems: {
handler(nVal) {
// console.log('watch selectionItems =>', this.from, this.data, nVal)
this.$nextTick(() => {
if (this.$refs.elTable) {
const array = this.data
if (Array.isArray(nVal) && Array.isArray(array) && array.length > 0) {
const selectedKeys = nVal.map((e) => e[this.rowKey])
array.forEach((item) => {
// 判断列表数据是否能被选中,如果被选中了但是这条数据已被设置为不可选中,则将此数据取消选中
const key = item[this.rowKey]
if (selectedKeys.includes(key) && item.selectable !== false) {
this.$refs.elTable.toggleRowSelection(item, true)
} else {
this.$refs.elTable.toggleRowSelection(item, false)
}
})
}
}
})
},
deep: true,
immediate: true
},
pageParams: {
handler(nVal) {
// console.log('watch pageParams =>', nVal)
// 同步更新分页信息
this.page.page = nVal.startPagePos ?? 1
this.page.limit = nVal.limit ?? 20
},
deep: true,
immediate: true
}
},
computed: {
tableStyle() {
let value = ' 1fr '
// 判断是否开启 action
if (this.action) {
value = 'auto' + value
}
// 判断是否开启 pagination
if (this.pagination) {
value = value + 'auto'
}
return {
'grid-template-rows': value
}
},
customListGlobalMenuCode() {
//列表自定义全局操作权限menuCode,和后端统一规则,tableName取的当前路由name
if (this.$attrs.isListManage && this.tableName) {
const tableName =
this.tableName.indexOf('-') === -1 ? this.tableName : this.tableName.substring(0, this.tableName.indexOf('-'))
return tableName + 'GlobalList'
} else {
return ''
}
},
currentPage() {
return this.page.page
},
keyList() {
let tableName = this.tableName
if (tableName && this.tableConfig[tableName] && this.tableConfig[tableName].length > 0) {
const saveColumn = this.tableConfig[tableName]
const column = this.$deepCopy(this.column)
let newArr = []
column.forEach((item, index) => {
let tarIndex = saveColumn.findIndex((p) => p.prop === item.prop)
let tar = saveColumn.find((p) => p.prop === item.prop)
if (tarIndex > -1) {
tar.sortIndex = tarIndex
tar.label = item.label
for (let i in item) {
if (!tar.hasOwnProperty(i)) {
tar[i] = item[i]
}
//列表中有formView使用代码中的formView配置,不用自定义列表的formView
if (i === 'formView') {
tar[i] = item[i]
}
}
newArr.push(tar)
} else {
item.sortIndex = 9999
item.width = null
if (!item.hasOwnProperty('display')) {
item.display = 'Y'
}
if (!item.hasOwnProperty('adaption')) {
item.adaption = 'Y'
}
newArr.push(item)
}
})
// 按照保存的排序
return this.sortFunc(newArr, 'sortIndex')
} else {
const column = this.$deepCopy(this.column)
return column.map((i) => {
if (!i.width && !i.minWidth && i.label?.length > 4) {
i.minWidth = i.label.length * 15
}
return i
})
}
},
filterColumn() {
//避免列拖动顺序后无法改变宽度
this.keyList.forEach((i, k) => {
i.resizable = true
if (k === this.keyList.length - 1) {
i.resizable = false
}
})
// this.keyList[this.keyList.length - 1].resizable = false
return this.keyList.filter((item) => (item.display === 'Y' || !item.display) && !item.hiddenColumn)
},
/**
* 来自 Karen 的帅气注释 2022-06-01 15:33:17
* 获取展示列
*/
showKeys() {
if (this.tableName && this.tableConfig[this.tableName]) {
return this.tableConfig[this.tableName].filter((item) => item.display === 'Y' || !item.display)
} else {
return []
}
},
tableConfig() {
return this.$store?.state?.tableConfig ?? {}
},
dataLength() {
return (this.data && this.data.length) || 0
},
theme() {
return this.$store.state.theme
}
},
methods: {
cloneDeep,
clearTableSort() {
this.$refs.elTable.clearSort()
},
async handleResize() {
if (this.column.length === 0) {
await this.setTableMaxWidth()
}
},
setTableMaxWidth() {
const refTable = this.$refs.refTable
if (refTable) {
const rect = refTable.getBoundingClientRect()
const width = rect && rect.width ? rect.width : 1000
const paddingWidth = 20 // table padding width
const checkboxWitdh = 35 // checkbox column width
const borderWidth = 2 // border width
this.fullTableWidth = width - paddingWidth - checkboxWitdh - borderWidth + 'px'
}
},
// 排序
sortFunc(array, key) {
return array.sort(function (a, b) {
let x = key ? a[key] : a
let y = key ? b[key] : b
return x < y ? -1 : x > y ? 1 : 0
})
},
renderText(param) {
if (param === undefined || param === null || param === '') {
return this.defaultText
}
return param
},
/**
* 渲染单元格内容
* @param { Object } item
* @param { Object } scope
*/
renderHtml(item, scope) {
const result = typeof item.html === 'function' ? item.html(scope) : item.html
return this.renderText(result)
},
/**
* 渲染单元格内容
* @param { Object } item
* @param { Object } scope
*/
renderCellHtml(item, scope) {
const result =
item.formViewFormatter && typeof item.formViewFormatter === 'function'
? item.formViewFormatter(scope.row[item.prop], scope.row, item.formView)
: item.formatter
? item.formatter(scope.row)
: this.changeHandler(scope.row[item.prop])
return this.renderText(result)
},
/**
* 更新selectionItems数据值
* @param { Array } array 当前表格的数据
* @param { Object } item 选择后需要更新的数据项
*/
chooseSingleItem(array = [], item = {}) {
this.selectionItems.splice(0, array.length)
this.$set(this.selectionItems, 0, item)
},
handleSelectionChange(selection) {
// console.log(111, this.from, selection)
this.multipleSelection = this.$deepCopy(selection)
this.$emit('changeSelection', selection)
},
// 渲染当前行是否能被选中
renderSelectable(row, index) {
// console.log('render Selectable =>', index, row, row.selectable)
return row && row.selectable === false ? false : true
},
// 打开innerLoading
opLoading() {
if (!this.isOpenLoading) {
return
}
if (!this.innerLoading) {
this.innerLoading = true
}
},
// 关闭innerLoading
closeLoading() {
this.innerLoading = false
},
initIndex(index = 0) {
// const index = this.clickRowIndex
// console.log('initIndex =>', index)
this.getRowIndex = ''
this.targetRow = {}
this.clickRowIndex = index
},
/**
* 初始化表格数据:设置是否默认选中第一行数据
*/
initTableData(flag = false) {
this.$nextTick(() => {
// console.log('init tableData =>', this.from, flag, this.defaultSelectedFirstRow, this.data)
if (flag) {
if (this.data.length > 0) {
const item = this.data[0]
this.targetRow = item
this.clickRowIndex = 0
this.$refs.elTable.toggleRowSelection(item, true)
} else {
this.clickRowIndex = -1
this.getRowIndex = ''
this.targetRow = {}
}
} else {
this.clickRowIndex = -1
this.getRowIndex = ''
this.targetRow = {}
}
})
},
setPage() {
this.page.page -= 1
},
initPage() {
this.page.page = 1
},
setTotal(total) {
this.totalNumber = total
},
toggleSelection(rows) {
if (rows) {
rows.forEach((row) => {
this.$refs.elTable && this.$refs.elTable?.toggleRowSelection(row)
})
} else {
this.$refs.elTable && this.$refs.elTable?.clearSelection()
}
},
/**
* 来自 Karen 的帅气注释 2022-05-25 13:20:16
* 单选
*/
tableSelect(selection, row) {
console.log('%c 第878行', 'color: red; font-size: 2em')
console.log(selection)
// console.log(222, this.from, selection, row)
row.className = 'normal'
// if (!this.isSelectOnlyOne) {
if (selection.length !== 1) {
this.$emit('rowClick', {})
}
if (selection.length === 1) {
this.$emit('rowClick', cloneDeep(selection[0]))
}
// }
selection.forEach((item) => {
item.className = 'tableSelectedRowBgColor'
})
// this.$emit('changeSelection', selection)
this.$emit('tableSelect', selection, row)
},
/**
* 来自 Karen 的帅气注释 2022-06-24 14:06:12
*
*/
tableSelectAll(selection) {
this.$emit('rowClick', {})
if (!selection.length) {
this.$refs.elTable.data.forEach((item) => {
item.className = 'normal'
})
} else {
selection.forEach((item) => {
item.className = 'tableSelectedRowBgColor'
})
}
this.$emit('tableSelectAll', selection)
},
tableRowClassName({ row, rowIndex }) {
if (this.setTableRowClassName) {
return this.setTableRowClassName({ row, rowIndex })
}
// 返回选中样式
return row.className
},
handleRowClick(row) {
this.resetPickStyle()
// console.log('diapatch row Click =>', row)
if ((!this.isSelection && !this.isSelectRadio) || !this.isRowclick) {
return
}
console.log('this.needClearSelection', this.needClearSelection)
if (!this.isSelectRadio) {
this.needClearSelection && this.clearSelection()
if (this.selectable && typeof this.selectable === 'function') {
//当前行可选
if (
this.clickRowToSelect &&
this.selectable(
row,
this.data.findIndex((i) => i == row)
)
) {
this.$refs.elTable.toggleRowSelection(row)
}
} else {
if (this.clickRowToSelect) {
this.$refs.elTable.toggleRowSelection(row)
}
}
}
this.targetRow = row
this.getRowIndex = row.rowIndex
let cloneRow = cloneDeep(row)
if (!this.selectDisabled && !row.selectRadioDisabled) {
if (this.canSelectRadioCancel) {
if (this.clickRowIndex === this.data.findIndex((i) => i == row)) {
//重复选择选中数据则取消,不用setTimeout会出现点击同一条数据的radio时,选中或者取消状态无法更新
this.timer = setTimeout(() => {
this.clickRowIndex = -1
}, 0)
cloneRow = {}
} else {
this.timer = setTimeout(() => {
this.clickRowIndex = this.data.findIndex((i) => i == row)
}, 0)
}
} else {
this.clickRowIndex = this.data.findIndex((i) => i == row)
}
// console.log('%c 第778行', 'color:red;font-size:2em')
// console.log(this.clickRowIndex)
}
this.$emit('rowClick', cloneRow)
if (this.clickRowToSelect) {
row.className = 'tableSelectedRowBgColor'
// 修改于 2023年2月27日17:15:21
// let ids = this.selectionItems.map((item) => item.id)
// let lists = this.$deepCopy(this.selectionItems)
// if (ids.indexOf(row.id) === -1) {
// lists.push(row)
// }
this.chooseSingleItem(this.data, row) // 设置selectionItems的值
}
},
handleCellClick(row, column, cell, event) {
this.$emit('cellClick', row, column, cell, event)
},
changeTableSort({ column, order, prop }) {
if (order === null) {
} else {
}
},
resetPickStyle() {
this.$refs.elTable.data.forEach((item) => {
item.className = 'normal'
})
},
clearSelection() {
console.log('clear Selection')
this.resetPickStyle()
this.$emit('changeSelection', [])
this.$refs.elTable && this.$refs.elTable.clearSelection()
},
toggleRowSelection(row, selected) {
this.$refs.elTable && this.$refs.elTable.toggleRowSelection(row, selected)
},
toggleAllSelection() {
this.$refs.elTable && this.$refs.elTable.toggleAllSelection()
},
toggleRowExpansion(row, expanded) {
this.$refs.elTable && this.$refs.elTable.toggleRowExpansion(row, expanded)
},
setCurrentRow(row, value) {
this.$nextTick(() => {
if (row) {
let tar = this.$refs.elTable.data.find((item) => item.id === row.id)
if (tar) {
// 选中
this.$refs.elTable.data.forEach((item) => {
if (item.id === tar) {
item.className = 'tableSelectedRowBgColor'
this.$refs.elTable.toggleRowSelection(item)
}
})
}
}
if (row) {
this.$refs.elTable.data.forEach((item) => {
if (item.id === row.id) {
item.className = 'tableSelectedRowBgColor'
this.$refs.elTable.toggleRowSelection(item, value)
}
})
} else {
}
})
},
clearSort() {
this.$refs.elTable && this.$refs.elTable.clearSort()
},
clearFilter(columnKey) {
this.$refs.elTable && this.$refs.elTable.clearFilter(columnKey)
},
headerDragend() {
// this.$refs.elTable && this.$refs.elTable.doLayout()
this.doLayout()
},
handleSortChange({ column, prop, order }) {
// console.log('column, prop, order', column, prop, order)
let label = prop
if (prop.indexOf('#') >= 0 || prop.indexOf('_') >= 0) {
label = prop.split('#')[1] || prop.split('_')[1] || ''
}
this.$emit('sortChange', order ? label + ':' + order.replace('ending', '') : '')
},
doLayout() {
this.$nextTick(() => {
this.$refs.elTable && this.$refs.elTable.doLayout()
})
},
sort(prop, order) {
this.$refs.elTable && this.$refs.elTable.sort(prop, order)
},
paginationCurrentChange(val) {
this.$emit('p-current-change', val)
},
getMergeArr(tableData, merge) {
if (!merge) return
this.mergeLine = {}
this.mergeIndex = {}
merge.forEach((item, k) => {
tableData.forEach((data, i) => {
if (i === 0) {
this.mergeIndex[item] = this.mergeIndex[item] || []
this.mergeIndex[item].push(1)
this.mergeLine[item] = 0
} else {
if (data[item] === tableData[i - 1][item]) {
this.mergeIndex[item][this.mergeLine[item]] += 1
this.mergeIndex[item].push(0)
} else {
this.mergeIndex[item].push(1)
this.mergeLine[item] = i
}
}
})
})
},
mergeMethod({ row, column, rowIndex, columnIndex }) {
const index = this.merge.indexOf(column.property)
if (index > -1) {
const _row = this.mergeIndex[this.merge[index]][rowIndex]
const _col = _row > 0 ? 1 : 0
return {
rowspan: _row,
colspan: _col
}
}
},
handlerChange(name) {
if (name === 'config') {
this.$refs.customColumn.isShow = true
} else {
this.$emit('handlerChange', name, this.multipleSelection)
}
},
handlerExport(exportForm) {
this.$emit('reportClick')
},
dataURLtoBlob(base64Str) {
let bstr = atob(base64Str),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
// 下载的是excel格式的文件
return new Blob([u8arr], { type: 'application/vnd.ms-excel' })
},
findSelectForm(vm) {
if (vm.selectForm) {
return vm.selectForm
} else {
return this.findSelectForm(vm.$parent)
}
},
findRefs(vm, refName) {
if (vm.$refs[refName]) {
return vm.$refs[refName]
} else {
return this.findRefs(vm.$parent, refName)
}
},
//
/**
* 转义< 防止v-html解析不出来用户输入的内容
*/
changeHandler(val) {
if (typeof val === 'string') {
return val?.replace(/[<]/g, '<')
} else {
return val
}
},
/**
* 表单校验
*@param {paraName}
*/
async formValidate() {
let ref = this.$refs.mdform
let allCalibrationCompleted = true // 是否全部校验成功
for (let i in ref) {
ref[i].$refs.elform.validate((valid) => {
if (valid) {
// console.log('success submit!!')
} else {
allCalibrationCompleted = false
// console.log('error submit!!')
return false
}
})
}
return allCalibrationCompleted
},
formViewMethod(scope, columnIndex) {
if (this.formViewShowMethod && typeof this.formViewShowMethod === 'function') {
return this.formViewShowMethod({
row: scope.row,
column: scope.column,
rowIndex: scope.$index,
columnIndex
})
}
return true
},
/**
* 重载列配置里面的render函数
*@param {paraName}
*/
handleRendel(renderFunc, scope) {
let cel = this.$createElement
return {
render: () => renderFunc(cel, scope)
}
},
// 解析groupcode
async handelTableColumngGroupCode() {
// console.log('%c 第726行', 'color:red;font-size:2em')
// console.log(this.column)
for (let i of this.column) {
if (i && i.groupCode && i.prop && !i.formatter) {
if (i.groupCode in optionsConfigs) {
let options = this.groupCodeData[i.groupCode]
if (!options) {
options = await getSelectData(i.groupCode, i.params)
this.groupCodeData[i.groupCode] = options
}
this.$set(i, 'formatter', (row, column, cellValue, index) => {
let v = (row && row[i.prop]) ?? ''
return this.handleValue(i.groupCode, v)
})
} else {
// 字典类型的后端转译
this.$set(i, 'formatter', (row, column, cellValue, index) => {
return (row && row[i.prop + 'Desc']) ?? row[i.prop] ?? ''
})
}
}
if (i && i.linkSetField && !i.formatter) {
// 关联的显示字段
this.$set(i, 'formatter', (row, column, cellValue, index) => {
return (row && row[i.linkSetField]) ?? row[i.prop] ?? ''
})
}
}
// console.log('this.column', this.column);
},
handleValue(groupCode, value) {
if (typeof value === 'string' && value.includes(',')) {
let arr = value.split(',')
return arr
.map((v) => {
return this.groupCodeData[groupCode]?.find((i) => i.value == v)?.label ?? v
})
.filter((i) => !!i)
.join(',')
} else {
return this.groupCodeData[groupCode]?.find((i) => i.value == value)?.label ?? value
}
},
setShowOverFlow(column) {
// console.log('column', column)
let showOverFlow = true
if (column.formView) {
//拿到formView的第一个属性
const firstProperty = Object.keys(column.formView)[0]
const firstPropertyValue = column.formView[firstProperty]
if (firstPropertyValue.itemtype === 'Checkbox' || column?.viewAlways) {
//组件不需要showOverFlow
showOverFlow = false
}
}
if (column.hasOwnProperty('showOverflowTooltip') && column.showOverflowTooltip === false) {
showOverFlow = false
}
if (this.editTableRowIndex !== -1) {
showOverFlow = false
}
return showOverFlow
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-empty__description {
margin-top: 0;
p {
font-size: 12px;
}
}
.md-table {
&.no-padding {
padding: 0 !important;
}
width: 100%;
padding: 10px;
height: 100%;
// display: flex;
// flex-direction: column;
display: grid;
grid-template-rows: auto;
/deep/ .el-table--mini .el-table__cell {
padding: 2px 0;
}
.table-container {
width: 100%;
height: 100%;
overflow: hidden;
}
}
.customClass thead {
tr {
.el-checkbox {
display: none !important;
}
}
}
.class-name {
background: #ffffff;
}
*::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: transparent;
}
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
*::-webkit-scrollbar-track {
background-color: #fff;
}
/*定义滚动条轨道 内阴影+圆角*/
*::-webkit-scrollbar-thumb {
background-color: rgba(170, 179, 192, 0.6);
border-radius: 10px;
}
/*定义滑块 内阴影+圆角*/
/*.scrollbarHide::-webkit-scrollbar{display: none}*/
/*.scrollbarShow::-webkit-scrollbar{display: block}*/
.tableSelectedRowBgColor td {
/*background-color: var(--theme_item_color)!important;*/
background-color: #aab3c0 !important;
/*color: #ffffff!important;*/
/*border: none!important;*/
}
.tableClass {
::v-deep .el-table__fixed {
height: 100% !important; //设置高优先,以覆盖内联样式
}
::v-deep .el-table__fixed-right {
height: 100% !important; //设置高优先,以覆盖内联样式
}
// ::v-deep .el-table__body {
// width: 100% !important;
// }
}
::v-deep .tableForm {
.el-form-item .el-form-item__label {
padding: 0px;
}
.el-input--small .el-input__inner {
height: 26px;
line-height: 26px;
padding: 0 2px;
}
.el-form-item__error {
position: sticky;
}
}
::v-deep .el-loading-spinner .path {
stroke: #909399 !important;
}
::v-deep .el-loading-text {
color: #909399 !important;
}
::v-deep .el-table {
//解决操作列覆盖了下方滚动条,无法进行点击或拖动
.el-table__fixed-right {
// height: auto !important; // 此处的important表示优先于element.style
bottom: 17px; // 改为自动高度后,设置与父容器的底部距离,则高度会动态改变
}
.el-table__body-wrapper.is-scrolling-none ~ .el-table__fixed-right,
.el-table__body-wrapper.is-scrolling-none ~ .el-table__fixed {
height: 100% !important;
box-shadow: none !important;
}
}
</style>