<template>
|
<!-- 2021.11.18移除voltable方法@cell-mouse-leave="rowEndEdit" -->
|
<div
|
class="vol-table"
|
:class="[
|
textInline ? 'text-inline' : '',
|
fxRight ? 'fx-right' : '',
|
isChrome ? 'chrome' : '',
|
smallCell ? 'small-table' : ''
|
]"
|
>
|
<div class="mask" v-show="loading"></div>
|
<div class="message" v-show="loading">加载中.....</div>
|
<el-table
|
:show-summary="summary"
|
:summary-method="getSummaryData"
|
:row-key="rowKey"
|
:key="randomTableKey"
|
:lazy="lazy"
|
:defaultExpandAll="defaultExpandAll"
|
:expand-row-keys="rowKey ? expandRowKeys : undefined"
|
stripe
|
:load="loadTreeChildren"
|
@select="userSelect"
|
@select-all="userSelect"
|
@selection-change="selectionChange"
|
@row-dblclick="rowDbClick"
|
@row-click="rowClick"
|
@header-click="headerClick"
|
:highlight-current-row="highlightCurrentRow"
|
ref="table"
|
class="v-table"
|
@sort-change="sortChange"
|
tooltip-effect="dark"
|
:height="realHeight"
|
:max-height="realMaxHeight"
|
:data="url ? rowData : tableData"
|
border
|
:row-class-name="initIndex"
|
:cell-style="getCellStyle"
|
style="width: 100%"
|
:scrollbar-always-on="true"
|
:span-method="cellSpanMethod"
|
@expand-change="expandChange"
|
>
|
<el-table-column v-if="columnIndex" type="index" :fixed="fixed" width="55"></el-table-column>
|
<el-table-column
|
v-if="ck"
|
type="selection"
|
:fixed="fixed"
|
:selectable="selectable"
|
width="55"
|
></el-table-column>
|
|
<!-- 2020.10.10移除table第一行强制排序 -->
|
<el-table-column
|
v-for="(column, cindex) in filterColumns"
|
:prop="column.field"
|
:label="column.title"
|
:min-width="column.width"
|
:formatter="formatter"
|
:fixed="column.fixed"
|
:key="column.field + cindex"
|
:align="column.align"
|
:sortable="column.sort ? 'custom' : false"
|
:show-overflow-tooltip="true"
|
>
|
<template #header>
|
<span v-if="(column.require || column.required) && column.edit" class="column-required"
|
>*</span
|
>{{ column.title }}
|
</template>
|
|
<template #default="scope">
|
<!-- 2022.01.08增加多表头,现在只支持常用功能渲染,不支持编辑功能(涉及到组件重写) -->
|
<el-table-column
|
style="border: none"
|
v-for="columnChildren in filterChildrenColumn(column.children)"
|
:key="columnChildren.field"
|
:min-width="columnChildren.width"
|
:class-name="columnChildren.class"
|
:prop="columnChildren.field"
|
:align="columnChildren.align"
|
:label="columnChildren.title"
|
>
|
<template #default="scopeChildren">
|
<a
|
href="javascript:void(0);"
|
style="text-decoration: none"
|
@click="link(scopeChildren.row, columnChildren, $event)"
|
v-if="columnChildren.link"
|
v-text="scopeChildren.row[columnChildren.field]"
|
></a>
|
<table-render
|
v-else-if="columnChildren.render && typeof columnChildren.render == 'function'"
|
:row="scopeChildren.row"
|
key="rd-01"
|
:index="scope.$index"
|
:column="columnChildren"
|
:render="columnChildren.render"
|
></table-render>
|
<div
|
v-else-if="columnChildren.formatter"
|
@click="
|
columnChildren.click &&
|
columnChildren.click(scopeChildren.row, columnChildren, scopeChildren.$index)
|
"
|
v-html="
|
columnChildren.formatter(scopeChildren.row, columnChildren, scopeChildren.$index)
|
"
|
></div>
|
<div v-else-if="columnChildren.bind">
|
{{ formatter(scopeChildren.row, columnChildren, true) }}
|
</div>
|
<span v-else-if="columnChildren.type == 'date'">{{
|
formatterDate(scopeChildren.row, columnChildren)
|
}}</span>
|
<template v-else>
|
{{ scopeChildren.row[columnChildren.field] }}
|
</template>
|
</template>
|
</el-table-column>
|
<!-- 2020.06.18增加render渲染自定义内容 -->
|
<table-render
|
v-if="column.render && typeof column.render == 'function'"
|
:row="scope.row"
|
key="rd-01"
|
:index="scope.$index"
|
:column="column"
|
:render="column.render"
|
></table-render>
|
<!-- 启用双击编辑功能,带编辑功能的不会渲染下拉框文本背景颜色 -->
|
<!-- @click="rowBeginEdit(scope.$index,cindex)" -->
|
<!-- 2021.09.21增加编辑时对readonly属性判断 -->
|
<template
|
v-else-if="
|
column.edit &&
|
!column.readonly &&
|
['file', 'img', 'excel'].indexOf(column.edit.type) != -1
|
"
|
>
|
<div style="display: flex; align-items: center" @click.stop>
|
<i
|
v-if="!column.showUpload || column.showUpload(scope.row, column)"
|
style="padding: 3px; margin-right: 10px; color: #8f9293; cursor: pointer"
|
@click="showUpload(scope.row, column)"
|
class="el-icon-upload"
|
></i>
|
<template v-if="column.edit.type == 'img'">
|
<img
|
v-for="(file, imgIndex) in getFilePath(scope.row[column.field], column)"
|
:key="imgIndex"
|
@error="handleImageError"
|
@click="viewImg(scope.row, column, file.path, $event, imgIndex)"
|
class="table-img"
|
:src="file.path"
|
/>
|
</template>
|
<a
|
style="margin-right: 8px"
|
v-else
|
class="t-file"
|
v-for="(file, fIndex) in getFilePath(scope.row[column.field], column)"
|
:key="fIndex"
|
@click="dowloadFile(file)"
|
>{{ file.name }}</a
|
>
|
</div>
|
</template>
|
<div
|
v-else-if="
|
column.edit && !column.readonly && (column.edit.keep || edit.rowIndex == scope.$index)
|
"
|
class="edit-el"
|
>
|
<div @click.stop class="e-item">
|
<div>
|
<!-- 2020.07.24增加日期onChange事件 -->
|
<el-date-picker
|
clearable
|
size="default"
|
style="width: 100%"
|
v-if="['date', 'datetime'].indexOf(column.edit.type) != -1"
|
v-model="scope.row[column.field]"
|
@change="
|
(val) => {
|
column.onChange && column.onChange(scope.row, column, val)
|
}
|
"
|
:type="column.edit.type"
|
:placeholder="column.placeholder || column.title"
|
:disabledDate="(val) => getDateOptions(val, column)"
|
:value-format="getDateFormat(column)"
|
:disabled="initColumnDisabled(scope.row, column)"
|
>
|
</el-date-picker>
|
<el-time-picker
|
clearable
|
size="default"
|
style="width: 100%"
|
v-else-if="column.edit.type == 'time'"
|
v-model="scope.row[column.field]"
|
@change="
|
(val) => {
|
column.onChange && column.onChange(scope.row, column, val)
|
}
|
"
|
:placeholder="column.placeholder || column.title"
|
:value-format="column.format || 'HH:mm:ss'"
|
:disabled="initColumnDisabled(scope.row, column)"
|
>
|
</el-time-picker>
|
<el-switch
|
v-else-if="column.edit.type == 'switch'"
|
v-model="scope.row[column.field]"
|
active-color="#0f84ff"
|
inactive-color="rgb(194 194 194)"
|
active-text="是"
|
inactive-text="否"
|
inline-prompt
|
@change="
|
(val) => {
|
switchChange(val, scope.row, column)
|
}
|
"
|
:active-value="
|
typeof scope.row[column.field] == 'boolean'
|
? true
|
: typeof scope.row[column.field] == 'string'
|
? '1'
|
: 1
|
"
|
:inactive-value="
|
typeof scope.row[column.field] == 'boolean'
|
? false
|
: typeof scope.row[column.field] == 'string'
|
? '0'
|
: 0
|
"
|
:disabled="initColumnDisabled(scope.row, column)"
|
>
|
</el-switch>
|
<template v-else-if="['select', 'selectList'].indexOf(column.edit.type) != -1">
|
<el-select-v2
|
style="width: 100%"
|
:size="size"
|
v-if="column.bind.data.length >= select2Count"
|
v-model="scope.row[column.field]"
|
filterable
|
:multiple="column.edit.type == 'select' ? false : true"
|
:placeholder="column.placeholder || column.title"
|
:autocomplete="column.autocomplete"
|
:options="column.bind.data"
|
@change="column.onChange && column.onChange(scope.row, column)"
|
clearable
|
:disabled="initColumnDisabled(scope.row, column)"
|
>
|
<template #default="{ item }">
|
{{ item.label }}
|
</template>
|
</el-select-v2>
|
|
<el-select
|
size="default"
|
style="width: 100%"
|
v-else
|
v-model="scope.row[column.field]"
|
:filterable="column.filter || column.bind.data.length > 10 ? true : false"
|
:multiple="column.edit.type == 'select' ? false : true"
|
:placeholder="column.placeholder || column.title"
|
:allow-create="column.autocomplete"
|
@change="column.onChange && column.onChange(scope.row, column)"
|
clearable
|
:disabled="initColumnDisabled(scope.row, column)"
|
>
|
<el-option
|
v-for="item in column.bind.data"
|
:key="item.key"
|
v-show="!item.hidden"
|
:disabled="item.disabled"
|
:label="item.value"
|
:value="item.key"
|
>{{ item.value }}
|
</el-option>
|
</el-select>
|
</template>
|
<el-tree-select
|
style="width: 100%"
|
v-else-if="column.edit.type == 'treeSelect' || column.edit.type == 'cascader'"
|
v-model="scope.row[column.field]"
|
:data="column.bind.data"
|
:multiple="column.multiple === undefined ? true : column.multiple"
|
:render-after-expand="false"
|
:show-checkbox="true"
|
:check-strictly="column.checkStrictly === undefined ? true : column.checkStrictly"
|
check-on-click-node
|
node-key="key"
|
@change="column.onChange && column.onChange(scope.row, column)"
|
:props="{ label: 'label' }"
|
>
|
<template #default="{ data, node }"> {{ data.label }}</template>
|
</el-tree-select>
|
<!-- <div v-else-if="column.edit.type == 'cascader'">4444444</div> -->
|
<!-- <el-cascader
|
clearable
|
style="width: 100%;"
|
v-model="scope.row[column.field]"
|
v-else-if="column.edit.type == 'cascader'"
|
:data="column.bind.data"
|
:props="{
|
checkStrictly: column.changeOnSelect || column.checkStrictly,
|
}"
|
@change="column.onChange && column.onChange(scope.row, column)"
|
>
|
</el-cascader> -->
|
<el-input
|
v-else-if="column.edit.type == 'textarea'"
|
type="textarea"
|
:placeholder="column.placeholder || column.title"
|
v-model="scope.row[column.field]"
|
:disabled="initColumnDisabled(scope.row, column)"
|
>
|
</el-input>
|
<input
|
class="table-input"
|
v-else-if="!column.summary && !column.onKeyPress"
|
v-model.lazy="scope.row[column.field]"
|
:placeholder="column.placeholder || column.title"
|
:disabled="initColumnDisabled(scope.row, column)"
|
/>
|
<el-input
|
v-else
|
@change="inputKeyPress(scope.row, column, $event)"
|
@input="inputKeyPress(scope.row, column, $event)"
|
@keyup.enter="inputKeyPress(scope.row, column, $event)"
|
size="default"
|
v-model="scope.row[column.field]"
|
:placeholder="column.placeholder || column.title"
|
:disabled="initColumnDisabled(scope.row, column)"
|
></el-input>
|
</div>
|
<div class="extra" v-if="column.extra && edit.rowIndex == scope.$index">
|
<a
|
:style="column.extra.style"
|
style="text-decoration: none"
|
@click="extraClick(scope.row, column)"
|
>
|
<i v-if="column.extra.icon" :class="[column.extra.icon]" />
|
{{ column.extra.text }}
|
</a>
|
</div>
|
</div>
|
</div>
|
<!--没有编辑功能的直接渲染标签-->
|
<template v-else>
|
<a
|
href="javascript:void(0)"
|
style="text-decoration: none; line-height: 1.3"
|
@click="link(scope.row, column, $event)"
|
v-if="column.link"
|
v-text="scope.row[column.field]"
|
></a>
|
<img
|
v-else-if="column.type == 'img'"
|
v-for="(file, imgIndex) in getFilePath(scope.row[column.field], column)"
|
:key="imgIndex"
|
@error="handleImageError"
|
@click="viewImg(scope.row, column, file.path, $event, imgIndex)"
|
class="table-img"
|
:src="file.path"
|
/>
|
<a
|
style="margin-right: 8px"
|
v-else-if="column.type == 'file' || column.type == 'excel'"
|
class="t-file"
|
v-for="(file, fIndex) in getFilePath(scope.row[column.field], column)"
|
:key="fIndex"
|
@click="dowloadFile(file)"
|
>{{ file.name }}</a
|
>
|
<span v-else-if="column.type == 'date'">{{ formatterDate(scope.row, column) }}</span>
|
<div
|
v-else-if="column.formatter"
|
@click="formatterClick(scope.row, column, $event)"
|
v-html="column.formatter(scope.row, column)"
|
></div>
|
<!-- 2021.11.18修复table数据源设置为normal后点击行$event缺失的问题 -->
|
<div
|
v-else-if="column.bind && (column.normal || column.edit)"
|
@click="formatterClick(scope.row, column, $event)"
|
:style="column.getStyle && column.getStyle(scope.row, column)"
|
>
|
{{ formatter(scope.row, column, true) }}
|
</div>
|
<div
|
v-else-if="column.click && !column.bind"
|
@click="formatterClick(scope.row, column)"
|
>
|
{{ scope.row[column.field] }}
|
</div>
|
<div
|
@click="
|
() => {
|
column.click && formatterClick(scope.row, column)
|
}
|
"
|
v-else-if="column.bind"
|
>
|
<el-tag
|
v-if="useTag"
|
class="cell-tag"
|
:class="[isEmptyTag(scope.row, column)]"
|
:type="getColor(scope.row, column)"
|
:effect="column.effect"
|
>{{ formatter(scope.row, column, true) }}</el-tag
|
>
|
<template v-else>{{ formatter(scope.row, column, true) }}</template>
|
</div>
|
|
<span v-else>{{ formatter(scope.row, column, true) }}</span>
|
</template>
|
</template>
|
</el-table-column>
|
</el-table>
|
<template v-if="!paginationHide">
|
<div class="block pagination" key="pagination-01" style="display: flex">
|
<div style="flex: 1"></div>
|
<el-pagination
|
key="pagination-02"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
:current-page="paginations.page"
|
:page-sizes="paginations.sizes"
|
:page-size="paginations.size"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="paginations.total"
|
></el-pagination>
|
</div>
|
</template>
|
</div>
|
|
<VolBox v-model="uploadModel" title="上传" :height="228" :width="500" :padding="15" lazy>
|
<!-- 上传图片、excel或其他文件、文件数量、大小限制都可以,参照volupload组件api -->
|
<div style="height: 200px; display: flex; align-items: center">
|
<VolUpload
|
style="text-align: center"
|
:autoUpload="currentColumn.edit.autoUpload"
|
:multiple="currentColumn.edit.multiple"
|
:url="uploadUrl"
|
:max-file="currentColumn.edit.maxFile"
|
:img="currentColumn.edit.type == 'img'"
|
:excel="currentColumn.edit.type == 'excel'"
|
:fileTypes="currentColumn.edit.fileTypes ? currentColumn.edit.fileTypes : []"
|
:fileInfo="fileInfo"
|
:upload-after="uploadAfter"
|
:upload-before="uploadBefore"
|
:append="currentColumn.edit.accept"
|
>
|
<div>{{ currentColumn.message }}</div>
|
</VolUpload>
|
</div>
|
<template #footer>
|
<div style="text-align: center">
|
<el-button type="default" size="small" @click="uploadModel = false">关闭</el-button>
|
<el-button type="primary" size="small" @click="saveUpload">保存</el-button>
|
</div>
|
</template>
|
</VolBox>
|
<vol-image-viewer ref="viewer"></vol-image-viewer>
|
</template>
|
<script>
|
import VolTableRender from './VolTable/VolTableRender'
|
let _errMsg
|
import { defineComponent, defineAsyncComponent } from 'vue'
|
export default defineComponent({
|
emits: ['loadBefore', 'loadAfter', 'rowChange', 'rowClick', 'rowDbClick', 'selectionChange'],
|
//https://github.com/element-plus/element-plus/issues/1483
|
//没有原先的selection属性了,看issue上使用select/selectall获取
|
//监听数组长度,如果删除了数据,现在只能被迫清除所有选中的行
|
watch: {
|
'tableData.length': {
|
handler(newLen, oldLen) {
|
this.watchRowSelectChange(newLen, oldLen)
|
}
|
},
|
'rowData.length': {
|
handler(newLen, oldLen) {
|
this.watchRowSelectChange(newLen, oldLen)
|
}
|
}
|
},
|
components: {
|
'vol-image-viewer': defineAsyncComponent(() => import('./VolImageViewer.vue')),
|
'table-render': VolTableRender,
|
VolUpload: defineAsyncComponent(() => import('./VolUpload.vue')),
|
VolBox: defineAsyncComponent(() => import('./VolBox.vue'))
|
},
|
props: {
|
rowKey: {
|
// 树形结构的主键字段,如果设置值默认会开启树形table;注意rowKey字段的值必须是唯一(2021.05.02)
|
typeof: String,
|
default: undefined
|
},
|
loadTreeChildren: {
|
// 树形结构加载子节点
|
type: Function,
|
default: (tree, treeNode, resolve) => {
|
if (resolve) {
|
return resolve([])
|
}
|
}
|
},
|
textInline: {
|
// 表格内容超出后是否换行显示(2020.01.16)
|
type: Boolean,
|
default: true
|
},
|
tableData: {
|
// 表数据源,配置了url就不用传这个参数了
|
type: Array,
|
default: () => {
|
return []
|
}
|
},
|
columns: {
|
type: Array,
|
default: []
|
},
|
height: {
|
type: Number,
|
default: 0
|
},
|
maxHeight: {
|
type: Number,
|
default: 0
|
},
|
linkView: {
|
type: Function,
|
default: function () {
|
return 1
|
}
|
},
|
pagination: {
|
type: Object,
|
default: function () {
|
return { total: 0, size: 30, sortName: '' }
|
}
|
},
|
url: {
|
type: String,
|
default: ''
|
},
|
paginationHide: {
|
type: Boolean,
|
default: true
|
},
|
color: {
|
type: Boolean,
|
default: true
|
},
|
index: {
|
// 是否创建索引号,如果需要表格编辑功能,这里需要设置为true
|
type: Boolean,
|
default: false
|
},
|
allowEmpty: {
|
// 表格数据为空时是否默认为--
|
type: Boolean,
|
default: true
|
},
|
defaultLoadPage: {
|
// 传入了url,是否默认加载表格数据
|
type: Boolean,
|
default: true
|
},
|
loadKey: {
|
// 是否自动从后台加载数据源
|
type: Boolean,
|
default: true
|
},
|
single: {
|
type: Boolean, // 是否单选
|
default: false
|
},
|
doubleEdit: {
|
type: Boolean, // 是否双击启用编辑功能
|
default: true
|
},
|
beginEdit: {
|
// 编辑开始
|
type: Function,
|
default: function (row, column, index) {
|
return true
|
}
|
},
|
endEditBefore: {
|
// 结束编辑前
|
type: Function,
|
default: function (row, column, index) {
|
return true
|
}
|
},
|
endEditAfter: {
|
// 结束编辑前
|
type: Function,
|
default: function (row, column, index) {
|
return true
|
}
|
},
|
ck: {
|
// 是否显示checkbox
|
type: Boolean,
|
default: true
|
},
|
columnIndex: {
|
// 是否显示行号(2020..11.1)
|
type: Boolean,
|
default: true
|
},
|
highlightCurrentRow: {
|
//增加选中行高亮显示(2022.10.07)
|
type: Boolean,
|
default: true
|
},
|
select2Count: {
|
//超出数量显示select2组件
|
type: Number,
|
default: 2000
|
},
|
selectable: {
|
type: Function,
|
default: (row, index) => {
|
return true
|
}
|
},
|
spanMethod: {
|
type: Function,
|
default: ({ row, column, rowIndex, columnIndex }) => {}
|
},
|
lazy: {
|
//树形表格是否默认延迟加载
|
type: Boolean,
|
default: true
|
},
|
defaultExpandAll: {
|
//树形表格是否展开所有
|
type: Boolean,
|
default: false
|
},
|
expandRowKeys: {
|
//默认展开行
|
type: Array,
|
default: () => {
|
return []
|
}
|
},
|
rowParentField: {
|
//树形表格父级id
|
type: String,
|
default: ''
|
}
|
},
|
data() {
|
return {
|
fixed: false, //是固定行号与checkbox
|
clickEdit: true, //2021.07.17设置为点击行结束编辑
|
randomTableKey: 1,
|
visiblyColumns: [],
|
key: '',
|
realHeight: 0,
|
realMaxHeight: 0,
|
enableEdit: false, // 是否启表格用编辑功能
|
empty: this.allowEmpty ? '' : '--',
|
defaultImg: new URL('@/assets/imgs/error-img.png', import.meta.url).href,
|
loading: false,
|
footer: {},
|
total: 0,
|
formatConfig: {},
|
// defaultColor: "",
|
// 2020.09.06调整table列数据源的背景颜色
|
colors: ['primary', 'success', 'info', 'warning', 'danger'], // ["warning", "success", "danger", "info"],
|
rule: {
|
phone: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
|
decimal: /(^[\-0-9][0-9]*(.[0-9]+)?)$/,
|
number: /(^[\-0-9][0-9]*([0-9]+)?)$/
|
},
|
columnNames: [],
|
rowData: [],
|
paginations: {
|
sort: '',
|
order: 'desc',
|
Foots: '',
|
total: 0,
|
// 2020.08.29增加自定义分页条大小
|
sizes: [30, 60, 100, 120],
|
size: 30, // 默认分页大小
|
Wheres: [],
|
page: 1,
|
rows: 30
|
},
|
errorFiled: '',
|
edit: { columnIndex: -1, rowIndex: -1 }, // 当前双击编辑的行与列坐标
|
editStatus: {},
|
summary: false, // 是否显示合计
|
// 目前只支持从后台返回的summaryData数据
|
summaryData: [],
|
summaryIndex: {},
|
remoteColumns: [], // 需要每次刷新或分页后从后台加载字典数据源的列配置
|
cellStyleColumns: {}, // 有背景颜色的配置
|
fxRight: false, //是否有右边固定表头
|
selectRows: [], //当前选中的行
|
isChrome: false,
|
//vol-table带数据源的单元格是否启用tag标签(下拉框等单元格以tag标签显示)
|
//2023.04.02更新voltable与main.js
|
useTag: true,
|
currentRow: {},
|
currentColumn: [],
|
fileInfo: [],
|
uploadUrl: '',
|
uploadModel: false,
|
smallCell: true
|
}
|
},
|
created() {
|
try {
|
this.useTag = this.$global.table && this.$global.table.useTag
|
this.smallCell = this.$global.table && this.$global.table.smallCell
|
} catch (error) {
|
console.log(error.message)
|
}
|
|
this.realHeight = this.getHeight()
|
this.realMaxHeight = this.getMaxHeight()
|
this.fxRight = this.columns.some((x) => {
|
return x.fixed == 'right'
|
})
|
//2021.09.21移除强制固定行号与checkbox列
|
if (
|
this.columns.some((x) => {
|
return x.fixed && x.fixed != 'right'
|
})
|
) {
|
this.fixed = true
|
}
|
//2022.04.06优化table合计固定列显示
|
// if (
|
// this.columns.some((x) => {
|
// return x.summary;
|
// })
|
// ) {
|
// this.columns.forEach((x) => {
|
// if (x.fixed && x.fixed != 'right') {
|
// x.fixed = false;
|
// }
|
// });
|
// this.fixed = false;
|
// }
|
|
// 从后台加下拉框的[是否启用的]数据源
|
let keys = []
|
let columnBind = []
|
this.summaryData.push('合计')
|
if (this.columnIndex) {
|
this.summaryData.push(' ')
|
}
|
this.initCellStyleColumns()
|
this.columns.forEach((x, _index) => {
|
if (!x.hidden) {
|
// this.summaryIndex[x.field] = _index;
|
// 2020.10.11修复求和列错位的问题
|
this.summaryData.push('')
|
this.summaryIndex[x.field] = this.summaryData.length - 1
|
}
|
// 求和
|
if (x.summary && !this.summary) {
|
this.summary = true
|
}
|
if (x.children && Array.isArray(x.children)) {
|
x.children.forEach((cl) => {
|
if (cl.bind && cl.bind.key && (!cl.bind.data || cl.bind.data.length == 0)) {
|
keys.push(cl.bind.key)
|
cl.bind.valueType = cl.type
|
columnBind.push(cl.bind)
|
}
|
})
|
} else if (x.bind && x.bind.key && (!x.bind.data || x.bind.data.length == 0)) {
|
// 写入远程
|
if (!x.bind.data) x.bind.data = []
|
if (x.bind.remote) {
|
this.remoteColumns.push(x)
|
} else if (this.loadKey) {
|
keys.push(x.bind.key)
|
x.bind.valueType = x.type
|
if (x.edit && x.edit.type) {
|
x.bind.editType = x.edit.type
|
}
|
columnBind.push(x.bind)
|
}
|
}
|
})
|
if (keys.length > 0) {
|
this.http.post('/api/Sys_Dictionary/GetVueDictionary', keys).then((dic) => {
|
dic.forEach((x) => {
|
if (x.data.length > this.select2Count) {
|
x.data.forEach((item) => {
|
item.label = item.value
|
item.value = item.key
|
})
|
}
|
const arrType = ['cascader', 'treeSelect']
|
columnBind.forEach((c) => {
|
if (arrType.indexOf(c.valueType) != -1 || arrType.indexOf(c.editType) != -1) {
|
this.columns.forEach((col) => {
|
if (col.bind && col.bind.key == c.key) {
|
col.bind.orginData = JSON.parse(JSON.stringify(x.data))
|
}
|
})
|
x.data = this.base.convertTree(x.data, (node, data, isRoot) => {
|
if (!node.inited) {
|
node.inited = true
|
node.label = node.value
|
node.value = node.key + ''
|
}
|
})
|
}
|
// 转换数据源的类型与列的类型一致(2020.04.04)
|
else if (c.key == x.dicNo && (c.valueType == 'int' || c.valueType == 'sbyte')) {
|
x.data.forEach((d) => {
|
// 2020.09.01增加对数字类型的二次判断
|
if (!isNaN(d.key)) {
|
d.key = ~~d.key
|
}
|
})
|
}
|
if (c.key == x.dicNo) c.data.push(...x.data)
|
})
|
})
|
})
|
}
|
|
this.paginations.sort = this.pagination.sortName
|
// 2020.08.29增加自定义分页条大小
|
Object.assign(this.paginations, this.pagination)
|
if (this.pagination.size) {
|
this.paginations.rows = this.pagination.size
|
}
|
this.enableEdit = this.columns.some((x) => {
|
return x.hasOwnProperty('edit')
|
})
|
let keyColumn = this.columns.find((x) => {
|
return x.isKey
|
})
|
if (keyColumn) {
|
this.key = keyColumn.field
|
}
|
this.defaultLoadPage && this.load()
|
},
|
computed: {
|
filterColumns() {
|
return this.columns.filter((x, index) => {
|
if (!x.field) {
|
x.field = x.title + index
|
}
|
return !x.hidden
|
})
|
}
|
},
|
methods: {
|
initCellStyleColumns() {
|
this.columns.forEach((x) => {
|
if (x.cellStyle) {
|
this.cellStyleColumns[x.field] = x.cellStyle
|
}
|
})
|
},
|
watchRowSelectChange(newLen, oldLen) {
|
if (newLen < oldLen && this.selectRows.length) {
|
this.selectRows = []
|
this.$refs.table.clearSelection()
|
}
|
},
|
switchChange(val, row, column) {
|
//这里在初始化的时候也会触发change事件
|
if (Object.keys(row).length <= 1) {
|
return
|
}
|
if (column.onChange) {
|
column.onChange(val, row, column)
|
}
|
},
|
inputKeyPress(row, column, $event, $e) {
|
column.onKeyPress && column.onKeyPress(row, column, $event)
|
this.getInputSummaries(null, null, $event, column)
|
},
|
extraClick(row, column) {
|
column.extra.click &&
|
column.extra.click(row, column, this.url ? this.rowData : this.tableData)
|
},
|
headerClick(column, event) {
|
if (this.clickEdit && this.edit.rowIndex != -1) {
|
if (
|
this.rowEndEdit(
|
this.url ? this.rowData[this.edit.rowIndex] : this.tableData[this.edit.rowIndex],
|
column
|
)
|
) {
|
this.edit.rowIndex = -1
|
}
|
}
|
// this.edit.rowIndex = -1;
|
},
|
rowDbClick(row, column, event) {
|
//2021.05.23增加双击行事件
|
this.$emit('rowDbClick', { row, column, event })
|
},
|
rowClick(row, column, event) {
|
//2022.02.20增加点击时表格参数判断
|
if (!column) {
|
return
|
}
|
//正在编辑时,禁止出发rowClick事件
|
if (this.edit.rowIndex == -1) {
|
this.$emit('rowClick', { row, column, event })
|
}
|
// 点击行事件(2020.11.07)
|
|
if (!this.doubleEdit) {
|
return
|
}
|
// 点击其他行时,如果点击的行与正在编辑的行相同,保持编辑状态
|
if (this.clickEdit && this.edit.rowIndex != -1) {
|
if (row.elementIndex == this.edit.rowIndex) {
|
// 点击的单元格如果不可以编辑,直接结束编辑
|
// 2020.10.12修复结束编辑时,element table高版本属性获取不到的问题
|
let _col = this.columns.find((x) => {
|
return x.field == ((event && event.property) || column.property)
|
})
|
if (_col && (!_col.edit || _col.readonly)) {
|
if (this.rowEndEdit(row, event)) {
|
this.edit.rowIndex = -1
|
}
|
}
|
return
|
}
|
if (this.rowEndEdit(row, event && event.property ? event : column)) {
|
this.edit.rowIndex = -1
|
}
|
//当正在编辑,且点击到其他行时,在原编辑的行结束编辑后,触发新行的rowClick事件
|
//正在编辑时,禁止出发rowClick事件
|
if (this.edit.rowIndex == -1) {
|
this.$emit('rowClick', { row, column, event })
|
}
|
}
|
this.rowBeginEdit(row, column)
|
},
|
dowloadFile(file) {
|
this.base.dowloadFile(
|
file.path,
|
file.name,
|
{
|
Authorization: this.$store.getters.getToken()
|
},
|
this.http.ipAddress
|
)
|
},
|
getFilePath(pathSring, column) {
|
// 获取表的图片与文件显示
|
if (!pathSring) return []
|
// 增加图片自定义操作
|
// 返回格式必须是[{name:"文件名",path:"图片全路径或base64格式"}]
|
if (column.formatter) {
|
return column.formatter(pathSring)
|
}
|
let filePath
|
if (column.base64 && pathSring.indexOf('data') != -1) {
|
filePath = (',' + pathSring)
|
.split(',data')
|
.filter((x) => {
|
return x
|
})
|
.map((m) => {
|
return 'data' + m
|
})
|
} else {
|
filePath = pathSring.replace(/\\/g, '/').split(',')
|
}
|
|
let fileInfo = []
|
for (let index = 0; index < filePath.length; index++) {
|
let file = filePath[index]
|
// 2020.12.19增加base64图片显示
|
if (column.base64) {
|
fileInfo.push({
|
name: '',
|
path: (file.indexOf('data') == -1 ? 'data:image/png;base64,' : '') + file
|
})
|
} else if (file.indexOf('.') != -1) {
|
let splitFile = file.split('/')
|
if (splitFile.length > 0) {
|
fileInfo.push({
|
name: splitFile[splitFile.length - 1],
|
path: this.base.isUrl(file) ? file : this.http.ipAddress + file
|
})
|
}
|
}
|
}
|
return fileInfo
|
},
|
// 重置table
|
reset() {
|
if (this.tableData && this.tableData.length > 0) {
|
this.tableData.splice(0)
|
}
|
if (this.rowData && this.rowData.length > 0) {
|
this.rowData.splice(0)
|
}
|
if (!this.paginationHide) {
|
this.paginations.page = 1
|
// this.paginations.rows = 30;
|
if (this.paginations.wheres && this.paginations.wheres.length > 0) {
|
this.paginations.wheres.splice(0)
|
}
|
}
|
this.errorFiled = ''
|
this.edit.columnIndex = -1
|
this.edit.rowIndex = -1
|
},
|
getHeight() {
|
// 没有定义高度与最大高度,使用table默认值
|
if (!this.height && !this.maxHeight) {
|
return null
|
}
|
// 定义了最大高度则不使用高度
|
if (this.maxHeight) {
|
return null
|
}
|
// 使用当前定义的高度
|
return this.height
|
},
|
getMaxHeight() {
|
// 没有定义高度与最大高度,使用table默认值
|
if (!this.height && !this.maxHeight) {
|
return null
|
}
|
// 定义了最大高度使用最大高度
|
if (this.maxHeight) {
|
return this.maxHeight
|
}
|
// 不使用最大高度
|
return null
|
},
|
getSelectedOptions(column) {
|
if (column.bind && column.bind.data && column.bind.data.length > 0) {
|
return column.bind.data
|
}
|
return []
|
},
|
formatterClick(row, column, event) {
|
if (column.click) {
|
column.click(row, column, event)
|
event.stopPropagation && event.stopPropagation()
|
} else {
|
this.rowClick(row, column, event)
|
}
|
},
|
initIndex({ row, rowIndex }) {
|
if (this.index) {
|
row.elementIndex = rowIndex
|
}
|
// if (rowIndex%2!==0) {
|
// return "even-row";
|
// }
|
return
|
},
|
toggleEdit(event) {},
|
setEditStatus(status) {
|
// this.columns.forEach((x) => {
|
// if (x.hasOwnProperty("edit")) {
|
// this.$set(x.edit, "status", status);
|
// }
|
// });
|
},
|
// 通过button按钮启用编辑
|
beginWithButtonEdit(scope) {
|
// url?rowData:tableData
|
this.rowBeginEdit(scope.row, this.columns[scope.$index])
|
},
|
rowBeginEdit(row, column) {
|
if (this.edit.rowIndex != -1) {
|
return
|
}
|
let _row = this.columns.find((x) => x.field == column.property)
|
if (_row) {
|
if (_row.readonly) {
|
return
|
}
|
if (
|
//不能编辑的字段、switch,点击不开启启编辑功能
|
!_row.edit ||
|
(_row.edit.keep && _row.edit.type == 'switch')
|
) {
|
return
|
}
|
}
|
if (!this.enableEdit) return
|
_errMsg = ''
|
// 编辑前
|
this.columns
|
.filter((x) => {
|
return x.bind && x.bind.data && x.bind.data.length
|
})
|
.forEach((column) => {
|
let val = row[column.field]
|
if (typeof column.bind.data[0].key == 'string') {
|
if (typeof val == 'number') {
|
row[column.field] = row[column.field] + ''
|
}
|
} else {
|
//多选或者级联编辑回写,2023.01.06
|
if (Array.isArray(val)) {
|
val = val.map((v) => {
|
return v * 1
|
})
|
row[column.field] = val
|
} else if (typeof val == 'string' && val) {
|
let _val = val * 1
|
if (_val + '' === val) {
|
row[column.field] = _val
|
}
|
}
|
}
|
})
|
if (!this.beginEdit(row, column, row.elementIndex)) return
|
if (row.hasOwnProperty('elementIndex')) {
|
if (this.edit.rowIndex == row.elementIndex) {
|
return
|
}
|
this.edit.rowIndex = row.elementIndex
|
}
|
},
|
rowEndEdit(row, column, event) {
|
if (this.clickEdit && event) {
|
return true
|
}
|
if (!this.enableEdit) {
|
if (!this.errorFiled) {
|
if (this.edit.rowIndex != -1 && !this.endEditAfter(row, column, this.edit.rowIndex)) {
|
return false
|
}
|
this.edit.rowIndex = -1
|
}
|
return true
|
}
|
if (!this.doubleEdit && event) {
|
return true
|
}
|
let _row = this.url ? this.rowData[this.edit.rowIndex] : this.tableData[this.edit.rowIndex]
|
// 结束编辑前
|
if (!this.endEditBefore(_row, column, this.edit.rowIndex)) return false
|
if (this.edit.rowIndex != -1) {
|
//2022.06.26修复表格内容切换后行数不一致时不能编辑的问题
|
if (this.edit.rowIndex - 1 > (this.rowData || this.tableData).length) {
|
this.edit.rowIndex = -1
|
return
|
}
|
let row = (this.url ? this.rowData : this.tableData)[this.edit.rowIndex]
|
for (let index = 0; index < this.columns.length; index++) {
|
const _column = this.columns[index]
|
if (_column.edit) {
|
if (!this.validateRow(row, _column)) {
|
return
|
}
|
}
|
}
|
}
|
if (!this.endEditAfter(_row, column, this.edit.rowIndex)) return false
|
this.edit.rowIndex = -1
|
return true
|
},
|
validateRow(row, option1) {
|
if (!this.validateColum(option1, row)) {
|
this.errorFiled = option1.field
|
// 2022.05.06 修改错误信息重复的问题
|
this.$message.error(option1.title + _errMsg)
|
return false
|
}
|
this.errorFiled = ''
|
return true
|
},
|
validateColum(option, data) {
|
if (option.hidden || option.bind || !data) return true
|
let val = data[option.field]
|
if (option.require || option.required) {
|
if (val != '0' && (val === '' || val === undefined)) {
|
if (!this.errorFiled) {
|
_errMsg = '不能为空'
|
}
|
return false
|
}
|
}
|
if (!option.edit) {
|
return true
|
}
|
let editType = option.edit.type
|
// 验证数字
|
if (editType == 'int' || editType == 'decimal' || editType == 'number') {
|
if (val == '' || val == undefined) return true
|
if (editType == 'decimal') {
|
if (!this.rule.decimal.test(val)) {
|
_errMsg = '只能是数字'
|
return false
|
}
|
} else if (!this.rule.decimal.test(val)) {
|
_errMsg = '只能是数字'
|
return false
|
}
|
if (
|
option.edit.min != undefined &&
|
typeof option.edit.min === 'number' &&
|
val < option.edit.min
|
) {
|
_errMsg = '不能小于' + option.edit.min
|
return false
|
}
|
if (
|
option.edit.max != undefined &&
|
typeof option.edit.max === 'number' &&
|
val > option.edit.max
|
) {
|
_errMsg = '不能大于' + option.edit.max
|
return false
|
}
|
return true
|
}
|
|
// 验证字符串
|
if (val && (editType == 'text' || editType == 'string')) {
|
if (
|
option.edit.min != undefined &&
|
typeof option.edit.min === 'number' &&
|
val.length < option.edit.min
|
) {
|
_errMsg = '至少' + option.edit.min + '个字符'
|
return false
|
}
|
if (
|
option.edit.max != undefined &&
|
typeof option.edit.max === 'number' &&
|
val.length > option.edit.max
|
) {
|
_errMsg = '最多' + option.edit.max + '个字符'
|
return false
|
}
|
}
|
return true
|
},
|
delRow() {
|
let rows = this.getSelected()
|
if (rows.length == 0) return this.$Message.error('请选择要删除的行!')
|
|
let data = this.url ? this.rowData : this.tableData
|
let indexArr = this.getSelectedIndex()
|
if (indexArr.length == 0) {
|
return this.$Message.error("删除操作必须设置VolTable的属性index='true'")
|
}
|
// if (indexArr.length == 0 || !this.key) {
|
// return this.$message.error(
|
// "请设置index=true属性或指columns的字段为key"
|
// );
|
// }
|
if (indexArr.length == 0) {
|
// let keyValues=[]
|
// rows.forEach(x=>{
|
// if (x[this.key]) {
|
// }
|
// keyValues.push(x[this.key])
|
// })
|
// data.find(x=>)
|
} else {
|
for (let i = data.length - 1; i >= 0; i--) {
|
if (indexArr.indexOf(i) != -1) {
|
data.splice(i, 1)
|
}
|
}
|
}
|
this.edit.rowIndex = -1
|
return rows
|
},
|
addRow(row) {
|
if (!row) {
|
row = {}
|
}
|
this.columns.forEach((x) => {
|
// 2022.05.06 添加行时,如果列有编辑属性,设置开启编辑(避免关闭编辑后,无法再次启用编辑)??
|
//x.readonly = false;
|
if (!row.hasOwnProperty(x.field)) {
|
if (x.edit && x.edit.type == 'switch') {
|
row[x.field] = x.type == 'bool' ? false : 0
|
} else if (!row.hidden) {
|
// 2020.09.06添加行时,设置默认字段
|
row[x.field] = undefined
|
}
|
}
|
})
|
if (!this.url) {
|
this.tableData.push(row)
|
return
|
}
|
this.rowData.push(row)
|
},
|
viewImg(row, column, url, $event, index) {
|
$event.stopPropagation()
|
const imgs = this.getFilePath(row[column.field], column).map((x) => {
|
return x.path
|
})
|
this.$refs.viewer.show(imgs, index)
|
//this.base.previewImg(url);
|
// window.open(row[column.field]);
|
},
|
link(row, column, $e) {
|
$e.stopPropagation()
|
this.$props.linkView(row, column)
|
},
|
getSelected() {
|
return this.selectRows
|
},
|
getSelectedIndex() {
|
if (!this.index) {
|
// 只有设置了属性index才有索引行
|
return []
|
}
|
let indexArr = this.selectRows.map((x) => {
|
return x.elementIndex
|
})
|
return indexArr || []
|
},
|
GetTableDictionary(rows) {
|
// 分页或刷新或重新绑定数据源
|
if (this.remoteColumns.length == 0 || !rows || rows.length == 0) return
|
let remoteInfo = {}
|
for (let index = 0; index < this.remoteColumns.length; index++) {
|
const column = this.remoteColumns[index]
|
// column.bind.data.splice(0);
|
let key = column.bind.key
|
let data = []
|
rows.forEach((row) => {
|
if (row[column.field] || row[column.field] == '0') {
|
if (data.indexOf(row[column.field]) == -1) {
|
data.push(row[column.field])
|
}
|
}
|
})
|
if (data.length > 0) {
|
remoteInfo[key] = data
|
}
|
}
|
if (remoteInfo.length == 0) return
|
// ha= Object.assign([], ha, hb)
|
this.http.post('/api/Sys_Dictionary/GetTableDictionary', remoteInfo).then((dic) => {
|
dic.forEach((x) => {
|
this.remoteColumns.forEach((column) => {
|
if (column.bind.key == x.key) {
|
column.bind.data = Object.assign([], column.bind.data, x.data)
|
// column.bind.data.push(...x.data);
|
}
|
})
|
})
|
this.$emit('dicInited', dic)
|
})
|
},
|
load(query, isResetPage) {
|
// isResetPage重置分页数据
|
if (!this.url) return
|
if (isResetPage) {
|
this.resetPage()
|
}
|
let param = {
|
page: this.paginations.page,
|
rows: this.paginationHide ? 1000 : this.paginations.rows,
|
sort: this.paginations.sort,
|
order: this.paginations.order,
|
wheres: [] // 查询条件,格式为[{ name: "字段", value: "xx" }]
|
}
|
let status = true
|
// 合并查询信息(包查询分页、排序、查询条件等)
|
if (query) {
|
param = Object.assign(param, query)
|
}
|
/* 查询前处理(如果需要查询条件,实现组件方法loadBefore方法即可:
|
loadBefore=(param, callBack)=>{
|
param.wheres = [{ name: "PhoneNo", value: "13419098211" }];
|
callBack(true);
|
})
|
*/
|
this.$emit('loadBefore', param, (result) => {
|
status = result
|
})
|
if (!status) return
|
|
if (param.wheres && param.wheres instanceof Array) {
|
param.wheres = JSON.stringify(param.wheres)
|
}
|
this.loading = true
|
let url = param.url || this.url
|
param.url = undefined
|
this.http.post(url, param).then(
|
(data) => {
|
//2021.06.04修复tree不刷新的问题
|
if (this.rowKey) {
|
this.randomTableKey++
|
this.rowData.splice(0)
|
}
|
this.loading = false
|
let rows = data.rows || []
|
// 查询返回结果后处理
|
// 2020.10.30增加查询后返回所有的查询信息
|
this.$emit(
|
'loadAfter',
|
rows,
|
(result) => {
|
status = result
|
},
|
data
|
)
|
if (!status) return
|
this.GetTableDictionary(data.rows)
|
|
if (this.rowParentField) {
|
rows = this.base.convertTree(rows, null, this.rowKey, this.rowParentField)
|
}
|
this.rowData = rows
|
this.paginations.total = data.total
|
// 合计
|
this.getSummaries(data)
|
// this.$nextTick(() => {
|
// this.$refs.table.doLayout();
|
// });
|
},
|
(error) => {
|
this.loading = false
|
// this.$Message.error(error || "网络异常");
|
}
|
)
|
}, // 获取统计
|
getSummaries(data) {
|
if (!this.summary || !data.summary) return
|
this.summaryData.splice(0)
|
// 开启了行号的,+1
|
if (this.columnIndex) {
|
this.summaryData.push('')
|
}
|
// 如果有checkbox,应该算作是第一行
|
if (this.ck) {
|
this.summaryData.push('')
|
}
|
|
this.columns.forEach((col) => {
|
if (col.children && col.children.length) {
|
col.children.forEach((item) => {
|
this.getColumnSummaries(item, data)
|
})
|
} else {
|
this.getColumnSummaries(col, data)
|
}
|
})
|
if (this.summaryData.length > 0 && this.summaryData[0] == '') {
|
this.summaryData[0] = '合计'
|
}
|
},
|
getColumnSummaries(col, data) {
|
if (!col.hidden) {
|
if (data.summary.hasOwnProperty(col.field)) {
|
let sum = data.summary[col.field]
|
//2024.01.07增加自定义合计格式化
|
if (col.summaryFormatter) {
|
sum = col.summaryFormatter(sum, col, data, this.summaryData)
|
} else if (sum) {
|
sum = (sum * 1.0).toFixed(col.numberLength || 2).replace('.00', '') * 1.0
|
}
|
this.summaryData.push(sum)
|
} else {
|
this.summaryData.push('')
|
}
|
}
|
},
|
getInputChangeSummaries() {},
|
handleSizeChange(val) {
|
this.paginations.size = val
|
this.paginations.rows = val
|
this.load()
|
},
|
handleCurrentChange(val) {
|
this.paginations.page = val
|
this.load()
|
},
|
sortChange(sort) {
|
this.paginations.sort = sort.prop
|
this.paginations.order = sort.order == 'ascending' ? 'asc' : 'desc'
|
this.load()
|
},
|
resetPage() {
|
// 重置查询分页
|
// this.paginations.rows = 30;
|
this.paginations.page = 1
|
},
|
selectionChange(selection) {
|
// console.log(selection);
|
// 选择行事件,只有单选才触发
|
this.selectRows = selection
|
if (this.single) {
|
if (selection.length == 1) {
|
this.$emit('rowChange', selection[0])
|
}
|
if (selection.length > 1) {
|
let _row = selection[selection.length - 1]
|
this.$refs.table.toggleRowSelection(selection[0])
|
this.selectRows = [_row]
|
}
|
}
|
// 将selectionchange暴露出去
|
this.$emit('selectionChange', selection)
|
},
|
getColor(row, column) {
|
let val = row[column.field]
|
if (column.getColor && typeof column.getColor === 'function') {
|
let _color = column.getColor(row, column)
|
if (_color) {
|
return _color
|
}
|
}
|
if (!val && val != '0') {
|
return undefined
|
}
|
if (!this.formatConfig[column.field]) {
|
this.formatConfig[column.field] = [val]
|
return this.colors[0]
|
}
|
let index = this.formatConfig[column.field].indexOf(val)
|
if (index != -1) {
|
return this.colors[index]
|
}
|
if (this.formatConfig[column.field].length > 5) {
|
return ''
|
}
|
|
if (index == -1) {
|
this.formatConfig[column.field].push(val)
|
index = this.formatConfig[column.field].length - 1
|
}
|
return this.colors[index] || 'info'
|
},
|
formatterDate(row, column) {
|
return (row[column.field] || '').substr(0, 10)
|
},
|
formatter(row, column, template) {
|
if (!template) return row[column.property]
|
let val = row[column.field]
|
if (!val && val != 0) return val
|
// 是否值
|
if (column.edit && column.edit.type == 'switch') {
|
return val ? '是' : '否'
|
}
|
if (!column.bind || !column.bind.data) {
|
return row[column.field]
|
}
|
|
if (
|
column.edit &&
|
(column.edit.type == 'selectList' ||
|
column.edit.type == 'treeSelect' ||
|
column.bind.type == 'cascader' ||
|
column.bind.type == 'treeSelect')
|
) {
|
if (!Array.isArray(val)) {
|
row[column.field] = (val + '').split(',')
|
} else {
|
val = val.join(',')
|
}
|
return this.getSelectFormatter(column, val)
|
}
|
// 编辑多选table显示
|
// if (
|
// column.bind.type == "selectList" ||
|
// column.bind.type == "checkbox" ||
|
// column.bind.type == "cascader" ||
|
// column.bind.type == "treeSelect"
|
// ) {
|
if (typeof val === 'string' && val.indexOf(',') != -1) {
|
return this.getSelectFormatter(column, val)
|
}
|
//}
|
let source = column.bind.data.filter((x) => {
|
// return x.key != "" && x.key == val;
|
// 2020.06.06修复单独使用table组件时,key为数字0时转换成文本失败的问题
|
return x.key !== '' && x.key !== undefined && x.key + '' === val + ''
|
})
|
if (source && source.length > 0) val = source[0].label || source[0].value
|
return val
|
},
|
getSelectFormatter(column, val) {
|
// 编辑多选table显示
|
let valArr = (val + '').split(',')
|
for (let index = 0; index < valArr.length; index++) {
|
;(column.bind.orginData && column.bind.orginData.length
|
? column.bind.orginData
|
: column.bind.data
|
).forEach((x) => {
|
// 2020.06.06修复数据源为selectList时,key为数字0时不能转换文本的问题
|
if (x.key !== '' && x.key !== undefined && x.key + '' == valArr[index] + '') {
|
valArr[index] = x.label || x.value
|
}
|
})
|
}
|
return valArr.join(',')
|
},
|
onChange(scope, val, event, column) {
|
// 2020.09.03修复onChange不触发的问题
|
let row = scope.row
|
if (column.onChange && !column.onChange(row, val, event)) {
|
return
|
}
|
// 输入框求和实时计算
|
this.getInputSummaries(scope, val, event, column)
|
},
|
// input输入实时求和
|
getInputSummaries(scope, val, event, column) {
|
// column列设置了summary属性的才计算值
|
if (!column.summary) return
|
let sum = 0
|
// let _index = 0;
|
;(this.url ? this.rowData : this.tableData).forEach((x, index) => {
|
if (x.hasOwnProperty(column.field) && !isNaN(x[column.field])) {
|
// _index = index;
|
sum += x[column.field] * 1
|
}
|
})
|
if (sum) {
|
if (column.summary == 'avg') {
|
sum = sum / (this.rowData.length || this.tableData.length || 1)
|
}
|
sum = (sum * 1.0).toFixed(column.numberLength || 2).replace('.00', '') * 1.0
|
}
|
this.summaryData[this.summaryIndex[column.field]] = sum
|
},
|
getSummaryData({ columns, data }) {
|
return this.summaryData
|
},
|
getCellStyle(row) {
|
// 2020.12.13增加设置单元格颜色
|
if (row.column.property) {
|
return (
|
this.cellStyleColumns[row.column.property] &&
|
this.cellStyleColumns[row.column.property](row.row, row.rowIndex, row.columnIndex)
|
)
|
}
|
},
|
compareDate(date1, date2) {
|
if (!date2) {
|
return true
|
}
|
return date1.valueOf() < (typeof date2 == 'number' ? date2 : new Date(date2).valueOf())
|
},
|
getDateOptions(date, item) {
|
//2021.07.17设置时间可选范围
|
if ((!item.min && !item.max) || !date) {
|
return false
|
}
|
if (item.min && item.min.indexOf(' ') == -1) {
|
//不设置时分秒,后面会自动加上 08:00
|
item.min = item.min + ' 00:00:000'
|
}
|
return this.compareDate(date, item.min) || !this.compareDate(date, item.max)
|
},
|
getDateFormat(column) {
|
if (column.format) {
|
return column.format
|
}
|
if (column.edit.type == 'month') {
|
return 'YYYY-MM'
|
}
|
//见https://day.js.org/docs/zh-CN/display/format
|
return column.edit.type == 'date' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
|
},
|
userSelect(selection, row) {
|
this.selectRows = selection
|
if (!this.single) {
|
this.$emit('rowChange', { row, selection })
|
}
|
},
|
isEmptyTag(row, column) {
|
if (!row[column.field] && row[column.field] != '0') {
|
return 'empty-tag'
|
}
|
return ''
|
},
|
filterChildrenColumn(children) {
|
if (!children) {
|
return []
|
}
|
return children.filter((x) => {
|
return !x.hidden
|
})
|
},
|
initColumnDisabled(row, column) {
|
return column.getDisabled && column.getDisabled(row, column)
|
},
|
showUpload(row, column) {
|
this.fileInfo = (row[column.field] || '')
|
.split(',')
|
.filter((x) => {
|
return x
|
})
|
.map((item) => {
|
return { path: item, name: '' }
|
})
|
this.currentRow = row
|
this.currentColumn = column
|
if (this.currentColumn.edit.autoUpload === undefined) {
|
this.currentColumn.edit.autoUpload = true
|
}
|
if (this.currentColumn.edit.multiple === undefined) {
|
this.currentColumn.edit.multiple = false
|
}
|
|
if (this.currentColumn.edit.url === undefined) {
|
this.uploadUrl = 'api/' + (this.url || '').replace('/api', 'api').split('/')[1] + '/upload'
|
} else {
|
this.uploadUrl = this.currentColumn.edit.url
|
}
|
this.uploadModel = true
|
},
|
uploadAfter(result, files) {
|
this.currentColumn.uploadAfter && this.currentColumn.uploadAfter(result, files)
|
return true
|
},
|
uploadBefore(files, params) {
|
this.currentColumn.uploadBefore &&
|
this.currentColumn.uploadBefore(files, this.currentRow, params)
|
return true
|
},
|
saveUpload() {
|
//生成保存后返回的路径
|
let arr = this.fileInfo.map((x) => {
|
if (x.path) {
|
return x.path
|
}
|
return result.data + x.name
|
})
|
|
this.currentRow[this.currentColumn.field] = arr.join(',')
|
this.uploadModel = false
|
return true
|
},
|
expandChange(row, expandedRows) {
|
// 当用户对某一行展开或者关闭的时
|
if (!this.defaultExpandAll && !this.lazy) {
|
if (expandedRows) {
|
if (this.expandRowKeys.indexOf(row[this.rowKey]) == -1) {
|
this.expandRowKeys.push(row[this.rowKey])
|
}
|
} else {
|
let _index = this.expandRowKeys.findIndex((x) => {
|
return x == row[this.rowKey]
|
})
|
if (_index != -1) {
|
this.expandRowKeys.splice(_index, 1)
|
}
|
}
|
}
|
},
|
handleImageError($e) {
|
$e.target.src = this.defaultImg
|
},
|
cellSpanMethod({ row, column, rowIndex, columnIndex }) {
|
return this.spanMethod(
|
{ row, column, rowIndex, columnIndex },
|
this.url ? this.rowData : this.tableData
|
)
|
}
|
}
|
})
|
</script>
|
<style lang="less" scoped>
|
.vol-table {
|
position: relative;
|
|
.mask {
|
opacity: 0.2;
|
position: absolute;
|
width: 100%;
|
height: 100%;
|
background: #d0d0d0;
|
z-index: 100;
|
}
|
|
.message {
|
text-align: center;
|
color: #635c5c;
|
font-size: 15px;
|
font-weight: 600;
|
background: #eee;
|
transform: translateY(-50%);
|
top: 50%;
|
position: absolute;
|
z-index: 200;
|
left: 0;
|
right: 0;
|
width: 150px;
|
margin: 0 auto;
|
line-height: 40px;
|
border-radius: 4px;
|
border: 1px solid #a09e9e;
|
}
|
}
|
|
.e-item {
|
display: flex;
|
|
> div:first-child {
|
flex: 1;
|
}
|
}
|
|
.vol-table ::v-deep(.el-pager .number) {
|
padding: 0 7px;
|
border-radius: 5px;
|
border: 1px solid #e6e6e6;
|
margin-left: 8px;
|
font-weight: 500;
|
min-width: 28px;
|
height: 27px;
|
}
|
|
.vol-table ::v-deep(.el-pager .number.active) {
|
background: #ed4014;
|
color: #fff;
|
}
|
|
.vol-table ::v-deep(.el-pagination .el-input__wrapper) {
|
height: 27px;
|
}
|
|
.vol-table .t-file {
|
color: #1e8cff;
|
cursor: pointer;
|
border-bottom: 1px solid;
|
padding-bottom: 2px;
|
}
|
|
.vol-table .empty-tag {
|
border: none;
|
background: none;
|
}
|
|
.v-table ::v-deep(.el-date-editor .el-icon-date),
|
.v-table ::v-deep(.el-date-editor .el-icon-time) {
|
width: 10px;
|
}
|
|
.column-required {
|
position: relative;
|
color: #f20303;
|
font-size: 14px;
|
top: 2px;
|
right: 2px;
|
}
|
</style>
|
|
<style scoped>
|
/* .v-table ::v-deep(.even-row){
|
background: rgb(245,247,250);
|
} */
|
.pagination {
|
text-align: right;
|
padding: 2px 28px;
|
border: 1px solid #eee;
|
border-top: 0px;
|
}
|
|
/* .v-table ::v-deep(.el-input .el-input__inner) {
|
padding: 0 7px;
|
} */
|
.v-table ::v-deep(.el-table__header th) {
|
/* padding: 0px !important; */
|
background-color: #f8f8f9 !important;
|
font-size: 13px;
|
/* height: 46px; */
|
color: #616161;
|
}
|
|
.v-table ::v-deep(.el-table__header th.is-sortable) {
|
padding: 3px !important;
|
}
|
|
.vol-table.text-inline ::v-deep(.el-table__body .cell),
|
.vol-table.text-inline ::v-deep(.el-table__header-wrapper .cell) {
|
word-break: inherit !important;
|
white-space: nowrap !important;
|
}
|
|
/* .v-table ::v-deep(.el-table__body td) {
|
padding: 9px 0 !important;
|
} */
|
|
.v-table ::v-deep(.el-table__footer td) {
|
padding: 7px 0 !important;
|
}
|
|
.vol-table ::v-deep(.el-table-column--selection .cell) {
|
display: inline;
|
}
|
|
.vol-table.text-inline ::v-deep(.el-table th > .cell) {
|
white-space: nowrap !important;
|
}
|
|
.vol-table .table-img {
|
height: 40px;
|
border-radius: 5px;
|
margin-right: 10px;
|
width: 40px;
|
object-fit: cover;
|
}
|
|
.vol-table .table-img:hover {
|
cursor: pointer;
|
}
|
|
.vol-table ::v-deep(.cell) {
|
padding: 2px 10px;
|
}
|
|
.vol-table ::v-deep(.cell .el-tag) {
|
padding: 5px 9px;
|
}
|
|
.table-input {
|
color: rgb(104, 103, 103);
|
padding: 3px 10px;
|
height: 32px;
|
line-height: 32px;
|
width: 100%;
|
border-radius: 4px;
|
border: 1px solid #dcdcdc;
|
}
|
|
.table-input:focus {
|
outline: 1px solid #49a3fd;
|
}
|
|
.small-table ::v-deep(.el-pagination .el-input__wrapper) {
|
height: 27px;
|
}
|
|
.small-table ::v-deep(.el-table__cell) {
|
padding: 6px 0;
|
font-size: 13px;
|
}
|
|
.small-table ::v-deep(.cell-tag) {
|
padding: 0 5px !important;
|
height: 19px;
|
}
|
</style>
|