11 changed files with 325 additions and 69 deletions
			
			
		- 
					13src/components/table/Table.tsx
 - 
					8src/pages/db/vod/index.tsx
 - 
					6src/pages/x-form/hooks/useApi.tsx
 - 
					61src/pages/x-form/index.tsx
 - 
					15src/pages/x-form/style.ts
 - 
					146src/pages/x-form/utils/index.tsx
 - 
					54src/service/base.ts
 - 
					12src/service/x-form/model.ts
 - 
					45src/store/x-form/model.ts
 - 
					20src/types/x-form/model.d.ts
 - 
					14src/utils/index.ts
 
@ -0,0 +1,146 @@ | 
				
			|||
import { XForm } from '@/types/x-form/model' | 
				
			|||
import { ProColumns } from '@ant-design/pro-components' | 
				
			|||
import Switch from '@/components/switch' | 
				
			|||
import { Checkbox, DatePicker, Input, Radio, Select, TreeSelect } from 'antd' | 
				
			|||
import request from '@/request' | 
				
			|||
import { convertToBool, genProTableColumnWidthProps } from '@/utils' | 
				
			|||
import { ReactNode } from 'react' | 
				
			|||
 | 
				
			|||
const getValueType = (column: XForm.IColumn) => { | 
				
			|||
  switch (column.type) { | 
				
			|||
    case 'input': | 
				
			|||
      return 'text' | 
				
			|||
    case 'select': | 
				
			|||
      return 'select' | 
				
			|||
    case 'date': | 
				
			|||
      return 'date' | 
				
			|||
    case 'switch': | 
				
			|||
      return 'switch' | 
				
			|||
    case 'radio': | 
				
			|||
      return 'radio' | 
				
			|||
    case 'checkbox': | 
				
			|||
      return 'checkbox' | 
				
			|||
    case 'textarea': | 
				
			|||
      return 'textarea' | 
				
			|||
    case 'tree': | 
				
			|||
      return 'treeSelect' | 
				
			|||
    default: | 
				
			|||
      return 'text' | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
//根据type返回对应的组件
 | 
				
			|||
const getComponent = (column: XForm.IColumn) => { | 
				
			|||
  const type = getValueType(column) as any | 
				
			|||
  switch (type) { | 
				
			|||
    case 'input': | 
				
			|||
      return Input | 
				
			|||
    case 'select': | 
				
			|||
      return Select | 
				
			|||
    case 'date': | 
				
			|||
      return DatePicker | 
				
			|||
    case 'switch': | 
				
			|||
      return Switch | 
				
			|||
    case 'radio': | 
				
			|||
      return Radio | 
				
			|||
    case 'checkbox': | 
				
			|||
      return Checkbox | 
				
			|||
    case 'textarea': | 
				
			|||
      return Input.TextArea | 
				
			|||
    case 'tree': | 
				
			|||
    case 'treeSelect': | 
				
			|||
      return TreeSelect | 
				
			|||
    default: | 
				
			|||
      return Input | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
 | 
				
			|||
export const transformAntdTableProColumns = (columns: XForm.IColumn[]) => { | 
				
			|||
 | 
				
			|||
  return (columns || []).map(item => { | 
				
			|||
    const { value, props, multiple, checkStrictly } = item | 
				
			|||
 | 
				
			|||
    const { width, fieldProps: _fieldProps } = genProTableColumnWidthProps(item.width) | 
				
			|||
    const fieldProps: ProColumns['fieldProps'] = { | 
				
			|||
      dataFiledNames: props, | 
				
			|||
      ...(multiple ? { multiple: true } : {}), | 
				
			|||
      ...(checkStrictly ? { treeCheckStrictly: true } : {}), | 
				
			|||
      ..._fieldProps, | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    const formItemProps: ProColumns['formItemProps'] = (form, config) => { | 
				
			|||
 | 
				
			|||
      return { | 
				
			|||
        rules: item.rules?.map(i => { | 
				
			|||
          return { | 
				
			|||
            required: i.required, | 
				
			|||
            message: i.message | 
				
			|||
          } | 
				
			|||
        }), | 
				
			|||
        ...(value ? { valuePropName: value } : {}) | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    const rowProps = item.gutter ? { gutter: item.gutter } : { gutter: [ 16, 0 ], } | 
				
			|||
    const colProps = item.span ? { span: item.span } : {} | 
				
			|||
 | 
				
			|||
    const type = getValueType(item) | 
				
			|||
    return { | 
				
			|||
      title: item.label, | 
				
			|||
      dataIndex: item.prop, | 
				
			|||
      key: item.prop, | 
				
			|||
      width, | 
				
			|||
      valueType: type, | 
				
			|||
      hideInSearch: !item.search, | 
				
			|||
      hideInTable: item.hide, | 
				
			|||
      fieldProps, | 
				
			|||
      formItemProps, | 
				
			|||
      colProps, | 
				
			|||
      rowProps, | 
				
			|||
      request: item.dicUrl ? async (params, props) => { | 
				
			|||
        const { fieldProps: { dataFiledNames } } = props | 
				
			|||
        const { value, res: resKey, label } = dataFiledNames || {} | 
				
			|||
        const url = `/${item.dicUrl.replace(/^:/, '/')}` | 
				
			|||
        return request[item.dicMethod || 'get'](url, params).then(res => { | 
				
			|||
          return (res.data?.[resKey] || res.data || []).map((i: any) => { | 
				
			|||
            // console.log(i)
 | 
				
			|||
            const disabled = 'disabled' in i ? i.disabled : | 
				
			|||
                    ('status' in i ? !convertToBool(i.status) : false) | 
				
			|||
            return { | 
				
			|||
              title: i[label || 'label'], | 
				
			|||
              label: i[label || 'label'], | 
				
			|||
              value: i[value || 'id'], | 
				
			|||
              disabled, | 
				
			|||
              data: i | 
				
			|||
            } | 
				
			|||
          }) | 
				
			|||
        }) | 
				
			|||
      } : undefined, | 
				
			|||
      renderFormItem: (_scheam, config) => { | 
				
			|||
        const Component = getComponent(item) as any | 
				
			|||
        const { options, ...props } = config as any | 
				
			|||
 | 
				
			|||
        if ([ 'tree', 'treeSelect' ].includes(_scheam.valueType as string)) { | 
				
			|||
          return <Component {...props} treeData={options}/> | 
				
			|||
        } | 
				
			|||
        if (_scheam.valueType as string === 'select') { | 
				
			|||
          return <Select {...props} options={options}/> | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        return <Component {...config} /> | 
				
			|||
      }, | 
				
			|||
      render: (text: any, record: any) => { | 
				
			|||
        if (type === 'switch' || type === 'checkbox' || type === 'radio') { | 
				
			|||
          return <Switch size={'small'} value={record[item.prop]}/> | 
				
			|||
        } | 
				
			|||
        if (item.colorFormat) { | 
				
			|||
          return <span style={{ color: item.colorFormat }}>{text}</span> | 
				
			|||
        } | 
				
			|||
        return text | 
				
			|||
 | 
				
			|||
      } | 
				
			|||
    } as ProColumns | 
				
			|||
  }) | 
				
			|||
 | 
				
			|||
} | 
				
			|||
@ -1,9 +1,21 @@ | 
				
			|||
import { createCURD } from '@/service/base.ts' | 
				
			|||
import { XForm } from '@/types/x-form/model' | 
				
			|||
import request from '@/request.ts' | 
				
			|||
 | 
				
			|||
const model = (api: string) => { | 
				
			|||
  return { | 
				
			|||
    ...createCURD<any, XForm.IModel>(api), | 
				
			|||
    proxy: async <T = XForm.IModelCURD>(params?: { | 
				
			|||
      path: string, | 
				
			|||
      body: any, | 
				
			|||
      method?: string | 
				
			|||
    }) => { | 
				
			|||
      return request.post<T>(`/x_form/proxy`, { | 
				
			|||
        api: `${api}/ui/curd`, | 
				
			|||
        method: 'post', | 
				
			|||
        ...params | 
				
			|||
      }) | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue