Antd-ProComponents使用心得

公司项目中挺多用到Antd表单和列表的,自己封装感觉api太多总是封装得不够好,恰好看到Antd这边有自己的封装,用了一下发现真的很方便,在此记录一下使用心得。


ProComponents

编辑数据校验任务.png

基础表单

类似这样的表单页,用一个BetaSchemaForm组件就能实现,配置表单项和前后端数据转换都可以在一个配置对象里搞定,能剩下很多时间,代码更加简洁

import { createElement } from "react";
import type {
  ProFormColumnsType,
} from '@ant-design/pro-components';
import {ArrowRightOutlined,MinusCircleOutlined,PlusCircleOutlined} from '@ant-design/icons';
import { Button } from "antd";
import { queryTaskNameListUsingPOST } from "@/services/cluster/IServerDataMigrationAPI";
import to from "await-to-js";
import { validationTypeMap,validationEMap,validationFMap } from "../../config";

type DataItem = {
  name: string;
  state: string;
};

export default function getColumn(info:any){
  return [
    {
      title:'是否编辑',
      dataIndex:'isEdit',
      formItemProps:{
        hidden:true
      },
      initialValue:false
    },
    {
      title:'',
      dataIndex:'id',
      formItemProps:{
        hidden:true
      },
      initialValue:undefined
    },
    {
      title:'数据校验任务名称',
      dataIndex:'validationName',
      colProps: {
        span:12
      },
      formItemProps: {
        rules: [
          {
            required: true,
            message: '此项为必填项',
          },
        ],
      }
    },
    {
      title: '数据迁移任务',
      dataIndex: 'taskName',
      valueType:'select',
      formItemProps: {
        rules: [
          {
            required: true,
            message: '此项为必填项',
          },
        ],
      },
      colProps: {
        span:12,
      },
      fieldProps:{
        labelInValue:true
      },
      params: {clusterId:info.ClusterId},
      async request(){
        const [err,res] = await to(queryTaskNameListUsingPOST({
          clusterId:info.ClusterId
        }))
        if (res?.Message === 'Success' && res?.Code === '00000') {
            // message.success('提交成功')
            return res.Data?.map?.(d=>({label:d.taskName,value:d.taskId}))
          } else {
            // message.error(res?.Message || String(err))
            return []
          }
      }
    },
    {
      title: '数据校验任务描述',
      dataIndex: 'validationDesc',
      valueType: 'textarea',
      colProps: {
        span:24
      },
      fieldProps:{
        // showCount:true,
        rows:3
      }
    },
    {
      title: '校验类型',
      dataIndex: 'validationType',
      valueType: 'select',
      initialValue:'QUICK_COUNT',
      valueEnum:validationTypeMap,
      formItemProps: {
        rules: [
          {
            required: true,
            message: '此项为必填项'
          }
        ]
      },
      colProps: {
        span:12
      },
      fieldProps:{
        // showCount:true,
        rows:1
      }
    },
    {
      title: '校验频次',
      dataIndex: 'validationFrequency',
      valueType: 'select',
      valueEnum:validationFMap,
      initialValue:'SINGLE',
      formItemProps: {
        rules: [
          {
            required: true,
            message: '此项为必填项',
          }
        ]
      },
      colProps: {
        span:12
      },
      fieldProps:{
        // showCount:true,
        rows:1
      }
    },
    {
      title: '错误数据保存条数',
      dataIndex: 'validationKeep',
      valueType: 'select',
      initialValue:'ONE_HUNDRED',
      valueEnum:validationEMap,
      formItemProps: {
        rules: [
          {
            required: true,
            message: '此项为必填项',
          },
        ],
      },
      colProps: {
        span:12
      },
      fieldProps:{
        // showCount:true,
        rows:1
      }
    },
    // 大标题
    {
      title: '',
      colProps:{
        span:24
      },
      formItemProps:{
        noStyle:true
      },
      // rowProps:{gutter:48},
      renderFormItem:()=>
        createElement(
          'h4',
          null,
          [
            createElement('div',{className:'check-condition'}),
            '校验条件'
          ]
        )
    },
    {
      valueType:'dependency',
      name:['taskName'],
      columns({taskName}) {
        return [
          {
            title: '待校验表',
            valueType: 'formList',
            dataIndex: 'tables',
            initialValue:[{}],
            fieldProps:{
              min:1,
              copyIconProps:false,
              deleteIconProps:{
                // Icon:createElement(MinusCircleOutlined,{style:{color:'#ff8'}})
                Icon:(props:any)=>createElement(MinusCircleOutlined,{style:{color:'#FF4D4F'},...props})
              },
              creatorButtonProps:{
                creatorButtonText:'手动添加待校验表',
                icon:createElement(PlusCircleOutlined),
                type:'link',
                block:false,
              },
            },
            formItemProps:{
                rules: [
                  {
                    required: true,
                    message: '此项为必填项',
                  },
                ]
            },
            colProps: {
              span:24
            },
            columns:[
              {
                valueType: 'group',
                columns: [
                  {
                    valueType:'dependency',
                    name:['tables'],
                    fieldProps: {
                      ignoreFormListField:true
                    },
                    columns({tables}) {
                      return [
                        {
                          title: '',
                          dataIndex: 'sourceTablename',
                          valueType: 'select',
                          colProps: {
                            flex:'438px'
                          },
                          params:{taskName,tables},
                          formItemProps: {
                            rules: [
                              {
                                required: true,
                                message: '此项为必填项',
                              },
                            ],
                          },
                          debounceTime:100,
                          request(){
                            return info.tableMapping?.map?.(d=>({
                              label:d.sourceTablename,
                              value:d.sourceTablename,
                              disabled:tables.map(t=>t.sourceTablename).includes(d.sourceTablename)
                            })) || []
                          },

                        },
                      ]
                    },
                  },
                  {
                    title: '',
                    valueType: 'text',
                    colProps: {
                      flex:'31px'
                    },
                    renderFormItem(){
                      return createElement('div',{className:'rarrow-icon'},[createElement(ArrowRightOutlined)])
                    }
                  },
                  {
                    valueType:'dependency',
                    name:['tables','sourceTablename'],
                    columns({tables,sourceTablename}) {
                      // console.log(sourceTablename,'sourceTablename',info.tableMapping,'info.tableMapping',info.tableMapping.find?.(t=>t.sourceTablename === sourceTablename)?.destTablename)
                      return [
                        {
                          title: '',
                          dataIndex: 'destTablename',
                          valueType: 'select',
                          colProps: {
                            flex:'438px'
                          },
                          params:{taskName,tables},
                          // formItemProps:{
                          //   readOnly:true
                          // },
                          fieldProps:{
                            disabled:true,
                            value:info.tableMapping.find?.(t=>t.sourceTablename === sourceTablename)?.destTablename,
                          },
                          debounceTime:100,
                          request(){
                            return info.tableMapping?.map?.(d=>({
                              label:d.destTablename,
                              value:d.destTablename
                            }))
                          }
                        },
                      ]
                    },
                  },
                ],
              }]
          }
        ]
      },
    },
    {
      title: '',
      formItemProps:{
        style:{
          height:0,
          margin:0
        }
      },
      renderFormItem:(schema,config,form)=>
        createElement(
          Button,
          {
            type:'link',
            icon:createElement(PlusCircleOutlined),
            className:'autoadd-button',
            onClick(){
              form.setFieldValue('tables',info.tableMapping.length? info.tableMapping: [{}])
            }
          },
          '自动添加待校验表'
        )
    },
] as ProFormColumnsType<DataItem>[]
}

