config.ts 11.4 KB
import { TaskTargetEnum, TaskTargetNameEnum, TaskTypeEnum, TaskTypeNameEnum } from '../../config';
import { findDictItemByCode } from '/@/api/system/dict';
import { FormSchema, useComponentRegister } from '/@/components/Form';
import {
  DevicePicker,
  validateDevicePicker,
  FormFieldsEnum as DeviceCascadePickerFieldsEnum,
} from '../DevicePicker';
import { PollCommandInput, ModeEnum } from '../PollCommandInput';
import { DeviceProfileModel } from '/@/api/device/model/deviceModel';
import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
import { JSONEditorValidator } from '/@/components/CodeEditor/src/JSONEditor';
import { TimeUnitEnum, TimeUnitNameEnum } from '/@/enums/toolEnum';
import { dateUtil } from '/@/utils/dateUtil';
import { ProductPicker, validateProductPicker } from '../ProductPicker';

useComponentRegister('DevicePicker', DevicePicker);
useComponentRegister('ProductPicker', ProductPicker);
useComponentRegister('PollCommandInput', PollCommandInput);

export enum FormFieldsEnum {
  // 任务名称
  NAME = 'name',
  // 目标类型
  TARGET_TYPE = 'targetType',
  // 设备类型选择
  DEVICE_PROFILE = 'deviceProfile',
  // 执行目标源
  EXECUTE_TARGET_DATA = 'executeTargetData',
  // 执行任务类型
  EXECUTE_CONTENT_TYPE = 'executeContentType',
  // 下发命令
  RPC_COMMAND = 'rpcCommand',
  // 推送方式
  PUSH_WAY = 'pushWay',
  // 执行周期类型
  EXECUTE_TIME_TYPE = 'executeTimeType',
  // 执行间隔时间
  EXECUTE_TIME_INTERVAL = 'interval',
  // 执行周期类型
  EXECUTE_TIME_PERIOD_TYPE = 'periodType',
  // 周期 每月 每周
  EXECUTE_TIME_PERIOD = 'period',
  // time时间
  TIME = 'time',
  // 设备传输协议
  TRANSPORT_TYPE = 'transportType',
  // 间隔时间单位
  POLL_UNIT = 'pollUnit',
}

export enum PushWayEnum {
  MQTT = 'MQTT',
  TCP = 'TCP',
}

export enum ExecuteTimeTypeEnum {
  CUSTOM = 'CUSTOM',
  POLL = 'POLL',
}

export enum ExecuteTimeTypeNameEnum {
  CUSTOM = '自定义',
  POLL = '间隔时间重复',
}

export enum PeriodTypeEnum {
  MONTH = 'MONTH',
  WEEK = 'WEEK',
  DAY = 'DAY',
}

export enum PeriodTypeNameEnum {
  MONTH = '每月',
  WEEK = '每周',
  DAY = '每日',
}

const isShowCustomIntervalTimeSetting = (model: Recordable, flag: PeriodTypeEnum) => {
  return (
    model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.CUSTOM &&
    model[FormFieldsEnum.EXECUTE_TIME_PERIOD_TYPE] === flag
  );
};

