|
@@ -1,5 +1,8 @@
|
|
-import { forwardRef, memo, useImperativeHandle } from 'react'
|
|
|
|
-import { Form, Input, Select } from 'antd'
|
|
|
|
|
|
+import { forwardRef, memo, useEffect, useImperativeHandle } from 'react'
|
|
|
|
+import { dictMapping, useNoAuthDict } from '@/hooks/useDict'
|
|
|
|
+import { DatePicker, Form, Input, InputNumber, Select } from 'antd'
|
|
|
|
+
|
|
|
|
+const { RangePicker } = DatePicker
|
|
|
|
|
|
export interface DynamicFormRef {
|
|
export interface DynamicFormRef {
|
|
onSubmit: () => void
|
|
onSubmit: () => void
|
|
@@ -20,53 +23,221 @@ const DynamicForm = memo(
|
|
onSubmit
|
|
onSubmit
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
+
|
|
|
|
+ const { dictArray: inputUnitTypeOptions, dictRequestFn: getInputUnitTypeOptions } =
|
|
|
|
+ useNoAuthDict('input_unit_type')
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ getInputUnitTypeOptions()
|
|
|
|
+ }, [])
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ console.log(inputUnitTypeOptions)
|
|
|
|
+ }, [inputUnitTypeOptions])
|
|
|
|
+
|
|
|
|
+ const [form] = Form.useForm()
|
|
|
|
+ const onSubmit = () => {
|
|
|
|
+ form.submit()
|
|
|
|
+ }
|
|
|
|
+ const onFinish = (values: any) => {
|
|
|
|
+ console.log('Finish:', values)
|
|
|
|
+ for (const key in values) {
|
|
|
|
+ if (values[key]) {
|
|
|
|
+ console.log(values[key].format('YYYY-MM-DD'))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ const onFinishFailed = (errorInfo: any) => {
|
|
|
|
+ console.log('Failed:', errorInfo)
|
|
|
|
+ }
|
|
console.log(formData)
|
|
console.log(formData)
|
|
console.log(formItems)
|
|
console.log(formItems)
|
|
console.log(setFormData)
|
|
console.log(setFormData)
|
|
|
|
|
|
|
|
+ const FieldWrapper = (props: { children: React.ReactNode }) => {
|
|
|
|
+ return (
|
|
|
|
+ <div className='px-[20px] py-[16px] mb-[16px] rounded-[10px] bg-[#ecf5ff]'>
|
|
|
|
+ {props.children}
|
|
|
|
+ </div>
|
|
|
|
+ )
|
|
|
|
+ }
|
|
const renderField = (field: API.TmplItem) => {
|
|
const renderField = (field: API.TmplItem) => {
|
|
const options = field.itemStruct
|
|
const options = field.itemStruct
|
|
- const { type, label, placeholder, visible, valid, expand, widgetId } = options!
|
|
|
|
- // if (hidden && hidden(form.getFieldsValue())) return null // 条件渲染
|
|
|
|
- console.log(visible)
|
|
|
|
|
|
+ const { type, label, desc, placeholder, visible, valid, expand, widgetId } = options!
|
|
|
|
+ if (!visible) return null // 条件渲染
|
|
console.log(valid)
|
|
console.log(valid)
|
|
|
|
|
|
|
|
+ const labelContent = (
|
|
|
|
+ <div>
|
|
|
|
+ <div>{label.text}</div>
|
|
|
|
+ {desc && (
|
|
|
|
+ <div className='text-text-secondary mt-[4px]' style={{ fontSize: '12px' }}>
|
|
|
|
+ {desc}
|
|
|
|
+ </div>
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ )
|
|
switch (type) {
|
|
switch (type) {
|
|
- case 'INPUT':
|
|
|
|
|
|
+ case 'INPUT': {
|
|
|
|
+ const expandVal = expand as API.FD_COM['INPUT']
|
|
|
|
+
|
|
|
|
+ return (
|
|
|
|
+ <FieldWrapper key={widgetId}>
|
|
|
|
+ <Form.Item name={widgetId} label={labelContent} style={{ marginBottom: 0 }}>
|
|
|
|
+ <Input
|
|
|
|
+ placeholder={placeholder}
|
|
|
|
+ maxLength={parseInt(expandVal.maxChars)}
|
|
|
|
+ prefix={expandVal.prefix}
|
|
|
|
+ suffix={expandVal.suffix}
|
|
|
|
+ showCount
|
|
|
|
+ allowClear
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </FieldWrapper>
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ case 'NUMBER_INPUT': {
|
|
|
|
+ const expandVal = expand as API.FD_COM['NUMBER_INPUT']
|
|
|
|
+ const min = typeof expandVal.min === 'number' ? expandVal.min : undefined
|
|
|
|
+ const max = typeof expandVal.max === 'number' ? expandVal.max : undefined
|
|
|
|
+ const decimalDigits = expandVal.decimalPlacesNumber || 0
|
|
|
|
+
|
|
return (
|
|
return (
|
|
- <Form.Item name={widgetId} label={label.text} key={widgetId}>
|
|
|
|
- <Input
|
|
|
|
- placeholder={placeholder}
|
|
|
|
- maxLength={parseInt((expand as API.FD_COM['INPUT']).maxChars)}
|
|
|
|
- showCount
|
|
|
|
- prefix={(expand as API.FD_COM['INPUT']).prefix}
|
|
|
|
- suffix={(expand as API.FD_COM['INPUT']).suffix}
|
|
|
|
- />
|
|
|
|
- </Form.Item>
|
|
|
|
|
|
+ <FieldWrapper key={widgetId}>
|
|
|
|
+ <Form.Item name={widgetId} label={labelContent} style={{ marginBottom: 0 }}>
|
|
|
|
+ <InputNumber
|
|
|
|
+ className='!w-full'
|
|
|
|
+ placeholder={`${min !== undefined ? '最小值:' + min.toFixed(decimalDigits) + ';' : ''}${
|
|
|
|
+ max !== undefined ? '最大值:' + max.toFixed(decimalDigits) + ';' : ''
|
|
|
|
+ }${'小数位数:' + decimalDigits + ';'}`}
|
|
|
|
+ maxLength={parseInt(expandVal.maxChars)}
|
|
|
|
+ prefix={expandVal.prefix}
|
|
|
|
+ suffix={
|
|
|
|
+ (expandVal.suffix ||
|
|
|
|
+ (expandVal.featureType === 'NUMBER' && expandVal.unit)) &&
|
|
|
|
+ (expandVal.featureType === 'NUMBER' && expandVal.unit !== 'NONE'
|
|
|
|
+ ? expandVal.unit
|
|
|
|
+ : expandVal.suffix)
|
|
|
|
+ }
|
|
|
|
+ min={min}
|
|
|
|
+ max={max}
|
|
|
|
+ precision={decimalDigits}
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </FieldWrapper>
|
|
)
|
|
)
|
|
- case 'SELECT':
|
|
|
|
|
|
+ }
|
|
|
|
+ case 'AMOUNT_INPUT': {
|
|
|
|
+ const expandVal = expand as API.FD_COM['NUMBER_INPUT']
|
|
|
|
+ const min = typeof expandVal.min === 'number' ? expandVal.min : undefined
|
|
|
|
+ const max = typeof expandVal.max === 'number' ? expandVal.max : undefined
|
|
|
|
+ const decimalDigits = expandVal.decimalPlacesNumber || 0
|
|
|
|
+
|
|
|
|
+ return (
|
|
|
|
+ <FieldWrapper key={widgetId}>
|
|
|
|
+ <Form.Item name={widgetId} label={labelContent} style={{ marginBottom: 0 }}>
|
|
|
|
+ <InputNumber
|
|
|
|
+ className='!w-full'
|
|
|
|
+ placeholder={`${min !== undefined ? '最小值:' + min.toFixed(decimalDigits) + ';' : ''}${
|
|
|
|
+ max !== undefined ? '最大值:' + max.toFixed(decimalDigits) + ';' : ''
|
|
|
|
+ }${'小数位数:' + decimalDigits + ';'}`}
|
|
|
|
+ maxLength={parseInt(expandVal.maxChars)}
|
|
|
|
+ prefix={expandVal.prefix}
|
|
|
|
+ suffix={
|
|
|
|
+ (expandVal.suffix || expandVal.unit) &&
|
|
|
|
+ (expandVal.unit
|
|
|
|
+ ? dictMapping({ unit: expandVal.unit }, 'unit', inputUnitTypeOptions)
|
|
|
|
+ : expandVal.suffix)
|
|
|
|
+ }
|
|
|
|
+ min={min}
|
|
|
|
+ max={max}
|
|
|
|
+ precision={decimalDigits}
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </FieldWrapper>
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ case 'SELECT': {
|
|
|
|
+ const expandVal = expand as API.FD_COM['SELECT']
|
|
|
|
+
|
|
return (
|
|
return (
|
|
- <Form.Item name={widgetId} label={label.text} key={widgetId}>
|
|
|
|
- <Select placeholder={placeholder} />
|
|
|
|
- </Form.Item>
|
|
|
|
|
|
+ <FieldWrapper key={widgetId}>
|
|
|
|
+ <Form.Item name={widgetId} label={labelContent} style={{ marginBottom: 0 }}>
|
|
|
|
+ <Select
|
|
|
|
+ mode={expandVal.multiple ? 'multiple' : undefined}
|
|
|
|
+ placeholder={placeholder}
|
|
|
|
+ options={expandVal.userInput}
|
|
|
|
+ allowClear
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </FieldWrapper>
|
|
)
|
|
)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case 'DATETIME_PICKER': {
|
|
|
|
+ const expandVal = expand as API.FD_COM['DATETIME_PICKER']
|
|
|
|
+
|
|
|
|
+ const datePickerType = expandVal.dateType.toLowerCase()
|
|
|
|
+ const datePickerTypeMap = {
|
|
|
|
+ year: { picker: 'year', showTime: false, dateFormat: 'YYYY' },
|
|
|
|
+ month: { picker: 'month', showTime: false, dateFormat: 'YYYY-MM' },
|
|
|
|
+ date: { picker: undefined, showTime: false, dateFormat: 'YYYY-MM-DD' },
|
|
|
|
+ week: { picker: 'week', showTime: false, dateFormat: 'YYYY-WW' },
|
|
|
|
+ datetime: { picker: undefined, showTime: true, dateFormat: 'YYYY-MM-DD HH:mm:ss' },
|
|
|
|
+ daterange: { picker: 'range', showTime: false, dateFormat: 'YYYY-MM-DD' },
|
|
|
|
+ datetimerange: { picker: 'range', showTime: true, dateFormat: 'YYYY-MM-DD HH:mm:ss' }
|
|
|
|
+ }
|
|
|
|
+ if (!datePickerType.includes('range')) {
|
|
|
|
+ return (
|
|
|
|
+ <FieldWrapper key={widgetId}>
|
|
|
|
+ {datePickerType}
|
|
|
|
+ {datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap].dateFormat}
|
|
|
|
+ <Form.Item name={widgetId} label={labelContent} style={{ marginBottom: 0 }}>
|
|
|
|
+ <DatePicker
|
|
|
|
+ className='w-full'
|
|
|
|
+ picker={
|
|
|
|
+ datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap]
|
|
|
|
+ .picker as any
|
|
|
|
+ }
|
|
|
|
+ showTime={
|
|
|
|
+ datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap].showTime
|
|
|
|
+ }
|
|
|
|
+ format={
|
|
|
|
+ datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap]
|
|
|
|
+ .dateFormat
|
|
|
|
+ }
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </FieldWrapper>
|
|
|
|
+ )
|
|
|
|
+ } else {
|
|
|
|
+ return (
|
|
|
|
+ <FieldWrapper key={widgetId}>
|
|
|
|
+ {datePickerType}
|
|
|
|
+ <Form.Item name={widgetId} label={labelContent} style={{ marginBottom: 0 }}>
|
|
|
|
+ <RangePicker
|
|
|
|
+ className='w-full'
|
|
|
|
+ picker={
|
|
|
|
+ datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap]
|
|
|
|
+ .picker as any
|
|
|
|
+ }
|
|
|
|
+ showTime={
|
|
|
|
+ datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap].showTime
|
|
|
|
+ }
|
|
|
|
+ format={
|
|
|
|
+ datePickerTypeMap[datePickerType as keyof typeof datePickerTypeMap]
|
|
|
|
+ .dateFormat
|
|
|
|
+ }
|
|
|
|
+ />
|
|
|
|
+ </Form.Item>
|
|
|
|
+ </FieldWrapper>
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+ }
|
|
// 其他组件类型...
|
|
// 其他组件类型...
|
|
default:
|
|
default:
|
|
return null
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- const [form] = Form.useForm()
|
|
|
|
- const onSubmit = () => {
|
|
|
|
- form.submit()
|
|
|
|
- }
|
|
|
|
- const onFinish = (values: any) => {
|
|
|
|
- console.log('Finish:', values)
|
|
|
|
- }
|
|
|
|
- const onFinishFailed = (errorInfo: any) => {
|
|
|
|
- console.log('Failed:', errorInfo)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return (
|
|
return (
|
|
<Form
|
|
<Form
|
|
form={form}
|
|
form={form}
|