PhysicalModelModal.vue 5.9 KB
<template>
  <div>
    <BasicModal
      :maskClosable="false"
      destroy-on-close
      v-bind="$attrs"
      width="55rem"
      @register="register"
      @ok="handleSubmit"
      @cancel="handleCancel"
    >
      <div class="relative">
        <div v-if="openModalMode === OpenModelMode.CREATE">
          <Typography>
            <TypographyParagraph>
              <blockquote class="bg-gray-100">{{ blockContent }}</blockquote>
            </TypographyParagraph>
          </Typography>
        </div>
        <Tabs
          v-if="openModalMode === OpenModelMode.CREATE"
          type="card"
          v-model:activeKey="activeKey"
          :size="size"
        >
          <TabPane :key="FunctionType.PROPERTIES" tab="属性" />
          <TabPane :key="FunctionType.SERVICE" :disabled="isTCPGatewaySubDevice" tab="服务" />
          <TabPane :key="FunctionType.EVENTS" tab="事件" :disabled="isTCPGatewaySubDevice" />
        </Tabs>
        <Attribute v-if="activeKey === FunctionType.PROPERTIES" ref="AttrRef" />
        <Service
          v-if="activeKey === FunctionType.SERVICE"
          :record="$props.record"
          ref="ServiceRef"
        />
        <Events v-if="activeKey === FunctionType.EVENTS" ref="EventsRef" />
        <div
          v-if="openModalMode === OpenModelMode.VIEW"
          class="absolute w-full h-full top-0 cursor-not-allowed z-50"
        ></div>
      </div>
    </BasicModal>
  </div>
</template>
<script lang="ts" setup>
  import { ref, unref, nextTick, computed } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { Tabs, TabPane, Typography, TypographyParagraph } from 'ant-design-vue';
  import Attribute from './cpns/Attribute.vue';
  import Service from './cpns/Service.vue';
  import Events from './cpns/Events.vue';
  import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
  import { createModel, updateModel } from '/@/api/device/modelOfMatter';
  import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { OpenModelMode, OpenModelOfMatterModelParams } from './types/index';
  import { FunctionType } from './cpns/config';

  const emit = defineEmits(['register', 'success']);

  const props = defineProps<{
    record: DeviceRecord;
  }>();

  const isTCPGatewaySubDevice = computed(() => {
    const { record } = props;
    const { deviceType, transportType } = record;
    return deviceType === DeviceTypeEnum.SENSOR && transportType === 'TCP';
  });

  const blockContent = `属性一般是设备的运行状态,如当前温度等;服务是设备可被调用的方法,支持定义参数,如执行某项任务;事件则是设备上报的
通知,如告警,需要被及时处理。`;
  const activeKey = ref<FunctionType>(FunctionType.PROPERTIES);
  const size = ref('small');

  const AttrRef = ref<InstanceType<typeof Attribute>>();

  const ServiceRef = ref<InstanceType<typeof Service>>();

  const EventsRef = ref<InstanceType<typeof Events>>();
  const openModalMode = ref<OpenModelMode>(OpenModelMode.CREATE);
  const openModalParams = ref<OpenModelOfMatterModelParams>();

  const functionType = ref<FunctionType>();
  const { createMessage } = useMessage();

  const setAttrFormData = (data: ModelOfMatterParams) => AttrRef.value?.setFormData(data);
  const setServiceFormData = (data: ModelOfMatterParams) => ServiceRef.value?.setFormData(data);
  const setEventsFormData = (data: ModelOfMatterParams) => EventsRef.value?.setFormData(data);

  const enums = {
    [FunctionType.PROPERTIES]: setAttrFormData,
    [FunctionType.SERVICE]: setServiceFormData,
    [FunctionType.EVENTS]: setEventsFormData,
  };

  function setFormData(type: FunctionType, value: ModelOfMatterParams) {
    const setFn = enums[type];
    setFn(value);
  }

  const [register, { closeModal, setModalProps }] = useModalInner(
    async (data: OpenModelOfMatterModelParams) => {
      openModalParams.value = data;
      const { mode, record } = data;
      openModalMode.value = mode;
      if (record) {
        functionType.value = data.record.functionType;
        activeKey.value = data.record.functionType;
        await nextTick();
        setFormData(record.functionType, record as unknown as ModelOfMatterParams);
      }
      if (unref(openModalMode) === OpenModelMode.VIEW) {
        setModalProps({ showOkBtn: false, showCancelBtn: false, title: '查看物模型' });
      } else {
        const title = unref(openModalMode) === OpenModelMode.UPDATE ? '编辑物模型' : '新增物模型';
        setModalProps({ title, showOkBtn: true, showCancelBtn: true });
      }
    }
  );

  const handleCancel = (flag) => {
    AttrRef.value?.resetFormData();
    ServiceRef.value?.resetFormData();
    EventsRef.value?.resetFormData();
    activeKey.value = FunctionType.PROPERTIES;
    if (flag) {
      closeModal();
    }
  };

  const handleSubmit = async () => {
    try {
      setModalProps({ loading: false, okButtonProps: { loading: true } });

      let params: Partial<ModelOfMatterParams>;
      if (activeKey.value == FunctionType.PROPERTIES) {
        params = (await AttrRef.value?.getFormData()) || {};
      } else if (activeKey.value == FunctionType.SERVICE) {
        params = (await ServiceRef.value?.getFormData()) || {};
      } else {
        params = (await EventsRef.value?.getFormData()) || {};
      }
      params.deviceProfileId = props.record.id;
      if (unref(openModalMode) === OpenModelMode.CREATE) {
        await createModel(params);
        createMessage.success('创建成功');
      } else {
        params.id = unref(openModalParams)?.record.id;
        await updateModel(params);
        createMessage.success('修改成功');
      }
      closeModal();
      emit('success');
    } catch (error) {
      throw Error(error);
    } finally {
      setModalProps({ loading: false, okButtonProps: { loading: false } });
    }
  };
</script>

<style lang="less" scope></style>