325 lines
8.8 KiB
Vue
325 lines
8.8 KiB
Vue
<template>
|
|
<t-form
|
|
:data="formData"
|
|
labelWidth="calc(8em + 8px)"
|
|
ref="form"
|
|
@reset="onReset"
|
|
:rules="formRules"
|
|
@submit="onSubmit"
|
|
scrollToFirstError="smooth"
|
|
>
|
|
<g-filter-wrapper :expand="expand" :colNum="colNum" col-style="margin-bottom: 24px" class="filter-from">
|
|
<t-form-item
|
|
class="form-item-wrap"
|
|
v-for="(item, key) in config"
|
|
:key="key"
|
|
v-bind="colProps"
|
|
:name="item.key"
|
|
:rules="item.rule"
|
|
>
|
|
<template slot="label">
|
|
<t-tooltip v-if="shouldEllipsis(item.label)" :content="item.label">
|
|
<span>{{ sliceText(item.label) }}</span>
|
|
</t-tooltip>
|
|
<span v-else>{{ item.label }}</span>
|
|
</template>
|
|
<slot :name="item.key" :item="item" :formData="formData">
|
|
<t-select
|
|
v-if="item.type === 'select'"
|
|
v-bind="item.selectProps"
|
|
v-model="formData[item.key]"
|
|
:options="item.selectList"
|
|
:disabled="item.disabled || false"
|
|
:placeholder="item.placeholder || '请选择'"
|
|
:multiple="item.multiple || false"
|
|
v-on="item.events || {}"
|
|
:clearable="item.clearable || false"
|
|
:onChange="(value) => handleSelectChange(value, item)"
|
|
></t-select>
|
|
<t-date-picker
|
|
v-else-if="item.type === 'datepicker'"
|
|
v-model="formData[item.key]"
|
|
mode="date"
|
|
style="width: 100%"
|
|
placeholder="请选择"
|
|
:clearable="item.clearable || true"
|
|
:disableDate="(date) => getDisableDate(date, item)"
|
|
/>
|
|
<t-date-picker
|
|
v-else-if="item.type === 'range-datepicker'"
|
|
range
|
|
v-model="formData[item.key]"
|
|
mode="date"
|
|
style="width: 100%"
|
|
v-bind="item.rangeDatepickerProps"
|
|
:placeholder="['开始时间', '结束时间']"
|
|
:clearable="item.clearable || true"
|
|
/>
|
|
<t-tree-select
|
|
v-else-if="item.type === 'tree-select'"
|
|
style="width: 100%"
|
|
v-bind="item.treeSelectProps"
|
|
:data="item.selectList"
|
|
v-model="formData[item.key]"
|
|
placeholder="请选择"
|
|
:multiple="item.multiple || false"
|
|
:filterable="item.filterable || false"
|
|
/>
|
|
<all-select
|
|
v-else-if="item.type === 'all-select'"
|
|
v-bind="item.allSelectProps"
|
|
v-model="formData[item.key]"
|
|
:options="item.selectList"
|
|
:minCollapsedNum="1"
|
|
:placeholder="'请选择'"
|
|
:allowCheckAll="item.allowCheckAll || true"
|
|
/>
|
|
<t-tooltip
|
|
:content="formData[item.key]"
|
|
:showArrow="false"
|
|
:overlayStyle="{ display: !formData[item.key] || !item.popup ? 'none' : 'block' }"
|
|
v-else
|
|
>
|
|
<t-input
|
|
v-bind="item.inputProps"
|
|
v-model="formData[item.key]"
|
|
:placeholder="item.placeholder || '请输入'"
|
|
:clearable="item.clearable || false"
|
|
:disabled="item.disabled || false"
|
|
>
|
|
<t-icon v-if="item.iconName" :name="item.iconName" slot="suffix-icon" />
|
|
</t-input>
|
|
</t-tooltip>
|
|
</slot>
|
|
</t-form-item>
|
|
<t-form-item class="filter-btns" :class="shouldShowExtend ? 'float-right' : ''" labelWidth="0">
|
|
<t-button theme="default" variant="base" type="reset">重置</t-button>
|
|
<t-button theme="primary" type="submit">{{ submitText }}</t-button>
|
|
<t-button v-if="shouldShowExtend" theme="primary" variant="text" @click="changeChevron">
|
|
<span>
|
|
{{ expand ? '收起' : '展开' }}
|
|
<t-icon :name="expand ? 'chevron-up' : 'chevron-down'" slot="icon" />
|
|
</span>
|
|
</t-button>
|
|
</t-form-item>
|
|
</g-filter-wrapper>
|
|
</t-form>
|
|
</template>
|
|
|
|
<script>
|
|
// import FilterWrapper from '../filter-wrapper.vue';
|
|
import dayjs from 'dayjs';
|
|
import { GFilterWrapper } from '@gtff/tdesign-gt-vue';
|
|
import allSelect from '@/pages/index/components/all-select/_base.vue';
|
|
|
|
const LABEL_THRESHOLD = 8;
|
|
const DOUBLE_BYTE_THRESHOLD = 255;
|
|
|
|
export default {
|
|
components: {
|
|
GFilterWrapper,
|
|
allSelect,
|
|
},
|
|
props: {
|
|
config: [Object, Array],
|
|
colNum: {
|
|
type: Number,
|
|
default: 4,
|
|
},
|
|
defaultExpand: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
formRules: {
|
|
type: Object,
|
|
default: () => {},
|
|
},
|
|
submitText: {
|
|
type: String,
|
|
default: '查询',
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
expand: true,
|
|
colProps: {
|
|
xs: 6, // >= 768
|
|
md: 4, // >= 992px
|
|
lg: 3, // >= 1200px
|
|
xl: 3, // >= 1400 px
|
|
xxl: 2, // >= 1880
|
|
},
|
|
isShowHighSearchButton: false,
|
|
formData: {},
|
|
formRef: null,
|
|
inputRef: null,
|
|
};
|
|
},
|
|
computed: {
|
|
shouldShowExtend() {
|
|
return Object.keys(this.config).length >= this.colNum;
|
|
},
|
|
},
|
|
watch: {
|
|
formData: {
|
|
immediate: true,
|
|
deep: true,
|
|
handler(val, oldVal) {
|
|
// 忽略首次加载
|
|
if (oldVal) {
|
|
this.$emit('formChange', val);
|
|
}
|
|
},
|
|
},
|
|
},
|
|
mounted() {
|
|
this.expand = this.defaultExpand;
|
|
this.setFormData(this.config);
|
|
this.formRef = this.$refs.form;
|
|
this.formRef.reset();
|
|
this.inputRef = this.$refs.input;
|
|
},
|
|
methods: {
|
|
handleSelectChange(value, item) {
|
|
const { multiple, multipleAllValue, selectList } = item;
|
|
|
|
function isEqualArr(arr1, arr2) {
|
|
return arr1.every((values) => arr2.includes(values));
|
|
}
|
|
|
|
// 处理多选情况下,有全选的值
|
|
if (multiple && typeof multipleAllValue !== 'undefined') {
|
|
// without all value
|
|
const allSelectValue = selectList
|
|
.filter((itemss) => itemss.value !== multipleAllValue)
|
|
.map((items1) => items1.value);
|
|
console.log(allSelectValue, value, isEqualArr(allSelectValue, value));
|
|
if (value.includes(multipleAllValue) || isEqualArr(allSelectValue, value)) {
|
|
this.formData[item.key] = selectList.map((itemss) => itemss.value);
|
|
}
|
|
}
|
|
// 增加回调方法
|
|
this.$emit('changeSelect', value, item);
|
|
},
|
|
getDisableDate(date, item) {
|
|
if (!item.relation || !item.timeRange) return false;
|
|
const selectData = this.formData[item.relation];
|
|
if (!selectData) return false;
|
|
|
|
const formatDate = dayjs(selectData).hour(0).minute(0).second(0);
|
|
|
|
if (item.timeRange === 'start') {
|
|
// 大于选中结束时间的都不可选
|
|
return date > new Date(formatDate);
|
|
}
|
|
|
|
if (item.timeRange === 'end') {
|
|
// 小于选中开始时间的都不可选
|
|
return date < new Date(formatDate);
|
|
}
|
|
|
|
return false;
|
|
},
|
|
changeChevron() {
|
|
this.expand = !this.expand;
|
|
},
|
|
// 计算字符串字节长度,英文字母为单字节字符,中文汉字为双字节字符
|
|
getStringLength(str) {
|
|
const strLength = str.length;
|
|
|
|
let count = 0;
|
|
for (let i = 0; i < strLength; i++) {
|
|
count += str.charCodeAt(i) > DOUBLE_BYTE_THRESHOLD ? 2 : 1;
|
|
}
|
|
return count;
|
|
},
|
|
// 根据预设值判断label是否显示省略
|
|
shouldEllipsis(str) {
|
|
return this.getStringLength(str) > LABEL_THRESHOLD * 2;
|
|
},
|
|
// label文字切割
|
|
sliceText(text, length = 7) {
|
|
if (this.shouldEllipsis(text)) {
|
|
return `${text.slice(0, length)}...`;
|
|
}
|
|
return text;
|
|
},
|
|
onReset() {
|
|
this.$emit('reset');
|
|
},
|
|
onSubmit({ validateResult }) {
|
|
if (validateResult === true) {
|
|
this.$emit('search');
|
|
}
|
|
},
|
|
setFormData(data) {
|
|
const formData = {};
|
|
Object.keys(data).forEach((key) => {
|
|
const item = data[key];
|
|
if (item) {
|
|
formData[item.key] = item.value;
|
|
}
|
|
});
|
|
this.formData = formData;
|
|
},
|
|
getParams(key) {
|
|
if (key) return this.formData[key];
|
|
return { ...this.formData };
|
|
},
|
|
setParams(formData) {
|
|
this.formData = formData;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.float-right {
|
|
float: right;
|
|
}
|
|
.filter-btns {
|
|
button {
|
|
margin-right: 8px;
|
|
&:last-child {
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
}
|
|
// .float-right {
|
|
// float: right;
|
|
// }
|
|
.ie-wrapper {
|
|
.filter-from /deep/ .form-item-wrap {
|
|
min-height: 0;
|
|
}
|
|
.g-filter-wrapper {
|
|
padding: 0 24px;
|
|
margin-bottom: 24px;
|
|
}
|
|
}
|
|
// .filter-btns {
|
|
// button {
|
|
// margin-right: 8px;
|
|
// &:last-child {
|
|
// margin-right: 0;
|
|
// }
|
|
// }
|
|
// }
|
|
// .ie-wrapper .g-filter-wrapper {
|
|
// padding: 0 24px;
|
|
// }
|
|
|
|
.g-filter-wrapper {
|
|
padding: 0 24px;
|
|
/deep/ .t-row {
|
|
// g-filter-wrapper组件问题
|
|
|
|
/* stylelint-disable-next-line declaration-no-important */
|
|
row-gap: 0 !important;
|
|
}
|
|
}
|
|
.form-item-wrap {
|
|
min-height: 56px;
|
|
}
|
|
</style>
|