index.ts 9.57 KB
import { FormSchema } from '/@/components/Form';
import { findDictItemByCode } from '/@/api/system/dict';
import { h, unref } from 'vue';
import { getDeviceProfile } from '/@/api/alarm/position';
import { BasicColumn, BasicTableProps } from '/@/components/Table';
import { devicePage } from '/@/api/device/deviceManager';
import { Tag } from 'ant-design-vue';
import { DeviceRecord } from '/@/api/device/model/deviceModel';
import { FETCH_SETTING } from '/@/components/Table/src/const';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import { useMessage } from '/@/hooks/web/useMessage';
import {
  BasicInfoFormField,
  DataSourceType,
  DeviceStatusEnum,
  DeviceStatusNameEnum,
  DeviceTypeNameEnum,
} from '../enum';

export const stepConfig = ['选择流转方式', '完善配置参数'];

export const removeFieldByModeForm = ['name', 'description'];

//表单通用配置
export const modelFormPublicConfig = {
  labelWidth: 120,
  actionColOptions: {
    span: 14,
  },
  showResetButton: false,
  showSubmitButton: false,
};

const handleGroupDevice = (options: DeviceRecord[]) => {
  const map = new Map<string, string[]>();
  options.forEach((item) => {
    if (map.has(item.profileId)) {
      const deviceList = map.get(item.profileId)!;
      deviceList.push(item.tbDeviceId);
    } else {
      map.set(item.profileId, [item.tbDeviceId]);
    }
  });
  const value = Array.from(map.entries()).map(([product, devices]) => ({ product, devices }));

  return value;
};

const deviceTableFormSchema: FormSchema[] = [
  {
    field: 'name',
    label: '设备名称',
    component: 'Input',
    colProps: { span: 9 },
    componentProps: {
      placeholder: '请输入设备名称',
    },
  },
  {
    field: 'deviceType',
    label: '设备类型',
    component: 'ApiSelect',
    colProps: { span: 9 },
    componentProps: {
      placeholder: '请选择设备类型',
      api: findDictItemByCode,
      params: {
        dictCode: 'device_type',
      },
      labelField: 'itemText',
      valueField: 'itemValue',
    },
  },
];

const { clipboardRef, isSuccessRef } = useCopyToClipboard();

const { createMessage } = useMessage();

const deviceTableColumn: BasicColumn[] = [
  {
    title: '状态',
    dataIndex: 'deviceState',
    customRender: ({ text }) => {
      return h(
        Tag,
        {
          color:
            text === DeviceStatusEnum.INACTIVE
              ? 'warning'
              : text === DeviceStatusEnum.OFFLINE
              ? 'error'
              : 'success',
        },
        () => DeviceStatusNameEnum[text]
      );
    },
  },
  {
    title: '别名/设备名称',
    dataIndex: 'name',
    customRender: ({ record }) => {
      return h('div', [
        h(
          'div',
          {
            class: 'cursor-pointer',
            onClick: () => {
              clipboardRef.value = record.name;
              if (unref(isSuccessRef)) createMessage.success('复制成功~');
            },
          },
          [
            record.alias && h('div', { class: 'truncate' }, record.alias),
            h('div', { class: 'text-blue-400 truncate' }, record.name),
          ]
        ),
      ]);
    },
  },
  {
    title: '设备类型',
    dataIndex: 'deviceType',
    customRender: ({ text }) => {
      return h(Tag, { color: 'success' }, () => DeviceTypeNameEnum[text]);
    },
  },
  {
    title: '所属产品',
    dataIndex: 'deviceProfile.name',
  },
  {
    title: '所属组织',
    dataIndex: 'organizationDTO.name',
  },
];

const TransferTableProps: BasicTableProps = {
  formConfig: {
    layout: 'inline',
    labelWidth: 80,
    schemas: deviceTableFormSchema,
    actionColOptions: { span: 6 },
  },
  size: 'small',
  maxHeight: 240,
  useSearchForm: true,
  columns: deviceTableColumn,
  showIndexColumn: false,
  fetchSetting: FETCH_SETTING,
} as BasicTableProps;

