<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="column.showOverflowTooltip">
|
<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>
|