// tsx 文件
      <BetaSchemaForm<DataItem>
        className="datav-form"
        layoutType="Form"
        grid
        shouldUpdate
        rowProps={{gutter:24}}
        formRef={formRef}
        // onFinish={handleFinish}
        columns={formColumn({ClusterId,tableMapping:formRef.current?.getFieldValue('taskName')?tableMapping:[]})}
        submitter={{render:false}}
        onValuesChange={changeValues=>{
          // console.log(changeValues,'changeValues')
          Object.keys(changeValues).map(k=>{
            if (k === 'taskName') {
              formRef.current?.setFieldValue('tables',[{}])
              getTableMapping(changeValues[k])
            }
          })
        }}
      />

分步表单

分步表单会复杂一些,但是框架也提供了StepsForm,用法与BaseForm一致,只要稍微注意一下配置对象就能完美搭建一个分布表单的页面

// index.tsx
import { Space,message,Button,Layout,Col,Row,ConfigProvider,Popover, Steps } from 'antd';
import React,{useRef,useEffect,useState} from 'react';
import formColumn from "./formColumn";
import { CloseOutlined } from "@ant-design/icons";
import './index.less';
import moment from "moment";
import { useModel } from "umi";
import type {
  FormInstance,
  ProFormColumnsType,
} from '@ant-design/pro-components';
import { BetaSchemaForm } from '@ant-design/pro-components';
import to from "await-to-js";
import { history,useLocation } from "umi";
import { isEmpty } from "lodash";
import { createOrEditTaskUsingPOST } from "@/services/cluster/IServerDataMigrationAPI";
import type { ProFormInstance } from '@ant-design/pro-components';
import CryptoJS from 'crypto-js';
import { encrypt } from '@/utils/utils';


