<template>
|
<div class="datalist-container">
|
<!--工具栏-->
|
<data-list-toolbar :fields="fields" :buttons="buttons" :auth-nodes="authNodes" :refresh-loading="refreshLoading" :btn-read-only="btnReadOnly" :load-data="loadData" :editor-ref="editorRef" :data-list-selections="currentDataListSelections" :search-fields="searchFields" :dropdown-data="dropdownData" :button-click="buttonClick" :quick-search="quickSearch" :quick-search-value.sync="quickSearchValue" :quick-search-type.sync="quickSearchType" :quick-search-fields="quickSearchFields" :right-width="rightWidth" :data-options="dataOptions" @on-super-reset="onSuperReset">
|
<template slot="button-tool2-slot">
|
<slot name="button-tool2-slot">
|
</slot>
|
</template>
|
</data-list-toolbar>
|
|
<!--数据Table-->
|
<template>
|
<!-- 自定义区域内容 -->
|
<slot name="datalist-customer-area"></slot>
|
<!--tab导航-->
|
<tabs-nav :tab-nav-list="tabNavList" @on-tabs-nav-change="onTabsNavChange"></tabs-nav>
|
<!--table数据列表-->
|
<el-table v-table-footer-scroll v-loading.lock="initLoading" ref="dataList" :data="dataList" :show-summary="dataOptions.showSumField" :summary-method="getSummaries" :render-header="renderHeader" :max-height="maxHeight" :row-style="rowStyle" :cell-style="cellStyle" highlight-current-row size="mini" class="table-region" @selection-change="handleSelectionChange" @header-click="headerClick" @sort-change="sortChange" @expand-change="expandChange">
|
<el-table-column :width="'30px'" type="selection" class="col-selection">
|
</el-table-column>
|
<el-table-column :width="'30px'" :index="(index)=>{return (dataOptions.pageIndex-1) * dataOptions.pageSize + index+1}" :render-header="renderHeader" type="index" class="col-index">
|
</el-table-column>
|
<el-table-column v-if="openExpand" :width="'30px'" type="expand">
|
<template slot-scope="{row, column, $index}">
|
<slot :row="row" :col="column" name="expand-slot">
|
</slot>
|
</template>
|
</el-table-column>
|
<template v-for="(col, index) in currentFields">
|
<!--操作列插槽-->
|
<el-table-column v-if="col.prop=='_action' && !col.hidden && dataOptions.showActionField" :key="index" :sortable="!!col.sortable" :label="col.label" :width="col.width || 'auto'" :header-align="col.headerAlign || 'left'" :align="col.align || 'left'" :render-header="renderHeader" fixed="right">
|
<template slot-scope="{row, column, $index}">
|
<slot :row="row" :col="col" name="action-column-slot">
|
<el-button v-for="(btn, btnIndex) in col.action" :key="btnIndex" type="text" size="mini" @click="()=>onRowActionClick(btn, col, row)">{{ btn.label }}</el-button>
|
</slot>
|
</template>
|
</el-table-column>
|
<el-table-column v-else-if="col.prop!='_action' && !col.hidden" :key="index" :sortable="!!col.sortable" :prop="col.prop" :label="col.label" :width="col.width || 'auto'" :min-width="col.minWidth" :header-align="col.headerAlign || 'left'" :align="col.align || 'left'" :render-header="renderHeader">
|
<template slot-scope="{row, column, $index}">
|
<!--通用列插槽-->
|
<slot :row="row" :col="col" :translateText="translateText" name="common-column-slot">
|
<template v-if="col.prop==dataOptions.linkColumn">
|
<el-link type="primary" @click.native="()=>{linkEditor(row[dataOptions.idField], row);}">
|
<template v-if="['date', 'datetime'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatDate(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else-if="['byte', 'int32', 'int64', 'decimal', 'double'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatNumber(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else>
|
{{ row[col.prop] }}
|
</template>
|
</el-link>
|
</template>
|
<template v-else-if="['select'].indexOf(col.type)>=0">
|
{{ translateText(col.prop, row[col.prop], col.dropdown_Id, col) }}
|
</template>
|
<template v-else>
|
<template v-if="['date', 'datetime'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatDate(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else-if="['byte', 'int32', 'int64', 'decimal', 'double'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatNumber(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else>
|
<template v-if="['date', 'datetime'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatDate(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else-if="['byte', 'int32', 'int64', 'decimal', 'double'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatNumber(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else>
|
{{ row[col.prop] }}
|
</template>
|
</template>
|
</template>
|
</slot>
|
</template>
|
</el-table-column>
|
</template>
|
</el-table>
|
<div class="pagination-container">
|
<el-pagination :current-page.sync="dataOptions.pageIndex" :page-sizes="[5, 10, 15, 20, 50, 100, 200, 300, 500, 1000]" :page-size="dataOptions.pageSize" :total="dataOptions.total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange">
|
</el-pagination>
|
</div>
|
</template>
|
|
<!--设置是否可以显示字段-->
|
<el-dialog v-dialogDrag :visible.sync="showSetDialog" title="参数设置" top="10vh" class="show-set-dialog" width="600px">
|
<el-alert :closable="false" title="拖动字段可以调整顺序,点击右侧开关可以设置字段是否显示" type="success" class="alert-msg">
|
</el-alert>
|
<ul class="draggable-main">
|
<li class="item">
|
<span>字段名</span>
|
<span class="right">
|
字段显示
|
</span>
|
<span class="right margin-right-10">
|
显示排序
|
</span>
|
</li>
|
</ul>
|
<el-scrollbar :noresize="false" :native="false" wrap-class="scrollbar-wrap">
|
<draggable v-model="currentFields" :options="{group:'a', animation:300, handle:'.handle', chosenClass:'chosen-item'}" :move="fielSetMove" class="draggable-main" tag="ul" @start="startDrag" @end="endDrag">
|
<transition-group :name="!drag? 'list-complete' : null" :css="true">
|
<li v-for="(item, index) in currentFields" :class="['item', {'over': item===targetElement}]" :key="'key' + index">
|
<i class="handle el-icon-yrt-yidong1"></i>
|
<span>{{ item.label }}</span>
|
<el-switch v-model="item.hidden" :active-value="false" :inactive-value="true" class="right">
|
</el-switch>
|
<el-switch v-model="item.sortable" :active-value="true" :inactive-value="false" class="right margin-right-30">
|
</el-switch>
|
</li>
|
</transition-group>
|
</draggable>
|
</el-scrollbar>
|
|
<span slot="footer" class="dialog-footer">
|
<template v-if="isCustomField">
|
<span>字段排序已自定义</span>
|
<el-button type="text" @click="resetTableConfig">点击还原默认</el-button>
|
</template>
|
<el-button @click="showSetDialog = false">取 消</el-button>
|
<el-button type="primary" icon="el-icon-yrt-baocun" @click="saveTableConfig">确 定</el-button>
|
</span>
|
</el-dialog>
|
|
<!-- 批量导入对话框 -->
|
<import-dialog :options="batchImport.options" :visible.sync="batchImport.visible"></import-dialog>
|
|
<!-- 批量导出对话框 -->
|
<export-dialog ref="export-dialog" :options="batchExport.options" :visible.sync="batchExport.visible" :export-data="exportData">
|
<template slot="export-module-list">
|
<slot name="export-module-list">
|
</slot>
|
</template>
|
</export-dialog>
|
|
<!--显示字段属性-->
|
<table-info-dialog :visible.sync="showAttrDialog" :data-options="dataOptions" :fields="fields">
|
</table-info-dialog>
|
</div>
|
</template>
|
|
<script>
|
import draggable from 'vuedraggable'
|
import emitter from '@/components/common/emitter.mixin.js'
|
import ImportDialog from './components/import-dialog'
|
import ExportDialog from './components/export-dialog'
|
import TabsNav from './components/tabs-nav'
|
import DataListToolbar from './components/data-list-toolbar'
|
import { tableFooterScroll } from '@/directive/tableFooterScroll.js'
|
// var moment = require("moment");
|
import TableInfoDialog from './components/table-info-dialog'
|
|
export default {
|
name: 'data-list',
|
components: {
|
draggable,
|
ImportDialog,
|
ExportDialog,
|
TabsNav,
|
DataListToolbar,
|
TableInfoDialog
|
},
|
directives: {
|
tableFooterScroll
|
},
|
mixins: [emitter],
|
props: {
|
// 数据加载地址
|
loadUrl: {
|
type: String,
|
default: '/api/common/loadDataList'
|
},
|
// 默认数据
|
data: {
|
type: Array,
|
default: () => []
|
},
|
// 字段定义
|
fields: {
|
type: Array,
|
required: true,
|
default: () => []
|
},
|
// 按钮定义
|
buttons: {
|
type: Array,
|
required: false,
|
default: () => []
|
},
|
// 按钮点击事件
|
buttonClick: {
|
type: Function,
|
required: false,
|
default: null
|
},
|
// 数据参数
|
dataOptions: {
|
type: Object,
|
default: () => {}
|
},
|
// 操作列自定义
|
actionField: {
|
type: Object,
|
default: null
|
},
|
// 选中项
|
dataListSelections: {
|
type: Array,
|
required: true,
|
default: () => []
|
},
|
// 编辑器ref名
|
editorRef: {
|
type: String,
|
default: 'editor-dialog'
|
},
|
// 固定条件
|
fixedWhere: {
|
type: Object,
|
default: null
|
},
|
// 权限集合
|
authNodes: {
|
type: Object,
|
required: true,
|
default: () => {}
|
},
|
// 按钮是否可用
|
btnReadOnly: {
|
type: Object,
|
required: false,
|
default: () => {
|
return {
|
save: false,
|
auditing: false,
|
add: false,
|
delete: false,
|
stop: false,
|
open: false
|
}
|
}
|
},
|
// 删除前事件
|
onDeleteBefore: {
|
type: Function,
|
default: () => {
|
return true
|
}
|
},
|
// 终止前事件
|
onStopBefore: {
|
type: Function,
|
default: () => {
|
return true
|
}
|
},
|
// 打开页面默认时加载数据
|
isInitLoad: {
|
type: Boolean,
|
default: () => {
|
return true
|
}
|
},
|
// tab导航数据结构
|
tabNavList: {
|
type: Array,
|
default: () => {
|
return []
|
}
|
},
|
// 快捷查询扩展条件集合
|
quickSearchFields: {
|
type: Array,
|
default: () => {
|
return []
|
}
|
},
|
// 右侧搜索宽度
|
rightWidth: {
|
type: Number,
|
default: () => {
|
return 380
|
}
|
},
|
// 加载数据前事件
|
loadDataBefore: {
|
type: Function,
|
default: () => {
|
return true
|
}
|
},
|
// 批量申请事件
|
onBatchAuditingBefore: {
|
type: Function,
|
default: () => {
|
return () => {
|
return true
|
}
|
}
|
},
|
// 表格最大高度
|
maxHeight: {
|
type: [String, Number],
|
default: 700
|
},
|
// 数据转换
|
onTranslate: {
|
type: Function,
|
default: () => {
|
return () => {
|
return true
|
}
|
}
|
},
|
// 行样式
|
rowStyle: {
|
type: Function,
|
default: () => {
|
return () => {
|
return ''
|
}
|
}
|
},
|
// 单元格样式
|
cellStyle: {
|
type: Function,
|
default: () => {
|
return () => {
|
return ''
|
}
|
}
|
},
|
// 开启展开
|
openExpand: {
|
type: Boolean,
|
default: () => {
|
return false
|
}
|
}
|
},
|
data() {
|
return {
|
drag: false,
|
targetElement: null,
|
// 可以显示字段
|
showFields: this.fields.map(v => {
|
return !v.hidden && v.label
|
}),
|
// 显示设置对话框
|
showSetDialog: false,
|
// 数据集合
|
dataList: [],
|
// 加载数据初始化loading
|
initLoading: false,
|
// 刷新数据
|
refreshLoading: false,
|
// 初始化加载完成
|
isLoadFinished: false,
|
// 下拉框数据集合
|
dropdownData: {},
|
// 下拉框是否已加载
|
dropdownLoaded: false,
|
// 高级查询字段
|
searchFields: [],
|
// 操作列默认定义
|
actionFieldDefault: {
|
prop: '_action',
|
label: '操作',
|
width: '100',
|
headerAlign: 'center',
|
align: 'center',
|
action: [
|
{
|
type: 'button',
|
action: 'edit',
|
label: '编辑'
|
},
|
{
|
type: 'button',
|
action: 'delete',
|
label: '删除'
|
}
|
],
|
hidden: false
|
},
|
// 显示批量导入对话框参数
|
batchImport: {
|
visible: false,
|
label: '批量导入',
|
options: {
|
url: '/api/common/uploadSingleFile',
|
importInfo_Id: 0
|
}
|
},
|
// 显示批量导出对话框参数
|
batchExport: {
|
visible: false,
|
label: '批量导出',
|
options: {
|
exportInfo_Id: 0
|
}
|
},
|
// 显示字段属性对话框
|
showAttrDialog: false,
|
// 查询关键词
|
quickSearchValue: '',
|
// 查询类别
|
quickSearchType: '精确',
|
// tabNav 查询条件
|
tabNavWhere: {}
|
}
|
},
|
computed: {
|
// 可用字段
|
currentFields: {
|
get: function() {
|
var _fields = [...this.fields]
|
var _index = _fields.findIndex((item, index, arr) => {
|
return item.prop === '_action'
|
})
|
if (_index < 0 && this.dataOptions.showActionField) {
|
if (this.actionField) {
|
_fields.push(this.actionField)
|
} else {
|
_fields.push(this.actionFieldDefault)
|
}
|
}
|
return _fields
|
},
|
set: function(newValue) {
|
this.$emit('update:fields', newValue) // 双向绑定prop.action,通知父级组件变量值同步更新
|
}
|
},
|
// 快速查询
|
quickSearch: function() {
|
var quick = {
|
fields: this.fields
|
.filter(item => {
|
return item.isQuickSearch === true
|
})
|
.map(v => {
|
var item = {
|
prop: v.prop,
|
label: v.label,
|
type: v.type
|
}
|
return item
|
}),
|
placeholder: this.getQuickSearchPlaceolder(),
|
type: '精确'
|
}
|
return quick
|
},
|
// 选中items
|
currentDataListSelections: {
|
get: function() {
|
return this.dataListSelections
|
},
|
set: function(val) {
|
this.$emit('update:dataListSelections', val)
|
}
|
},
|
// 排序是否自定义
|
isCustomField: function() {
|
var router = this.$route.fullPath
|
var key = 'tableConfig_' + router
|
var fields = localStorage.getItem(key)
|
return !!fields
|
}
|
},
|
watch: {
|
fields: {
|
handler(val) {
|
// if (this.searchFields.length) {
|
// return;
|
// }
|
// 获得已经设置查询条件
|
var fields = this.fields.filter(item => {
|
return item.prop !== '_action'
|
})
|
// 如果没有设置条件,默认显示所有字段
|
if (!fields.length) {
|
fields = this.fields.filter(item => {
|
return item.prop !== '_action'
|
})
|
}
|
fields = fields.map(v => {
|
var operator = '='
|
if (v.type === 'select' || v.type === 'tree' || v.type === 'radio') {
|
operator = '='
|
}
|
var item = {
|
prop: v.prop,
|
keyProp: v.keyProp,
|
label: v.label,
|
dataType: v.dataType,
|
type: v.type,
|
options: v.options,
|
operator: operator,
|
value: null,
|
dropdown_Id: v.dropdown_Id,
|
searchRowNo: v.searchRowNo,
|
multiple: v.multiple,
|
filterable: v.filterable,
|
isExpandField: v.isExpandField
|
}
|
if (v.type === 'tree') {
|
item.ajaxParams = v.ajaxParams
|
item.onlySelectLeaf = v.onlySelectLeaf
|
}
|
return item
|
})
|
this.searchFields = fields
|
},
|
deep: true
|
}
|
},
|
created() {
|
// this.loadData();
|
// this.loadDropDown(); // 加载下拉框值
|
},
|
methods: {
|
// 表格头部定义显示
|
renderHeader(createElement, { column, _self }) {
|
var _showCols = this.currentFields.filter(item => {
|
var isShow = false
|
if (item.prop === '_action') {
|
isShow = !item.hidden && this.dataOptions.showActionField
|
} else {
|
isShow = !item.hidden
|
}
|
return isShow
|
})
|
var _findLastCol = _showCols.find((item, index, arr) => {
|
return item.label === column.label && index === _showCols.length - 1
|
})
|
if (_findLastCol) {
|
return (
|
<span class="table-op-col">
|
<span class="prop">{column.label}</span>
|
<span
|
class="set"
|
on-click={() => {
|
this.showSetDialog = true
|
}}
|
>
|
设置
|
</span>
|
</span>
|
)
|
} else {
|
var fieldInfo = _showCols.find((item, index, arr) => {
|
return item.label === column.label
|
})
|
if (fieldInfo && fieldInfo.remark) {
|
return (
|
<span>
|
<span>{column.label}</span>
|
<el-tooltip class="item" effect="dark" placement="top">
|
<span slot="content">
|
<pre style="margin:0px;">{fieldInfo.remark}</pre>
|
</span>
|
<i class="el-icon-question margin-left-5" />
|
</el-tooltip>
|
</span>
|
)
|
} else if (column.label === '#') {
|
return (
|
<span
|
on-click={() => {
|
this.showAttrDialog = true
|
}}
|
>
|
{column.label}
|
</span>
|
)
|
} else {
|
return <span>{column.label}</span>
|
}
|
}
|
},
|
// 保存表格列参数设置
|
saveTableConfig() {
|
this.showSetDialog = false
|
var json = JSON.stringify(this.currentFields)
|
var router = this.$route.fullPath
|
var key = 'tableConfig_' + router
|
localStorage.setItem(key, json)
|
this.$message.success('保存成功!')
|
},
|
// 还原表格列参数设置
|
resetTableConfig() {
|
this.showSetDialog = false
|
var router = this.$route.fullPath
|
var key = 'tableConfig_' + router
|
localStorage.removeItem(key)
|
this.$message.success('还原成功,请刷新页面!')
|
},
|
// 获得高级查询条件
|
getWhere() {
|
// 将自定义查询条件合并到高级查询中
|
let fields = this.searchFields
|
.filter(item => {
|
let result = false
|
if (Array.isArray(item.value)) {
|
result = item.value.length > 0 || item.fromValue || item.toValue
|
} else if (item.operator === 'null') {
|
result = true
|
} else {
|
result = item.value || item.fromValue || item.toValue
|
}
|
return result
|
})
|
.map(item => {
|
let val = item.value
|
if (item.operator === 'in') {
|
val = val.replace(/\r/gi, '').split('\n')
|
}
|
const data = {
|
dataType: item.dataType,
|
label: item.label,
|
prop: item.keyProp || item.prop,
|
operator: item.operator,
|
value: val
|
}
|
// 扩展字段
|
if (item.isExpandField) {
|
data.prop = 'expandFields'
|
data.operator = 'like'
|
}
|
if (item.fromValue !== null && item.fromValue !== undefined) {
|
data.fromValue = item.fromValue
|
}
|
if (item.toValue) {
|
data.toValue = item.toValue
|
}
|
return data
|
})
|
|
this.quickSearchFields.forEach(item => {
|
if (!item.value || (Array.isArray(item.value) && !item.value.length)) {
|
return
|
}
|
|
if (typeof item.getWhere === 'function') {
|
const where = item.getWhere(item.value, this.$parent)
|
if (Array.isArray(where)) {
|
fields = fields.contact(where)
|
} else if (where) {
|
const existItem = fields.find(item => item.prop === where.prop)
|
if (existItem) {
|
existItem.value += ' AND ' + where.value
|
} else {
|
fields.push(where)
|
}
|
}
|
} else {
|
fields.push(item)
|
}
|
})
|
|
return fields
|
},
|
// 获得快速查询条件
|
getQuickWhere(type) {
|
let where = []
|
if (!this.quickSearch.fields.length) {
|
if (type === 'quick') {
|
this.$message.error('未设置快速查询字段!')
|
}
|
return where
|
}
|
// 快速查询
|
if (this.quickSearchValue && this.quickSearch.fields.length) {
|
const val = this.quickSearchValue
|
.trim()
|
.replace(/\r|'|=| /gi, '')
|
.replace(/\n/gi, ',')
|
const valList = val.split(/,|,|、/)
|
where = this.quickSearch.fields.map((item, index, arr) => {
|
const data = {
|
dataType: item.dataType,
|
label: item.label,
|
prop: item.prop,
|
value: valList
|
}
|
return data
|
})
|
|
let operator = '='
|
if (this.quickSearchType === '模糊') {
|
operator = 'like'
|
}
|
|
where = [
|
{
|
prop: '__quickSearch__',
|
operator: operator,
|
where: where
|
}
|
]
|
}
|
|
return where
|
},
|
// 获取全部查询条件
|
getAllWhere() {
|
// 高级查询条件
|
var where = this.getWhere()
|
// 合并快速查询条件
|
var quitWhere = this.getQuickWhere()
|
where = where.concat(quitWhere)
|
// 合并tabNav查询条件
|
if (Object.keys(this.tabNavWhere).length) {
|
where = where.concat(this.tabNavWhere)
|
}
|
return where
|
},
|
// 获得快速查询字段提示Placeholder
|
getQuickSearchPlaceolder() {
|
let label = ''
|
this.fields
|
.filter(item => {
|
return item.isQuickSearch === true
|
})
|
.forEach(v => {
|
if (label) label += '/'
|
label += v.label
|
})
|
if (!label) label = '没用可用查询字段'
|
else label = '请输入' + label
|
return label
|
},
|
// 加载数据
|
loadData(type) {
|
const where = this.getAllWhere()
|
this.reloadData(where)
|
},
|
// 重新加载数据
|
reloadData(where) {
|
if (this.fixedWhere) {
|
this.dataOptions.fixedWhere = this.fixedWhere
|
}
|
var sumColumnNames = this.fields
|
.filter(item => {
|
return item.isSum
|
})
|
.map(item => {
|
return item.prop
|
})
|
.join(',')
|
if (!this.dataOptions || !this.dataOptions.tableView) {
|
return
|
}
|
var params = Object.assign({}, this.dataOptions, {
|
tableName: this.dataOptions.tableView,
|
where: where,
|
pageIndex: this.dataOptions.pageIndex,
|
pageSize: this.dataOptions.pageSize,
|
sumColumnNames: sumColumnNames
|
})
|
// 加载前事件
|
if (this.loadDataBefore(params, this.searchFields) === false) {
|
return
|
}
|
|
this.initLoading = true
|
this.refreshLoading = true
|
this.common.ajax(
|
this.loadUrl,
|
params,
|
res => {
|
res = this.common.objectToCase(res)
|
this.common.showMsg(res)
|
if (res.result) {
|
this.dataList = res.data.rows
|
this.translate(this.dataList) // 内部默认数据转换
|
this.onTranslate(this.dataList) // 自定义数据转换事件
|
this.dataOptions.total = res.data.total
|
this.dataOptions.footerRows = res.data.footer
|
}
|
this.initLoading = false
|
this.refreshLoading = false
|
this.isLoadFinished = true
|
this.$emit('on-load-data-after', this.dataList)
|
},
|
false
|
)
|
},
|
// 重新加载数据
|
reload() {
|
this.loadData()
|
},
|
// 数据转换
|
translate(rows) {
|
for (const row of rows) {
|
this.fields.forEach(field => {
|
var prop = field.prop
|
if (field.dataType === 'date') {
|
const v = row[prop]
|
if (v) {
|
let formatter = 'yyyy-MM-dd'
|
if (field.formatter) formatter = field.formatter
|
row[prop] = this.common.formatDate(v, formatter)
|
}
|
} else if (field.dataType === 'datetime') {
|
const v = row[prop]
|
if (v) {
|
let formatter = 'yyyy-MM-dd HH:mm:ss'
|
if (field.formatter) formatter = field.formatter
|
row[prop] = this.common.formatDate(v, formatter)
|
}
|
} else if (field.dataType === 'decimal') {
|
const v = row[prop]
|
row[prop] = Math.Round(v, 4) // 保留两位小数
|
} else {
|
const v = row[prop]
|
if (Array.isArray(v)) {
|
row[prop] = v.join('/')
|
}
|
}
|
})
|
}
|
},
|
// 行数据操作事件
|
onRowActionClick(btnInfo, colInfo, rowData) {
|
const id = rowData[this.dataOptions.idField]
|
let result = null
|
if (btnInfo.onClick) {
|
result = btnInfo.onClick(btnInfo, rowData, colInfo, this.$parent)
|
}
|
if (result !== undefined && result !== null) {
|
return
|
}
|
switch (btnInfo.action) {
|
case 'edit':
|
var ref = this.findRef(this.editorRef)
|
ref.editData(id, rowData)
|
break
|
case 'delete':
|
this.delete([rowData])
|
break
|
case 'batchStop':
|
this.batchStop([rowData])
|
break
|
default:
|
this.$message.warning('未定义行数据操作事件')
|
break
|
}
|
},
|
// 删除数据
|
delete(rows) {
|
// 删除前事件
|
const reValue = this.onDeleteBefore(rows)
|
if (reValue === false) return
|
|
let isAuditing = false
|
if (Array.isArray(rows)) {
|
rows.forEach((item, index, Array) => {
|
if (item.auditing === 2) {
|
this.$message.error('已审核的数据不允许删除')
|
isAuditing = true
|
}
|
})
|
}
|
if (isAuditing) return
|
|
var deletedIDs = rows
|
if (Array.isArray(rows)) {
|
deletedIDs = rows.map((item, index, Array) => {
|
return item[this.dataOptions.idField]
|
})
|
} else {
|
this.$message.error('删除数据无效!')
|
return
|
}
|
if (!deletedIDs.length) {
|
this.$message.error('至少选择一项进行删除操作')
|
return
|
}
|
|
this.$confirm('此操作将永久删除选中的数据, 是否继续?', '删除操作', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(() => {
|
_delete()
|
})
|
.catch(() => {
|
this.$message.info('已取消删除')
|
})
|
|
const _delete = () => {
|
var deletedIDs = rows
|
if (Array.isArray(rows)) {
|
deletedIDs = rows
|
.map((item, index, Array) => {
|
return item[this.dataOptions.idField]
|
})
|
.join(',')
|
} else {
|
this.$message.error('删除数据无效!')
|
return
|
}
|
if (!deletedIDs) deletedIDs = '0'
|
|
var url = '/api/common/deleteData'
|
this.initLoading = true
|
var params = Object.assign({}, this.dataOptions, {
|
tableName: this.dataOptions.tableView,
|
deletedIDs: deletedIDs
|
})
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
if (res.result) {
|
this.loadData()
|
// 触发删除后事件
|
this.$emit('on-delete-after', rows)
|
}
|
this.initLoading = false
|
},
|
false
|
)
|
}
|
},
|
// 批量导入对话框
|
importDialog(btnOpts) {
|
this.batchImport.visible = true
|
this.batchImport.label = btnOpts.label
|
this.batchImport.options = btnOpts.options
|
},
|
// 批量导出对话框
|
exportDialog(btnOpts) {
|
this.batchExport.visible = true
|
this.batchExport.label = btnOpts.label
|
this.batchExport.options = btnOpts.options
|
// 初始化模板
|
this.$nextTick(() => {
|
this.$refs['export-dialog'].getTemplateList()
|
})
|
},
|
// 批量导出
|
exportData(exportInfo_Id, vueData_Id) {
|
const idValues = []
|
this.dataListSelections.forEach(rowData => {
|
idValues.push(rowData[this.dataOptions.idField])
|
})
|
var where = this.getAllWhere()
|
if (idValues.length) {
|
where.push({
|
prop: this.dataOptions.idField,
|
value: idValues
|
})
|
}
|
// 导出模板数据
|
var url = '/api/sys/export/exportDataVue'
|
var tableName = this.dataOptions.tableName || this.dataOptions.tableView
|
var params = Object.assign({}, this.dataOptions, {
|
tableName: tableName,
|
where: where,
|
exportInfo_Id: exportInfo_Id,
|
vueData_Id: vueData_Id
|
})
|
this.initLoading = true
|
var callback = res => {
|
if (res.msg) {
|
this.$alert(res.msg, '导出提示', {
|
confirmButtonText: '关闭',
|
callback: action => {}
|
})
|
}
|
if (res.result) {
|
const url = this.common.domain + '/api/common/download?url=' + res.data.url
|
window.open(url)
|
}
|
this.initLoading = false
|
}
|
this.common.ajax(url, params, callback, true)
|
},
|
// 批量打印
|
print() {
|
var ids = []
|
this.dataListSelections.forEach(item => {
|
ids.push(item[this.dataOptions.idField])
|
})
|
if (!ids.length) {
|
this.$message.error('至少选择一项!')
|
return
|
}
|
|
var params = Object.assign({}, this.dataOptions)
|
// 明细参数处理
|
var ref = this.findRef(this.editorRef)
|
params.detailList = ref.detailFields.map(item => {
|
const newItem = {
|
tableName: item.subTableView,
|
pageIndex: item.options.pageIndex,
|
pageSize: item.options.pageSize,
|
idField: item.options.idField,
|
orderBy: item.options.orderBy
|
}
|
if (item.options.showSumField) {
|
newItem.sumColumnNames = item.options.sumColumnNames
|
}
|
return newItem
|
})
|
const key = this.common.getGUID()
|
sessionStorage[key] = JSON.stringify(params)
|
var menu_Id = this.dataOptions.menu_Id
|
window.open('/#/print/base/' + menu_Id + '/' + ids.join(',') + '?key=' + key)
|
},
|
// 批量开启
|
batchOpen(rows) {
|
this.$confirm('确定要批量进行开启操作吗, 是否继续?', '开启操作', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(() => {
|
_batchOpen()
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消开启'
|
})
|
})
|
|
const _batchOpen = () => {
|
var OpenIds = rows
|
if (Array.isArray(rows)) {
|
OpenIds = rows.map((item, index, Array) => {
|
return item[this.dataOptions.idField]
|
})
|
}
|
if (!OpenIds) OpenIds = '0'
|
var url = '/api/common/open'
|
this.initLoading = true
|
var params = Object.assign({}, this.dataOptions, {
|
openNodeApi: true,
|
modelName: this.dataOptions.tableView,
|
idValues: OpenIds
|
})
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
if (res.result) {
|
this.loadData()
|
}
|
this.initLoading = false
|
},
|
false
|
)
|
}
|
},
|
// 批量终止
|
batchStop(rows) {
|
// 终止前事件
|
const reValue = this.onStopBefore(rows)
|
if (reValue === false) return
|
|
this.$confirm('终止后将清除现有占位,确定操作吗, 是否继续?', '终止操作', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(() => {
|
_batchStop()
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消终止'
|
})
|
})
|
|
const _batchStop = () => {
|
var stopIDs = rows
|
if (Array.isArray(rows)) {
|
stopIDs = rows.map((item, index, Array) => {
|
return item[this.dataOptions.idField]
|
})
|
}
|
if (!stopIDs) stopIDs = '0'
|
var url = '/api/common/stop'
|
this.initLoading = true
|
var params = Object.assign({}, this.dataOptions, {
|
modelName: this.dataOptions.tableView,
|
idValues: stopIDs
|
})
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
if (res.result) {
|
this.loadData()
|
}
|
this.initLoading = false
|
},
|
false
|
)
|
}
|
},
|
// 审核,这里默认调用批量审核
|
batchAuditing(rows) {
|
if (!rows.length) {
|
this.$message.error('至少选择一行')
|
return
|
}
|
if (this.onBatchAuditingBefore(rows) === false) {
|
return
|
} else {
|
for (const row of rows) {
|
if (row.auditing === 2) {
|
this.$message.error('已审核的单子不允许重复审核')
|
return
|
}
|
}
|
}
|
|
this.$confirm('确定要批量进行审核操作吗,审核后将无法进行修改, 是否继续?', '审核操作', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
.then(() => {
|
_batchAuditing()
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消审核'
|
})
|
})
|
|
const _batchAuditing = () => {
|
var AuditIDs = rows
|
if (Array.isArray(rows)) {
|
AuditIDs = rows.map((item, index, Array) => {
|
return item[this.dataOptions.idField]
|
})
|
}
|
var url = '/api/common/batchAuditing'
|
this.initLoading = true
|
var params = Object.assign({}, this.dataOptions, {
|
DBServer: 'Sys',
|
modelName: this.dataOptions.tableView,
|
tableView: this.dataOptions.tableView,
|
auditing: 2,
|
idField: this.dataOptions.idField,
|
idValues: AuditIDs
|
})
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
if (res.result) {
|
this.loadData()
|
}
|
this.initLoading = false
|
},
|
false
|
)
|
}
|
},
|
// 选择items
|
handleSelectionChange(val) {
|
this.currentDataListSelections = val
|
},
|
// 分页大小改变
|
handleSizeChange(val) {
|
this.dataOptions.pageSize = val
|
this.loadData()
|
},
|
// 当前页码大小改变
|
handleCurrentChange(val) {
|
this.dataOptions.pageIndex = val
|
this.loadData()
|
},
|
// 列表字段显示顺序移动
|
fielSetMove(evt) {
|
this.targetElement = evt.relatedContext.element
|
},
|
endDrag: function() {
|
this.targetElement = null
|
this.drag = false
|
},
|
startDrag: function() {
|
this.targetElement = null
|
this.drag = true
|
},
|
// 加载下拉框数据
|
loadDropDown(refresh) {
|
if (this.dropdownLoaded && !refresh) return // 已加载下拉框不在重复加载
|
|
// 获得下拉框ID
|
var ddIDs = []
|
var _getDropDownId = array => {
|
array.forEach(item => {
|
if (Array.isArray(item)) {
|
_getDropDownId(item)
|
} else {
|
if (item.options && item.options.dropdown_Id > 0) {
|
ddIDs.push(item.options.dropdown_Id)
|
} else if (item.dropdown_Id) {
|
ddIDs.push(item.dropdown_Id)
|
}
|
}
|
})
|
}
|
_getDropDownId(this.currentFields)
|
if (!ddIDs.length) {
|
this.dropdownLoaded = true
|
// 打开页面时加载默认数据
|
if (this.isInitLoad) {
|
this.loadData()
|
}
|
return
|
}
|
|
this.initLoading = true
|
var url = '/api/common/loadDropDown'
|
var params = Object.assign({}, this.dataOptions, {
|
where: ddIDs.join(','),
|
data: JSON.stringify(this.formData)
|
})
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
if (res.result) {
|
this.dropdownLoaded = true // 记录已加载下拉框数据
|
this.dropdownData = res.data
|
}
|
this.initLoading = false
|
// 打开页面时加载默认数据
|
if (this.isInitLoad) {
|
this.loadData()
|
}
|
this.$emit('on-load-dropdown-after', this.dropdownData)
|
},
|
false
|
)
|
},
|
// 重新加载下拉框数据
|
reLoadDropDown() {
|
this.dropdownLoaded = false
|
this.loadDropDown()
|
},
|
// 获得下拉框值
|
getDropDownData(dropdown_Id) {
|
var ddList = this.dropdownData['dropdown' + dropdown_Id]
|
return ddList
|
},
|
// 翻译下拉框值
|
translateText(prop, val, dropdown_Id, col) {
|
if (col && col.options) {
|
if (col.options.remote === 'bindDropdown') {
|
const _dropdown_Id = col.options.dropdown_Id
|
if (_dropdown_Id > 0) {
|
dropdown_Id = _dropdown_Id
|
}
|
const ddList = this.dropdownData['dropdown' + dropdown_Id]
|
if (!ddList) return val
|
const item = ddList.find((item, index, arr) => {
|
return item.value === val
|
})
|
if (!item) return val
|
return item.label
|
} else if (col.options.remote === false) {
|
const ddList = col.options.options
|
if (!ddList) return val
|
const item = ddList.find((item, index, arr) => {
|
return item.value === val
|
})
|
if (!item) return val
|
return item.label
|
} else {
|
return val
|
}
|
} else {
|
const ddList = this.dropdownData['dropdown' + dropdown_Id]
|
if (!ddList) return val
|
const item = ddList.find((item, index, arr) => {
|
return item.value === val
|
})
|
if (!item) return val
|
return item.label
|
}
|
},
|
// 连接弹出对话框编辑器
|
linkEditor(id, rowData) {
|
var ref = this.findRef(this.editorRef)
|
ref.editData(id, rowData)
|
},
|
// 获取查询条件
|
getSearchFields() {
|
return this.searchFields
|
},
|
// 计算求和
|
getSummaries({ columns, data }) {
|
const sums = []
|
// 求和字段
|
var sumColumnNames = this.fields
|
.filter(item => {
|
return item.isSum
|
})
|
.map(item => {
|
return item.prop
|
})
|
|
sums[0] = '合计'
|
sums[1] = ''
|
this.fields
|
.filter(item => {
|
return !item.hidden
|
})
|
.forEach((field, index) => {
|
var footerRows = this.dataOptions.footerRows
|
if (sumColumnNames.indexOf(field.prop) >= 0 && footerRows && footerRows.length) {
|
var footerRow = footerRows[0]
|
sums[index + 2] = footerRow[field.prop]
|
} else {
|
sums[index + 2] = ''
|
}
|
})
|
|
return sums
|
},
|
// tabnav导航筛选条件改变
|
onTabsNavChange(where) {
|
this.tabNavWhere = where
|
this.reload()
|
},
|
// 表头单击事件
|
headerClick(column, event) {
|
if (event.target && event.target.innerText === '#') {
|
this.showAttrDialog = true
|
}
|
},
|
// 添加高级查询条件
|
addSearchFields(addList) {
|
// var addList= [{propName:"",value:""},{propName:"",value:""}];
|
addList.forEach(item => {
|
const fieldInfo = this.searchFields.find(f => {
|
return f.prop === item.propName
|
})
|
if (fieldInfo) {
|
fieldInfo.value = item.value
|
}
|
})
|
},
|
// 重置查询条件
|
onSuperReset() {
|
// 重置导航查询条件
|
this.tabNavWhere = {}
|
this.tabNavList.forEach(item => {
|
item.value = null
|
item._value = null
|
})
|
// 重置事件
|
this.$emit('on-super-reset')
|
},
|
// 获得是否加载完毕
|
getLoadFinished() {
|
return this.isLoadFinished
|
},
|
// 排序
|
sortChange({ column, prop, order }) {
|
this.dataOptions.orderBy = {}
|
order = order === 'ascending' ? 'ASC' : 'DESC'
|
this.dataOptions.orderBy[prop] = order
|
this.reload()
|
},
|
// 展开子集
|
expandChange(row, expandedRows) {
|
this.$emit('on-expand-change', row, expandedRows)
|
},
|
// 目的是让列表页面重新渲染一下
|
setCurrentRow() {
|
if (this.dataList.length) {
|
this.$refs.dataList.setCurrentRow(this.dataList[0])
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.datalist-container {
|
background-color: white;
|
border-radius: 4px;
|
padding: 10px;
|
|
.search-region {
|
.tool-left {
|
.tool-group + .tool-group {
|
margin-left: 10px;
|
}
|
.el-button--medium {
|
padding: 10px 10px;
|
}
|
}
|
.tool-right {
|
text-align: right;
|
.search-input {
|
width: calc(100% - 80px);
|
max-width: 300px;
|
.search-btn {
|
padding: 10px;
|
}
|
}
|
.show-supper-searcher {
|
margin-left: 10px;
|
}
|
.popup-right {
|
text-align: left;
|
line-height: 1.2;
|
z-index: 10;
|
.header {
|
background-color: #f6f6f6;
|
padding: 10px;
|
}
|
.main {
|
background-color: #fff;
|
padding: 0;
|
min-height: 400px;
|
/deep/ .el-scrollbar {
|
height: 395px;
|
}
|
/deep/ .scrollbar-wrap {
|
max-height: 410px;
|
overflow-x: hidden;
|
.el-form {
|
padding: 10px;
|
.el-form-item {
|
margin-bottom: 10px;
|
}
|
}
|
}
|
}
|
.footer {
|
background-color: #f6f6f6;
|
padding: 10px;
|
overflow: hidden;
|
}
|
}
|
}
|
/deep/ .el-form-item__content {
|
position: static;
|
}
|
}
|
|
.table-region {
|
z-index: 0;
|
/* begin 解决合计滚动条问题 */
|
// overflow: auto;
|
// &::after {
|
// position: relative;
|
// }
|
// /deep/ .el-table__header-wrapper,
|
// /deep/ .el-table__body-wrapper,
|
// /deep/ .el-table__footer-wrapper {
|
// overflow: visible;
|
// }
|
/* end 解决合计滚动条问题 */
|
|
/deep/ .cell {
|
line-height: 20px;
|
padding-left: 2px;
|
padding-right: 2px;
|
}
|
.el-button--mini {
|
padding: 2px 0;
|
}
|
/deep/ .el-button--medium {
|
padding: 2px 0px;
|
}
|
/deep/ td {
|
padding: 5px 0;
|
}
|
}
|
}
|
|
/* el-popover列是否显示设置 */
|
.table-op-col {
|
.set {
|
color: #0465a8;
|
cursor: pointer;
|
display: inline-block;
|
margin-left: 20px;
|
}
|
}
|
.col-set-group {
|
padding-bottom: 30px;
|
.col-set-item {
|
width: 50%;
|
padding-top: 15px;
|
}
|
.el-checkbox + .el-checkbox {
|
margin-left: 0;
|
}
|
}
|
.col-set-footer {
|
padding: 20px 0px 10px;
|
text-align: right;
|
border-top: 1px solid #e4e7ed;
|
}
|
|
/* ********************************************** */
|
.show-set-dialog {
|
/deep/ .el-dialog__body {
|
padding: 10px 20px;
|
}
|
/deep/ .scrollbar-wrap {
|
max-height: 400px;
|
}
|
.alert-msg {
|
margin-bottom: 10px;
|
}
|
|
.draggable-main {
|
margin: 0;
|
padding: 0;
|
li.item {
|
border: 1px solid #f8f8f8;
|
padding: 10px;
|
margin: 1px;
|
background-color: #f3f3f3;
|
&.over {
|
background-color: #fff;
|
}
|
&.chosen-item {
|
border: 1px dotted rgb(44, 104, 163);
|
background-color: #409eff;
|
color: white;
|
.handle {
|
color: white;
|
}
|
}
|
.handle {
|
cursor: move;
|
color: rgb(70, 70, 71);
|
}
|
}
|
}
|
}
|
|
.list-complete-enter-active {
|
overflow: hidden;
|
transition: all 1s;
|
}
|
|
.list-complete-leave-active {
|
margin-top: 0px;
|
overflow: hidden;
|
transition: all 1s;
|
}
|
|
.list-complete-enter,
|
.list-complete-leave-to {
|
height: 0px;
|
opacity: 0;
|
padding: 0px;
|
margin-top: 0px;
|
overflow: hidden;
|
}
|
</style>
|