config.ts 10.5 KB
import { FormFieldsEnum, FormFieldsNameEnum } from '../config';
import { findDictItemByCode } from '/@/api/system/dict';
import { FormSchema } from '/@/components/Form';
import { DictEnum } from '/@/enums/dictEnum';
import { DataTypeEnum, FunctionTypeEnum, FunctionTypeNameEnum } from '/@/enums/objectModelEnum';
import { isNullOrUnDef } from '/@/utils/is';

export const validateValueRange = (_rule, value: Record<'min' | 'max', number>, _callback) => {
  value = value || {};
  const { min, max } = value;
  if (min > max) {
    return Promise.reject('最大值小于最小值');
  }
  return Promise.resolve();
};

export const getFormSchemas = (): FormSchema[] => {
  return [
    {
      field: FormFieldsEnum.FUNCTION_TYPE,
      label: FormFieldsNameEnum.FUNCTION_TYPE,
      component: 'Segmented',
      defaultValue: FunctionTypeEnum.PROPERTIES,
      required: true,
      componentProps: ({ formActionType }) => {
        return {
          options: Object.keys(FunctionTypeEnum).map((key) => ({
            title: FunctionTypeNameEnum[key],
            value: FunctionTypeEnum[key],
          })),
          onChange() {
            const { setFieldsValue, clearValidate } = formActionType;
            setFieldsValue({
              [FormFieldsEnum.INPUT_DATA]: [],
              [FormFieldsEnum.OUTPUT_DATA]: [],
              [FormFieldsEnum.STRUCT_DATA]: [],
              [FormFieldsEnum.SERVICE_COMMAND]: null,
            });
            clearValidate();
          },
        };
      },
    },
    {
      field: FormFieldsEnum.FUNCTION_NAME,
      label: FormFieldsNameEnum.FUNCTION_NAME,
      component: 'Input',
      required: true,
      dynamicRules: ({ values }) => {
        return [
          { required: true, message: '请输入功能名称' },
          {
            validator: () => {
              const reg = /[,,]+/;
              if (reg.test(values?.[FormFieldsEnum.FUNCTION_NAME])) {
                return Promise.reject(`${FormFieldsNameEnum.FUNCTION_NAME}不能包含逗号`);
              }
              return Promise.resolve();
            },
          },
        ];
      },
      componentProps: {
        placeholder: `请输入${FormFieldsNameEnum.FUNCTION_NAME}`,
      },
    },
    {
      field: FormFieldsEnum.IDENTIFIER,
      label: FormFieldsNameEnum.IDENTIFIER,
      required: true,
      component: 'Input',
      componentProps: {
        maxLength: 128,
        placeholder: '请输入标识符',
      },
      dynamicRules: ({ values }) => {
        return [
          { required: true, message: '请输入标识符' },
          {
            validator: () => {
              const reg = /[,,]+/;
              if (reg.test(values?.[FormFieldsEnum.IDENTIFIER])) {
                return Promise.reject(`${FormFieldsNameEnum.IDENTIFIER}不能包含逗号`);
              }
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormFieldsEnum.DATA_TYPE,
      label: FormFieldsNameEnum.DATA_TYPE,
      required: true,
      component: 'ApiSelect',
      defaultValue: DataTypeEnum.NUMBER_INT,
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ),
      componentProps: () => {
        return {
          placeholder: '请选择数据类型',
          api: async (params: Recordable) => {
            const result = await findDictItemByCode(params);
            return result;
          },
          params: {
            dictCode: DictEnum.DATA_TYPE,
          },
          labelField: 'itemText',
          valueField: 'itemValue',
          getPopupContainer: () => document.body,
        };
      },
    },
    {
      field: FormFieldsEnum.VALUE_RANGE,
      label: FormFieldsNameEnum.VALUE_RANGE,
      component: 'CustomMinMaxInput',
      valueField: 'value',
      changeEvent: 'update:value',
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) &&
        (model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.NUMBER_INT ||
          model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.NUMBER_DOUBLE),
      rules: [{ validator: validateValueRange }],
    },
    {
      field: FormFieldsEnum.STEP,
      label: FormFieldsNameEnum.STEP,
      component: 'InputNumber',
      componentProps: {
        maxLength: 255,
        placeholder: '请输入步长',
        min: 1,
        formatter: (value: number | string) => {
          return value ? Math.floor(Number(value)) : value;
        },
      },
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) &&
        (model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.NUMBER_INT ||
          model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.NUMBER_DOUBLE),
      dynamicRules: ({ model }) => {
        const valueRange = model[FormFieldsEnum.VALUE_RANGE] || {};
        const { min, max } = valueRange;
        const step = model[FormFieldsEnum.STEP];
        return [
          {
            validator: () => {
              if ([min, max].every(isNullOrUnDef)) return Promise.resolve();
              if (step > max - min) {
                return Promise.reject('步长不能大于取值范围的差值');
              }
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormFieldsEnum.UNIT_NAME,
      label: FormFieldsNameEnum.UNIT_NAME,
      component: 'Input',
      show: false,
    },
    {
      field: FormFieldsEnum.UNIT,
      label: FormFieldsNameEnum.UNIT,
      component: 'ApiSelect',
      componentProps: ({ formActionType }) => {
        const { setFieldsValue } = formActionType;
        return {
          placeholder: '请选择单位',
          api: async (params: Recordable) => {
            const list = await findDictItemByCode(params);
            list.map((item) => (item.itemText = `${item.itemText} / ${item.itemValue}`));
            return list;
          },
          params: {
            dictCode: DictEnum.ATTRIBUTE_UNIT,
          },
          labelInValue: true,
          labelField: 'itemText',
          valueField: 'itemValue',
          onChange(_, record: Record<'label' | 'value', string>) {
            if (record) {
              const { label } = record;
              setFieldsValue({ [FormFieldsEnum.UNIT_NAME]: label });
            }
          },
          getPopupContainer: () => document.body,
          showSearch: true,
          filterOption: (inputValue: string, option: Record<'label' | 'value', string>) => {
            let { label, value } = option;
            label = label.toLowerCase();
            value = value.toLowerCase();
            inputValue = inputValue.toLowerCase();
            return label.includes(inputValue) || value.includes(inputValue);
          },
        };
      },
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) &&
        (model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.NUMBER_INT ||
          model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.NUMBER_DOUBLE),
    },
    {
      field: FormFieldsEnum.BOOL_CLOSE,
      component: 'Input',
      required: true,
      label: FormFieldsNameEnum.BOOL_CLOSE,
      componentProps: {
        placeholder: '如:关',
      },
      defaultValue: '关',
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) && model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.BOOL,
      dynamicRules: ({ model }) => {
        const close = model[FormFieldsEnum.BOOL_CLOSE];
        const open = model[FormFieldsEnum.BOOL_OPEN];
        return [
          {
            required: true,
            message: `布尔值不能为空`,
          },
          {
            validator() {
              if (open === close) return Promise.reject('布尔值不能相同');
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormFieldsEnum.BOOL_OPEN,
      component: 'Input',
      required: true,
      label: FormFieldsNameEnum.BOOL_OPEN,
      componentProps: {
        placeholder: '如:开',
      },
      defaultValue: '开',
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) && model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.BOOL,
      dynamicRules: ({ model }) => {
        const close = model[FormFieldsEnum.BOOL_CLOSE];
        const open = model[FormFieldsEnum.BOOL_OPEN];
        return [
          {
            required: true,
            message: `布尔值不能为空`,
          },
          {
            validator() {
              if (open === close) return Promise.reject('布尔值不能相同');
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormFieldsEnum.LENGTH,
      component: 'Input',
      required: true,
      label: FormFieldsNameEnum.LENGTH,
      defaultValue: '10240',
      colProps: {
        span: 8,
      },
      componentProps: {
        placeholder: '请输入数据长度',
      },
      renderComponentContent: () => {
        return {
          suffix: () => '字节',
        };
      },
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) && model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.STRING,
    },
    {
      field: FormFieldsEnum.ENUMS_DATA,
      label: FormFieldsNameEnum.ENUMS_DATA,
      component: 'Input',
      slot: FormFieldsEnum.ENUMS_DATA,
      changeEvent: 'update:value',
      valueField: 'value',
      ifShow: ({ model }) =>
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ) && model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.ENUM,
    },
    {
      field: FormFieldsEnum.STRUCT_DATA,
      label: FormFieldsNameEnum.STRUCT_DATA,
      component: 'Input',
      slot: FormFieldsEnum.STRUCT_DATA,
      changeEvent: 'update:value',
      valueField: 'value',
      required: true,
      ifShow: ({ model }) =>
        model[FormFieldsEnum.DATA_TYPE] === DataTypeEnum.STRUCT &&
        ![FunctionTypeEnum.SERVICE, FunctionTypeEnum.EVENTS].includes(
          model[FormFieldsEnum.FUNCTION_TYPE]
        ),
    },
  ];
};