fx-platform-ui 0.0.2 → 0.0.4
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/CHANGELOG.md +0 -0
- package/Readme.md +7 -38
- package/lib/fx-platform-ui.mjs +32182 -9268
- package/lib/fx-platform-ui.umd.js +58 -14
- package/lib/packages/components/form/index.d.ts +2 -0
- package/lib/packages/components/form/src/hook/index.d.ts +9 -0
- package/lib/packages/components/form/src/hook/useFormContext.d.ts +3 -0
- package/lib/packages/components/form/src/hook/useFormEvents.d.ts +29 -0
- package/lib/packages/components/form/src/hook/useFormLabel.d.ts +79 -0
- package/lib/packages/components/form/src/hook/useFormMethods.d.ts +13 -0
- package/lib/packages/components/form/src/methods.d.ts +7 -0
- package/lib/packages/components/form/src/plat-form-emits.d.ts +9 -0
- package/lib/packages/components/form/src/types/form.d.ts +70 -0
- package/lib/packages/components/form/src/types/index.d.ts +2 -0
- package/lib/packages/components/table/index.d.ts +2 -0
- package/lib/packages/components/table/src/components/index.d.ts +2 -0
- package/lib/packages/components/table/src/components/tool-bar.vue.d.ts +2 -0
- package/lib/packages/components/table/src/hook/index.d.ts +2 -0
- package/lib/packages/components/table/src/hook/useTableMethods.d.ts +21 -0
- package/lib/packages/components/table/src/plat-table-emits.d.ts +2 -0
- package/lib/packages/components/table/src/type/column.d.ts +24 -0
- package/lib/packages/components/table/src/type/index.d.ts +3 -0
- package/lib/packages/components/table/src/type/table.d.ts +8 -0
- package/lib/packages/components/table/src/type/tableAction.d.ts +12 -0
- package/lib/packages/types/global.d.ts +81 -0
- package/lib/packages/types/index.d.ts +27 -0
- package/lib/packages/utils/dateUtil.d.ts +7 -0
- package/lib/packages/utils/index.d.ts +11 -0
- package/lib/packages/utils/is/index.d.ts +22 -0
- package/lib/style.css +1 -1
- package/package.json +11 -5
- package/packages/component.ts +4 -3
- package/packages/components/form/index.tsx +10 -0
- package/packages/components/form/src/components/form-action.vue +135 -0
- package/packages/components/form/src/hook/index.ts +12 -0
- package/packages/components/form/src/hook/useForm.tsx +61 -0
- package/packages/components/form/src/hook/useFormContext.ts +12 -0
- package/packages/components/form/src/hook/useFormEvents.ts +272 -0
- package/packages/components/form/src/hook/useFormLabel.ts +42 -0
- package/packages/components/form/src/hook/useFormMethods.ts +134 -0
- package/packages/components/form/src/hook/useFormState.ts +80 -0
- package/packages/components/form/src/index.vue +124 -0
- package/packages/components/form/src/methods.ts +49 -0
- package/packages/components/form/src/plat-form-emits.ts +13 -0
- package/packages/components/form/src/plat-form-item.vue +418 -0
- package/packages/components/form/src/plat-form-props.ts +108 -0
- package/packages/components/form/src/types/component.ts +167 -0
- package/packages/components/form/src/types/form.ts +130 -0
- package/packages/components/form/src/types/index.ts +2 -0
- package/packages/components/table/index.ts +10 -0
- package/packages/components/table/src/components/index.ts +2 -0
- package/packages/components/table/src/components/table-action.vue +25 -0
- package/packages/components/table/src/components/tool-bar.vue +7 -0
- package/packages/components/table/src/hook/index.ts +2 -0
- package/packages/components/table/src/hook/useTableMethods.tsx +128 -0
- package/packages/components/table/src/hook/useTableState.tsx +92 -0
- package/packages/components/table/src/index.vue +93 -0
- package/packages/components/table/src/plat-table-emits.ts +3 -0
- package/packages/components/table/src/plat-table-props.ts +68 -0
- package/packages/components/table/src/type/column.ts +29 -0
- package/packages/components/table/src/type/index.ts +3 -0
- package/packages/components/table/src/type/table.ts +13 -0
- package/packages/components/table/src/type/tableAction.ts +13 -0
- package/packages/types/global.d.ts +81 -0
- package/packages/types/index.d.ts +27 -0
- package/packages/utils/dateUtil.ts +24 -0
- package/packages/utils/index.ts +33 -0
- package/packages/utils/is/index.ts +104 -0
- package/lib/packages/component.d.ts +0 -7
- package/lib/packages/components/card/index.d.ts +0 -2
- package/lib/packages/components/card/src/index.vue.d.ts +0 -2
- package/packages/components/card/index.tsx +0 -11
- package/packages/components/card/src/index.vue +0 -22
- package/packages/utils/className.ts +0 -28
package/packages/component.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 导出所有组件
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
4
|
+
import PlForm from './components/form'
|
|
5
|
+
import PlTable from './components/table'
|
|
5
6
|
|
|
6
|
-
export default [
|
|
7
|
+
export default [PlForm, PlTable]
|
|
7
8
|
|
|
8
|
-
export {
|
|
9
|
+
export { PlForm, PlTable }
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Col v-if="showActionButtonGroup" v-bind="actionColOpt">
|
|
3
|
+
<div
|
|
4
|
+
style="width: 100%"
|
|
5
|
+
:style="{ textAlign: actionColOpt.style.textAlign }"
|
|
6
|
+
>
|
|
7
|
+
<FormItem>
|
|
8
|
+
<slot name="resetBefore"></slot>
|
|
9
|
+
<AButton
|
|
10
|
+
type="default"
|
|
11
|
+
class="btn-mr"
|
|
12
|
+
v-bind="getResetBtnOptions"
|
|
13
|
+
@click="resetFields"
|
|
14
|
+
>
|
|
15
|
+
{{ getResetBtnOptions.text }}
|
|
16
|
+
</AButton>
|
|
17
|
+
<slot name="submitBefore"></slot>
|
|
18
|
+
<AButton
|
|
19
|
+
type="primary"
|
|
20
|
+
class="btn-mr"
|
|
21
|
+
v-bind="getSubmitBtnOptions"
|
|
22
|
+
@click="submit"
|
|
23
|
+
>
|
|
24
|
+
{{ getSubmitBtnOptions.text }}
|
|
25
|
+
</AButton>
|
|
26
|
+
<slot name="advanceBefore"></slot>
|
|
27
|
+
<AButton
|
|
28
|
+
v-if="showAdvancedButton && !hideAdvanceBtn"
|
|
29
|
+
type="link"
|
|
30
|
+
size="small"
|
|
31
|
+
@click="toggleAdvanced"
|
|
32
|
+
>
|
|
33
|
+
<BasicArrow class="ml-1" :expand="!isAdvanced" />
|
|
34
|
+
</AButton>
|
|
35
|
+
</FormItem>
|
|
36
|
+
</div>
|
|
37
|
+
</Col>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script lang="ts" setup name="platFormAction">
|
|
41
|
+
import { ExtractPropTypes, computed, type PropType } from 'vue'
|
|
42
|
+
import buttonProps from 'ant-design-vue/es/button/buttonTypes'
|
|
43
|
+
import { FormItem, Col } from 'ant-design-vue'
|
|
44
|
+
import { useFormContext } from '../hook'
|
|
45
|
+
import type { ColEx } from '../types'
|
|
46
|
+
type ButtonProps = Partial<ExtractPropTypes<typeof buttonProps>>
|
|
47
|
+
// { text: string } 主要用来显示按钮文字
|
|
48
|
+
type ButtonOptions = Partial<ButtonProps> & { text?: string }
|
|
49
|
+
|
|
50
|
+
defineOptions({
|
|
51
|
+
inheritAttrs: false
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const emit = defineEmits(['toggle-advanced'])
|
|
55
|
+
const props = defineProps({
|
|
56
|
+
showActionButtonGroup: {
|
|
57
|
+
type: Boolean,
|
|
58
|
+
default: true
|
|
59
|
+
},
|
|
60
|
+
showResetButton: {
|
|
61
|
+
type: Boolean,
|
|
62
|
+
default: true
|
|
63
|
+
},
|
|
64
|
+
showSubmitButton: {
|
|
65
|
+
type: Boolean,
|
|
66
|
+
default: true
|
|
67
|
+
},
|
|
68
|
+
showAdvancedButton: {
|
|
69
|
+
type: Boolean,
|
|
70
|
+
default: true
|
|
71
|
+
},
|
|
72
|
+
resetButtonOptions: {
|
|
73
|
+
type: Object as PropType<ButtonOptions>,
|
|
74
|
+
default: () => ({})
|
|
75
|
+
},
|
|
76
|
+
submitButtonOptions: {
|
|
77
|
+
type: Object as PropType<ButtonOptions>,
|
|
78
|
+
default: () => ({})
|
|
79
|
+
},
|
|
80
|
+
actionColOptions: {
|
|
81
|
+
type: Object as PropType<Partial<ColEx>>,
|
|
82
|
+
default: () => ({})
|
|
83
|
+
},
|
|
84
|
+
actionSpan: {
|
|
85
|
+
type: Number,
|
|
86
|
+
default: 6
|
|
87
|
+
},
|
|
88
|
+
isAdvanced: Boolean,
|
|
89
|
+
hideAdvanceBtn: Boolean
|
|
90
|
+
})
|
|
91
|
+
const { resetFields, submit } = useFormContext()
|
|
92
|
+
|
|
93
|
+
const actionColOpt = computed(() => {
|
|
94
|
+
const { showAdvancedButton, actionSpan: span, actionColOptions } = props
|
|
95
|
+
const actionSpan = 24 - span
|
|
96
|
+
const advancedSpanObj = showAdvancedButton
|
|
97
|
+
? { span: actionSpan < 6 ? 24 : actionSpan }
|
|
98
|
+
: {}
|
|
99
|
+
const actionColOpt: Partial<ColEx> = {
|
|
100
|
+
style: { textAlign: 'right' },
|
|
101
|
+
span: showAdvancedButton ? 6 : 4,
|
|
102
|
+
...advancedSpanObj,
|
|
103
|
+
...actionColOptions
|
|
104
|
+
}
|
|
105
|
+
return actionColOpt
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
const getResetBtnOptions = computed((): ButtonOptions => {
|
|
109
|
+
return Object.assign(
|
|
110
|
+
{
|
|
111
|
+
text: '重置'
|
|
112
|
+
},
|
|
113
|
+
props.resetButtonOptions
|
|
114
|
+
)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const getSubmitBtnOptions = computed((): ButtonOptions => {
|
|
118
|
+
return Object.assign(
|
|
119
|
+
{
|
|
120
|
+
text: '提交'
|
|
121
|
+
},
|
|
122
|
+
props.submitButtonOptions
|
|
123
|
+
)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
function toggleAdvanced() {
|
|
127
|
+
emit('toggle-advanced', props.isAdvanced)
|
|
128
|
+
}
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<style lang="less" scoped>
|
|
132
|
+
.btn-mr {
|
|
133
|
+
margin-right: 10px;
|
|
134
|
+
}
|
|
135
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FormState } from './useFormState'
|
|
2
|
+
import type { FormEvents } from './useFormEvents'
|
|
3
|
+
import type { FormMethods } from './useFormMethods'
|
|
4
|
+
|
|
5
|
+
export * from './useFormState'
|
|
6
|
+
export * from './useFormContext'
|
|
7
|
+
export * from './useFormMethods'
|
|
8
|
+
export * from './useFormEvents'
|
|
9
|
+
export * from './useFormLabel'
|
|
10
|
+
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
export type PlatFormType = FormState & FormEvents & FormMethods
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { nextTick, ref, unref, watch, onMounted } from 'vue'
|
|
2
|
+
import { isEmpty } from 'lodash-es'
|
|
3
|
+
import PlatForm from '../../index'
|
|
4
|
+
import type { Ref, SetupContext } from 'vue'
|
|
5
|
+
import type { PlatFormInstance, PlatFormProps } from '../plat-form-props'
|
|
6
|
+
|
|
7
|
+
export function useForm(props?: Partial<PlatFormProps>) {
|
|
8
|
+
const formRef = ref<PlatFormInstance>({} as PlatFormInstance)
|
|
9
|
+
async function getFormInstance() {
|
|
10
|
+
await nextTick()
|
|
11
|
+
const form = unref(formRef)
|
|
12
|
+
if (isEmpty(form)) {
|
|
13
|
+
console.error('未获取表单实例!')
|
|
14
|
+
}
|
|
15
|
+
return form
|
|
16
|
+
}
|
|
17
|
+
watch(
|
|
18
|
+
() => props,
|
|
19
|
+
() => {
|
|
20
|
+
props &&
|
|
21
|
+
onMounted(async () => {
|
|
22
|
+
;(await getFormInstance())?.setSchemaFormProps(props)
|
|
23
|
+
})
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
immediate: true,
|
|
27
|
+
deep: true
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const methods = new Proxy<Ref<PlatFormInstance>>(formRef, {
|
|
32
|
+
get(target, key) {
|
|
33
|
+
if (Reflect.has(target, key)) {
|
|
34
|
+
return unref(target)
|
|
35
|
+
}
|
|
36
|
+
if (Reflect.has(target.value, key)) {
|
|
37
|
+
return target.value[key]
|
|
38
|
+
}
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
return async (...rest) => {
|
|
41
|
+
const form = await getFormInstance()
|
|
42
|
+
return form?.[key](...rest)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const SchemaFormRender = (
|
|
48
|
+
compProps: Partial<PlatFormProps>,
|
|
49
|
+
{ attrs, slots }: SetupContext
|
|
50
|
+
) => {
|
|
51
|
+
return (
|
|
52
|
+
<PlatForm
|
|
53
|
+
ref={formRef}
|
|
54
|
+
{...{ ...attrs, ...props, ...compProps }}
|
|
55
|
+
v-slots={slots}
|
|
56
|
+
></PlatForm>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return [SchemaFormRender, unref(methods)] as const
|
|
61
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { provide, inject } from 'vue'
|
|
2
|
+
import type { PlatFormType } from '../hook'
|
|
3
|
+
|
|
4
|
+
const key = Symbol('plat-form')
|
|
5
|
+
// todo any需要修改
|
|
6
|
+
export async function createFormContext(instance: PlatFormType) {
|
|
7
|
+
provide(key, instance)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function useFormContext() {
|
|
11
|
+
return inject(key) as PlatFormType
|
|
12
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { unref, toRaw } from 'vue'
|
|
2
|
+
import dayjs from 'dayjs'
|
|
3
|
+
import { cloneDeep, uniqBy } from 'lodash-es'
|
|
4
|
+
import { dateItemType, handleInputNumberValue } from '../methods'
|
|
5
|
+
import { isArray, isFunction, isObject, isString } from '../../../../utils/is'
|
|
6
|
+
import { deepMerge } from '../../../../utils'
|
|
7
|
+
import type { FormState } from './useFormState'
|
|
8
|
+
import type { PlatFormEmitFn } from '../plat-form-emits'
|
|
9
|
+
import type { FormMethods } from '../hook'
|
|
10
|
+
import type { NamePath } from 'ant-design-vue/lib/form/interface'
|
|
11
|
+
import type { FormSchema } from '../types'
|
|
12
|
+
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
export type FormEvents = ReturnType<typeof useFormEvents>
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
type UseFormActionContext = FormState & {
|
|
17
|
+
emit: PlatFormEmitFn
|
|
18
|
+
handleFormValues: FormMethods['handleFormValues']
|
|
19
|
+
}
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
export function useFormEvents(formActionContext: UseFormActionContext) {
|
|
22
|
+
const {
|
|
23
|
+
emit,
|
|
24
|
+
formPropsRef,
|
|
25
|
+
formSchemasRef,
|
|
26
|
+
formModel,
|
|
27
|
+
cacheFormModel,
|
|
28
|
+
getFormProps,
|
|
29
|
+
platFormRef,
|
|
30
|
+
defaultFormValues,
|
|
31
|
+
handleFormValues
|
|
32
|
+
} = formActionContext
|
|
33
|
+
|
|
34
|
+
function getFieldsValue(): Recordable {
|
|
35
|
+
const formEl = unref(platFormRef)
|
|
36
|
+
if (!formEl) return {}
|
|
37
|
+
return handleFormValues(toRaw(unref(formModel)))
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* @description: Is it time
|
|
41
|
+
*/
|
|
42
|
+
function itemIsDateType(key: string) {
|
|
43
|
+
return unref(formPropsRef).schemas?.some((item) => {
|
|
44
|
+
return item.field === key && isString(item.component)
|
|
45
|
+
? dateItemType.includes(item.component)
|
|
46
|
+
: false
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @description 更新formItemSchema
|
|
52
|
+
*/
|
|
53
|
+
async function updateSchema(
|
|
54
|
+
data: Partial<FormSchema> | Partial<FormSchema>[]
|
|
55
|
+
) {
|
|
56
|
+
let updateData: Partial<FormSchema>[] = []
|
|
57
|
+
if (isObject(data)) {
|
|
58
|
+
updateData.push(data as FormSchema)
|
|
59
|
+
}
|
|
60
|
+
if (isArray(data)) {
|
|
61
|
+
updateData = [...data]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const hasField = updateData.every(
|
|
65
|
+
(item) =>
|
|
66
|
+
item.component === 'Divider' ||
|
|
67
|
+
(Reflect.has(item, 'field') && item.field)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if (!hasField) {
|
|
71
|
+
console.error(
|
|
72
|
+
'All children of the form Schema array that need to be updated must contain the `field` field'
|
|
73
|
+
)
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
const schemas: FormSchema[] = []
|
|
77
|
+
updateData.forEach((item) => {
|
|
78
|
+
unref(formSchemasRef).forEach((val) => {
|
|
79
|
+
if (val.field === item.field) {
|
|
80
|
+
const newSchema = deepMerge(val, item)
|
|
81
|
+
schemas.push(newSchema)
|
|
82
|
+
} else {
|
|
83
|
+
schemas.push(val)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
unref(formPropsRef).schemas = uniqBy(schemas, 'field')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @description: 插入到指定 filed 后面,如果没传指定 field,则插入到最后,当 first = true 时插入到第一个位置
|
|
94
|
+
*/
|
|
95
|
+
async function appendSchemaByField(
|
|
96
|
+
schemaItem: FormSchema,
|
|
97
|
+
prefixField?: string,
|
|
98
|
+
first = false
|
|
99
|
+
) {
|
|
100
|
+
const schemaList = cloneDeep<FormSchema[]>(unref(formSchemasRef))
|
|
101
|
+
|
|
102
|
+
const index = schemaList.findIndex((schema) => schema.field === prefixField)
|
|
103
|
+
|
|
104
|
+
if (!prefixField || index === -1 || first) {
|
|
105
|
+
first ? schemaList.unshift(schemaItem) : schemaList.push(schemaItem)
|
|
106
|
+
formModel[schemaItem.field] = schemaItem.defaultValue
|
|
107
|
+
formPropsRef.value.schemas = schemaList
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
if (index !== -1) {
|
|
111
|
+
schemaList.splice(index + 1, 0, schemaItem)
|
|
112
|
+
}
|
|
113
|
+
formModel[schemaItem.field] = schemaItem.defaultValue
|
|
114
|
+
formPropsRef.value.schemas = schemaList
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @description: 根据 field 删除 Schema
|
|
119
|
+
*/
|
|
120
|
+
async function removeSchemaByFiled(fields: string | string[]): Promise<void> {
|
|
121
|
+
const schemaList = cloneDeep<FormSchema[]>(unref(formSchemasRef))
|
|
122
|
+
|
|
123
|
+
if (!fields) {
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let fieldList: string[] = isString(fields) ? [fields] : fields
|
|
128
|
+
if (isString(fields)) {
|
|
129
|
+
fieldList = [fields]
|
|
130
|
+
}
|
|
131
|
+
for (const field of fieldList) {
|
|
132
|
+
if (isString(field)) {
|
|
133
|
+
const index = schemaList.findIndex((schema) => schema.field === field)
|
|
134
|
+
if (index !== -1) {
|
|
135
|
+
Reflect.deleteProperty(formModel, field)
|
|
136
|
+
schemaList.splice(index, 1)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
formPropsRef.value.schemas = schemaList
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function resetSchema(
|
|
144
|
+
data: Partial<FormSchema> | Partial<FormSchema>[]
|
|
145
|
+
) {
|
|
146
|
+
let updateData: Partial<FormSchema>[] = []
|
|
147
|
+
if (isObject(data)) {
|
|
148
|
+
updateData.push(data as FormSchema)
|
|
149
|
+
}
|
|
150
|
+
if (isArray(data)) {
|
|
151
|
+
updateData = [...data]
|
|
152
|
+
}
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
unref(formPropsRef).schemas = updateData as FormSchema[]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @description: 设置表单字段值
|
|
159
|
+
*/
|
|
160
|
+
async function setFieldsValue(values: Recordable): Promise<void> {
|
|
161
|
+
const schemas = unref(formSchemasRef)
|
|
162
|
+
const fields = schemas.map((item) => item.field).filter(Boolean)
|
|
163
|
+
|
|
164
|
+
Object.assign(cacheFormModel, values)
|
|
165
|
+
|
|
166
|
+
const validKeys: string[] = []
|
|
167
|
+
Object.keys(values).forEach((key) => {
|
|
168
|
+
const schema = schemas.find((item) => item.field === key)
|
|
169
|
+
let value = values[key]
|
|
170
|
+
|
|
171
|
+
const hasKey = Reflect.has(values, key)
|
|
172
|
+
if (isString(schema?.component)) {
|
|
173
|
+
value = handleInputNumberValue(schema?.component, value)
|
|
174
|
+
}
|
|
175
|
+
// 0| '' is allow
|
|
176
|
+
if (hasKey && fields.includes(key)) {
|
|
177
|
+
// time type
|
|
178
|
+
if (itemIsDateType(key)) {
|
|
179
|
+
if (Array.isArray(value)) {
|
|
180
|
+
const arr: any[] = []
|
|
181
|
+
for (const ele of value) {
|
|
182
|
+
arr.push(ele ? dayjs(ele) : null)
|
|
183
|
+
}
|
|
184
|
+
formModel[key] = arr
|
|
185
|
+
} else {
|
|
186
|
+
const { componentProps } = schema || {}
|
|
187
|
+
let _props = componentProps as any
|
|
188
|
+
if (isFunction(componentProps)) {
|
|
189
|
+
_props = _props({ formPropsRef, formModel })
|
|
190
|
+
}
|
|
191
|
+
formModel[key] = value
|
|
192
|
+
? _props?.valueFormat
|
|
193
|
+
? value
|
|
194
|
+
: dayjs(value)
|
|
195
|
+
: null
|
|
196
|
+
}
|
|
197
|
+
} else {
|
|
198
|
+
formModel[key] = value
|
|
199
|
+
}
|
|
200
|
+
validKeys.push(key)
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
validateFields(validKeys)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async function resetFields(): Promise<void> {
|
|
207
|
+
const { resetFunc, submitOnReset } = unref(getFormProps)
|
|
208
|
+
resetFunc && isFunction(resetFunc) && (await resetFunc())
|
|
209
|
+
|
|
210
|
+
Object.keys(formModel).forEach((key) => {
|
|
211
|
+
formModel[key] = defaultFormValues[key]
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
emit('reset', formModel)
|
|
215
|
+
submitOnReset && handleSubmit()
|
|
216
|
+
await clearValidate()
|
|
217
|
+
// setTimeout(clearValidate)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function validateFields(nameList?: NamePath[] | undefined) {
|
|
221
|
+
return platFormRef.value?.validateFields(nameList)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function validate(nameList?: NamePath[] | undefined) {
|
|
225
|
+
return await platFormRef.value?.validate(nameList)!
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async function clearValidate(name?: string | string[]) {
|
|
229
|
+
await platFormRef.value?.clearValidate(name)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async function scrollToField(
|
|
233
|
+
name: NamePath,
|
|
234
|
+
options?: ScrollOptions | undefined
|
|
235
|
+
) {
|
|
236
|
+
await platFormRef.value?.scrollToField(name, options)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// todo 需要测试一下
|
|
240
|
+
async function handleSubmit(e?: Event): Promise<void> {
|
|
241
|
+
e && e.preventDefault()
|
|
242
|
+
const { submitFunc } = unref(getFormProps)
|
|
243
|
+
if (submitFunc && isFunction(submitFunc)) {
|
|
244
|
+
await submitFunc()
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
const formEl = unref(platFormRef)
|
|
248
|
+
if (!formEl) return
|
|
249
|
+
try {
|
|
250
|
+
const values = await validate()
|
|
251
|
+
const res = handleFormValues(values)
|
|
252
|
+
emit('submit', res)
|
|
253
|
+
} catch (error: any) {
|
|
254
|
+
return Promise.reject(error)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return {
|
|
259
|
+
submit: handleSubmit,
|
|
260
|
+
clearValidate,
|
|
261
|
+
validate,
|
|
262
|
+
validateFields,
|
|
263
|
+
getFieldsValue,
|
|
264
|
+
updateSchema,
|
|
265
|
+
resetSchema,
|
|
266
|
+
appendSchemaByField,
|
|
267
|
+
removeSchemaByFiled,
|
|
268
|
+
resetFields,
|
|
269
|
+
setFieldsValue,
|
|
270
|
+
scrollToField
|
|
271
|
+
}
|
|
272
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { unref } from 'vue'
|
|
2
|
+
import type { Ref } from 'vue'
|
|
3
|
+
import type { FormSchema } from '../types'
|
|
4
|
+
import type { PlatFormProps } from '../plat-form-props'
|
|
5
|
+
import { isNumber } from '../../../../utils/is'
|
|
6
|
+
|
|
7
|
+
export function useFormLabel(
|
|
8
|
+
schemaRef: Ref<FormSchema>,
|
|
9
|
+
formPropsRef: Ref<PlatFormProps>
|
|
10
|
+
) {
|
|
11
|
+
const schemaItem = unref(schemaRef)
|
|
12
|
+
const { labelCol = {}, wrapperCol = {} } = schemaItem.formItemProps || {}
|
|
13
|
+
const { labelWidth, disabledLabelWidth } = schemaItem
|
|
14
|
+
const {
|
|
15
|
+
labelWidth: globalLabelWidth,
|
|
16
|
+
labelCol: globalLabelCol,
|
|
17
|
+
wrapperCol: globWrapperCol
|
|
18
|
+
} = unref(formPropsRef)
|
|
19
|
+
|
|
20
|
+
// 如果labelWidth是全局设置的,则会设置所有项
|
|
21
|
+
if (
|
|
22
|
+
(!globalLabelWidth && !labelWidth && !globalLabelCol) ||
|
|
23
|
+
disabledLabelWidth
|
|
24
|
+
) {
|
|
25
|
+
labelCol.style = {
|
|
26
|
+
textAlign: 'left'
|
|
27
|
+
}
|
|
28
|
+
return { labelCol, wrapperCol }
|
|
29
|
+
}
|
|
30
|
+
let width = labelWidth || globalLabelWidth
|
|
31
|
+
const col = { ...globalLabelCol, ...labelCol }
|
|
32
|
+
const wrapCol = { ...globWrapperCol, ...wrapperCol }
|
|
33
|
+
|
|
34
|
+
if (width) {
|
|
35
|
+
width = isNumber(width) ? `${width}px` : width
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
labelCol: { style: { width }, ...col },
|
|
40
|
+
wrapperCol: { style: { width: `calc(100% - ${width})` }, ...wrapCol }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { unref } from 'vue'
|
|
2
|
+
import { set } from 'lodash-es'
|
|
3
|
+
import { deepMerge } from '../../../../utils'
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import { dateUtil } from '../../../../utils/dateUtil'
|
|
6
|
+
import {
|
|
7
|
+
isFunction,
|
|
8
|
+
isNullOrUnDef,
|
|
9
|
+
isObject,
|
|
10
|
+
isArray,
|
|
11
|
+
isString
|
|
12
|
+
} from '../../../../utils/is'
|
|
13
|
+
import type { FormState } from './useFormState'
|
|
14
|
+
import type { FormSchema } from '../types'
|
|
15
|
+
import type { PlatFormProps } from '../plat-form-props'
|
|
16
|
+
// deepMerge 深度合并
|
|
17
|
+
|
|
18
|
+
export type FormMethods = ReturnType<typeof useFormMethods>
|
|
19
|
+
|
|
20
|
+
type UseFormMethodsContext = FormState
|
|
21
|
+
|
|
22
|
+
export const useFormMethods = (formMethodsContext: UseFormMethodsContext) => {
|
|
23
|
+
const {
|
|
24
|
+
compRefs,
|
|
25
|
+
formModel,
|
|
26
|
+
formPropsRef,
|
|
27
|
+
cacheFormModel,
|
|
28
|
+
defaultFormValues,
|
|
29
|
+
platFormRef,
|
|
30
|
+
getFormProps
|
|
31
|
+
} = formMethodsContext
|
|
32
|
+
|
|
33
|
+
// 将所有的表单组件实例保存起来
|
|
34
|
+
const setItemRef = (formItem: FormSchema) => {
|
|
35
|
+
return (el) => {
|
|
36
|
+
if (el) {
|
|
37
|
+
compRefs[formItem.field] = el
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// todo 设置某个字段的值
|
|
43
|
+
const setFormModel = (key: string, value: any) => {
|
|
44
|
+
formModel[key] = value
|
|
45
|
+
cacheFormModel[key] = value
|
|
46
|
+
const { validateTrigger } = unref(getFormProps)
|
|
47
|
+
if (!validateTrigger || validateTrigger === 'change') {
|
|
48
|
+
platFormRef.value?.validateFields([key])
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 更新表单props
|
|
53
|
+
const setSchemaFormProps = (formProps: Partial<PlatFormProps>) => {
|
|
54
|
+
formPropsRef.value = deepMerge(unref(formPropsRef) || {}, formProps)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Processing form values
|
|
58
|
+
function handleFormValues(values: Recordable) {
|
|
59
|
+
if (!isObject(values)) {
|
|
60
|
+
return {}
|
|
61
|
+
}
|
|
62
|
+
const res: Recordable = {}
|
|
63
|
+
for (const item of Object.entries(values)) {
|
|
64
|
+
let [, value] = item
|
|
65
|
+
const [key] = item
|
|
66
|
+
if (!key || (isArray(value) && value.length === 0) || isFunction(value)) {
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
const transformDateFunc = unref(getFormProps).transformDateFunc
|
|
70
|
+
if (isObject(value)) {
|
|
71
|
+
value = transformDateFunc?.(value)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isArray(value) && value[0]?.format && value[1]?.format) {
|
|
75
|
+
value = value.map((item) => transformDateFunc?.(item))
|
|
76
|
+
}
|
|
77
|
+
// Remove spaces
|
|
78
|
+
if (isString(value)) {
|
|
79
|
+
value = value.trim()
|
|
80
|
+
}
|
|
81
|
+
set(res, key, value)
|
|
82
|
+
}
|
|
83
|
+
return handleRangeTimeValue(res)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @description: Processing time interval parameters
|
|
88
|
+
*/
|
|
89
|
+
function handleRangeTimeValue(values: Recordable) {
|
|
90
|
+
const fieldMapToTime = unref(getFormProps).fieldMapToTime
|
|
91
|
+
|
|
92
|
+
if (!fieldMapToTime || !Array.isArray(fieldMapToTime)) {
|
|
93
|
+
return values
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const [
|
|
97
|
+
field,
|
|
98
|
+
[startTimeKey, endTimeKey],
|
|
99
|
+
format = 'YYYY-MM-DD'
|
|
100
|
+
] of fieldMapToTime) {
|
|
101
|
+
if (!field || !startTimeKey || !endTimeKey || !values[field]) {
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const [startTime, endTime]: string[] = values[field]
|
|
106
|
+
|
|
107
|
+
values[startTimeKey] = dateUtil(startTime).format(format)
|
|
108
|
+
values[endTimeKey] = dateUtil(endTime).format(format)
|
|
109
|
+
Reflect.deleteProperty(values, field)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return values
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 初始化数据
|
|
116
|
+
const initFormValues = () => {
|
|
117
|
+
unref(formPropsRef).schemas?.forEach((item) => {
|
|
118
|
+
const { defaultValue } = item
|
|
119
|
+
if (!isNullOrUnDef(defaultValue)) {
|
|
120
|
+
formModel[item.field] = defaultValue
|
|
121
|
+
defaultFormValues[item.field] = defaultValue
|
|
122
|
+
cacheFormModel[item.field] = defaultValue
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
setItemRef,
|
|
129
|
+
initFormValues,
|
|
130
|
+
setFormModel,
|
|
131
|
+
setSchemaFormProps,
|
|
132
|
+
handleFormValues
|
|
133
|
+
}
|
|
134
|
+
}
|