export const formSchemas: FormSchema[] = [
  {
    field: FormFieldsEnum.NAME,
    component: 'Input',
    label: '任务名称',
    rules: [{ required: true, message: '请填写任务名称' }],
    componentProps: {
      placeholder: '请输入任务名称',
      maxlength: 64,
    },
  },
  {
    field: FormFieldsEnum.TARGET_TYPE,
    component: 'RadioGroup',
    label: '目标类型',
    defaultValue: TaskTargetEnum.DEVICES,
    helpMessage: ['执行任务的目标设备,可以是多个指定的设备,也可以是一个设备类型下的所有设备.'],
    componentProps: {
      options: [
        { label: TaskTargetNameEnum.DEVICES, value: TaskTargetEnum.DEVICES },
        { label: TaskTargetNameEnum.PRODUCTS, value: TaskTargetEnum.PRODUCTS },
      ],
    },
  },
  {
    field: FormFieldsEnum.DEVICE_PROFILE,
    component: 'ProductPicker',
    label: '产品',
    ifShow: ({ model }) => model[FormFieldsEnum.TARGET_TYPE] === TaskTargetEnum.PRODUCTS,
    valueField: 'value',
    changeEvent: 'update:value',
    rules: [validateProductPicker()],
    helpMessage: ['任务可以对目标产品按预设的时间策略执行任务。'],
    componentProps: ({ formActionType }) => {
      const { setFieldsValue } = formActionType;
      return {
        onChange(key: string, _value: string | string[], option: DeviceProfileModel) {
          if (key === DeviceCascadePickerFieldsEnum.DEVICE_PROFILE) {
            const isTCP = (option || {}).transportType === TransportTypeEnum.TCP;
            setFieldsValue({
              [FormFieldsEnum.TRANSPORT_TYPE]: _value ? option.transportType : null,
              [FormFieldsEnum.PUSH_WAY]: isTCP ? PushWayEnum.TCP : PushWayEnum.MQTT,
              ...(isTCP ? {} : { [FormFieldsEnum.EXECUTE_CONTENT_TYPE]: TaskTypeEnum.CUSTOM }),
            });
          }
        },
        getPopupContainer: () => document.body,
      };
    },
  },
  {
    field: FormFieldsEnum.EXECUTE_TARGET_DATA,
    component: 'DevicePicker',
    label: '设备',
    helpMessage: ['任务可以对目标设备按预设的时间策略执行任务。'],
    ifShow: ({ model }) => model[FormFieldsEnum.TARGET_TYPE] === TaskTargetEnum.DEVICES,
    rules: [validateDevicePicker()],
    valueField: 'value',
    changeEvent: 'update:value',
    componentProps: ({ formActionType }) => {
      const { setFieldsValue } = formActionType;
      return {
        multiple: true,
        onChange(key: string, _value: string | string[], option: DeviceProfileModel) {
          if (key === DeviceCascadePickerFieldsEnum.DEVICE_PROFILE) {
            const isTCP = (option || {}).transportType === TransportTypeEnum.TCP;
            setFieldsValue({
              [FormFieldsEnum.TRANSPORT_TYPE]: _value ? option.transportType : null,
              [FormFieldsEnum.PUSH_WAY]: isTCP ? PushWayEnum.TCP : PushWayEnum.MQTT,
              ...(isTCP ? {} : { [FormFieldsEnum.EXECUTE_CONTENT_TYPE]: TaskTypeEnum.CUSTOM }),
            });
          }
        },
      };
    },
  },
  {
    field: FormFieldsEnum.TRANSPORT_TYPE,
    component: 'Input',
    label: '',
    show: false,
  },
  {
    field: FormFieldsEnum.EXECUTE_CONTENT_TYPE,
    component: 'RadioGroup',
    label: '任务类型',
    defaultValue: TaskTypeEnum.CUSTOM,
    componentProps: ({ formActionType, formModel }) => {
      const { setFieldsValue } = formActionType;
      const transportType = Reflect.get(formModel, FormFieldsEnum.TRANSPORT_TYPE);
      return {
        options: [
          {
            label: TaskTypeNameEnum.CUSTOM,
            value: TaskTypeEnum.CUSTOM,
          },
          {
            label: TaskTypeNameEnum.MODBUS_RTU,
            value: TaskTypeEnum.MODBUS_RTU,
            disabled: transportType && transportType !== PushWayEnum.TCP,
          },
        ],
        onChange(value: TaskTypeEnum) {
          value &&
            setFieldsValue({
              [FormFieldsEnum.RPC_COMMAND]: '',
            });
        },
      };
    },
  },
  {
    field: FormFieldsEnum.PUSH_WAY,
    component: 'RadioGroup',
    label: '推送方式',
    defaultValue: PushWayEnum.TCP,
    show: false,
    componentProps: {
      options: [
        { label: PushWayEnum.MQTT, value: PushWayEnum.MQTT },
        { label: PushWayEnum.TCP, value: PushWayEnum.TCP },
      ],
    },
  },
  {
    field: FormFieldsEnum.RPC_COMMAND,
    component: 'PollCommandInput',
    label: '自定义数据流',
    rules: [{ required: true, message: '请输入自定义数据流' }],
    dynamicRules: ({ model }) =>
      model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.MQTT ? JSONEditorValidator() : [],
    ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.CUSTOM,
    valueField: 'value',
    changeEvent: 'update:value',
    componentProps: ({ formModel }) => {
      const pushMode = Reflect.get(formModel, FormFieldsEnum.PUSH_WAY);
      return {
        inputProps: {
          placeholder: '请输入自定义数据流',
        },
        mode: pushMode === PushWayEnum.MQTT ? ModeEnum.JSON : ModeEnum.NORMAL,
      };
    },
  },
  {
    field: FormFieldsEnum.RPC_COMMAND,
    component: 'PollCommandInput',
    label: 'ModbusRTU轮询',
    rules: [{ required: true, message: '请输入Modbus RTU 轮询指令' }],
    ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS_RTU,
    valueField: 'value',
    changeEvent: 'update:value',
    componentProps: () => {
      return {
        inputProps: {
          placeholder: '请输入Modbus RTU 轮询指令',
        },
        showSettingAddonAfter: false,
        openSettingOnInputFocus: true,
        mode: ModeEnum.NORMAL,
      };
    },
  },
  {
    field: FormFieldsEnum.EXECUTE_TIME_TYPE,
    label: '任务定时设置',
    component: 'RadioGroup',
    defaultValue: ExecuteTimeTypeEnum.POLL,
    componentProps: {
      options: [
        { label: ExecuteTimeTypeNameEnum.POLL, value: ExecuteTimeTypeEnum.POLL },
        { label: ExecuteTimeTypeNameEnum.CUSTOM, value: ExecuteTimeTypeEnum.CUSTOM },
      ],
    },
  },
  {
    field: FormFieldsEnum.EXECUTE_TIME_PERIOD_TYPE,
    component: 'Select',
    label: '周期',
    required: true,
    defaultValue: PeriodTypeEnum.MONTH,
    componentProps: ({ formActionType }) => {
      const { setFieldsValue } = formActionType;
      return {
        placeholder: '请选择周期',
        options: [
          { label: PeriodTypeNameEnum.DAY, value: PeriodTypeEnum.DAY },
          { label: PeriodTypeNameEnum.WEEK, value: PeriodTypeEnum.WEEK },
          { label: PeriodTypeNameEnum.MONTH, value: PeriodTypeEnum.MONTH },
        ],
        getPopupContainer: () => document.body,
        onChange() {
          setFieldsValue({ [FormFieldsEnum.EXECUTE_TIME_PERIOD]: null });
        },
      };
    },
    ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.CUSTOM,
  },
  {
    field: FormFieldsEnum.EXECUTE_TIME_PERIOD,
    component: 'ApiSelect',
    label: '每月',
    required: true,
    componentProps: {
      placeholder: '请选择月份',
      api: findDictItemByCode,
      params: {
        dictCode: 'every_month',
      },
      labelField: 'itemText',
      valueField: 'itemValue',
      getPopupContainer: () => document.body,
    },
    ifShow: ({ model }) => isShowCustomIntervalTimeSetting(model, PeriodTypeEnum.MONTH),
  },
  {
    field: FormFieldsEnum.EXECUTE_TIME_PERIOD,
    component: 'ApiSelect',
    label: '每周',
    required: true,
    componentProps: {
      placeholder: '请选择周期',
      api: findDictItemByCode,
      params: {
        dictCode: 'every_week',
      },
      labelField: 'itemText',
      valueField: 'itemValue',
      getPopupContainer: () => document.body,
    },
    ifShow: ({ model }) => isShowCustomIntervalTimeSetting(model, PeriodTypeEnum.WEEK),
  },
  {
    field: FormFieldsEnum.TIME,
    component: 'TimePicker',
    label: '时间',
    required: true,
    ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.CUSTOM,
    componentProps: {
      getPopupContainer: () => document.body,
      valueFormat: 'HH:mm:ss',
      defaultOpenValue: dateUtil('00:00:00', 'HH:mm:ss'),
    },
  },
  {
    field: FormFieldsEnum.POLL_UNIT,
    component: 'RadioGroup',
    label: '时间单位',
    ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.POLL,
    defaultValue: TimeUnitEnum.SECOND,
    componentProps: {
      options: [
        { label: TimeUnitNameEnum.SECOND, value: TimeUnitEnum.SECOND },
        { label: TimeUnitNameEnum.MINUTE, value: TimeUnitEnum.MINUTE },
        { label: TimeUnitNameEnum.HOUR, value: TimeUnitEnum.HOUR },
      ],
    },
  },
  {
    field: FormFieldsEnum.EXECUTE_TIME_INTERVAL,
    label: '间隔时间',
    component: 'InputNumber',
    ifShow: ({ model }) => model[FormFieldsEnum.EXECUTE_TIME_TYPE] === ExecuteTimeTypeEnum.POLL,
    componentProps: ({ formModel }) => {
      const unit = formModel[FormFieldsEnum.POLL_UNIT];
      return {
        min: 0,
        max: unit === TimeUnitEnum.HOUR ? 23 : 59,
        step: 1,
        placeholder: '请输入间隔时间',
      };
    },
  },
];