rt-sim-training-client/src/components/QueryListPage/QueryForm.vue

488 lines
16 KiB
Vue
Raw Normal View History

2019-07-02 16:29:52 +08:00
<template>
<div class="query-form-main-custom" style="margin-bottom: 10px;">
<el-card>
<el-form
ref="queryForm"
:model="formModel"
:label-position="queryForm.labelPosition"
:label-width="queryForm.labelWidth"
size="small"
style="padding-top: 18px;"
>
<el-row>
<el-col :span="18">
<template v-for="(colNum, rIndex) in rowColumnList">
<el-row :key="rIndex" :gutter="20">
<template v-for="(field, name, index) in queryObject">
<template v-if="checkColumnIndex(rIndex, index)">
<el-col :key="index" :span="24/columnNum*field.columnNeed">
<template v-if="checkFieldType(field, 'text', name)">
<el-form-item :prop="name" :label="field.label">
<el-input
v-model="formModel[name]"
type="text"
clearable
:placeholder="field.placeholder"
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'date', name)">
<el-form-item :prop="name" :label="field.label">
<el-date-picker
v-model="formModel[name]"
type="date"
:value-format="field.valueFormat || 'yyyy-MM-dd'"
2019-08-29 17:16:33 +08:00
:placeholder="field.placeholder || $t('global.chooseDate')"
2019-07-02 16:29:52 +08:00
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'daterange', name)">
<el-form-item :prop="name" :label="field.label">
<el-date-picker
v-model="formModel[name]"
type="daterange"
:value-format="field.valueFormat || 'yyyy-MM-dd'"
2019-08-29 17:16:33 +08:00
:range-separator="$t('global.to')"
2019-07-02 16:29:52 +08:00
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'time', name)">
<el-form-item :prop="name" :label="field.label">
<el-time-picker
v-model="formModel[name]"
type="time"
:value-format="field.valueFormat || 'HH:mm:ss'"
2019-08-29 17:16:33 +08:00
:placeholder="field.placeholder || $t('global.chooseTime')"
2019-07-02 16:29:52 +08:00
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'timerange', name)">
<el-form-item :prop="name" :label="field.label">
<el-time-picker
v-model="formModel[name]"
type="timerange"
is-range
:value-format="field.valueFormat || 'HH:mm:ss'"
2019-08-29 17:16:33 +08:00
:range-separator="$t('global.to')"
2019-07-02 16:29:52 +08:00
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'datetime', name)">
<el-form-item :prop="name" :label="field.label">
<el-date-picker
v-model="formModel[name]"
type="datetime"
:value-format="field.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
2019-08-29 17:16:33 +08:00
:placeholder="field.placeholder || $t('global.chooseDateTime')"
2019-07-02 16:29:52 +08:00
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'datetimerange', name)">
<el-form-item :prop="name" :label="field.label">
<el-date-picker
v-model="formModel[name]"
type="datetimerange"
:value-format="field.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
2019-08-29 17:16:33 +08:00
:range-separator="$t('global.to')"
2019-07-02 16:29:52 +08:00
/>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'select', name)">
<el-form-item :prop="name" :label="field.label">
<el-select
v-if="field.show !== false"
:ref="name"
v-model="formModel[name]"
:multiple="field.config.multiple"
clearable
2019-08-29 17:16:33 +08:00
:placeholder="field.placeholder || $t('global.choose')"
2019-07-02 16:29:52 +08:00
filterable
@change="selectChange(field, formModel)"
>
<template v-if="field.config.data instanceof Array ? true : false">
<template v-for="(item, idx) in field.config.data">
<el-option :key="idx" :value="item.value" :label="item.label">{{
item.label }}</el-option>
</template>
</template>
</el-select>
</el-form-item>
</template>
<template v-else-if="checkFieldType(field, 'complete')">
<el-form-item :prop="name" :label="field.label">
<el-autocomplete
v-if="field.show !== false"
v-model="formModel[name]"
:fetch-suggestions="field.querySearchAsync"
:placeholder="field.placeholder"
:style="{width: '80%'}"
clearable
@select="field.handleSelect"
/>
</el-form-item>
</template>
</el-col>
</template>
</template>
</el-row>
</template>
</el-col>
<el-col :span="5" :offset="1">
2019-09-30 17:56:16 +08:00
<el-button class="button_style" type="primary" size="small" :disabled="!canQuery" @click="query">{{ $t('global.query') }}</el-button>
<el-button class="button_style" v-if="queryForm.reset" type="primary" size="small" :disabled="!canQuery" @click="doClean">{{ $t('global.reset') }}</el-button>
<el-button class="button_style" v-if="exportFlag" type="primary" size="small" :disabled="!canQuery" @click="doExport">{{ $t('global.export') }}</el-button>
2019-07-02 16:29:52 +08:00
<template v-for="(button, index) in queryList.actions">
<el-button
v-if="button.hasOwnProperty('show') ? button.show: true"
:key="index"
:type="button.type ? button.type: 'primary'"
size="small"
:style="button.style"
@click="button.handler"
2019-09-30 17:56:16 +08:00
class="button_style"
2019-07-02 16:29:52 +08:00
>{{ button.text }}</el-button>
</template>
</el-col>
</el-row>
</el-form>
</el-card>
</div>
</template>
<script>
2019-08-08 14:32:32 +08:00
import localStore from 'storejs';
2019-07-02 16:29:52 +08:00
export default {
name: 'QueryForm',
props: {
queryList: {
type: Object,
default: function() {
2019-08-08 14:32:32 +08:00
return { actions: [] };
2019-07-02 16:29:52 +08:00
}
},
queryForm: {
type: Object,
required: true
},
beforeQuery: {
2019-08-08 15:57:36 +08:00
type: Function,
default(val) {
return val;
}
2019-07-02 16:29:52 +08:00
},
canQuery: {
type: Boolean,
required: true
}
},
data() {
return {
columnNum: 4,
queryObject: {},
queryFlag: this.canQuery,
exportFlag: false,
resetShow: true,
formModel: {},
modelFields: [],
ossConfig: {
accessKeyId: 'LTAIuLzS7VK3mV8d',
accessKeySecret: '7F7aWIi3ymq3J7uGxs9M2c2DnfSiF3',
bucket: 'kfexcel'
}
2019-08-08 14:32:32 +08:00
};
2019-07-02 16:29:52 +08:00
},
computed: {
rowColumnList() {
const alocateColumnNum = function(field) {
2019-08-08 14:32:32 +08:00
let need = 1;
2019-07-02 16:29:52 +08:00
switch (field.type) {
case 'daterange':
2019-08-08 14:32:32 +08:00
need = 2;
break;
2019-07-02 16:29:52 +08:00
case 'timerange':
2019-08-08 14:32:32 +08:00
need = 2;
break;
2019-07-02 16:29:52 +08:00
case 'datetimerange':
2019-08-08 14:32:32 +08:00
need = 2;
break;
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
field.columnNeed = need;
return need;
};
const objNumList = [];
let tempColumnNum = 0;
let rowColumnNum = 0;
2019-07-02 16:29:52 +08:00
for (const item in this.queryObject) {
2019-08-08 14:32:32 +08:00
var colNum = alocateColumnNum(this.queryObject[item]);
tempColumnNum = tempColumnNum + colNum;
2019-07-02 16:29:52 +08:00
if (tempColumnNum > this.columnNum) {
2019-08-08 14:32:32 +08:00
objNumList.push(rowColumnNum);
rowColumnNum = 1;
tempColumnNum = colNum;
2019-07-02 16:29:52 +08:00
} else if (tempColumnNum === this.columnNum) {
2019-08-08 14:32:32 +08:00
objNumList.push(++rowColumnNum);
rowColumnNum = 0;
tempColumnNum = 0;
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
++rowColumnNum;
2019-07-02 16:29:52 +08:00
}
}
if (tempColumnNum > 0 && rowColumnNum > 0) {
2019-08-08 14:32:32 +08:00
objNumList.push(rowColumnNum);
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
return objNumList;
2019-07-02 16:29:52 +08:00
}
},
watch: {
'queryForm.queryObject': function(newVal) {
2019-08-08 14:32:32 +08:00
this.initPageData();
2019-07-02 16:29:52 +08:00
},
canQuery(newVal) {
2019-08-08 14:32:32 +08:00
this.queryFlag = newVal;
2019-07-02 16:29:52 +08:00
},
formModel: {
handler: function(form) {
if (form) {
2019-08-08 14:32:32 +08:00
localStore.set(this.$route.path, form);
2019-07-02 16:29:52 +08:00
}
},
deep: true
}
},
mounted() {
2019-08-08 14:32:32 +08:00
this.initPageData();
this.initQueryModel();
2019-07-02 16:29:52 +08:00
},
methods: {
// 获取默认查询参数
initQueryModel() {
2019-08-08 14:32:32 +08:00
this.formModel = localStore.get(this.$route.path) || this.formModel;
2019-07-02 16:29:52 +08:00
if (typeof this.queryForm.initLoadCallback === 'function') {
2019-08-08 14:32:32 +08:00
this.queryForm.initLoadCallback(this.formModel);
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
this.query();
2019-07-02 16:29:52 +08:00
},
// 初始化页面数据
initPageData() {
2019-08-08 14:32:32 +08:00
this.modelFields = [];
this.exportFlag = this.queryForm.canExport;
this.resetShow = this.queryForm.reset;
this.buildQueryField();
this.buildForm();
2019-07-02 16:29:52 +08:00
},
// 构建查询表单对象、显示的查询对象
buildForm() {
// 获取表单Field的默认值
const getDefaultValueByField = function(field) {
2019-08-08 14:32:32 +08:00
let defaultValue = '';
2019-07-02 16:29:52 +08:00
switch (field.type) {
case 'select':
if (field.config.multiple) {
2019-08-08 14:32:32 +08:00
defaultValue = [];
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
defaultValue = '';
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
break;
2019-07-02 16:29:52 +08:00
case 'daterange':
2019-08-08 14:32:32 +08:00
defaultValue = [];
break;
2019-07-02 16:29:52 +08:00
case 'timerange':
2019-08-08 14:32:32 +08:00
defaultValue = [];
break;
2019-07-02 16:29:52 +08:00
case 'datetimerange':
2019-08-08 14:32:32 +08:00
defaultValue = [];
break;
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
return defaultValue;
};
2019-07-02 16:29:52 +08:00
// 构建查询表单对象、显示的查询对象
2019-08-08 14:32:32 +08:00
const queryObject = {};
const model = {};
2019-07-02 16:29:52 +08:00
for (const item in this.queryForm.queryObject) {
if (this.queryForm.queryObject.show === false) {
2019-08-08 14:32:32 +08:00
continue;
2019-07-02 16:29:52 +08:00
} else if (this.queryForm.queryObject.visible === false) {
2019-08-08 14:32:32 +08:00
model[item] = this.queryForm.queryObject[item].value;
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
queryObject[item] = this.queryForm.queryObject[item];
model[item] = this.queryForm.queryObject[item].value || getDefaultValueByField(this.queryForm.queryObject[item]);
2019-07-02 16:29:52 +08:00
}
}
2019-08-08 14:32:32 +08:00
this.queryObject = queryObject;
this.formModel = model;
2019-07-02 16:29:52 +08:00
},
// 构建查询fieldName列表
buildQueryField() {
2019-08-08 14:32:32 +08:00
const fields = [];
2019-07-02 16:29:52 +08:00
for (const item in this.queryForm.queryObject) {
if (this.queryForm.queryObject.show === false) {
2019-08-08 14:32:32 +08:00
continue;
2019-07-02 16:29:52 +08:00
} else if (this.queryForm.queryObject.visible === false) {
2019-08-08 14:32:32 +08:00
fields.push({ field: item });
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
const type = this.queryForm.queryObject[item].type;
2019-07-02 16:29:52 +08:00
switch (type) {
case 'text':
2019-08-08 14:32:32 +08:00
fields.push({ field: item });
break;
2019-07-02 16:29:52 +08:00
case 'date':
2019-08-08 14:32:32 +08:00
fields.push({ field: item });
break;
2019-07-02 16:29:52 +08:00
case 'daterange':
2019-08-08 14:32:32 +08:00
fields.push({ field: item, subFields: this.queryForm.queryObject[item].fieldsName });
break;
2019-07-02 16:29:52 +08:00
case 'time':
2019-08-08 14:32:32 +08:00
fields.push({ field: item });
break;
2019-07-02 16:29:52 +08:00
case 'timerange':
2019-08-08 14:32:32 +08:00
fields.push({ field: item, subFields: this.queryForm.queryObject[item].fieldsName });
break;
2019-07-02 16:29:52 +08:00
case 'datetime':
2019-08-08 14:32:32 +08:00
fields.push({ field: item });
break;
2019-07-02 16:29:52 +08:00
case 'datetimerange':
2019-08-08 14:32:32 +08:00
fields.push({ field: item, subFields: this.queryForm.queryObject[item].fieldsName });
break;
2019-07-02 16:29:52 +08:00
case 'select':
2019-08-08 14:32:32 +08:00
fields.push({ field: item });
break;
2019-07-02 16:29:52 +08:00
}
}
}
2019-08-08 14:32:32 +08:00
this.modelFields = fields;
2019-07-02 16:29:52 +08:00
},
checkColumnIndex(rowIndex, objIndex) {
2019-08-08 14:32:32 +08:00
var flag = false;
2019-07-02 16:29:52 +08:00
if (rowIndex === 0) {
if (objIndex >= 0 && objIndex < this.rowColumnList[rowIndex]) {
2019-08-08 14:32:32 +08:00
flag = true;
2019-07-02 16:29:52 +08:00
}
} else {
2019-08-08 14:32:32 +08:00
let objNum = 0;
2019-07-02 16:29:52 +08:00
for (var i = 0; i < rowIndex; ++i) {
2019-08-08 14:32:32 +08:00
objNum += this.rowColumnList[i];
2019-07-02 16:29:52 +08:00
}
if (objIndex >= objNum && objIndex < objNum + this.rowColumnList[rowIndex]) {
2019-08-08 14:32:32 +08:00
flag = true;
2019-07-02 16:29:52 +08:00
}
}
2019-08-08 14:32:32 +08:00
return flag;
2019-07-02 16:29:52 +08:00
},
checkFieldType(field, type, name) {
if (field.type === type) {
2019-08-08 14:32:32 +08:00
return true;
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
return false;
2019-07-02 16:29:52 +08:00
}
},
handleTreeListChildren(treeList) {
const traverse = function(list) {
if (list && list.length > 0) {
list.forEach(element => {
if (element.children != null && element.children.length > 0) {
2019-08-08 14:32:32 +08:00
traverse(element.children);
2019-07-02 16:29:52 +08:00
} else if (element.children != null && element.children.length === 0) {
2019-08-08 14:32:32 +08:00
element.children = null;
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
});
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
};
2019-07-02 16:29:52 +08:00
if (treeList && treeList.length > 0) {
2019-08-08 14:32:32 +08:00
traverse(treeList);
return treeList;
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
return [];
2019-07-02 16:29:52 +08:00
}
},
// 重置操作
doClean() {
2019-08-08 14:32:32 +08:00
this.initPageData();
this.query();
2019-07-02 16:29:52 +08:00
},
// 导出操作
doExport() {
2019-08-08 14:32:32 +08:00
this.doExportFront();
2019-07-02 16:29:52 +08:00
},
// 前端方式导出
doExportFront() {
2019-08-08 14:32:32 +08:00
const resultData = this.prepareQueryData();
2019-07-02 16:29:52 +08:00
if (resultData === false) {
2019-08-08 14:32:32 +08:00
return;
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
this.$emit('queryExport', resultData);
2019-07-02 16:29:52 +08:00
},
// 将表单对象转换为查询对象
prepareQueryData() {
2019-08-08 14:32:32 +08:00
let resultData = {};
2019-07-02 16:29:52 +08:00
// 将formModel转换为查询对象
for (const item in this.formModel) {
for (var i = 0; i < this.modelFields.length; ++i) {
if (item === this.modelFields[i].field) {
if (this.modelFields[i].type === 'treeSelect') {
2019-08-08 14:32:32 +08:00
const qo = this.queryForm.queryObject[item];
const nodeKey = qo.treeConfig.nodeKey ? qo.treeConfig.nodeKey : 'id';
const tmpIds = [];
2019-07-02 16:29:52 +08:00
for (var v = 0; v < this.formModel[item].length; ++v) {
2019-08-08 14:32:32 +08:00
tmpIds[v] = this.formModel[item][v][nodeKey];
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
resultData[item] = tmpIds;
break;
2019-07-02 16:29:52 +08:00
} else {
if (this.modelFields[i].subFields) {
for (var j = 0; j < this.modelFields[i].subFields.length; ++j) {
if (this.formModel[item] && this.formModel[item].length > j) {
2019-08-08 14:32:32 +08:00
resultData[this.modelFields[i].subFields[j]] = this.formModel[item][j];
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
resultData[this.modelFields[i].subFields[j]] = '';
2019-07-02 16:29:52 +08:00
}
}
2019-08-08 14:32:32 +08:00
break;
2019-07-02 16:29:52 +08:00
} else {
2019-08-08 14:32:32 +08:00
resultData[item] = this.formModel[item];
break;
2019-07-02 16:29:52 +08:00
}
}
}
}
}
// 对所有的数据进行trim操作
for (const item in resultData) {
2019-08-08 15:27:30 +08:00
if (resultData[item] && resultData[item].trim) {
2019-08-08 14:32:32 +08:00
resultData[item] = resultData[item].trim();
2019-07-02 16:29:52 +08:00
}
}
// 查询前数据处理
2019-08-08 15:57:36 +08:00
resultData = this.beforeQuery(resultData);
2019-08-08 14:32:32 +08:00
return resultData;
2019-07-02 16:29:52 +08:00
},
query() {
2019-08-08 14:32:32 +08:00
const resultData = this.prepareQueryData();
2019-07-02 16:29:52 +08:00
if (resultData === false) {
2019-08-08 14:32:32 +08:00
return;
2019-07-02 16:29:52 +08:00
}
2019-08-08 14:32:32 +08:00
this.$emit('query', resultData);
2019-07-02 16:29:52 +08:00
},
selectChange(row, form) {
if (row.change) {
2019-08-08 14:32:32 +08:00
row.change(form);
2019-07-02 16:29:52 +08:00
}
}
}
2019-08-08 14:32:32 +08:00
};
2019-07-02 16:29:52 +08:00
</script>
<style scoped>
.query-form-main-custom .el-input {
max-width: 240px;
min-width: 100px;
}
.query-form-main-custom .el-select {
max-width: 240px;
min-width: 100px;
}
2019-09-30 17:56:16 +08:00
.button_style {
margin-bottom: 10px;
}
2019-07-02 16:29:52 +08:00
</style>