export type SettingDrawerProps = {
  visible: boolean;
  info:any
  onCancel: () => any;
  onOk: () => any;
};
type DataItem = {
  name: string;
  state: string;
};

const NewTask: React.FC<SettingDrawerProps> = (props:SettingDrawerProps) => {
  // const {visible,onCancel,info} = props
  const [current, setCurrent] = useState(0)
  const formMapRef = useRef<
    React.MutableRefObject<ProFormInstance<any> | undefined>[]
  >([]);
  const { ClusterId } = useModel('clusterModel', (ret: { clusterId: any }) => ({
    ClusterId: ret.clusterId,
  }));
  const { setFormData,setStep } = useModel('jformModel');
  const [tableLoading, setTableLoading] = useState(false)
  const location = useLocation()
  const isEdit = location?.state?.isEdit
  const record = location?.state?.record
  useEffect(()=>{
    // console.log(location?.state?.record)
    if (!isEmpty(record) && isEdit) {
      // console.log(record,record?.destTables,'record?.destTables')
      formMapRef?.current?.forEach((formInstanceRef,i) => {
        if(i === 1){
          formInstanceRef?.current?.setFieldsValue({
            destTables:isEdit?(record?.destTables?.split(',') || []):[],
            sourceTables:isEdit?(record?.sourceTables?.split(',') || []):[],
            isEdit
          })
        } else {
          formInstanceRef?.current?.setFieldsValue({
            ...record,
            isEdit
          })
          if (i === 2) {
            if (moment(record.readStartCommit).isValid()) {
              setTimeout(() => {
                formInstanceRef?.current?.setFieldsValue({
                  readStartCommit:'2',
                  diyDate:moment(record.readStartCommit)
                })
              })
            }
          }
        }
      })
    }
  },[record,isEdit])

  // 设置是否编辑状态
  // useEffect(()=>{
  //   formMapRef?.current?.forEach((formInstanceRef,i) => {
  //     formInstanceRef?.current?.setFieldValue('isEdit',isEdit)
  //   })
  // },[isEdit])

  //控制提交
  async function handleFinish(val:any) {

    // const myKey = 'xB2]dZ2?pY0&rK5['
    //AES加密createOrEditTaskUsingPOST

    const params = {
      ...val,
      clusterId:ClusterId,
      sourceTables:val.destTables,
      sourceNamenodes:val.sourceNamenodes?.split(','),
      sourceNamenodeRpcAddress:val.sourceNamenodeRpcAddress?.split(',')
      // id:record.id
    }
    if (isEdit) {
      params.id = record.id
    }
    if (val.readStartCommit === '2') {
      params.readStartCommit = val.diyDate
    }
    // console.log(params,'handleFinish');
    const [err,res] = await to(createOrEditTaskUsingPOST(params))
    if (res?.Message === 'Success' && res?.Code === '00000') {
      message.success('提交成功');
    } else {
      message.error(res?.Message || String(err))
    }
    formMapRef?.current?.forEach((formInstanceRef) => {
      formInstanceRef?.current?.resetFields()
    });
    setFormData(undefined)
    setStep(0)
    history.replace('/migration/tasks')
  }

  // 下一步或者一步回调
  function onCurrentChange(current:number) {
    // console.log('====================================');
    // console.log('onCurrentChange',current,formRef.current?.validateFieldsReturnFormatValue());
    // console.log('onCurrentChange',current,formRef.current?.getFieldsValue());
    // console.log('====================================');
    setCurrent(current)
    setStep(current)
  }

  return (
    <div className='new-task-block'>
      <div className='new-task'>
        {/* <section className='title'>新建迁移任务<CloseOutlined className='icon-close' onClick={()=>history.replace('/migration/tasks')}/></section> */}
        <BetaSchemaForm<DataItem>
          layoutType="StepsForm"
          width="100%"
          steps={[
            {
              title: '选择数据源和目标库',
              name:'base',
              rowProps:{
                gutter: 48
              },
              onFinish(values){
                setFormData(values)
                return true
              }
            },
            {
              title: '选择迁移对象',
              name:'tableShow',
              rowProps:{
                gutter: 48
              }
            },
            {
              title: '配置任务',
              name:'task',
              rowProps:{
                gutter: 48
              }
            }
          ]}
          onCurrentChange={onCurrentChange}
          stepsProps={{size:'small',direction:"vertical",progressDot:true}}
          grid
          stepFormRender={form =>
            <div className='steps-form-wrap'>
              <div className='steps-form'>
                {form}
                {!current && <div className='long-div'></div>}
              </div>
            </div>
          }
          stepsFormRender={(form,submitter)=><div className='form-wrap-index'>{[form,submitter]}</div>}
          stepsRender={(steps,dom)=>
            <div className='steps-container'>
              <div className='steps-title'>{`${isEdit?'编辑':'新建'}数据迁移任务`}</div>
              <ConfigProvider theme={{
                token:{
                  colorText:'#fff',
                  colorTextDisabled:'#CCC',
                  colorTextDescription:'#CCC',
                  colorSplit:'#fff'
                }
              }}>
                {dom}
              </ConfigProvider>
            </div>
          }
          formMapRef={formMapRef}
          onFinish={handleFinish}
          columns={formColumn(tableLoading,setTableLoading) as ProFormColumnsType<DataItem>[][]}
          submitter={{
            submitButtonProps:{
              // disabled:current === 1 && !formMapRef.current?.[1].current?.getFieldValue('destTables')?.length
              disabled:tableLoading
            },
            render:(props,dom)=>
              <div className='submitter'>
                <Space>
                  <Button onClick={()=>{setStep(0);setFormData({});history.replace('/migration/tasks')}}>取消</Button>
                  {dom}
                </Space>
              </div>
          }}
        />
      </div>
    </div>
  )
}