export const modeForm = (submitFn?: Function): FormSchema[] => {
  return [
    {
      field: BasicInfoFormField.CONVERT_CONFIG_ID,
      label: '',
      component: 'Input',
      show: false,
    },
    {
      field: BasicInfoFormField.DATA_SOURCE_TYPE,
      label: '数据源',
      component: 'RadioGroup',
      defaultValue: DataSourceType.ALL,
      componentProps: {
        options: [
          { label: '全部', value: DataSourceType.ALL },
          { label: '产品', value: DataSourceType.PRODUCT },
          { label: '设备', value: DataSourceType.DEVICE },
        ],
      },
    },
    {
      field: BasicInfoFormField.DATA_SOURCE_PRODUCT,
      label: '数据源产品',
      component: 'TransferModal',
      ifShow: ({ model }) => {
        return model[BasicInfoFormField.DATA_SOURCE_TYPE] !== DataSourceType.ALL;
      },
      valueField: 'value',
      changeEvent: 'update:value',
      componentProps: ({ formActionType }) => {
        const { setFieldsValue } = formActionType;
        return {
          api: getDeviceProfile,
          labelField: 'name',
          valueField: 'tbProfileId',
          transferProps: {
            listStyle: { height: '400px' },
            showSearch: true,
            filterOption: (inputValue: string, option: Recordable) => {
              const upperCaseInputValue = inputValue.toUpperCase();
              const upperCaseOptionValue = option.name.toUpperCase();
              return upperCaseOptionValue.includes(upperCaseInputValue);
            },
          },
          onChange: () => {
            setFieldsValue({ [BasicInfoFormField.DATA_SOURCE_DEVICE]: [] });
          },
        };
      },
    },
    {
      field: BasicInfoFormField.DATA_SOURCE_DEVICE,
      label: '数据源设备',
      component: 'TransferTableModal',
      ifShow: ({ model }) => {
        return model[BasicInfoFormField.DATA_SOURCE_TYPE] === DataSourceType.DEVICE;
      },
      valueField: 'value',
      changeEvent: 'update:value',
      componentProps: ({ formActionType }) => {
        const { getFieldsValue } = formActionType;
        const values = getFieldsValue();
        const convertConfigId = Reflect.get(values, BasicInfoFormField.CONVERT_CONFIG_ID);
        const devices = Reflect.get(values, BasicInfoFormField.DATA_SOURCE_DEVICE);

        return {
          labelField: 'name',
          valueField: 'tbDeviceId',
          primaryKey: 'tbDeviceId',
          pendingTableProps: {
            ...TransferTableProps,
            api: devicePage,
            beforeFetch: (params) => {
              const values = getFieldsValue();
              const deviceProfileIds = Reflect.get(values, BasicInfoFormField.DATA_SOURCE_PRODUCT);
              const convertConfigId = Reflect.get(values, BasicInfoFormField.CONVERT_CONFIG_ID);
              if (convertConfigId) {
                Object.assign(params, { convertConfigId, selected: false });
              }
              return { ...params, deviceProfileIds };
            },
          } as BasicTableProps,
          selectedTableProps: {
            ...TransferTableProps,
            // api
            api: !!(convertConfigId && devices) ? devicePage : undefined,
            beforeFetch: (params) => {
              const values = getFieldsValue();
              const deviceProfileIds = Reflect.get(values, BasicInfoFormField.DATA_SOURCE_PRODUCT);
              const convertConfigId = Reflect.get(values, BasicInfoFormField.CONVERT_CONFIG_ID);
              if (convertConfigId) {
                Object.assign(params, { convertConfigId, selected: true });
              }
              return { ...params, deviceProfileIds };
            },
          } as BasicTableProps,
          initSelectedOptions: async ({ setSelectedTotal }) => {
            const values = getFieldsValue();
            const convertConfigId = Reflect.get(values, BasicInfoFormField.CONVERT_CONFIG_ID);
            const deviceProfileIds = Reflect.get(values, BasicInfoFormField.DATA_SOURCE_PRODUCT);
            const devices = Reflect.get(values, BasicInfoFormField.DATA_SOURCE_DEVICE);
            if (convertConfigId && devices) {
              const { items, total } = await devicePage({
                page: 1,
                pageSize: 10,
                convertConfigId: values[BasicInfoFormField.CONVERT_CONFIG_ID],
                deviceProfileIds,
                selected: true,
              });
              setSelectedTotal(total);
              return items;
            }
            return [];
          },
          onSelectedAfter: async () => {
            submitFn && (await submitFn(false));
          },
          onRemoveAfter: async ({ reloadSelected }) => {
            submitFn && (await submitFn(false));
            reloadSelected();
          },
          transformValue: (_selectedRowKeys: string[], selectedRows: DeviceRecord[]) => {
            return handleGroupDevice(selectedRows);
          },
        };
      },
    },
    {
      field: 'type',
      label: '转换方式',
      component: 'ApiSelect',
      required: true,
      colProps: {
        span: 24,
      },
      componentProps({}) {
        return {
          api: findDictItemByCode,
          params: {
            dictCode: 'convert_data_to',
          },
          labelField: 'itemText',
          valueField: 'itemValue',
        };
      },
    },
    {
      field: 'remark',
      label: '描述',
      colProps: { span: 24 },
      component: 'Input',
      componentProps: {
        maxLength: 255,
        placeholder: '请输入描述',
      },
    },
  ];
};