flame-plus 0.1.8 → 0.1.9
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 +1 -1
- package/packages/components/base/flmButton/flmButton.vue +29 -0
- package/packages/components/base/flmCascader/flmCascader.vue +39 -0
- package/packages/components/base/flmCheckbox/flmCheckbox.vue +34 -0
- package/packages/components/base/flmCheckbox/flmCheckboxGroup.vue +71 -0
- package/packages/components/base/flmColorPicker/flmColorPicker.vue +34 -0
- package/packages/components/base/flmDatePicker/flmDatePicker.vue +47 -0
- package/packages/components/base/flmDialog/flmDialog.vue +39 -0
- package/packages/components/base/flmInput/flmInput.vue +38 -0
- package/packages/components/base/flmInputNumber/flmInputNumber.vue +36 -0
- package/packages/components/base/flmPagination/flmPagination.vue +37 -0
- package/packages/components/base/flmRadio/flmRadio.vue +64 -0
- package/packages/components/base/flmRate/flmRate.vue +34 -0
- package/packages/components/base/flmRead/flmRead.vue +18 -0
- package/packages/components/base/flmSelect/flmSelect.vue +74 -0
- package/packages/components/base/flmSlider/flmSlider.vue +35 -0
- package/packages/components/base/flmSwitch/flmSwitch.vue +29 -0
- package/packages/components/base/flmTimePicker/flmTimePicker.vue +37 -0
- package/packages/components/base/flmTimeSelect/flmTimeSelect.vue +36 -0
- package/packages/components/base/flmTransfer/flmTransfer.vue +42 -0
- package/packages/components/complex/flmForm/flmForm.vue +223 -0
- package/packages/components/complex/flmSearch/flmSearch.vue +148 -0
- package/packages/components/complex/flmTable/flmTable.vue +90 -0
- package/packages/components/complex/flmToolbar/flmToolbar.vue +55 -0
- package/packages/components/index.ts +29 -0
- package/packages/components/page/flmReportPage/flmReportPage.vue +690 -0
- package/packages/index.ts +8 -0
- package/packages/model/flmComponentConfig/base/flmButton.ts +50 -0
- package/packages/model/flmComponentConfig/base/flmCascader.ts +77 -0
- package/packages/model/flmComponentConfig/base/flmCheckbox.ts +51 -0
- package/packages/model/flmComponentConfig/base/flmColorPicker.ts +30 -0
- package/packages/model/flmComponentConfig/base/flmDatePicker.ts +73 -0
- package/packages/model/flmComponentConfig/base/flmDialog.ts +49 -0
- package/packages/model/flmComponentConfig/base/flmInput.ts +57 -0
- package/packages/model/flmComponentConfig/base/flmInputNumber.ts +37 -0
- package/packages/model/flmComponentConfig/base/flmPagination.ts +38 -0
- package/packages/model/flmComponentConfig/base/flmRadio.ts +42 -0
- package/packages/model/flmComponentConfig/base/flmRate.ts +49 -0
- package/packages/model/flmComponentConfig/base/flmRead.ts +6 -0
- package/packages/model/flmComponentConfig/base/flmSelect.ts +104 -0
- package/packages/model/flmComponentConfig/base/flmSlider.ts +51 -0
- package/packages/model/flmComponentConfig/base/flmSwitch.ts +37 -0
- package/packages/model/flmComponentConfig/base/flmTimePicker.ts +61 -0
- package/packages/model/flmComponentConfig/base/flmTimeSelect.ts +44 -0
- package/packages/model/flmComponentConfig/index.ts +30 -0
- package/packages/model/flmComponentConfig/public.ts +293 -0
- package/packages/utils/filterConfig.ts +39 -0
- package/packages/utils/index.ts +2 -0
- package/packages/utils/isValidKey.ts +13 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="tsx">
|
|
2
|
+
import { defineComponent, PropType, computed, reactive } from 'vue'
|
|
3
|
+
import { TimePickerConfig, TimePickerDefaultEvent, timePickerDefaultConfig } from '@/model/flmComponentConfig'
|
|
4
|
+
import { filterConfig } from '@/utils'
|
|
5
|
+
|
|
6
|
+
export default defineComponent({
|
|
7
|
+
emits: ['change', 'blur', 'focus', 'visible-change' ],
|
|
8
|
+
props: {
|
|
9
|
+
// 默认设置
|
|
10
|
+
config: {
|
|
11
|
+
type: Object as PropType<TimePickerConfig>,
|
|
12
|
+
default: {}
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
setup(props, ctx) {
|
|
16
|
+
// 时间选择器设置
|
|
17
|
+
const timePickerConfig = computed((): TimePickerConfig => {
|
|
18
|
+
return filterConfig(timePickerDefaultConfig, props.config)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// 时间选择器事件
|
|
22
|
+
const timePickerDefaultEvent: TimePickerDefaultEvent = reactive({
|
|
23
|
+
'onUpdate:modelValue': (value: TimePickerConfig['model-value']) => ctx.emit('change', value), // v-model 不用改不了值
|
|
24
|
+
onBlur: (event: any) => ctx.emit('blur', event),
|
|
25
|
+
onFocus: (event: any) => ctx.emit('focus', event),
|
|
26
|
+
onVisibleChange: (event: boolean) => ctx.emit('visible-change', event),
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
return () => (
|
|
30
|
+
<el-time-picker
|
|
31
|
+
{...timePickerConfig.value}
|
|
32
|
+
{...timePickerDefaultEvent}
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
</script>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="tsx">
|
|
2
|
+
import { defineComponent, PropType, computed, reactive } from 'vue'
|
|
3
|
+
import { TimeSelectConfig, timeSelectDefaultConfig } from '@/model/flmComponentConfig'
|
|
4
|
+
import { filterConfig } from '@/utils'
|
|
5
|
+
|
|
6
|
+
export default defineComponent({
|
|
7
|
+
emits: ['change', 'blur', 'focus'],
|
|
8
|
+
props: {
|
|
9
|
+
// 默认设置
|
|
10
|
+
config: {
|
|
11
|
+
type: Object as PropType<TimeSelectConfig>,
|
|
12
|
+
default: {}
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
setup(props, ctx) {
|
|
16
|
+
// 时间选择设置
|
|
17
|
+
const timeSelectConfig = computed((): TimeSelectConfig => {
|
|
18
|
+
return filterConfig(timeSelectDefaultConfig, props.config)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// 时间选择默认事件
|
|
22
|
+
const timeSelectDefaultEvent: any = reactive({
|
|
23
|
+
onChange: (value: TimeSelectConfig['model-value']) => ctx.emit('change', value),
|
|
24
|
+
onBlur: () => ctx.emit('blur'),
|
|
25
|
+
onFocus: () => ctx.emit('focus'),
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return () => (
|
|
29
|
+
<el-timeSelect
|
|
30
|
+
{...timeSelectConfig.value}
|
|
31
|
+
{...timeSelectDefaultEvent}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="tsx">
|
|
2
|
+
import { defineComponent, PropType, computed, reactive } from 'vue'
|
|
3
|
+
import { TransferConfig, TransferDefaultEvent, transferDefaultConfig } from '@/model/flmComponentConfig'
|
|
4
|
+
import { filterConfig } from '@/utils'
|
|
5
|
+
|
|
6
|
+
export default defineComponent({
|
|
7
|
+
emits: ['change', 'left-check-change', 'right-check-change'],
|
|
8
|
+
props: {
|
|
9
|
+
// 默认设置
|
|
10
|
+
config: {
|
|
11
|
+
type: Object as PropType<TransferConfig>,
|
|
12
|
+
default: {}
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
setup(props, ctx) {
|
|
16
|
+
// 穿梭框设置
|
|
17
|
+
const transferConfig = computed((): TransferConfig => {
|
|
18
|
+
return filterConfig(transferDefaultConfig, props.config)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
// 穿梭框默认事件
|
|
22
|
+
const transferDefaultEvent: TransferDefaultEvent = reactive({
|
|
23
|
+
onChange: (value: TransferConfig['model-value']) => ctx.emit('change', value),
|
|
24
|
+
onLeftCheckChange: (value: TransferConfig['model-value']) => ctx.emit('left-check-change', value),
|
|
25
|
+
onRightCheckChange: (value: TransferConfig['model-value']) => ctx.emit('right-check-change', value),
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return () => (
|
|
29
|
+
<el-transfer
|
|
30
|
+
{...transferConfig.value}
|
|
31
|
+
{...transferDefaultEvent}
|
|
32
|
+
>
|
|
33
|
+
{{
|
|
34
|
+
'default': ({ option }: any) => ctx.slots['default']?.({ option }),
|
|
35
|
+
'left-footer': () => ctx.slots['left-footer']?.(),
|
|
36
|
+
'right-footer': () => ctx.slots['right-footer']?.(),
|
|
37
|
+
}}
|
|
38
|
+
</el-transfer>
|
|
39
|
+
)
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
</script>
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<script lang="tsx">
|
|
2
|
+
import {
|
|
3
|
+
defineComponent,
|
|
4
|
+
getCurrentInstance,
|
|
5
|
+
PropType,
|
|
6
|
+
reactive,
|
|
7
|
+
computed,
|
|
8
|
+
watch,
|
|
9
|
+
h,
|
|
10
|
+
resolveComponent,
|
|
11
|
+
onMounted
|
|
12
|
+
} from 'vue'
|
|
13
|
+
import {
|
|
14
|
+
flmButton,
|
|
15
|
+
flmCascader,
|
|
16
|
+
flmCheckbox,
|
|
17
|
+
flmColorPicker,
|
|
18
|
+
flmDatePicker,
|
|
19
|
+
flmInput,
|
|
20
|
+
flmInputNumber,
|
|
21
|
+
flmRadio,
|
|
22
|
+
flmRate,
|
|
23
|
+
flmRead,
|
|
24
|
+
flmSelect,
|
|
25
|
+
flmSlider,
|
|
26
|
+
flmSwitch,
|
|
27
|
+
flmTimePicker,
|
|
28
|
+
flmTimeSelect,
|
|
29
|
+
flmTransfer,
|
|
30
|
+
} from '@/components'
|
|
31
|
+
import {
|
|
32
|
+
ControlTypes,
|
|
33
|
+
ControlConfig,
|
|
34
|
+
isInputControl,
|
|
35
|
+
FormModel,
|
|
36
|
+
FormConfig,
|
|
37
|
+
FormItemConfig,
|
|
38
|
+
FormButtonConfig,
|
|
39
|
+
formDefaultConfig
|
|
40
|
+
} from '@/model/flmComponentConfig'
|
|
41
|
+
import { filterConfig, isValidKey } from '@/utils'
|
|
42
|
+
|
|
43
|
+
export default defineComponent({
|
|
44
|
+
components: {
|
|
45
|
+
flmButton,
|
|
46
|
+
flmCascader,
|
|
47
|
+
flmCheckbox,
|
|
48
|
+
flmColorPicker,
|
|
49
|
+
flmDatePicker,
|
|
50
|
+
flmInput,
|
|
51
|
+
flmInputNumber,
|
|
52
|
+
flmRadio,
|
|
53
|
+
flmRate,
|
|
54
|
+
flmRead,
|
|
55
|
+
flmSelect,
|
|
56
|
+
flmSlider,
|
|
57
|
+
flmSwitch,
|
|
58
|
+
flmTimePicker,
|
|
59
|
+
flmTimeSelect,
|
|
60
|
+
flmTransfer,
|
|
61
|
+
},
|
|
62
|
+
emits: ['submit', 'cancel', 'customEvent'],
|
|
63
|
+
props: {
|
|
64
|
+
// 默认设置
|
|
65
|
+
config: {
|
|
66
|
+
type: Object as PropType<FormConfig>,
|
|
67
|
+
default: {}
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
setup(props, { slots, emit, expose }) {
|
|
71
|
+
const instance = getCurrentInstance() // 实例,必须在最外层声明
|
|
72
|
+
let formModel: FormModel = reactive({}) // 表单数据
|
|
73
|
+
|
|
74
|
+
// 监听表单配置的 model,变化后更新组件内部 formModel
|
|
75
|
+
watch(() => props.config.model, (newModel: FormModel) => upadateFormModel(newModel))
|
|
76
|
+
|
|
77
|
+
// 监听组件内部 formModel,变化后更新控件 value
|
|
78
|
+
watch(formModel, (newModel: FormModel) => updateControl(newModel))
|
|
79
|
+
|
|
80
|
+
onMounted(() => {
|
|
81
|
+
if (props.config?.model && Object.keys(props.config?.model).length) {
|
|
82
|
+
updateControl(props.config.model)
|
|
83
|
+
upadateFormModel(props.config.model)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 更新控件值
|
|
89
|
+
* @date 2022-05-09
|
|
90
|
+
* @param {FormModel} model
|
|
91
|
+
*/
|
|
92
|
+
const updateControl = (model: FormModel) => {
|
|
93
|
+
props.config.items?.forEach((formItem: FormItemConfig) => {
|
|
94
|
+
if (!isValidKey('isSlot', formItem) && typeof(formItem.prop) === 'string') {
|
|
95
|
+
const { controlConfig } = formItem
|
|
96
|
+
controlConfig && (
|
|
97
|
+
isInputControl(controlConfig)
|
|
98
|
+
? controlConfig['modelValue'] = model[formItem.prop]
|
|
99
|
+
: controlConfig['model-value'] = model[formItem.prop]
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 更新表单值
|
|
107
|
+
* @date 2022-05-09
|
|
108
|
+
* @param {FormModel} model
|
|
109
|
+
*/
|
|
110
|
+
const upadateFormModel = (model: FormModel) => {
|
|
111
|
+
Object.entries(model).forEach(([key, value]: Array<any>) => formModel[key] = value)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 表单修改
|
|
116
|
+
* @date 2022-04-14
|
|
117
|
+
* @param {any} value 修改值
|
|
118
|
+
* @param {string} prop 修改键名
|
|
119
|
+
*/
|
|
120
|
+
const formChange = (value: any, prop: string) => formModel[prop] = value
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 表单方法调用
|
|
124
|
+
* @date 2022-04-14
|
|
125
|
+
* @param {'submit' | 'cancel' | string} event 方法名(默认方法直接调用;自定义方法回传方法名及表单数据)
|
|
126
|
+
*/
|
|
127
|
+
const formEvent = (event: FormButtonConfig['event']) => {
|
|
128
|
+
const defaultEvent: Record<FormButtonConfig['event'], Function> = { submit, cancel }
|
|
129
|
+
isValidKey(event, defaultEvent)
|
|
130
|
+
? defaultEvent[event]()
|
|
131
|
+
: emit('customEvent', { event, formModel })
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 提交
|
|
135
|
+
const submit = () => {
|
|
136
|
+
const formRef: any = instance?.refs['formRef']
|
|
137
|
+
if (!formRef) return
|
|
138
|
+
formRef.validate((valid: boolean) => {
|
|
139
|
+
valid && emit('submit', formModel)
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 取消
|
|
144
|
+
const cancel = () => {
|
|
145
|
+
reset()
|
|
146
|
+
emit('cancel', formModel)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 重置
|
|
150
|
+
const reset = () => {
|
|
151
|
+
const formRef: any = instance?.refs['formRef']
|
|
152
|
+
if (!formRef) return
|
|
153
|
+
formRef.resetFields()
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 表单元素
|
|
158
|
+
* @date 2022-04-14
|
|
159
|
+
* @param {Array} items 表单项配置
|
|
160
|
+
* @returns {any} 表单项dom
|
|
161
|
+
*/
|
|
162
|
+
const formItemsDom = (items: FormConfig['items'] = []) => {
|
|
163
|
+
const controlDom = (prop: string, controlType: ControlTypes, controlConfig: ControlConfig) => {
|
|
164
|
+
const config: FormModel = { ...controlConfig }
|
|
165
|
+
const event = controlType === ControlTypes['flmInput'] ? 'onInput' : 'onChange'
|
|
166
|
+
config[event] = (value: any) => formChange(value, prop)
|
|
167
|
+
return h(resolveComponent(controlType), { config })
|
|
168
|
+
}
|
|
169
|
+
return items.map((item: FormItemConfig) => {
|
|
170
|
+
if (typeof(item.prop) === 'string') {
|
|
171
|
+
if (isValidKey('isSlot', item)) {
|
|
172
|
+
const { isSlot, ...itemConfig } = item
|
|
173
|
+
return (
|
|
174
|
+
<el-form-item {...itemConfig}>
|
|
175
|
+
{(slots[item.prop]?.({ prop: item.prop, formModel }))}
|
|
176
|
+
</el-form-item>
|
|
177
|
+
)
|
|
178
|
+
} else {
|
|
179
|
+
const { controlType, controlConfig, ...itemConfig } = item
|
|
180
|
+
if (controlType && controlConfig) {
|
|
181
|
+
return (
|
|
182
|
+
<el-form-item {...itemConfig}>
|
|
183
|
+
{controlDom(item.prop, controlType, controlConfig)}
|
|
184
|
+
</el-form-item>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* 表单按钮
|
|
194
|
+
* @date 2022-04-14
|
|
195
|
+
* @param {Array} buttons 表单按钮配置
|
|
196
|
+
* @returns {any} 表单按钮dom
|
|
197
|
+
*/
|
|
198
|
+
const buttonsDom = (buttons: FormConfig['buttons'] = []) => {
|
|
199
|
+
if (buttons.length) {
|
|
200
|
+
return (
|
|
201
|
+
<el-form-item>
|
|
202
|
+
{buttons.map(({ event, ...config }: FormButtonConfig) =>
|
|
203
|
+
<flm-button config={config} onButtonClick={() => formEvent(event)} />
|
|
204
|
+
)}
|
|
205
|
+
</el-form-item>
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
expose({ formModel, reset })
|
|
211
|
+
|
|
212
|
+
// 表单设置
|
|
213
|
+
const formConfig = computed((): FormConfig => filterConfig(formDefaultConfig, props.config))
|
|
214
|
+
const { items = [], buttons = [], model, ...defaultConfig } = formConfig.value
|
|
215
|
+
return () => (
|
|
216
|
+
<el-form ref='formRef' {...defaultConfig} model={formModel}>
|
|
217
|
+
{formItemsDom(items)}
|
|
218
|
+
{buttonsDom(buttons)}
|
|
219
|
+
</el-form>
|
|
220
|
+
)
|
|
221
|
+
},
|
|
222
|
+
})
|
|
223
|
+
</script>
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<flmForm
|
|
4
|
+
class="search-default"
|
|
5
|
+
ref="searchDefaultRef"
|
|
6
|
+
:config="defaultConfig"
|
|
7
|
+
@submit="searchSubmit"
|
|
8
|
+
@cancel="searchCancel"
|
|
9
|
+
@customEvent="searchCustomEvent"
|
|
10
|
+
>
|
|
11
|
+
<template v-for="defaultSlot in defaultSlots" #[defaultSlot]="{ prop, formModel }">
|
|
12
|
+
<slot :name="defaultSlot" :prop="prop" :formModel="formModel"></slot>
|
|
13
|
+
</template>
|
|
14
|
+
</flmForm>
|
|
15
|
+
<el-drawer
|
|
16
|
+
v-if="hasExtra"
|
|
17
|
+
v-model="showExtra"
|
|
18
|
+
title="搜索"
|
|
19
|
+
:before-close="closeDrawer"
|
|
20
|
+
:close-on-click-modal="false"
|
|
21
|
+
:close-on-press-escape="false"
|
|
22
|
+
:show-close="false"
|
|
23
|
+
direction="ltr"
|
|
24
|
+
>
|
|
25
|
+
<flmForm
|
|
26
|
+
ref="searchExtraRef"
|
|
27
|
+
:config="extraConfig"
|
|
28
|
+
@submit="drawerSubmit"
|
|
29
|
+
@cancel="closeDrawer"
|
|
30
|
+
>
|
|
31
|
+
<template v-for="extraSlot in extraSlots" #[extraSlot]="{ prop, formModel }">
|
|
32
|
+
<slot :name="extraSlot" :prop="prop" :formModel="formModel"></slot>
|
|
33
|
+
</template>
|
|
34
|
+
</flmForm>
|
|
35
|
+
</el-drawer>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script lang="ts" setup>
|
|
40
|
+
import { defineProps, PropType, ref, Ref, computed, ComputedRef } from 'vue'
|
|
41
|
+
import { ElMessage } from 'element-plus'
|
|
42
|
+
import { flmForm } from '@/components'
|
|
43
|
+
import {
|
|
44
|
+
ElementSize,
|
|
45
|
+
ControlTypes,
|
|
46
|
+
FormConfig,
|
|
47
|
+
} from '@/model/flmComponentConfig'
|
|
48
|
+
import { isValidKey } from '@/utils'
|
|
49
|
+
import { nextTick } from 'process'
|
|
50
|
+
|
|
51
|
+
const emit = defineEmits(['searchSubmit', 'searchCancel', 'searchCustomEvent'])
|
|
52
|
+
const props = defineProps({
|
|
53
|
+
config: {
|
|
54
|
+
type: Object as PropType<FormConfig>,
|
|
55
|
+
default() {
|
|
56
|
+
return {}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const searchDefaultRef: Ref<any> = ref() // 默认搜索栏实例
|
|
62
|
+
const searchExtraRef: Ref<any> = ref() // 额外搜索栏实例
|
|
63
|
+
|
|
64
|
+
let showExtra: Ref<boolean> = ref(false) // 显示额外搜索条件
|
|
65
|
+
let hasExtra: Ref<boolean> = ref(false) // 有额外搜索条件
|
|
66
|
+
let extraFormModel: Ref<FormConfig> = ref({}) // 额外搜索条件
|
|
67
|
+
|
|
68
|
+
const maxFormItem = 3 // 默认搜索栏最大条件数
|
|
69
|
+
|
|
70
|
+
// 默认搜索栏设置
|
|
71
|
+
const defaultConfig: ComputedRef<FormConfig> = computed(() => {
|
|
72
|
+
const { items = [], buttons, ...config } = props.config
|
|
73
|
+
hasExtra.value = items.length > maxFormItem
|
|
74
|
+
hasExtra.value && buttons?.unshift({ 'text': '更多', 'event': 'openDrawer' }) // 搜索条件大于最大数量,插入更多按钮
|
|
75
|
+
return {
|
|
76
|
+
...config,
|
|
77
|
+
inline: true,
|
|
78
|
+
items: items.slice(0, maxFormItem),
|
|
79
|
+
buttons
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
// 额外搜索栏设置
|
|
83
|
+
const extraConfig: ComputedRef<FormConfig> = computed(() => {
|
|
84
|
+
const { items, buttons, ...config } = props.config
|
|
85
|
+
return {
|
|
86
|
+
...config,
|
|
87
|
+
inline: false,
|
|
88
|
+
items: items?.slice(maxFormItem),
|
|
89
|
+
// 插入额外搜索栏按钮
|
|
90
|
+
buttons: [
|
|
91
|
+
{
|
|
92
|
+
'text': '取消',
|
|
93
|
+
'event': 'cancel'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
'type': 'primary',
|
|
97
|
+
'text': '搜索',
|
|
98
|
+
'event': 'submit'
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// 获取表格插槽
|
|
105
|
+
const getFormSlots = (items: FormConfig['items'] = []): Array<string> => {
|
|
106
|
+
return items
|
|
107
|
+
.map(({ prop, isSlot }: FormItemConfig) => isSlot && prop)
|
|
108
|
+
.filter(item => item)
|
|
109
|
+
}
|
|
110
|
+
// 默认搜索栏插槽
|
|
111
|
+
const defaultSlots = computed((): Array<string> => getFormSlots(props.config.items.slice(0, maxFormItem)))
|
|
112
|
+
// 额外搜索栏插槽
|
|
113
|
+
const extraSlots = computed((): Array<string> => getFormSlots(props.config.items.slice(maxFormItem)))
|
|
114
|
+
|
|
115
|
+
// 搜索栏提交
|
|
116
|
+
const searchSubmit = (formModel: FormConfig['model']) => {
|
|
117
|
+
emit('searchSubmit', { ...formModel, ...extraFormModel.value })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 搜索栏取消
|
|
121
|
+
const searchCancel = () => {
|
|
122
|
+
searchExtraRef.value?.reset()
|
|
123
|
+
const extraFormMoadel = searchExtraRef.value?.formModel ?? {}
|
|
124
|
+
emit('searchCancel', { ...extraFormMoadel, ...searchDefaultRef.value.formModel })
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 搜索栏自定义操作
|
|
128
|
+
const searchCustomEvent = ({ event, formModel }: { event: string, formModel: FormConfig['model']}) => {
|
|
129
|
+
const customEvent: Record<string, Function> = { openDrawer }
|
|
130
|
+
if (isValidKey(event, customEvent)) {
|
|
131
|
+
customEvent[event](formModel)
|
|
132
|
+
} else {
|
|
133
|
+
emit('searchCustomEvent', event)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const openDrawer = () => showExtra.value = true // 打开额外搜索栏弹窗
|
|
138
|
+
const closeDrawer = () => showExtra.value = false // 关闭额外搜索栏弹窗
|
|
139
|
+
|
|
140
|
+
// 额外搜索栏提交
|
|
141
|
+
const drawerSubmit = (formModel: FormConfig['model']) => {
|
|
142
|
+
formModel && (extraFormModel.value = formModel)
|
|
143
|
+
emit('searchSubmit', { ...searchDefaultRef.value.formModel, ...formModel })
|
|
144
|
+
closeDrawer()
|
|
145
|
+
}
|
|
146
|
+
</script>
|
|
147
|
+
|
|
148
|
+
<style lang="scss"></style>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script lang="tsx">
|
|
2
|
+
import { defineComponent, PropType, computed } from 'vue'
|
|
3
|
+
import {
|
|
4
|
+
TableConfig,
|
|
5
|
+
TableColumnConfig,
|
|
6
|
+
tableDefaultConfig,
|
|
7
|
+
tableColumnDefaultConfig
|
|
8
|
+
} from '@/model/flmComponentConfig'
|
|
9
|
+
import { filterConfig } from '@/utils'
|
|
10
|
+
|
|
11
|
+
export default defineComponent({
|
|
12
|
+
emits: [
|
|
13
|
+
'select',
|
|
14
|
+
'select-all',
|
|
15
|
+
'selection-change',
|
|
16
|
+
'cell-mouse-enter',
|
|
17
|
+
'cell-mouse-leave',
|
|
18
|
+
'cell-click',
|
|
19
|
+
'cell-dblclick',
|
|
20
|
+
'cell-contextmenu',
|
|
21
|
+
'row-click',
|
|
22
|
+
'row-contextmenu',
|
|
23
|
+
'row-dblclick',
|
|
24
|
+
'header-click',
|
|
25
|
+
'header-contextmenu',
|
|
26
|
+
'sort-change',
|
|
27
|
+
'filter-change',
|
|
28
|
+
'current-change',
|
|
29
|
+
'header-dragend',
|
|
30
|
+
'expand-change',
|
|
31
|
+
],
|
|
32
|
+
props: {
|
|
33
|
+
// 默认设置
|
|
34
|
+
config: {
|
|
35
|
+
type: Object as PropType<TableConfig>,
|
|
36
|
+
default: {}
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
setup(props, { slots, emit }) {
|
|
40
|
+
/**
|
|
41
|
+
* 表格元素
|
|
42
|
+
* @date 2022-04-14
|
|
43
|
+
* @param {Array} tableColumns 表格列配置
|
|
44
|
+
* @returns {any} 表格列dom
|
|
45
|
+
*/
|
|
46
|
+
const tableColumnDom = (childColumns: TableConfig['columns'] = []) => {
|
|
47
|
+
return childColumns.map(({ isSlot, columns = [], ...childColumnConfig }: TableColumnConfig) => {
|
|
48
|
+
let childDom: any
|
|
49
|
+
if (columns.length) {
|
|
50
|
+
childDom = tableColumnDom(columns)
|
|
51
|
+
} else if (isSlot) {
|
|
52
|
+
childDom = { default: ({ $index: index, row, column }: any) => childColumnConfig.prop && slots[childColumnConfig.prop]?.({ index, row, column }) }
|
|
53
|
+
}
|
|
54
|
+
return (
|
|
55
|
+
<el-table-column {...filterConfig(tableColumnDefaultConfig, childColumnConfig)}>
|
|
56
|
+
{childDom}
|
|
57
|
+
</el-table-column>
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 表单设置
|
|
63
|
+
const tableConfig = computed((): TableConfig => filterConfig(tableDefaultConfig, props.config))
|
|
64
|
+
const { columns = [], ...defaultConfig } = tableConfig.value
|
|
65
|
+
return () => (
|
|
66
|
+
<el-table
|
|
67
|
+
{...defaultConfig}
|
|
68
|
+
onSelect={(selection: any, row: any) => emit('select', { selection, row })}
|
|
69
|
+
onSelectAll={(selection: any) => emit('select-all', selection)}
|
|
70
|
+
onSelectionChange={(row: any, column: any, cell: any, event: any) => emit('selection-change', { row, column, cell, event })}
|
|
71
|
+
onCellMouseEnter={(row: any, column: any, cell: any, event: any) => emit('cell-mouse-enter', { row, column, cell, event })}
|
|
72
|
+
onCellMouseLeave={(row: any, column: any, cell: any, event: any) => emit('cell-mouse-leave', { row, column, cell, event })}
|
|
73
|
+
onCellClick={(row: any, column: any, cell: any, event: any) => emit('cell-click', { row, column, cell, event })}
|
|
74
|
+
onCellDblclick={(row: any, column: any, cell: any, event: any) => emit('cell-dblclick', { row, column, cell, event })}
|
|
75
|
+
onCellContextmenu={(row: any, column: any, cell: any, event: any) => emit('cell-contextmenu', { row, column, cell, event })}
|
|
76
|
+
onRowClick={(row: any, column: any, event: any) => emit('row-click', { row, column, event })}
|
|
77
|
+
onRowContextmenu={(row: any, column: any, event: any) => emit('row-contextmenu', { row, column, event })}
|
|
78
|
+
onRowDblclick={(row: any, column: any, event: any) => emit('row-dblclick', { row, column, event })}
|
|
79
|
+
onHeaderClick={(column: any, event: any) => emit('header-click', { column, event })}
|
|
80
|
+
onHeaderContextmenu={(column: any, event: any) => emit('header-contextmenu', { column, event })}
|
|
81
|
+
onSortChange={({ column, prop, order }: any) => emit('sort-change', { column, prop, order })}
|
|
82
|
+
onFilterChange={(filters: any) => emit('filter-change', filters)}
|
|
83
|
+
onCurrentChange={(currentRow: any, oldCurrentRow: any) => emit('current-change', { currentRow, oldCurrentRow })}
|
|
84
|
+
onHeaderDragend={(newWidth: any, oldWidth: any, column: any, event: any) => emit('header-dragend', { newWidth, oldWidth, column, event })}
|
|
85
|
+
onExpandChange={(row: any, expanded: any) => emit('expand-change', { row, expanded })}
|
|
86
|
+
>{tableColumnDom(columns)}</el-table>
|
|
87
|
+
)
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
</script>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flm-toolbar">
|
|
3
|
+
<flm-button
|
|
4
|
+
v-for="buttonConfig in buttonGroup"
|
|
5
|
+
:config="{ ...config.publicConfig, ...buttonConfig }"
|
|
6
|
+
:key="buttonConfig.event"
|
|
7
|
+
@click="toolbarClick(buttonConfig.event)"
|
|
8
|
+
/>
|
|
9
|
+
<el-dropdown
|
|
10
|
+
v-if="props.config.buttons.length > maxButton"
|
|
11
|
+
style="margin-left: 12px;"
|
|
12
|
+
trigger="click"
|
|
13
|
+
@command="toolbarClick"
|
|
14
|
+
>
|
|
15
|
+
<flm-button :config="{ ...config.publicConfig, text: '更多' }" />
|
|
16
|
+
<template #dropdown>
|
|
17
|
+
<el-dropdown-menu>
|
|
18
|
+
<el-dropdown-item
|
|
19
|
+
v-for="buttonConfig in dropdown"
|
|
20
|
+
:config="buttonConfig"
|
|
21
|
+
:key="buttonConfig.event"
|
|
22
|
+
:command="buttonConfig.event"
|
|
23
|
+
>{{ buttonConfig.text }}</el-dropdown-item>
|
|
24
|
+
</el-dropdown-menu>
|
|
25
|
+
</template>
|
|
26
|
+
</el-dropdown>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script lang="ts" setup>
|
|
31
|
+
import { defineEmits, defineProps, PropType, computed, ComputedRef } from 'vue'
|
|
32
|
+
import { flmButton } from '@/components'
|
|
33
|
+
import { ToolbarConfig, ToolbarButtonConfig } from '@/model/flmComponentConfig'
|
|
34
|
+
|
|
35
|
+
const emit = defineEmits(['toolbarClick'])
|
|
36
|
+
const props = defineProps({
|
|
37
|
+
config: {
|
|
38
|
+
type: Object as PropType<ToolbarConfig>,
|
|
39
|
+
default(): ToolbarConfig {
|
|
40
|
+
return {
|
|
41
|
+
publicConfig: {},
|
|
42
|
+
maxButton: 3,
|
|
43
|
+
buttons: []
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const maxButton = props.config.maxButton
|
|
50
|
+
const buttonGroup: ComputedRef<Array<ToolbarButtonConfig>> = computed(() => props.config.buttons.slice(0, maxButton))
|
|
51
|
+
const dropdown: ComputedRef<Array<ToolbarButtonConfig>> = computed(() => props.config.buttons.slice(maxButton))
|
|
52
|
+
|
|
53
|
+
// 工具栏
|
|
54
|
+
const toolbarClick = (event: string) => emit('toolbarClick', event)
|
|
55
|
+
</script>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// 基础组件
|
|
2
|
+
export { default as flmButton } from './base/flmButton/flmButton.vue' // 按钮
|
|
3
|
+
export { default as flmCascader } from './base/flmCascader/flmCascader.vue' // 级联选择器
|
|
4
|
+
export { default as flmCheckbox } from './base/flmCheckbox/flmCheckbox.vue' // 多选框
|
|
5
|
+
export { default as flmCheckboxGroup } from './base/flmCheckbox/flmCheckboxGroup.vue' // 多选框组
|
|
6
|
+
export { default as flmColorPicker } from './base/flmColorPicker/flmColorPicker.vue' // 取色器
|
|
7
|
+
export { default as flmDatePicker } from './base/flmDatePicker/flmDatePicker.vue' // 日期选择器
|
|
8
|
+
export { default as flmDialog } from './base/flmDialog/flmDialog.vue' // 弹窗
|
|
9
|
+
export { default as flmInput } from './base/flmInput/flmInput.vue' // 输入框
|
|
10
|
+
export { default as flmInputNumber } from './base/flmInputNumber/flmInputNumber.vue' // 数字输入框
|
|
11
|
+
export { default as flmPagination } from './base/flmPagination/flmPagination.vue' // 分页器
|
|
12
|
+
export { default as flmRadio } from './base/flmRadio/flmRadio.vue' // 单选框
|
|
13
|
+
export { default as flmRate } from './base/flmRate/flmRate.vue' // 评分
|
|
14
|
+
export { default as flmRead } from './base/flmRead/flmRead.vue' // 查看
|
|
15
|
+
export { default as flmSelect } from './base/flmSelect/flmSelect.vue' // 选择器
|
|
16
|
+
export { default as flmSlider } from './base/flmSlider/flmSlider.vue' // 滑块
|
|
17
|
+
export { default as flmSwitch } from './base/flmSwitch/flmSwitch.vue' // 开关
|
|
18
|
+
export { default as flmTimePicker } from './base/flmTimePicker/flmTimePicker.vue' // 时间选择器
|
|
19
|
+
export { default as flmTimeSelect } from './base/flmTimeSelect/flmTimeSelect.vue' // 时间选择
|
|
20
|
+
export { default as flmTransfer } from './base/flmTransfer/flmTransfer.vue' // 穿梭框
|
|
21
|
+
|
|
22
|
+
// 复合组件
|
|
23
|
+
export { default as flmForm } from './complex/flmForm/flmForm.vue' // 表单
|
|
24
|
+
export { default as flmSearch } from './complex/flmSearch/flmSearch.vue' // 搜索
|
|
25
|
+
export { default as flmTable } from './complex/flmTable/flmTable.vue' // 表格
|
|
26
|
+
export { default as flmToolbar } from './complex/flmToolbar/flmToolbar.vue' // 操作栏
|
|
27
|
+
|
|
28
|
+
// 页面组件
|
|
29
|
+
export { default as flmReportPage } from './page/flmReportPage/flmReportPage.vue' // 报表页面
|