export default NewTask;
// 配置项
import type { ProFormColumnsType } from '@ant-design/pro-components';
import { DatePicker, Form, Radio } from 'antd';
import { createElement } from 'react';
import TableSelect from './TableSelect';
// import { Cron } from "react-js-cron";
import { existsUsingPOST } from '@/services/cluster/IServerDataMigrationAPI';
import { decrypt, encrypt } from '@/utils/utils';
import CronInput from './CronInput';
type DataItem = {
  name: string;
  state: string;
};
const valueEnum = {
  all: { text: '全部', status: 'Default' },
  open: {
    text: '未解决',
    status: 'Error',
  },
  closed: {
    text: '已解决',
    status: 'Success',
    disabled: true,
  },
  processing: {
    text: '解决中',
    status: 'Processing',
  },
};

export default (tableLoading: boolean, setTableLoading: (tableLoading: boolean) => void) =>
  [
    [
      {
        title: '是否编辑',
        dataIndex: 'isEdit',
        formItemProps: {
          hidden: true,
        },
      },
      {
        title: '标题',
        dataIndex: 'taskName',
        colProps: {
          span: 12,
          // offset:1
        },
        formItemProps: (form, config) => ({
          rules: [
            {
              required: true,
              // validateTrigger:'onBlur',
              validator: (_, value, callback) => {
                if (!value) return callback('请输入');
                setTimeout(() => {
                  existsUsingPOST({
                    // sourceCatalog:form.getFieldValue('sourceCatalog'),
                    sourceCatalog: '',
                    taskName: value,
                  })
                    .then((res) => {
                      if (res?.Message === 'Success' && res?.Code === '00000') {
                        if (res.Data?.Data && !form.getFieldValue('isEdit')) {
                          // return Promise.reject('已存在相同名称的任务名')
                          callback('已存在相同名称的任务名');
                        } else {
                          callback();
                        }
                        // return Promise.resolve()
                      } else {
                        // return Promise.reject(res?.Message || '已存在相同名称的任务名')
                        callback('已存在相同名称的任务名');
                      }
                    })
                    .catch((err) => err.Message || '已存在相同名称的任务名');
                });
              },
            },
          ],
        }),
      },
      {
        title: '任务描述',
        dataIndex: 'taskDesc',
        valueType: 'textarea',
        valueEnum,
        colProps: {
          span: 12,
        },
        fieldProps: {
          // showCount:true,
          rows: 1,
        },
      },
      {
        title: '',
        dataIndex: 'ff',
        colProps: {
          span: 12,
        },
        // rowProps:{gutter:48},
        renderFormItem: () => createElement('div', { className: 'form-item-box' }, '数据源'),
      },
      {
        title: '',
        dataIndex: 'f1',
        colProps: {
          span: 12,
        },
        // rowProps:{gutter:48},
        renderFormItem: () => createElement('div', { className: 'form-item-box' }, '目标库'),
      },
      {
        title: '数据源catalog名称',
        dataIndex: 'sourceCatalog',
        colProps: {
          span: 12,
        },
        formItemProps: (form, config) => ({
          rules: [
            {
              required: true,
              // validateTrigger:'onBlur',
              validator: (_, value, callback) => {
                if (!value) return callback('请输入');
                setTimeout(() => {
                  existsUsingPOST({
                    sourceCatalog: value,
                    taskName: '',
                  })
                    .then((res) => {
                      if (res?.Message === 'Success' && res?.Code === '00000') {
                        if (res.Data?.Data && !form.getFieldValue('isEdit')) {
                          // return Promise.reject('已存在相同名称的任务名')
                          callback('已存在相同名称的数据源catalog名称');
                        } else {
                          callback();
                        }
                        // return Promise.resolve()
                      } else {
                        // return Promise.reject(res?.Message || '已存在相同名称的任务名')
                        callback('已存在相同名称的数据源catalog名称');
                      }
                    })
                    .catch((err) => callback(err));
                });
              },
            },
          ],
        }),
      },
      {
        title: '目标库catalog名称',
        dataIndex: 'destCatalog',
        colProps: {
          span: 12,
        },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      {
        title: '数据源database名称',
        dataIndex: 'sourceDatabase',
        colProps: {
          span: 12,
        },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      {
        title: '目标库database名称',
        dataIndex: 'destDatabase',
        colProps: {
          span: 12,
        },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      // {
      //   title: '数据源URL',
      //   dataIndex: 'sourceUrl',
      //   colProps: {
      //     span:12
      //   },
      //   formItemProps: {
      //     rules: [
      //       {
      //         required: true,
      //         message: '此项为必填项',
      //       },
      //     ],
      //   },
      // },
      {
        title: 'hive配置路径',
        dataIndex: 'sourceHiveConfPath',
        colProps: {
          span: 12,
        },
        // width:'502px',
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      {
        title: '目标库URL',
        dataIndex: 'destUrl',
        colProps: {
          span: 12,
        },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      // {
      //   title: '数据源账号',
      //   dataIndex: 'sourceAccount',
      //   colProps: {
      //     span:12
      //   },
      //   formItemProps: {
      //     rules: [
      //       {
      //         required: true,
      //         message: '此项为必填项',
      //       },
      //     ],
      //   },
      // },
      // {
      //   title: '数据源密码',
      //   dataIndex: 'sourcePassword',
      //   valueType:'password',
      //   colProps: {
      //     span:12
      //   },
      //   formItemProps: {
      //     rules: [
      //       {
      //         required: true,
      //         message: '此项为必填项',
      //       },
      //     ],
      //   },
      // },
      {
        title: 'hadoop命名服务',
        dataIndex: 'sourceNameservices',
        colProps: {
          span: 12,
        },
        // width:'502px',
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      {
        title: '目标库账号',
        dataIndex: 'destAccount',
        colProps: {
          span: 12,
        },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      {
        title: '指定命名服务的高可用节点列表',
        dataIndex: 'sourceNamenodes',
        colProps: {
          span: 12,
        },
        // width:'502px',
        // transform:(value,namePath,allValues)=> {
        //   const a = value?.split?.(",")
        //   console.log(a);
        //   return a
        // },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
      {
        title: '目标库密码',
        dataIndex: 'destPassword',
        valueType: 'password',
        colProps: {
          span: 12,
        },
        transform(value) {
          const res = decrypt(value);
          return {
            destPassword: res ? value : encrypt(value),
          };
        },
        convertValue(convertValue) {
          // console.log(convertValue);
          const res = decrypt(convertValue);
          return res || convertValue;
        },
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },

      {
        title: '指定命名服务中每个节点的RPC地址列表',
        dataIndex: 'sourceNamenodeRpcAddress',
        colProps: {
          span: 12,
        },
        // width:'502px',
        // transform:(value,namePath,allValues)=> value?.split?.(","),
        formItemProps: {
          rules: [
            {
              required: true,
              message: '此项为必填项',
            },
          ],
        },
      },
    ],
    [
      {
        title: '是否编辑',
        dataIndex: 'isEdit',
        formItemProps: {
          hidden: true,
        },
      },
      {
        title: '原表',
        dataIndex: 'sourceTables',
        formItemProps: {
          hidden: true,
        },
        // convertValue(value) {
        //   return value?.split?.(',') || [];
        // },
      },
      {
        title: '',
        dataIndex: 'destTables',
        valueType: 'text',
        formItemProps: {
          rules: [
            {
              required: true,
              message: '请选择需要迁移的源表',
            },
          ],
        },
        // convertValue(value) {
        //   return value?.split?.(',') || [];
        // },
        renderFormItem: (schema, config, form) =>
          createElement(TableSelect, { form, tableLoading, setTableLoading }),
      },
    ],
    [
      {
        title: '是否实时',
        valueType: 'radio',
        dataIndex: 'readStreamingEnabled',
        colProps: {
          span: 12,
        },
        initialValue: 'TRUE',
        formItemProps: {
          rules: [
            {
              required: true,
              message: '请选择',
            },
          ],
        },
        fieldProps: {
          options: [
            {
              label: '是',
              value: 'TRUE',
            },
            {
              label: '否',
              value: 'FALSE',
            },
          ],
        },
      },
      {
        valueType: 'dependency',
        name: ['readStreamingEnabled'],
        columns: ({ readStreamingEnabled }) => {
          return readStreamingEnabled === 'TRUE'
            ? [
                {
                  title: '设置起始提交',
                  dataIndex: 'readStartCommit',
                  valueType: 'text',
                  initialValue: 'latest',
                  formItemProps: {
                    rules: [
                      {
                        required: true,
                        message: '请选择',
                      },
                    ],
                  },
                  renderFormItem(schema, config, form) {
                    return createElement(Radio.Group, { name: 'readStartCommit' }, [
                      createElement(Radio, { value: 'earliest', key: 'earliest' }, 'earliest'),
                      createElement(Radio, { value: 'latest', key: 'latest' }, 'latest'),
                      createElement(Radio, { value: '2', key: '2' }, [
                        '自定义时间',
                        form.getFieldValue('readStartCommit') === '2'
                          ? createElement(
                              Form.Item,
                              {
                                noStyle: true,
                                name: 'diyDate',
                                rules: [
                                  {
                                    required: form.getFieldValue('readStartCommit') === '2',
                                    message: '请确定起始提交时间',
                                  },
                                ],
                              },
                              createElement(DatePicker, {
                                showTime: true,
                                format: 'YYYY-MM-DD HH:mm:ss',
                                className: 'diy-date',
                              }),
                            )
                          : null,
                      ]),
                    ]);
                  },
                },
              ]
            : [];
        },
      },
      {
        valueType: 'dependency',
        name: ['readStreamingEnabled'],
        columns: ({ readStreamingEnabled }) => {
          return readStreamingEnabled === 'FALSE'
            ? [
                {
                  title: '模式',
                  dataIndex: 'mode',
                  valueType: 'radio',
                  initialValue: 'INCREMENTAL',
                  formItemProps: {
                    rules: [
                      {
                        required: true,
                        message: '请选择',
                      },
                    ],
                  },
                  fieldProps: {
                    options: [
                      {
                        label: '增量',
                        value: 'INCREMENTAL',
                      },
                      {
                        label: '全量',
                        value: 'FULL',
                      },
                    ],
                  },
                },
              ]
            : [];
        },
      },
      {
        valueType: 'dependency',
        name: ['readStreamingEnabled'],
        columns: ({ readStreamingEnabled }) => {
          return readStreamingEnabled === 'FALSE'
            ? [
                {
                  title: 'cron表达式',
                  dataIndex: 'cron',
                  valueType: 'text',
                  colProps: {
                    span: 12,
                  },
                  initialValue: '* * * * * ? *',
                  formItemProps: {
                    rules: [
                      {
                        required: true,
                        message: '请选择',
                      },
                    ],
                  },
                  renderFormItem(schema, config, form) {
                    return createElement(CronInput);
                  },
                },
              ]
            : [];
        },
      },
      {
        title: '表的合并任务数量',
        dataIndex: 'compactionTasks',
        valueType: 'digit',
        initialValue: 1,
        width: '160px',
        formItemProps: {
          rules: [
            {
              required: true,
              message: '请选择',
            },
          ],
        },
      },
      {
        title: '表写入操作的并行任务数',
        dataIndex: 'writeTasks',
        valueType: 'digit',
        initialValue: 1,
        width: '160px',
        formItemProps: {
          rules: [
            {
              required: true,
              message: '请选择',
            },
          ],
        },
      },
    ],
  ] as ProFormColumnsType<DataItem>[][];

值得一提的是改表单页面需要用到grid布局.这里贴一下less文件

.new-task-block{
  overflow-x: hidden;
  height: calc(100vh - 54px);
  width: 100%;

}
.new-task{
  position: relative;
  height: 100%;

  .ant-pro-steps-form{
    height: 100%;
  }
}
.form-wrap-index{
  height: 100%;
  div:first-of-type.ant-row.ant-row-stretch{
    height: 100%;
    display: grid;
    grid-template-columns: 256px auto;
    grid-template-rows: auto;
  }
  .ant-pro-steps-form-container{
    width: 100%;
    min-width: 100%;
    height: 100%;
    overflow-y: auto;
    padding-bottom: 80px;
  }
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容