config.ts 7.05 KB
import moment from 'moment';
import { Moment } from 'moment';
import { FormSchema } from '/@/components/Form';
import { ColEx } from '/@/components/Form/src/types';
import { useGridLayout } from '/@/hooks/component/useGridLayout';
import {
  getPacketIntervalByRange,
  getPacketIntervalByValue,
  intervalOption,
} from '/@/views/device/localtion/cpns/TimePeriodForm/helper';
import { OrderByEnum, OrderByNameEnum } from '/@/views/device/localtion/cpns/TimePeriodForm/config';
export enum QueryWay {
  LATEST = 'latest',
  TIME_PERIOD = 'timePeriod',
}

export enum SchemaFiled {
  DEVICE_ID = 'deviceId',
  WAY = 'way',
  TIME_PERIOD = 'timePeriod',
  KEYS = 'keys',
  DATE_RANGE = 'dataRange',
  START_TS = 'startTs',
  END_TS = 'endTs',
  INTERVAL = 'interval',
  LIMIT = 'limit',
  AGG = 'agg',
  ORDER_BY = 'orderBy',
}

export enum AggregateDataEnum {
  MIN = 'MIN',
  MAX = 'MAX',
  AVG = 'AVG',
  SUM = 'SUM',
  COUNT = 'COUNT',
  NONE = 'NONE',
}
export const formSchema = (): FormSchema[] => {
  return [
    {
      field: SchemaFiled.DEVICE_ID,
      label: '设备名称',
      component: 'Select',
      rules: [{ required: true, message: '设备名称为必选项', type: 'string' }],
      componentProps({ formActionType }) {
        const { setFieldsValue } = formActionType;
        return {
          placeholder: '请选择设备',
          onChange() {
            setFieldsValue({ [SchemaFiled.KEYS]: null });
          },
        };
      },
    },
    {
      field: SchemaFiled.WAY,
      label: '查询方式',
      component: 'RadioGroup',
      defaultValue: QueryWay.LATEST,
      componentProps({ formActionType }) {
        const { setFieldsValue } = formActionType;
        return {
          options: [
            { label: '最后', value: QueryWay.LATEST },
            { label: '时间段', value: QueryWay.TIME_PERIOD },
          ],
          onChange(event: ChangeEvent) {
            (event.target as HTMLInputElement).value === QueryWay.LATEST
              ? setFieldsValue({
                  [SchemaFiled.DATE_RANGE]: [],
                  [SchemaFiled.START_TS]: null,
                  [SchemaFiled.END_TS]: null,
                })
              : setFieldsValue({ [SchemaFiled.START_TS]: null });
          },
          getPopupContainer: () => document.body,
        };
      },
    },
    {
      field: SchemaFiled.START_TS,
      label: '最后数据',
      component: 'Select',
      ifShow({ values }) {
        return values[SchemaFiled.WAY] === QueryWay.LATEST;
      },
      componentProps({ formActionType }) {
        const { setFieldsValue } = formActionType;
        return {
          options: intervalOption,
          onChange() {
            setFieldsValue({ [SchemaFiled.INTERVAL]: null });
          },
          getPopupContainer: () => document.body,
        };
      },
      rules: [{ required: true, message: '最后数据为必选项', type: 'number' }],
    },
    {
      field: SchemaFiled.DATE_RANGE,
      label: '时间段',
      component: 'RangePicker',
      ifShow({ values }) {
        return values[SchemaFiled.WAY] === QueryWay.TIME_PERIOD;
      },
      rules: [{ required: true, message: '时间段为必选项' }],
      componentProps({ formActionType }) {
        const { setFieldsValue } = formActionType;
        let dates: Moment[] = [];
        return {
          showTime: {
            defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
          },
          onCalendarChange(value: Moment[]) {
            dates = value;
          },
          disabledDate(current: Moment) {
            if (!dates || dates.length === 0 || !current) {
              return false;
            }
            const diffDate = current.diff(dates[0], 'years', true);
            return Math.abs(diffDate) > 1;
          },
          onChange() {
            dates = [];
            setFieldsValue({ [SchemaFiled.INTERVAL]: null });
          },
          getPopupContainer: () => document.body,
        };
      },
      colProps: useGridLayout(2, 2, 2, 2, 2, 2) as unknown as ColEx,
    },
    {
      field: SchemaFiled.AGG,
      label: '数据聚合功能',
      component: 'Select',
      componentProps: {
        getPopupContainer: () => document.body,
        options: [
          { label: '最小值', value: AggregateDataEnum.MIN },
          { label: '最大值', value: AggregateDataEnum.MAX },
          { label: '平均值', value: AggregateDataEnum.AVG },
          { label: '求和', value: AggregateDataEnum.SUM },
          { label: '计数', value: AggregateDataEnum.COUNT },
          { label: '空', value: AggregateDataEnum.NONE },
        ],
      },
    },
    {
      field: SchemaFiled.INTERVAL,
      label: '分组间隔',
      component: 'Select',
      dynamicRules: ({ model }) => {
        return [
          {
            required: model[SchemaFiled.AGG] !== AggregateDataEnum.NONE,
            message: '分组间隔为必填项',
            type: 'number',
          },
        ];
      },
      ifShow({ values }) {
        return values[SchemaFiled.AGG] !== AggregateDataEnum.NONE;
      },
      componentProps({ formModel, formActionType }) {
        const options =
          formModel[SchemaFiled.WAY] === QueryWay.LATEST
            ? getPacketIntervalByValue(formModel[SchemaFiled.START_TS])
            : getPacketIntervalByRange(formModel[SchemaFiled.DATE_RANGE]);
        if (formModel[SchemaFiled.AGG] !== AggregateDataEnum.NONE) {
          formActionType.setFieldsValue({ [SchemaFiled.LIMIT]: null });
        }
        return {
          options,
          getPopupContainer: () => document.body,
        };
      },
    },
    {
      field: SchemaFiled.LIMIT,
      label: '最大条数',
      component: 'InputNumber',
      ifShow({ values }) {
        return values[SchemaFiled.AGG] === AggregateDataEnum.NONE;
      },
      helpMessage: ['根据查询条件, 查出的数据条数不超过这个值, 最大支持查询条数50000条.'],
      componentProps() {
        return {
          max: 50000,
          min: 7,
          getPopupContainer: () => document.body,
        };
      },
    },
    {
      field: SchemaFiled.KEYS,
      label: '设备属性',
      component: 'Select',
      componentProps: {
        getPopupContainer: () => document.body,
      },
    },
    {
      field: SchemaFiled.ORDER_BY,
      label: '数据排序',
      component: 'Select',
      defaultValue: OrderByEnum.ASC,
      componentProps: {
        options: Object.values(OrderByEnum).map((value) => ({
          value,
          label: OrderByNameEnum[value],
        })),
      },
    },
  ];
};

export function getHistorySearchParams(value: Recordable) {
  const { startTs, endTs, interval, agg, limit, way, keys, deviceId } = value;
  if (way === QueryWay.LATEST) {
    return {
      keys,
      entityId: deviceId,
      startTs: moment().subtract(startTs, 'ms').valueOf(),
      endTs: Date.now(),
      interval,
      agg,
      limit,
    };
  } else {
    return {
      keys,
      entityId: deviceId,
      startTs: moment(startTs).valueOf(),
      endTs: moment(endTs).valueOf(),
      interval,
      agg,
      limit,
    };
  }
}