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.
Files changed (74) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/Readme.md +7 -38
  3. package/lib/fx-platform-ui.mjs +32182 -9268
  4. package/lib/fx-platform-ui.umd.js +58 -14
  5. package/lib/packages/components/form/index.d.ts +2 -0
  6. package/lib/packages/components/form/src/hook/index.d.ts +9 -0
  7. package/lib/packages/components/form/src/hook/useFormContext.d.ts +3 -0
  8. package/lib/packages/components/form/src/hook/useFormEvents.d.ts +29 -0
  9. package/lib/packages/components/form/src/hook/useFormLabel.d.ts +79 -0
  10. package/lib/packages/components/form/src/hook/useFormMethods.d.ts +13 -0
  11. package/lib/packages/components/form/src/methods.d.ts +7 -0
  12. package/lib/packages/components/form/src/plat-form-emits.d.ts +9 -0
  13. package/lib/packages/components/form/src/types/form.d.ts +70 -0
  14. package/lib/packages/components/form/src/types/index.d.ts +2 -0
  15. package/lib/packages/components/table/index.d.ts +2 -0
  16. package/lib/packages/components/table/src/components/index.d.ts +2 -0
  17. package/lib/packages/components/table/src/components/tool-bar.vue.d.ts +2 -0
  18. package/lib/packages/components/table/src/hook/index.d.ts +2 -0
  19. package/lib/packages/components/table/src/hook/useTableMethods.d.ts +21 -0
  20. package/lib/packages/components/table/src/plat-table-emits.d.ts +2 -0
  21. package/lib/packages/components/table/src/type/column.d.ts +24 -0
  22. package/lib/packages/components/table/src/type/index.d.ts +3 -0
  23. package/lib/packages/components/table/src/type/table.d.ts +8 -0
  24. package/lib/packages/components/table/src/type/tableAction.d.ts +12 -0
  25. package/lib/packages/types/global.d.ts +81 -0
  26. package/lib/packages/types/index.d.ts +27 -0
  27. package/lib/packages/utils/dateUtil.d.ts +7 -0
  28. package/lib/packages/utils/index.d.ts +11 -0
  29. package/lib/packages/utils/is/index.d.ts +22 -0
  30. package/lib/style.css +1 -1
  31. package/package.json +11 -5
  32. package/packages/component.ts +4 -3
  33. package/packages/components/form/index.tsx +10 -0
  34. package/packages/components/form/src/components/form-action.vue +135 -0
  35. package/packages/components/form/src/hook/index.ts +12 -0
  36. package/packages/components/form/src/hook/useForm.tsx +61 -0
  37. package/packages/components/form/src/hook/useFormContext.ts +12 -0
  38. package/packages/components/form/src/hook/useFormEvents.ts +272 -0
  39. package/packages/components/form/src/hook/useFormLabel.ts +42 -0
  40. package/packages/components/form/src/hook/useFormMethods.ts +134 -0
  41. package/packages/components/form/src/hook/useFormState.ts +80 -0
  42. package/packages/components/form/src/index.vue +124 -0
  43. package/packages/components/form/src/methods.ts +49 -0
  44. package/packages/components/form/src/plat-form-emits.ts +13 -0
  45. package/packages/components/form/src/plat-form-item.vue +418 -0
  46. package/packages/components/form/src/plat-form-props.ts +108 -0
  47. package/packages/components/form/src/types/component.ts +167 -0
  48. package/packages/components/form/src/types/form.ts +130 -0
  49. package/packages/components/form/src/types/index.ts +2 -0
  50. package/packages/components/table/index.ts +10 -0
  51. package/packages/components/table/src/components/index.ts +2 -0
  52. package/packages/components/table/src/components/table-action.vue +25 -0
  53. package/packages/components/table/src/components/tool-bar.vue +7 -0
  54. package/packages/components/table/src/hook/index.ts +2 -0
  55. package/packages/components/table/src/hook/useTableMethods.tsx +128 -0
  56. package/packages/components/table/src/hook/useTableState.tsx +92 -0
  57. package/packages/components/table/src/index.vue +93 -0
  58. package/packages/components/table/src/plat-table-emits.ts +3 -0
  59. package/packages/components/table/src/plat-table-props.ts +68 -0
  60. package/packages/components/table/src/type/column.ts +29 -0
  61. package/packages/components/table/src/type/index.ts +3 -0
  62. package/packages/components/table/src/type/table.ts +13 -0
  63. package/packages/components/table/src/type/tableAction.ts +13 -0
  64. package/packages/types/global.d.ts +81 -0
  65. package/packages/types/index.d.ts +27 -0
  66. package/packages/utils/dateUtil.ts +24 -0
  67. package/packages/utils/index.ts +33 -0
  68. package/packages/utils/is/index.ts +104 -0
  69. package/lib/packages/component.d.ts +0 -7
  70. package/lib/packages/components/card/index.d.ts +0 -2
  71. package/lib/packages/components/card/src/index.vue.d.ts +0 -2
  72. package/packages/components/card/index.tsx +0 -11
  73. package/packages/components/card/src/index.vue +0 -22
  74. package/packages/utils/className.ts +0 -28
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * 导出所有组件
3
3
  */
4
- import PlCard from './components/card'
4
+ import PlForm from './components/form'
5
+ import PlTable from './components/table'
5
6
 
6
- export default [PlCard]
7
+ export default [PlForm, PlTable]
7
8
 
8
- export { PlCard }
9
+ export { PlForm, PlTable }
@@ -0,0 +1,10 @@
1
+ import { App } from 'vue'
2
+
3
+ import PlForm from './src/index.vue'
4
+ PlForm.install = function (app: App) {
5
+ // 组件注册,按需引入
6
+ app.component(PlForm.name, PlForm)
7
+ return app
8
+ }
9
+
10
+ export default PlForm
@@ -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
+ }