yw-common-list
Version:
基于vxe-table封装的自定义可配置表格
669 lines (667 loc) • 20.4 kB
JavaScript
/**
* lz,2022-09-26 10:12
* 高级查询
*/
import { Modal } from '../../modal'
import { Button } from '../../button'
// import { Form } from '../../form'
// import { FormItem } from '../../form-item'
// 引入axios用于请求接口
import { axios } from '../../ya-wei-list/src/request'
import options from './options'
import {
Radio as elRadio,
Checkbox as elCheckbox,
CheckboxGroup as elCheckboxGroup,
Input as elInput,
DatePicker as elDatePicker,
Switch as elSwitch,
Select as elSelect,
Option as elOption,
Cascader as elCascader,
Collapse as ElCollapse,
CollapseItem as ElCollapseItem,
Row as elRow,
Col as elCol,
Button as elButton,
Form,
FormItem
} from 'element-ui'
// 导入指令定义
import pickerClearable from './pickerClearable'
export default {
inheritAttrs: false,
name: 'advancedQuery',
data () {
return {
// 表单数据
formData: {},
// 表单校验规则
formRules: {},
// 数据库查询出的
dataBase: {},
// 选中的折叠面板
activeName: '0'
}
},
props: {
// 是否显示
visible: {
type: Boolean,
default: false
},
// 数据回显用
data: {
type: Object,
default: () => {
return {}
}
},
// 表格配置key
tableKey: {
type: String,
require: true
},
// 渲染页面用
option: {
type: Array,
required: true,
default: () => []
},
// 是否支持回车提交
enterSubmit: {
type: Boolean,
default: true
}
},
model: {
prop: 'visible',
event: 'updateVisible'
},
// 监听属性 类似于data概念",
computed: {},
// 监控data中的数据变化",
watch: {
visible (val) {
if (val) this.init()
}
},
directives: {
'picker-clearable': pickerClearable
},
methods: {
resetForm () {
this.formData = {}
this.$emit('resetForm')
},
// 通过接口调用获取高级查询数据
async queryByCode () {
const configName = this.tableKey
if (configName) {
let res = {}
if (this.$YaWeiListUseOption?.axios) {
this.$YaWeiListUseOption.axios.defaults.baseURL = options.baseUrl
res = await this.$YaWeiListUseOption.axios.get('/dict-common/queryByConfigName', { params: { configName } })
} else {
axios.defaults.baseURL = options.baseUrl
res = await axios.get('/dict-common/queryByConfigName', { params: { configName } })
}
this.dataBase = res.data.result || []
}
},
updateData (res) {
const formData = { ...this.formData }
const data = JSON.parse(JSON.stringify(res || {}))
this.formData = { ...formData, ...data }
},
init () {
const formData = { ...this.formData }
const data = JSON.parse(JSON.stringify(this.data || {}))
this.formData = { ...data, ...formData }
this.queryByCode()
},
// 格式化提交参数
formatSubmitData () {
// 表单数据
const data = JSON.parse(JSON.stringify(this.formData))
// 字典数据
const dataBase = { ...this.dataBase }
if (data) {
const keys = Object.keys(data)
if (keys.length > 0) {
const options = this.option
keys.filter(item => data[item] === null || item.includes('_custom_name')).map(item => {
delete data[item]
})
keys.filter(item => !item.includes('_custom_name')).map(item => {
options.map(item2 => {
const name = item2?.field?.fieldName
if (name && name === item) {
switch (item2.fieldShowType?.toLowerCase()) {
case 'radio': // 单选框
data[item] = dataBase[item2.field.dictCode].filter(base => base.label === data[item])[0].value
break
case 'checkbox': // 多选框
if (data[item]?.length === 0) {
delete data[item]
} else {
data[item] = dataBase[item2.field.dictCode].filter(base => data[item].includes(base.label)).map(item => item.value)
}
break
case 'string': // 文本输入框
break
case 'number': // 数字输入框
break
case 'date': // 日期选择器
if (typeof data[item] === 'object' && item2.field?.queryType === 2) {
data[`${item}_begin`] = data[item] ? data[item][0] : ''
data[`${item}_end`] = data[item] ? data[item][1] : ''
delete data[item]
} else {
data[`${item}_begin`] = ''
data[`${item}_end`] = ''
}
break
case 'switch': // 开关
break
case 'select': // 下拉选择
if (item2.field?.queryType === 2 && Array.isArray(data[item])) {
data[item] = data[item].join(',')
}
break
case 'cascader': // 级联选择
// 2022年11月15日,于宇强说需要全部的
// // 后台只取最后一个,说不通,所以在此格式化
// if (data[item] && data[item].length > 0) {
// data[item] = data[item][data[item].length - 1]
// }
break
default:
}
}
})
})
}
}
return data || {}
},
submit () {
this.$emit('submit', this.formatSubmitData())
this.updateVisible(false)
},
updateVisible (flag) {
this.$emit('updateVisible', flag)
},
// 根据类型分别渲染
getDom (item, type, h) {
let render = null
switch (type?.toLowerCase()) {
case 'radio': // 单选框
render = this.renderRadio(item, h)
break
case 'checkbox': // 多选框
render = this.renderCheckbox(item, h)
break
case 'string': // 文本输入框
render = this.renderInput(item, h)
break
case 'number': // 数字输入框
render = this.renderInput(item, h, 'number')
break
case 'date': // 日期选择器
render = this.renderDatePicker(item, h)
break
case 'switch': // 开关
render = this.renderSwitch(item, h)
break
case 'select': // 下拉选择
render = this.renderSelect(item, h)
break
case 'cascader': // 级联选择
render = this.renderCascader(item, h)
break
case 'custom': // 自定义效果
render = this.renderCustom(item, h)
break
default:
render = this.renderInput(item, h)
}
return render || this.renderInput(item, h)
},
setFormData (item, e) {
const data = { ...this.formData }
data[item.fieldCode || item.field.fieldName] = e
this.formData = data
},
// 渲染级联选择
renderCascader (item, h) {
const data = this.dataBase
const key = item.fieldCode || item.field.fieldName
const code = item.field.dictCode
if (!data[code]) return this.renderInput(item, h)
let multiple = false
let collapseTags = false
// 如果选择范围
if (item.field?.queryType === 2) {
multiple = true
collapseTags = true
}
return h(elCascader, {
ref: `refElCascader${key}`,
style: {
width: '100%'
},
attrs: {
value: this.formData[key],
options: data[code],
clearable: true,
filterable: true,
collapseTags,
props: {
checkStrictly: true,
expandTrigger: 'hover',
multiple
}
},
on: {
input: (e) => {
this.setFormData(item, e)
}
},
scopedSlots: {
default: (props) => {
return h('div', {
domProps: {
innerHTML: props.node.label
},
on: {
click: () => {
const cascader = this.$refs[`refElCascader${key}`].$refs.panel
if (multiple) {
cascader.calculateMultiCheckedValue()
props.node.doCheck(!props.node.checked)
cascader.calculateMultiCheckedValue()
} else {
cascader.handleCheckChange(props.node.path)
cascader.handleExpand(props.node)
}
}
}
})
}
}
})
},
// 渲染开关
renderSwitch (item, h) {
const key = item.fieldCode || item.field.fieldName
return h(elSwitch, {
attrs: {
value: this.formData[key]
},
on: {
input: (e) => {
this.setFormData(item, e)
}
}
})
},
// 渲染日期选择
renderDatePicker (item, h) {
const key = item.fieldCode || item.field.fieldName
let type = 'datetime'
let other = {}
// 如果选择范围
if (item.field?.queryType === 2) {
type = 'datetimerange'
other = {
rangeSeparator: '至',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期'
}
}
return h(elDatePicker, {
directives: item.field?.queryType === 2 ? [] : [{ name: 'picker-clearable' }],
style: {
width: '100%'
},
attrs: {
type,
placeholder: '请选择',
format: 'yyyy-MM-dd HH:mm:ss',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
value: this.formData[key],
...other
},
on: {
input: (e) => {
this.setFormData(item, e)
}
}
})
},
// 渲染下拉
renderSelect (item, h) {
const data = this.dataBase
const key = item.fieldCode || item.field.fieldName
const code = item.field.dictCode
let multiple = false
let collapseTags = false
// 如果选择范围
if (item.field?.queryType === 2) {
multiple = true
collapseTags = true
}
return h(elSelect, {
style: {
width: '100%'
},
attrs: {
value: this.formData[key],
placeholder: '请选择',
clearable: true,
filterable: true,
multiple,
collapseTags
},
on: {
input: (e) => {
this.setFormData(item, e)
}
}
}, data[code] && data[code].map((item, key) => {
return h(elOption, { key, attrs: { label: item.label, value: item.value } })
}))
},
// 渲染多选
renderCheckbox (option, h) {
const data = this.dataBase
const key = option.fieldCode || option.field.fieldName
const code = option.field.dictCode
if (!data || Object.keys(data).length <= 0 || !data[code]) return this.renderInput(option, h)
const render = []
data[code].map(item => {
render.push(
h(elCheckbox, {
attrs: {
// value: this.formData[key],
label: item.label
}
// on: {
// input: (e) => {
// this.setFormData(option, e)
// }
// }
})
)
})
// 初始化时进行字段默认赋值,避免组件报错无法渲染
if (typeof this.formData[key] === 'undefined') this.formData[key] = []
return h(elCheckboxGroup, {
attrs: {
value: this.formData[key]
},
on: {
input: (e) => {
this.setFormData(option, e)
}
}
}, render)
},
// 渲染单选
renderRadio (option, h) {
const data = this.dataBase
const key = option.fieldCode || option.field.fieldName
const code = option.field.dictCode
if (!data || Object.keys(data).length <= 0 || !data[code]) return this.renderInput(option, h)
const render = []
data[code].map(item => {
render.push(
h(elRadio, {
attrs: {
value: this.formData[key],
label: item.label
},
on: {
input: (e) => {
this.setFormData(option, e)
}
}
})
)
})
render.push(h(elButton, {
class: 'radio-clear-btn',
attrs: {
type: 'text',
icon: 'el-icon-circle-close'
},
on: {
click: () => {
this.setFormData(option, '')
delete this.formData[key]
}
}
}))
return render
},
// 渲染自定义效果
renderCustom (item, h) {
const key = item.fieldCode || item.field.fieldName
return h(elInput, {
style: {
width: '100%'
},
attrs: {
value: this.formData[`${key}_custom_name`],
placeholder: '请选择',
clearable: true,
type: 'text'
},
on: {
focus: () => {
this.$emit('focusCustom', key)
},
clear: () => {
this.$emit('clearCustom', key)
}
}
})
},
// 渲染表格
renderInput (item, h, type = 'text') {
const key = item.fieldCode || item.field.fieldName
return h(elInput, {
style: {
width: '100%'
},
attrs: {
value: this.formData[key],
placeholder: '请输入',
clearable: true,
type
},
on: {
input: (e) => {
this.setFormData(item, e)
}
}
})
},
// 渲染表格项
renderFormItem (h, group) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
const render = []
this.option
.filter(item => item.superShow === 1 || item.superShow === '1')
.map(item => {
if (!group || (group && group === item.groupName) || (group === 'default' && !item.groupName)) {
render.push(
h(elCol, { attrs: { span: item.fieldCol ? item.fieldCol * options.colSpan : options.defaultSpan } },
[
h(FormItem, {
// attrs: {
// field: item.configName,
// title: item.fieldCn,
// span: item.fieldCol ? item.fieldCol * options.colSpan : options.defaultSpan,
// itemRender: {}
// },
attrs: {
prop: item.configName,
label: item.fieldCn
},
scopedSlots: {
default () {
const type = item.fieldShowType
if (type) {
return that.getDom(item, type, h)
} else {
return that.renderInput(item, h)
}
}
}
})
]
)
)
}
})
return render
},
renderElCollapseItem (cascaderKey, h) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
const list = []
const allName = []
cascaderKey.map((item, index) => {
let title = item
if (item === 'default') title = '默认'
const formItems = that.renderFormItem(h, item)
if (formItems && formItems.length > 0) {
allName.push(`${index}`)
list.push(
h(ElCollapseItem, {
attrs: { title, name: `${index}` },
scopedSlots: {
default () {
return formItems
}
}
})
)
}
})
if (allName && allName.length > 0) this.activeName = allName[0]
return list
},
// 渲染查询区域
renderPageContent (h) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
const cascader = this.formatSuperQuery(this.option)
const cascaderKey = Object.keys(cascader)
let list = []
const submitDom = h(Button, {
attrs: {
type: 'submit'
},
style: {
display: 'none'
},
on: {
click () {
that.submit()
}
}
})
if (cascaderKey && cascaderKey.length > 1) {
list = [h(Form, {
// attrs: { data: this.formData, rules: this.formRules, titleAlign: 'right', titleWidth: '110' }
attrs: { model: this.formData, rules: this.formRules, labelWidth: '110px' },
nativeOn: {
submit: (e) => {
e.preventDefault()
}
}
},
[h(ElCollapse, {
attrs: { value: this.activeName },
on: {
input: (e) => {
this.activeName = e
}
}
}, this.renderElCollapseItem(cascaderKey, h)), this.enterSubmit && submitDom]
)
]
} else {
list = [
h(Form, {
// attrs: { data: this.formData, rules: this.formRules, titleAlign: 'right', titleWidth: '110' }
attrs: { model: this.formData, rules: this.formRules, inline: true, labelWidth: '110px' },
nativeOn: {
submit: (e) => {
e.preventDefault()
}
}
}, [h(elRow, this.renderFormItem(h)), this.enterSubmit && submitDom])
]
}
return list
},
// 格式化高级查询所需数据
formatSuperQuery (list) {
const data = {}
list.map(item => item.groupName).map(item => {
let key = item
if (!item) key = 'default'
data[key] = list.filter(item2 => item === item2.groupName)
})
return data
}
},
render (h) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
return h('div', { class: 'advanced-query' }, [
h(Modal, {
attrs: { value: this.visible, showFooter: true, width: 1000, title: '高级查询', position: { top: 47 } },
on: {
input: (flag) => {
this.updateVisible(flag)
},
close: () => {
this.updateVisible(false)
}
},
scopedSlots: {
footer () {
return [h(Button, {
attrs: { content: '关闭' },
on: {
click: () => {
that.updateVisible(false)
}
}
}), h(Button, {
attrs: { content: '重置', status: 'primary' },
on: {
click: () => {
that.resetForm()
}
}
}), h(Button, {
attrs: { content: '确定', status: 'primary' },
on: {
click: () => {
that.submit()
}
}
})]
}
}
}, this.renderPageContent(h))
])
}
}