@lx-frontend/wrap-element-ui 1.0.14 → 1.0.15-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/src/components/EditableTable/bizHooks/useColumnHeaderOperation.ts +112 -185
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizCheckboxFilter.vue +45 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizColorRadioFilter.vue +56 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizDoubleDatePickerFilter.vue +48 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizInputFilter.vue +26 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.helper.ts +131 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.vue +116 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/BizRadioFilter.vue +44 -0
- package/src/components/EditableTable/features/bizTableHeaderPopover/{sort.vue → BizSortFilter.vue} +2 -2
- package/src/components/EditableTable/features/bizTableHeaderPopover/index.vue +42 -63
- package/src/components/EditableTable/index.vue +8 -23
- package/src/components/EditableTable/types/index.ts +61 -48
- package/src/components/EditableTable/features/bizTableHeaderPopover/bizFilter.vue +0 -62
- package/src/components/EditableTable/features/bizTableHeaderPopover/search.vue +0 -74
package/src/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.helper.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import dayjs, { OpUnitType } from 'dayjs';
|
|
2
|
+
|
|
3
|
+
// 月份配置 - 月份对应的天数
|
|
4
|
+
const monthConfig = [
|
|
5
|
+
{ month: 1, day: 31 },
|
|
6
|
+
{ month: 2, day: 29 },
|
|
7
|
+
{ month: 3, day: 31 },
|
|
8
|
+
{ month: 4, day: 30 },
|
|
9
|
+
{ month: 5, day: 31 },
|
|
10
|
+
{ month: 6, day: 30 },
|
|
11
|
+
{ month: 7, day: 31 },
|
|
12
|
+
{ month: 8, day: 31 },
|
|
13
|
+
{ month: 9, day: 30 },
|
|
14
|
+
{ month: 10, day: 31 },
|
|
15
|
+
{ month: 11, day: 30 },
|
|
16
|
+
{ month: 12, day: 31 },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 组装极联选择组件默认选项
|
|
21
|
+
* example: [
|
|
22
|
+
* {
|
|
23
|
+
* value: '1',
|
|
24
|
+
* label: '1月',
|
|
25
|
+
* children: [
|
|
26
|
+
* { value: '1', label: '1日' },
|
|
27
|
+
* ... // 1月份的每一天
|
|
28
|
+
* ]
|
|
29
|
+
* },
|
|
30
|
+
* ... // 其他月份的选项
|
|
31
|
+
* ]
|
|
32
|
+
*/
|
|
33
|
+
export function getMonthDayPickerDefaultOptions() {
|
|
34
|
+
return monthConfig.map(
|
|
35
|
+
(item) => ({
|
|
36
|
+
value: item.month.toString(),
|
|
37
|
+
label: `${ item.month }月`,
|
|
38
|
+
children: Array.from(
|
|
39
|
+
{ length: item.day },
|
|
40
|
+
(_, i) => (
|
|
41
|
+
{ value: `${ i + 1 }`, label: `${ i + 1 }日` }
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 组装日期范围级联选择组件禁用选项
|
|
50
|
+
* @param date 日期 - 级联选择组件值
|
|
51
|
+
* @param isStartDate 区分传递的date是 开始日期 / 结束日期
|
|
52
|
+
* @param digits 时间范围 n个月
|
|
53
|
+
*/
|
|
54
|
+
export function disableOutOfRangeOptions({
|
|
55
|
+
date = [],
|
|
56
|
+
isStartDate = false,
|
|
57
|
+
digits = 3
|
|
58
|
+
}: { date: string[], isStartDate?: boolean, digits: number }) {
|
|
59
|
+
// 写死一个闰年年份 仅用于比较时间
|
|
60
|
+
// 如果非闰年 dayjs('year-02-29') 会输出 year-3-1 导致日期范围选择器出错
|
|
61
|
+
const year = 2024;
|
|
62
|
+
const baseMonthDay = 30;
|
|
63
|
+
const options = getMonthDayPickerDefaultOptions();
|
|
64
|
+
|
|
65
|
+
return options.map(
|
|
66
|
+
(month) => {
|
|
67
|
+
const children = month.children.map(
|
|
68
|
+
(day) => {
|
|
69
|
+
// 组装日期 - 当前这个选项对应的完整日期
|
|
70
|
+
const currentDate = dayjs([year, month.value, day.value].join('-'));
|
|
71
|
+
|
|
72
|
+
// 是否需要禁用当前日期
|
|
73
|
+
let disabled = false;
|
|
74
|
+
|
|
75
|
+
// 如果有传入日期,则判断是否在禁用日期范围内
|
|
76
|
+
if (date.length > 0) {
|
|
77
|
+
// 组装日期 - 传入日期对应的完整日期
|
|
78
|
+
const baseDate = dayjs([year, ...date].join('-'));
|
|
79
|
+
|
|
80
|
+
// 如果是开始时间,则结束时间范围为 baseDate + digits
|
|
81
|
+
// 如果是结束时间,则开始时间范围为 baseDate - digits
|
|
82
|
+
if (isStartDate) {
|
|
83
|
+
const maxDate = baseDate.add(digits * baseMonthDay - 1, 'day');
|
|
84
|
+
// 推算时间范围超过12月31号,结束时间可选年初时间
|
|
85
|
+
if (maxDate.year() > year) {
|
|
86
|
+
disabled = currentDate.isAfter(maxDate.subtract(366, 'day'), 'day') && currentDate.isBefore(baseDate, 'day');
|
|
87
|
+
} else {
|
|
88
|
+
disabled = currentDate.isAfter(maxDate, 'day') || currentDate.isBefore(baseDate, 'day');
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
const minDate = baseDate.subtract(digits * baseMonthDay - 1, 'day');
|
|
92
|
+
// 推算时间范围在1月1号前,开始时间可选年末时间
|
|
93
|
+
if (minDate.year() < year) {
|
|
94
|
+
disabled = currentDate.isBefore(minDate.add(366, 'day'), 'day') && currentDate.isAfter(baseDate, 'day');
|
|
95
|
+
} else {
|
|
96
|
+
disabled = currentDate.isBefore(minDate, 'day') || currentDate.isAfter(baseDate, 'day');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
...day,
|
|
103
|
+
disabled
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// 如果当前月份每天都是禁用日期,则整个月份禁用
|
|
109
|
+
const disabled = children.every((day) => day.disabled);
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
...month,
|
|
113
|
+
disabled,
|
|
114
|
+
children
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 格式化月日级联选择组件值 MM-dd
|
|
122
|
+
* @param date 日期 - 级联选择组件值
|
|
123
|
+
* @returns 格式化后的日期字符串
|
|
124
|
+
*/
|
|
125
|
+
export function formatMonthDayPickerValue(date: string[]) {
|
|
126
|
+
return date
|
|
127
|
+
.map(
|
|
128
|
+
(str) => str.padStart(2, '0')
|
|
129
|
+
)
|
|
130
|
+
.join('-');
|
|
131
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<!-- 月/日选择器 -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="editable-table-sort-filter__sort">
|
|
4
|
+
<div class="editable-table-sort-filter__search-title">
|
|
5
|
+
{{ config.label || '筛选' }}
|
|
6
|
+
</div>
|
|
7
|
+
<div
|
|
8
|
+
class="editable-table-sort-filter__date-picker-content"
|
|
9
|
+
style="display: flex;flex-direction: column;gap: 12px;"
|
|
10
|
+
>
|
|
11
|
+
<el-cascader
|
|
12
|
+
clearable
|
|
13
|
+
:value="startDate"
|
|
14
|
+
separator=""
|
|
15
|
+
placeholder="开始日期"
|
|
16
|
+
popper-class="month-day-picker"
|
|
17
|
+
:options="startDateOptions"
|
|
18
|
+
@change="value => handleDateChange(config.prop[0], value)"
|
|
19
|
+
/>
|
|
20
|
+
<el-cascader
|
|
21
|
+
clearable
|
|
22
|
+
:value="endDate"
|
|
23
|
+
separator=""
|
|
24
|
+
placeholder="结束日期"
|
|
25
|
+
popper-class="month-day-picker"
|
|
26
|
+
:options="endDateOptions"
|
|
27
|
+
@change="value => handleDateChange(config.prop[1], value)"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
32
|
+
<script setup lang="ts">
|
|
33
|
+
import {
|
|
34
|
+
disableOutOfRangeOptions, formatMonthDayPickerValue,
|
|
35
|
+
getMonthDayPickerDefaultOptions
|
|
36
|
+
} from '@/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.helper';
|
|
37
|
+
import { computed, toRefs } from 'vue';
|
|
38
|
+
import { IFilterMonthDayPicker } from '../../types';
|
|
39
|
+
|
|
40
|
+
const props = defineProps<{
|
|
41
|
+
config: IFilterMonthDayPicker
|
|
42
|
+
tempFilteredValue: Record<string, string>
|
|
43
|
+
}>()
|
|
44
|
+
const { config, tempFilteredValue } = toRefs(props)
|
|
45
|
+
|
|
46
|
+
const emit = defineEmits<{
|
|
47
|
+
(e: 'update:tempFilteredValue', key: string, value: string): void
|
|
48
|
+
}>()
|
|
49
|
+
|
|
50
|
+
const formatDate = (date: string) => {
|
|
51
|
+
if (date) {
|
|
52
|
+
return date
|
|
53
|
+
.split('-')
|
|
54
|
+
// 01 -> 1
|
|
55
|
+
.map(
|
|
56
|
+
(v) => String(Number(v))
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return []
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const startDate = computed(() => {
|
|
64
|
+
const { prop } = config.value;
|
|
65
|
+
return formatDate(tempFilteredValue.value[prop[0]]);
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const endDate = computed(() => {
|
|
69
|
+
const { prop } = config.value;
|
|
70
|
+
return formatDate(tempFilteredValue.value[prop[1]]);
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// 开始日期范围限制
|
|
74
|
+
const startDateOptions = computed(
|
|
75
|
+
() => {
|
|
76
|
+
if (endDate.value.length === 0) {
|
|
77
|
+
return getMonthDayPickerDefaultOptions();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return disableOutOfRangeOptions({
|
|
81
|
+
date: endDate.value,
|
|
82
|
+
isStartDate: false,
|
|
83
|
+
digits: config.value.limit
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// 结束日期范围限制
|
|
89
|
+
const endDateOptions = computed(
|
|
90
|
+
() => {
|
|
91
|
+
if (startDate.value.length === 0) {
|
|
92
|
+
return getMonthDayPickerDefaultOptions();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return disableOutOfRangeOptions({
|
|
96
|
+
date: startDate.value,
|
|
97
|
+
isStartDate: true,
|
|
98
|
+
digits: config.value.limit
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 选择时间更改统一回调
|
|
105
|
+
*/
|
|
106
|
+
const handleDateChange = (key: string, value: string[]) => {
|
|
107
|
+
const currentValue = value.length === 0
|
|
108
|
+
? ''
|
|
109
|
+
: formatMonthDayPickerValue(value)
|
|
110
|
+
emit('update:tempFilteredValue', key, currentValue);
|
|
111
|
+
}
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<style scoped lang="less">
|
|
115
|
+
|
|
116
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!-- 单选框 -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="editable-table-sort-filter__filter">
|
|
4
|
+
<div class="editable-table-sort-filter__filter-title">
|
|
5
|
+
{{ config.label || '筛选' }}
|
|
6
|
+
</div>
|
|
7
|
+
<el-radio-group
|
|
8
|
+
style="display: flex;flex-direction: column;gap: 6px;"
|
|
9
|
+
:value="tempFilteredValue[config.prop]"
|
|
10
|
+
@input="val => emit('update:tempFilteredValue', config.prop, val)"
|
|
11
|
+
>
|
|
12
|
+
<el-radio
|
|
13
|
+
v-for="item in config.options"
|
|
14
|
+
:key="item.value"
|
|
15
|
+
:label="item.value"
|
|
16
|
+
:title="item.text"
|
|
17
|
+
>
|
|
18
|
+
<slot
|
|
19
|
+
name="filter-item"
|
|
20
|
+
v-bind="item"
|
|
21
|
+
>
|
|
22
|
+
{{ item.text }}
|
|
23
|
+
</slot>
|
|
24
|
+
</el-radio>
|
|
25
|
+
</el-radio-group>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
import { IFilterSelect } from '../../types';
|
|
31
|
+
|
|
32
|
+
defineProps<{
|
|
33
|
+
config: IFilterSelect
|
|
34
|
+
tempFilteredValue: Record<string, string>
|
|
35
|
+
}>()
|
|
36
|
+
|
|
37
|
+
const emit = defineEmits<{
|
|
38
|
+
(e: 'update:tempFilteredValue', key: string, value: string): void
|
|
39
|
+
}>()
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<style scoped lang="less">
|
|
43
|
+
|
|
44
|
+
</style>
|
package/src/components/EditableTable/features/bizTableHeaderPopover/{sort.vue → BizSortFilter.vue}
RENAMED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
:key="item.prop"
|
|
6
6
|
>
|
|
7
7
|
<div class="editable-table-sort-filter__sort-title">
|
|
8
|
-
{{ item.label }}
|
|
8
|
+
{{ item.label || '排序' }}
|
|
9
9
|
</div>
|
|
10
10
|
<div class="editable-table-sort-filter__sort-btns">
|
|
11
11
|
<el-button
|
|
@@ -47,4 +47,4 @@ const sortConfigs = computed(() => {
|
|
|
47
47
|
if (Array.isArray(props.column._sortable)) return props.column._sortable
|
|
48
48
|
return [{ ...props.column, label: '排序' }]
|
|
49
49
|
})
|
|
50
|
-
</script>
|
|
50
|
+
</script>
|
|
@@ -27,77 +27,32 @@
|
|
|
27
27
|
{{ column.label }}
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
|
-
<
|
|
30
|
+
<BizSortFilter
|
|
31
31
|
v-if="column.isColumnSortable"
|
|
32
32
|
:column="column"
|
|
33
33
|
:temp-sort-prop="tempSortProp"
|
|
34
34
|
:temp-sort-type="tempSortType"
|
|
35
35
|
@update:sort="(type, prop) => emit('update:sort', type, prop)"
|
|
36
36
|
/>
|
|
37
|
-
|
|
38
|
-
<Search
|
|
39
|
-
v-if="!!column.search"
|
|
40
|
-
:column="column"
|
|
41
|
-
:temp-search-value="tempSearchValue"
|
|
42
|
-
@update:tempSearchValue="(key, val) => emit('update:tempSearchValue', key, val)"
|
|
43
|
-
>
|
|
44
|
-
<template
|
|
45
|
-
v-for="searchOption in (Array.isArray(column.search) ? column.search : []).filter(v => v.type === 'slot')"
|
|
46
|
-
#[searchOption.slotName]="rest"
|
|
47
|
-
>
|
|
48
|
-
<slot
|
|
49
|
-
:name="searchOption.slotName"
|
|
50
|
-
v-bind="rest"
|
|
51
|
-
/>
|
|
52
|
-
</template>
|
|
53
|
-
</Search>
|
|
54
|
-
|
|
37
|
+
|
|
55
38
|
<div
|
|
56
|
-
v-if="column.
|
|
57
|
-
class="editable-
|
|
39
|
+
v-if="column.filters"
|
|
40
|
+
class="editable-table__filter-group"
|
|
58
41
|
>
|
|
59
|
-
<div class="editable-table-sort-filter__search-title">
|
|
60
|
-
{{ column.doubleDatePicker.label }}
|
|
61
|
-
</div>
|
|
62
42
|
<div
|
|
63
|
-
|
|
64
|
-
|
|
43
|
+
v-for="(filterItem, index) in column.filters"
|
|
44
|
+
:key="index"
|
|
45
|
+
class="editable-table__filter-group__filter"
|
|
65
46
|
>
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
:
|
|
69
|
-
value
|
|
70
|
-
|
|
71
|
-
type="date"
|
|
72
|
-
size="small"
|
|
73
|
-
placeholder="开始日期"
|
|
74
|
-
/>
|
|
75
|
-
<el-date-picker
|
|
76
|
-
@input="val => emit('update:tempSearchValue', column.doubleDatePicker.props[1], val || '')"
|
|
77
|
-
:value="tempSearchValue[column.doubleDatePicker.props[1]]"
|
|
78
|
-
value-format="yyyy-MM-dd"
|
|
79
|
-
format="yyyy-MM-dd"
|
|
80
|
-
size="small"
|
|
81
|
-
type="date"
|
|
82
|
-
placeholder="结束日期"
|
|
47
|
+
<component
|
|
48
|
+
:is="componentMap[filterItem.type]"
|
|
49
|
+
:config="filterItem"
|
|
50
|
+
:temp-filtered-value="tempFilteredValue"
|
|
51
|
+
@update:tempFilteredValue="onUpdate"
|
|
83
52
|
/>
|
|
84
53
|
</div>
|
|
85
54
|
</div>
|
|
86
55
|
|
|
87
|
-
<BizFilter
|
|
88
|
-
v-if="column.filters && ((Array.isArray(column.filters) ? column.filters : column.filters.options).length > 0)"
|
|
89
|
-
:column="column"
|
|
90
|
-
:temp-filtered-value="tempFilteredValue"
|
|
91
|
-
@update:tempFilteredValue="(key, val) => emit('update:tempFilteredValue', key, val)"
|
|
92
|
-
>
|
|
93
|
-
<template #filter-item="item">
|
|
94
|
-
<slot
|
|
95
|
-
name="filter-item"
|
|
96
|
-
v-bind="item"
|
|
97
|
-
/>
|
|
98
|
-
</template>
|
|
99
|
-
</BizFilter>
|
|
100
|
-
|
|
101
56
|
<div
|
|
102
57
|
v-if="column.summary"
|
|
103
58
|
class="editable-table-sort-filter__filter"
|
|
@@ -144,12 +99,17 @@
|
|
|
144
99
|
</template>
|
|
145
100
|
|
|
146
101
|
<script setup lang="ts">
|
|
147
|
-
import
|
|
148
|
-
import
|
|
149
|
-
import
|
|
102
|
+
import BizCheckboxFilter from '@/components/EditableTable/features/bizTableHeaderPopover/BizCheckboxFilter.vue';
|
|
103
|
+
import BizColorRadioFilter from '@/components/EditableTable/features/bizTableHeaderPopover/BizColorRadioFilter.vue';
|
|
104
|
+
import BizDoubleDatePickerFilter
|
|
105
|
+
from '@/components/EditableTable/features/bizTableHeaderPopover/BizDoubleDatePickerFilter.vue';
|
|
106
|
+
import BizInputFilter from '@/components/EditableTable/features/bizTableHeaderPopover/BizInputFilter.vue';
|
|
107
|
+
import BizMonthDayPicker from '@/components/EditableTable/features/bizTableHeaderPopover/BizMonthDayPicker.vue';
|
|
108
|
+
import BizRadioFilter from '@/components/EditableTable/features/bizTableHeaderPopover/BizRadioFilter.vue';
|
|
109
|
+
import BizSortFilter from '@/components/EditableTable/features/bizTableHeaderPopover/BizSortFilter.vue';
|
|
150
110
|
|
|
151
111
|
import { ref } from 'vue'
|
|
152
|
-
import { IColumnConfig } from '../../types'
|
|
112
|
+
import { FilterItem, IColumnConfig } from '../../types'
|
|
153
113
|
|
|
154
114
|
defineProps<{
|
|
155
115
|
headActive: boolean
|
|
@@ -157,12 +117,10 @@ defineProps<{
|
|
|
157
117
|
tempSummaryList: string[]
|
|
158
118
|
tempSortType: 'ascending' | 'descending' | ''
|
|
159
119
|
tempSortProp: string
|
|
160
|
-
tempSearchValue: Record<string, string>
|
|
161
120
|
tempFilteredValue: Record<string, string | number | number[] | string[]>
|
|
162
121
|
}>()
|
|
163
122
|
|
|
164
123
|
const emit = defineEmits<{
|
|
165
|
-
(e: 'update:tempSearchValue', key: string, value: string): void
|
|
166
124
|
(e: 'update:tempFilteredValue', key: string, value: string): void
|
|
167
125
|
(e: 'update:tempSummaryList', value: string[]): void
|
|
168
126
|
(e: 'update:sort', type: 'ascending' | 'descending', prop: string): void
|
|
@@ -171,8 +129,29 @@ const emit = defineEmits<{
|
|
|
171
129
|
(e: 'confirm'): void
|
|
172
130
|
}>()
|
|
173
131
|
|
|
132
|
+
// 把 filterItem.type 映射到组件
|
|
133
|
+
const componentMap: Record<FilterItem['type'], any> = {
|
|
134
|
+
/** 输入框 */
|
|
135
|
+
input: BizInputFilter,
|
|
136
|
+
/** 日期范围 */
|
|
137
|
+
doubleDatePicker: BizDoubleDatePickerFilter,
|
|
138
|
+
/** 单选框 */
|
|
139
|
+
radio: BizRadioFilter,
|
|
140
|
+
/** 复选框 */
|
|
141
|
+
checkbox: BizCheckboxFilter,
|
|
142
|
+
/** 月日选择器 */
|
|
143
|
+
monthDayPicker: BizMonthDayPicker,
|
|
144
|
+
/** 颜色选择器 */
|
|
145
|
+
colorRadio: BizColorRadioFilter,
|
|
146
|
+
}
|
|
147
|
+
|
|
174
148
|
const popoverRef = ref(null as any)
|
|
175
149
|
|
|
150
|
+
// 统一的事件派发
|
|
151
|
+
function onUpdate(key: string, val: any) {
|
|
152
|
+
emit('update:tempFilteredValue', key, val)
|
|
153
|
+
}
|
|
154
|
+
|
|
176
155
|
defineExpose({
|
|
177
156
|
close: () => {
|
|
178
157
|
popoverRef.value?.doClose()
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
:fixed="leftFixedColumnCount > 0 ? 'left' : false"
|
|
105
105
|
:filtered-value="Array.isArray(filteredValue[colorFilterConfig?.prop]) ? filteredValue[colorFilterConfig?.prop] : []"
|
|
106
106
|
>
|
|
107
|
-
<template #header
|
|
107
|
+
<template #header>
|
|
108
108
|
<biz-table-header-popover
|
|
109
109
|
v-if="colorFilterConfig"
|
|
110
110
|
:head-active="isColumnHeadActive(colorFilterConfig)"
|
|
@@ -114,14 +114,12 @@
|
|
|
114
114
|
:temp-sort-prop="tempSortProp"
|
|
115
115
|
:temp-sort-type="tempSortType"
|
|
116
116
|
:temp-filtered-value="tempFilteredValue"
|
|
117
|
-
:temp-search-value="tempSearchValue"
|
|
118
117
|
@update:tempSummaryList="val => { tempSummaryList = val }"
|
|
119
118
|
@update:tempFilteredValue="(key, value) => { $set(tempFilteredValue, key, value) }"
|
|
120
|
-
@update:tempSearchValue="(key, value) => { $set(tempSearchValue, key, value) }"
|
|
121
119
|
@popover-show="() => handleHeaderPopoverShow(colorFilterConfig)"
|
|
122
120
|
@update:sort="handleSort"
|
|
123
|
-
@reset="() => handleHeaderOperationReset(colorFilterConfig
|
|
124
|
-
@confirm="() => handleHeaderOperationConfirm(colorFilterConfig
|
|
121
|
+
@reset="() => handleHeaderOperationReset(colorFilterConfig)"
|
|
122
|
+
@confirm="() => handleHeaderOperationConfirm(colorFilterConfig)"
|
|
125
123
|
>
|
|
126
124
|
<template #custom>
|
|
127
125
|
<div class="editable-table__color-icon" />
|
|
@@ -158,8 +156,8 @@
|
|
|
158
156
|
v-bind="getColumnBindProps(column)"
|
|
159
157
|
>
|
|
160
158
|
<template
|
|
159
|
+
#header
|
|
161
160
|
v-if="showColumnHeadSortIcon(column)"
|
|
162
|
-
#header="scope"
|
|
163
161
|
>
|
|
164
162
|
<biz-table-header-popover
|
|
165
163
|
:head-active="isColumnHeadActive(column)"
|
|
@@ -169,14 +167,12 @@
|
|
|
169
167
|
:temp-sort-prop="tempSortProp"
|
|
170
168
|
:temp-sort-type="tempSortType"
|
|
171
169
|
:temp-filtered-value="tempFilteredValue"
|
|
172
|
-
:temp-search-value="tempSearchValue"
|
|
173
170
|
@update:tempSummaryList="val => { tempSummaryList = val }"
|
|
174
171
|
@update:tempFilteredValue="(key, value) => { $set(tempFilteredValue, key, value) }"
|
|
175
|
-
@update:tempSearchValue="(key, value) => { $set(tempSearchValue, key, value) }"
|
|
176
172
|
@popover-show="() => handleHeaderPopoverShow(column)"
|
|
177
173
|
@update:sort="handleSort"
|
|
178
|
-
@reset="() => handleHeaderOperationReset(column
|
|
179
|
-
@confirm="() => handleHeaderOperationConfirm(column
|
|
174
|
+
@reset="() => handleHeaderOperationReset(column)"
|
|
175
|
+
@confirm="() => handleHeaderOperationConfirm(column)"
|
|
180
176
|
>
|
|
181
177
|
<template #filter-item="item">
|
|
182
178
|
<slot
|
|
@@ -194,15 +190,6 @@
|
|
|
194
190
|
{{ column.label }}
|
|
195
191
|
</slot>
|
|
196
192
|
</template>
|
|
197
|
-
<template
|
|
198
|
-
v-for="searchOption in (Array.isArray(column.search) ? column.search : []).filter(v => v.type === 'slot')"
|
|
199
|
-
#[searchOption.slotName]="rest"
|
|
200
|
-
>
|
|
201
|
-
<slot
|
|
202
|
-
:name="searchOption.slotName"
|
|
203
|
-
v-bind="rest"
|
|
204
|
-
/>
|
|
205
|
-
</template>
|
|
206
193
|
</biz-table-header-popover>
|
|
207
194
|
</template>
|
|
208
195
|
<!-- 默认操作按钮,defaultOperations属性不为空数组时展示。编辑状态下隐藏 -->
|
|
@@ -434,7 +421,7 @@ const props = withDefaults(defineProps<IProps>(), {
|
|
|
434
421
|
total: 0,
|
|
435
422
|
defaultOperations: () => [],
|
|
436
423
|
colorList: () => [],
|
|
437
|
-
colorFilterConfig:
|
|
424
|
+
colorFilterConfig: undefined,
|
|
438
425
|
leftFixedCount: 1,
|
|
439
426
|
dragSemiRange: 15,
|
|
440
427
|
loading: false,
|
|
@@ -516,7 +503,7 @@ const {
|
|
|
516
503
|
const {
|
|
517
504
|
setRowStyle,
|
|
518
505
|
} = useRowBgColor({
|
|
519
|
-
colorList: props.colorList,
|
|
506
|
+
colorList: props.colorList || [],
|
|
520
507
|
emit
|
|
521
508
|
});
|
|
522
509
|
|
|
@@ -554,13 +541,11 @@ const {
|
|
|
554
541
|
filteredValue,
|
|
555
542
|
showColumnHeadSortIcon,
|
|
556
543
|
sortProp,
|
|
557
|
-
tempSearchValue,
|
|
558
544
|
tempFilteredValue,
|
|
559
545
|
tempSummaryList,
|
|
560
546
|
tempSortType,
|
|
561
547
|
tempSortProp,
|
|
562
548
|
isColumnFiltering,
|
|
563
|
-
searchValue,
|
|
564
549
|
inSorting,
|
|
565
550
|
} = useColumnHeaderOperation({
|
|
566
551
|
tableDomRef,
|
|
@@ -6,6 +6,65 @@ export enum IEditType {
|
|
|
6
6
|
DATE_ONLY = 'date'
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
export interface ISortOption {
|
|
10
|
+
prop: string
|
|
11
|
+
label: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** 筛选组件 - 输入框 */
|
|
15
|
+
export interface IFilterInput {
|
|
16
|
+
type: 'input'
|
|
17
|
+
prop: string,
|
|
18
|
+
label?: string,
|
|
19
|
+
validator?: (value: string) => boolean
|
|
20
|
+
placeholder?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface IFilterSelectOptions {
|
|
24
|
+
value: any;
|
|
25
|
+
text: string;
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 筛选组件 - 单选/多选 */
|
|
30
|
+
export interface IFilterSelect {
|
|
31
|
+
type: 'radio' | 'checkbox'
|
|
32
|
+
prop: string
|
|
33
|
+
options: IFilterSelectOptions[]
|
|
34
|
+
label?: string
|
|
35
|
+
defaultValue?: any | any[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** 筛选组件 - 日期范围(拆分两个日期选择器) */
|
|
39
|
+
export interface IFilterDoubleDatePicker {
|
|
40
|
+
type: 'doubleDatePicker',
|
|
41
|
+
prop: [string, string],
|
|
42
|
+
label?: string,
|
|
43
|
+
pickerOptions?: DatePicker['pickerOptions']
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** 筛选组件 - 月日选择器 */
|
|
47
|
+
export interface IFilterMonthDayPicker {
|
|
48
|
+
type: 'monthDayPicker',
|
|
49
|
+
prop: [string, string],
|
|
50
|
+
label?: string,
|
|
51
|
+
/** 可选择的范围 */
|
|
52
|
+
limit: number,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 筛选组件 - 颜色选择器 */
|
|
56
|
+
export interface IFilterColorRadio {
|
|
57
|
+
type: 'colorRadio',
|
|
58
|
+
prop: string,
|
|
59
|
+
label?: string,
|
|
60
|
+
options: IFilterSelectOptions[]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type FilterItem = IFilterInput | IFilterSelect | IFilterDoubleDatePicker | IFilterMonthDayPicker | IFilterColorRadio
|
|
64
|
+
|
|
65
|
+
/** 筛选组件类型 */
|
|
66
|
+
export type FilterListType = Array<FilterItem>
|
|
67
|
+
|
|
9
68
|
type _IColumnConfigRequired = {
|
|
10
69
|
prop: string;
|
|
11
70
|
label: string;
|
|
@@ -20,65 +79,19 @@ type _IColumnConfigRequired = {
|
|
|
20
79
|
isAlwaysShow?: boolean; // 不可隐藏,显示设置中,该列不允许隐藏
|
|
21
80
|
/** 默认隐藏,显示设置中,该列默认隐藏 */
|
|
22
81
|
defaultHide?: boolean;
|
|
23
|
-
/** 列是否允许搜索,true则表头弹窗会多一个搜索框,一列中有多个搜索字段时传数组进行配置 */
|
|
24
|
-
search?: boolean | ISearchOptions
|
|
25
82
|
summary?: boolean; // 是否可以显示该列的统计
|
|
26
83
|
summaryMethod?: (values: any[]) => string | number; // 这一列的统计方法,values为该列的所有值
|
|
27
|
-
/** 过滤,传数组时默认复选框 */
|
|
28
|
-
filters?: {
|
|
29
|
-
type?: 'checkbox' | 'radio',
|
|
30
|
-
options: FiltersOption[]
|
|
31
|
-
default?: string | number | string[] | number[],
|
|
32
|
-
/** 自定义参数 优先于最外层的prop */
|
|
33
|
-
prop?: string
|
|
34
|
-
} | FiltersOption[]
|
|
35
84
|
/** 格式化函数,用于自定义渲染 */
|
|
36
85
|
formatter?: (row: any, column: IColumnConfig, value: any, index: number) => string | number;
|
|
37
86
|
width?: number | string;
|
|
38
87
|
minWidth?: number | string;
|
|
39
|
-
/** 是否开启日期范围选择器 */
|
|
40
|
-
doubleDatePicker?: {
|
|
41
|
-
props: [string, string],
|
|
42
|
-
label: string,
|
|
43
|
-
};
|
|
44
88
|
/** 自定义颜色表头label */
|
|
45
|
-
customColorLabel?: boolean
|
|
89
|
+
customColorLabel?: boolean;
|
|
90
|
+
filters?: FilterListType;
|
|
46
91
|
}
|
|
47
92
|
|
|
48
93
|
export type IColumnConfigRequired = _IColumnConfigRequired & Partial<Omit<TableColumn, keyof _IColumnConfigRequired>>
|
|
49
94
|
|
|
50
|
-
type FiltersOption = { value: string | number; text: string; [key: string]: any }
|
|
51
|
-
|
|
52
|
-
type ISortOption = {
|
|
53
|
-
prop: string
|
|
54
|
-
label: string
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
type InputSearchOption = {
|
|
58
|
-
prop: string
|
|
59
|
-
label: string
|
|
60
|
-
validator?: (value: string) => boolean
|
|
61
|
-
type?: 'input'
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
type DoubleDatePickerSearchOption = {
|
|
65
|
-
prop: [string, string]
|
|
66
|
-
label: string
|
|
67
|
-
type: 'doubleDatePicker'
|
|
68
|
-
pickerOptions?: DatePicker['pickerOptions']
|
|
69
|
-
validator?: (tempSearchValue: Record<string, any>) => boolean
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
type SlotSearchOption = {
|
|
73
|
-
prop: string | string[]
|
|
74
|
-
label: string
|
|
75
|
-
type: 'slot'
|
|
76
|
-
slotName: string
|
|
77
|
-
validator?: (tempSearchValue: Record<string, any>) => boolean
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
type ISearchOptions = (InputSearchOption | DoubleDatePickerSearchOption | SlotSearchOption)[]
|
|
81
|
-
|
|
82
95
|
type IInputColumn = IColumnConfigRequired & {
|
|
83
96
|
inputType: string | number;
|
|
84
97
|
}
|