config.ts 9.28 KB
import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
import { findDictItemByCode } from '/@/api/system/dict';
import { FormSchema } from '/@/components/Table';
import { isNullOrUnDef } from '/@/utils/is';
import { FormField } from '/@/views/device/profiles/step/cpns/physical/cpns/config';

export enum DataTypeEnum {
  IS_NUMBER_INT = 'INT',
  IS_NUMBER_DOUBLE = 'DOUBLE',
  IS_STRING = 'TEXT',
  IS_STRUCT = 'STRUCT',
  IS_BOOL = 'BOOL',
}

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 validateJSON = (_rule, value = [] as ModelOfMatterParams[], _callback) => {
  if (value.length) {
    return Promise.resolve();
  }
  return Promise.reject('JSON对象不能为空');
};

export const formSchemas = (
  hasStructForm: boolean,
  hiddenAccessMode: boolean,
  isTcp = false
): FormSchema[] => {
  return [
    {
      field: FormField.FUNCTION_NAME,
      label: '功能名称',
      required: true,
      component: 'Input',
      colProps: {
        span: 18,
      },
      componentProps: {
        maxLength: 32,
        placeholder: '请输入功能名称',
      },
    },
    {
      field: FormField.IDENTIFIER,
      label: '标识符',
      required: true,
      component: 'Input',
      colProps: {
        span: 18,
      },
      componentProps: {
        maxLength: 128,
        placeholder: '请输入标识符',
      },
    },
    {
      field: FormField.TYPE,
      label: '数据类型',
      required: true,
      component: 'ApiSelect',
      colProps: {
        span: 9,
      },
      defaultValue: 'INT',
      componentProps: ({ formActionType }) => {
        const { updateSchema, setFieldsValue } = formActionType;
        return {
          placeholder: '请选择数据类型',
          api: async (params: Recordable) => {
            try {
              const record = await findDictItemByCode(params);
              return hasStructForm
                ? record.filter((item) => item.itemValue !== DataTypeEnum.IS_STRUCT)
                : record;
            } catch (error) {
              console.log(error);
              return [];
            }
          },
          params: {
            dictCode: 'data_type',
          },
          labelField: 'itemText',
          valueField: 'itemValue',
          getPopupContainer: () => document.body,
          onChange: (value: string) => {
            if (value == DataTypeEnum.IS_STRUCT) {
              updateSchema({
                field: FormField.SPECS_LIST,
                componentProps: {
                  hasStructForm: true,
                },
              });
              setFieldsValue({ [FormField.SPECS_LIST]: [] });
            }
          },
        };
      },
    },
    {
      field: FormField.VALUE_RANGE,
      label: '取值范围',
      component: 'CustomMinMaxInput',
      valueField: 'value',
      changeEvent: 'update:value',
      colProps: {
        span: 18,
      },
      ifShow: ({ values }) =>
        values[FormField.TYPE] === DataTypeEnum.IS_NUMBER_INT ||
        values[FormField.TYPE] === DataTypeEnum.IS_NUMBER_DOUBLE,
      rules: [{ validator: validateValueRange }],
    },
    {
      field: FormField.STEP,
      label: '步长',
      component: 'InputNumber',
      colProps: {
        span: 18,
      },
      componentProps: {
        maxLength: 255,
        placeholder: '请输入步长',
        min: 1,
        formatter: (value: number | string) => {
          return value ? Math.floor(Number(value)) : value;
        },
      },
      ifShow: ({ values }) =>
        values[FormField.TYPE] === DataTypeEnum.IS_NUMBER_INT ||
        values[FormField.TYPE] === DataTypeEnum.IS_NUMBER_DOUBLE,
      dynamicRules: ({ model }) => {
        const valueRange = model[FormField.VALUE_RANGE] || {};
        const { min, max } = valueRange;
        const step = model[FormField.STEP];
        return [
          {
            validator: () => {
              if ([min, max].every(isNullOrUnDef)) return Promise.resolve();
              if (step > max - min) {
                return Promise.reject('步长不能大于取值范围的差值');
              }
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormField.UNIT_NAME,
      label: '单位名称',
      component: 'Input',
      show: false,
    },
    {
      field: FormField.UNIT,
      label: '单位',
      component: 'ApiSelect',
      colProps: {
        span: 9,
      },
      componentProps: ({ formActionType }) => {
        const { setFieldsValue } = formActionType;
        return {
          placeholder: '请选择单位',
          api: async (params) => {
            const list = await findDictItemByCode(params);
            list.map((item) => (item.itemText = `${item.itemText} / ${item.itemValue}`));
            return list;
          },
          params: {
            dictCode: 'attribute_unit',
          },
          labelInValue: true,
          labelField: 'itemText',
          valueField: 'itemValue',
          onChange(_, record: Record<'label' | 'value', string>) {
            if (record) {
              const { label } = record;
              setFieldsValue({ [FormField.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: ({ values }) =>
        values[FormField.TYPE] === DataTypeEnum.IS_NUMBER_INT ||
        values[FormField.TYPE] === DataTypeEnum.IS_NUMBER_DOUBLE,
    },
    {
      field: FormField.BOOL_CLOSE,
      component: 'Input',
      required: true,
      label: '0 -',
      colProps: {
        span: 18,
      },
      componentProps: {
        placeholder: '如:关',
      },
      defaultValue: '关',
      ifShow: ({ values }) => values[FormField.TYPE] === DataTypeEnum.IS_BOOL,
      dynamicRules: ({ model }) => {
        const close = model[FormField.BOOL_CLOSE];
        const open = model[FormField.BOOL_OPEN];
        return [
          {
            required: true,
          },
          {
            validator() {
              if (open === close) return Promise.reject('布尔值不能相同');
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormField.BOOL_OPEN,
      component: 'Input',
      required: true,
      label: '1 -',
      colProps: {
        span: 18,
      },
      componentProps: {
        placeholder: '如:开',
      },
      defaultValue: '开',
      ifShow: ({ values }) => values[FormField.TYPE] === DataTypeEnum.IS_BOOL,
      dynamicRules: ({ model }) => {
        const close = model[FormField.BOOL_CLOSE];
        const open = model[FormField.BOOL_OPEN];
        return [
          {
            required: true,
          },
          {
            validator() {
              if (open === close) return Promise.reject('布尔值不能相同');
              return Promise.resolve();
            },
          },
        ];
      },
    },
    {
      field: FormField.LENGTH,
      component: 'Input',
      required: true,
      label: '数据长度',
      defaultValue: '10240',
      colProps: {
        span: 8,
      },
      componentProps: {
        placeholder: '请输入数据长度',
      },
      renderComponentContent: () => {
        return {
          suffix: () => '字节',
        };
      },
      ifShow: ({ values }) => values[FormField.TYPE] === DataTypeEnum.IS_STRING,
    },
    {
      field: FormField.EXTENSION_DESC,
      component: 'ExtendDesc',
      label: '扩展描述',
      valueField: 'value',
      changeEvent: 'update:value',
      ifShow: isTcp,
      colProps: {
        span: 16,
      },
      componentProps: ({ formModel }) => {
        return {
          dataType: formModel[FormField.TYPE],
        };
      },
    },
    {
      field: FormField.ACCESS_MODE,
      component: 'ApiRadioGroup',
      label: '读写类型',
      required: true,
      colProps: {
        span: 24,
      },
      ifShow: () => !hiddenAccessMode && !hasStructForm,
      defaultValue: 'r',
      componentProps: {
        placeholder: '请选择读写类型',
        api: findDictItemByCode,
        params: {
          dictCode: 'read_write_type',
        },
        labelField: 'itemText',
        valueField: 'itemValue',
      },
    },
    {
      field: FormField.SPECS_LIST,
      label: 'JSON对象',
      component: 'StructForm',
      valueField: 'value',
      changeEvent: 'update:value',
      colProps: { span: 24 },
      ifShow: ({ values }) => values[FormField.TYPE] === DataTypeEnum.IS_STRUCT,
      rules: [{ required: true, validator: validateJSON }],
    },
    {
      field: FormField.REFARK,
      label: '备注',
      component: 'InputTextArea',
      componentProps: {
        rows: 4,
        maxLength: 100,
        placeholder: '请输入描述',
      },
    },
  ];
};