<template> <el-dialog class="innerDialogBox" :visible.sync="dialogVisible" width="95%" @open='openDialog' title='表格配置' :append-to-body='true' :close-on-click-modal='false'> <div class="toopBox"> <el-button-group > <el-button size='mini' @click="addPropViSayncTop()" type="primary" icon="el-icon-plus"></el-button> <el-button @click='deleteAll' size='mini' type="primary" icon="el-icon-delete">删除</el-button> <el-button @click='upStupe' size='mini' type="primary" icon="el-icon-arrow-left">上移</el-button> <el-button @click='downStupe' size='mini' type="primary">下移<i class="el-icon-arrow-right el-icon--right"></i></el-button> </el-button-group> </div> <el-table size='mini' border height='520px' ref="multipleTableColumn" :data='tableDataColums'> <el-table-column type="selection" width="55" fixed="left"></el-table-column> <el-table-column type="index" fixed="left"></el-table-column> <el-table-column prop='label' label='标题' width="150" fixed="left"> <template slot-scope="scope"> <el-input size='mini' v-model="scope.row.label" clearable> </el-input> </template> </el-table-column> <el-table-column prop='prop' label='列名' width="150" fixed="left"> <template slot-scope="scope"> <el-input size='mini' v-model="scope.row.prop" clearable> </el-input> </template> </el-table-column> <el-table-column prop='width' label='宽度' width="120"> <template slot-scope="scope"> <el-input size='mini' v-model="scope.row.width" clearable placeholder="80"> </el-input> </template> </el-table-column> <el-table-column prop='isSort' label='是否排序'> <template slot-scope="scope"> <el-switch v-model="scope.row.isSort"> </el-switch> </template> </el-table-column> <el-table-column prop='summarizing' label='是否汇总'> <template slot-scope="scope"> <el-switch v-model="scope.row.summarizing"> </el-switch> </template> </el-table-column> <el-table-column prop='type' label='列类型' width="120"> <template slot-scope="scope"> <el-select size='mini' v-model="scope.row.type" placeholder="请选择" clearable> <el-option v-for="item in optionsType" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </template> </el-table-column> <el-table-column prop='otherConfig' label='下拉备注框' width='200' > <template slot-scope="scope"> <el-input type="textarea" :rows="1" size='mini' v-model="scope.row.otherConfig" clearable> </el-input> </template> </el-table-column> <el-table-column prop='width' label='列样式' width="120"> <template slot-scope="scope"> <el-button size='mini' @click="showStyleColunm(scope.row,scope.$index)">设置样式</el-button> </template> </el-table-column> <el-table-column prop='isHide' label='隐藏'> <template slot-scope="scope"> <el-switch v-model="scope.row.isHide"> </el-switch> </template> </el-table-column> <el-table-column prop="type" label="展示类型" width="140" v-if="isEditColumns"> <template slot-scope="scope"> <el-select v-model="scope.row.showType" size='mini' clearable> <el-option v-for="(option,index) in typeOptions" :key="index" :value='option.value' :label='option.label' > </el-option> </el-select> </template> </el-table-column> <el-table-column prop='isDisabled' label='只读' width='70'> <template slot-scope="scope"> <el-switch v-model="scope.row.isDisabled"> </el-switch> </template> </el-table-column> <el-table-column prop='isRequired' label='必填' width='70'> <template slot-scope="scope"> <el-switch v-model="scope.row.isRequired"> </el-switch> </template> </el-table-column> <el-table-column label='操作' width=300 fixed="right"> <template slot-scope="scope"> <el-button size='mini' @click="addPropViSaync(scope.row,scope.$index)">新增列</el-button> <el-button size='mini' @click="deletProp(scope.row,scope.$index)">删除</el-button> <el-button size='mini' @click="upGo(scope.row,scope.$index)">上移</el-button> <el-button size='mini' @click="downGo(scope.row,scope.$index)">下移</el-button> </template> </el-table-column> </el-table> <div slot="footer" class="dialog-footer"> <el-button size='medium' type="primary" @click="tanTableHeaderAsync">确 定</el-button> <el-button size='mini' type="success" @click="generateTheHeaderBefore">生成表头</el-button> <el-button size='mini' type="warning" @click="cleanAll">清除所有</el-button> <el-button size='mini' type="info" @click="dialogVisible = false">取 消</el-button> </div> <tbaleColumStyleSet v-model="dialogVisibleTbaleColumStyle" :formInline='formInline' @submit='onSubmitStyle' > </tbaleColumStyleSet> </el-dialog> </template> <script> import _ from 'lodash' import uuidv1 from 'uuid/v1' import tbaleColumStyleSet from './tbaleColumStyleSet' export default { components: { tbaleColumStyleSet }, props: { value: Boolean, tableDataColums: { default() { return [] } }, mockSourceData: { default() { return [] } }, allSourceData: { default() { return { config: {}, sourceData: [] } } }, isSubmitSuccessFlage: { }, elInfo: {}, isEditColumns: { type: Boolean, default: false } }, watch: { value(val) { this.dialogVisible = val }, dialogVisible(val) { this.$emit('input', val) }, isSubmitSuccessFlage(val) { if (val === 'columnStyleSet') { this.dialogVisibleTbaleColumStyle = false } else { this.dialogVisible = false } } }, data() { return { dialogVisibleTbaleColumStyle: false, dialogVisible: false, optionsType: [{ value: 'checkBox', label: '勾选' }, { value: 'hyperlink', label: '超链接' }, { value: 'asyncQueryDetail', label: '弹框查询' }], formInline: {}, columnsProp: [], tableData: [], editIndex: 0, typeOptions: [ { value: 'input', label: '1输入框' }, { value: 'hsInput', label: '1-1配置输入框', isRequireControlName: true }, { value: 'hsSelectPlus', label: '2下拉框', isRequireControlName: true }, { value: 'text', label: '3文本' }, { value: 'elCheckbox', label: '4勾选' }, { value: 'elSwitch', label: '5开关' }, { value: 'elDatePicker', label: '6日期范围' }, { value: 'elDatePickerDatetime', label: '7日期时间' }, { value: 'hsComputed', label: '8计算文本', isRequireControlName: true } ], tableDataColumsCopy: [] } }, methods: { openDialog() { }, initConfig(data) { for (const index in data) { const item = data[index] if (!item.uuidv1) { item.uuidv1 = uuidv1() } } this.tableDataColumsCopy = _.cloneDeep(data) }, addPropViSayncTop() { this.tableDataColums.push({}) this.$nextTick(() => { const multipleTableColumn = this.$refs.multipleTableColumn multipleTableColumn.bodyWrapper.scrollTop = multipleTableColumn.bodyWrapper.scrollHeight }) }, deleteAll() { const selectedProp = this.$refs.multipleTableColumn.selection.map(item => { return item.prop }) const list = this.tableDataColums.filter(item => !selectedProp.includes(item.prop)) this.tableDataColums = list }, upStupe() { const selected = this.$refs.multipleTableColumn.selection const selectedIndexList = selected.map((item, index) => { return item.prop }) const indexList = [] selectedIndexList.forEach(prop => { const index_ = this.tableDataColums.findIndex(item => item.prop === prop) indexList.push(index_) }) indexList.sort((a, b) => { return a - b }) indexList.forEach((k, index) => { if (index !== 0 && indexList.includes(0)) { this.upSite(this.tableDataColums, k - 1) } else { this.upSite(this.tableDataColums, k) } }) }, downStupe() { const selected = this.$refs.multipleTableColumn.selection const selectedIndexList = selected.map((item, index) => { return item.prop }) const indexList = [] selectedIndexList.forEach(prop => { const index_ = this.tableDataColums.findIndex(item => item.prop === prop) indexList.push(index_) }) indexList.sort((a, b) => { return b - a }) indexList.forEach((k, index) => { if (index !== 0 && indexList.includes(this.tableDataColums.length - 1)) { this.downSite(this.tableDataColums, k + 1) } else { this.downSite(this.tableDataColums, k) } }) }, showStyleColunm(row, index) { this.editIndex = index this.formInline = {} this.dialogVisibleTbaleColumStyle = true this.formInline = _.cloneDeep(row.columnStyle || {}) }, addPropViSaync(row, index) { this.tableDataColums.splice(index + 1, 0, {}) }, deletProp(row, index) { this.tableDataColums.splice(index, 1) }, upGo(row, index) { this.upSite(this.tableDataColums, index) }, downGo(row, index) { this.downSite(this.tableDataColums, index) }, generateTheHeaderBefore() { const editor2Data = this.allSourceData && this.allSourceData.sourceData if ((Array.isArray(editor2Data) && !editor2Data.length) || (editor2Data.table && !editor2Data.table.length)) { this.$confirm('因没有返回表格的实体数据,是否根据模拟数据生成表头?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { const editor2Data = this.mockSourceData this.generateTheHeader(editor2Data) }).catch(() => { }) } else { this.generateTheHeader(editor2Data) } }, generateTheHeader(editor2Data) { if (Array.isArray(editor2Data)) { this.tableData = editor2Data } else { this.tableData = editor2Data.table } this.columnsProp = [...this.getAsyncProp()] const listProp = this.columnsProp.reduce((prue, curr) => { if (curr.childs) { prue.push(...curr.childs) } else { prue.push(curr) } return prue }, []) const existColum = this.tableDataColums.reduce((prue, curr) => { prue.push(curr.prop) return prue }, []) const appColum = listProp.filter(item => !existColum.includes(item.prop)) if (appColum.length) { this.tableDataColums.push(...appColum) } }, setHeaderAnynsProp(data) { data.forEach((item, index) => { if (item.prop === '*') { // 获取所有的动态列 const anyncProp = this.getAsyncProp(this.tableData, data) // 删除那一带*的行 替换成动态列 data.splice(index, 1, ...anyncProp) } }) }, getAsyncProp(data = this.tableData, columnsProp = []) { if (!data.length) return [] const props = Object.keys(data[0]) // 已经手动设置存在的表表头 const constProps = [] if (columnsProp.length) { columnsProp.forEach(item => { if (item.prop !== '*') { constProps.push(item.prop) } }) } // 动态设置1维表头 const constProps_ = [] props.forEach(prop => { if (!prop.includes('__') && !prop.startsWith('_') && !prop.includes('_data_') && prop !== 'isSelected') { constProps_.push({ prop: prop, label: prop, 'showOverflowTooltip': true }) } else if (prop.includes('__')) { const one_title = prop.split('__')[0] const one_title_list = props.filter(item => item.split('__')[0] === one_title) const one_title_list_prop = [] one_title_list.forEach(item => { one_title_list_prop.push({ prop: item, label: item, 'showOverflowTooltip': true }) }) const t = constProps_.find(item => item.prop === one_title) if (!t) { constProps_.push({ prop: one_title, label: one_title, childs: one_title_list_prop }) } } }) const result = constProps_.filter(item => !constProps.includes(item.prop)) return result || [] }, cleanAll() { this.$confirm('此操作将清空所有表头, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.tableDataColums.splice(0, this.tableDataColums.length) this.$message({ type: 'success', message: '删除成功!' }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }) }) }, tanTableHeaderAsync(flage) { for (const index in this.tableDataColums) { const item = this.tableDataColums[index] const index_number = parseInt(index) if (!item.label && !item.prop && Object.keys(item).length) { this.$message.error(`请完善第${index_number + 1}行的字段或者标题`) return } if (!item.label && item.prop && item.prop !== '*') { item.label = item.prop } } const columnsConfig = this.tableDataColums.filter(item => Object.keys(item).length) const f = true if (this.isEditColumns) { for (const index in columnsConfig) { const item = columnsConfig[index] const itemOptionType = this.typeOptions.find(xs => xs.value === item.showType) if (!itemOptionType) { item.showType = 'text' continue } if (itemOptionType && !itemOptionType.isRequireControlName) { delete item.elInfo delete item.control_name } if (itemOptionType && itemOptionType.isRequireControlName && !item.control_name) { item.control_name = uuidv1() item.elInfo = { position: item.control_name, el: item.showType } } } } if (!f) return this.$emit('submit', columnsConfig, flage) }, addOldProp(columnsConfig) { const olist = this.tableDataColumsCopy.filter(item => item.showType.startsWith('hs')) const newlist = columnsConfig.filter(item => item.uuidv1 && item.showType.startsWith('hs')) newlist.forEach(item => { const otarget = olist.find(oitem => item.uuidv1 === oitem.uuidv1) if (otarget && otarget.prop !== item.prop) { item.old_control_name = otarget.prop } else if (otarget && otarget.prop === item.prop) { delete item.old_control_name } }) }, tansFormAsyncProps(list) { const rasyncProps = _(list).groupBy(item => item.split('__')[0]).value() const Keys = Object.keys(rasyncProps) const result = [] Keys.forEach(k => { const obj = { prop: '', lebel: '', 'showOverflowTooltip': true, childs: [] } obj.prop = k obj.lebel = k rasyncProps[k].forEach(i => { obj.childs.push({ prop: i, lebel: i, 'showOverflowTooltip': true }) }) result.push(obj) }) return result }, upSite(fieldData, index) { if (index !== 0) { fieldData[index] = fieldData.splice(index - 1, 1, fieldData[index])[0] } else { fieldData.push(fieldData.shift()) } }, downSite(fieldData, index) { if (index !== fieldData.length - 1) { fieldData[index] = fieldData.splice(index + 1, 1, fieldData[index])[0] } else { fieldData.unshift(fieldData.splice(index, 1)[0]) } }, onSubmitStyle(data) { this.tableDataColums[this.editIndex].columnStyle = data this.dialogVisibleTbaleColumStyle = false this.tanTableHeaderAsync('columnStyleSet') } } } </script> <style scoped src='./dialog_table_inner.css'> </style>