index.vue 4.58 KB
<template>
  <BasicModal
    title="命令下发"
    :width="650"
    @register="registerModal"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <BasicForm @register="registerForm">
      <template #serviceCommand="{ field, model }">
        <ThingsModelForm
          :disabled="
            deviceDetail?.deviceData?.transportConfiguration?.type === TransportTypeEnum.TCP
          "
          ref="thingsModelFormRef"
          v-model:value="model[field]"
          :key="model[CommandFieldsEnum.SERVICE_OBJECT_MODEL]?.identifier"
          :inputData="model[CommandFieldsEnum.SERVICE_OBJECT_MODEL]?.functionJson?.inputData"
          :transportType="deviceDetail?.deviceData?.transportConfiguration?.type"
        />
      </template>
    </BasicForm>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { nextTick, ref, unref } from 'vue';
  import { BasicForm, ThingsModelForm, useForm } from '/@/components/Form';
  import { CommandDeliveryFormFieldType, CommandFieldsEnum, CommandSchemas } from './config';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { CommandDeliveryWayEnum } from '/@/enums/deviceEnum';
  import { CommandTypeEnum, RPCCommandMethodEnum, TransportTypeEnum } from '/@/enums/deviceEnum';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { getDeviceActiveTime } from '/@/api/alarm/position';
  import { RpcCommandType } from '/@/api/device/model/deviceConfigModel';
  import { parseStringToJSON } from '/@/components/CodeEditor';
  import { commandIssuanceApi } from '/@/api/device/deviceManager';
  import { EdgeDeviceItemType } from '/@/api/edgeManage/model/edgeInstance';

  defineEmits(['register']);

  const thingsModelFormRef = ref<InstanceType<typeof ThingsModelForm>>();
  const props = defineProps<{
    deviceDetail: EdgeDeviceItemType;
  }>();

  const [registerModal, { setModalProps }] = useModalInner(
    (params: ModalParamsType<EdgeDeviceItemType>) => {
      const { record } = params;
      setProps({
        schemas: CommandSchemas(record),
      });
    }
  );

  const { createMessage } = useMessage();

  const [registerForm, { setProps, getFieldsValue, validate, resetFields, clearValidate }] =
    useForm({
      labelWidth: 120,
      baseColProps: { span: 20 },
      labelAlign: 'right',
      showSubmitButton: false,
      showResetButton: false,
    });

  const handleCancel = async () => {
    await resetFields();
    await nextTick();
    await clearValidate();
  };

  const handleValidate = async () => {
    await validate();
    await unref(thingsModelFormRef)?.validate?.();
  };

  const handleValidateDeviceActive = async (): Promise<boolean> => {
    const result = await getDeviceActiveTime(unref(props.deviceDetail)!.id?.id);
    const [firstItem] = result;
    return !!firstItem.value;
  };

  const handleCommandParams = (
    values: CommandDeliveryFormFieldType,
    serviceCommand: Recordable
  ) => {
    const { commandType, service } = values;

    const isTcpDevice =
      unref(props.deviceDetail)?.deviceData?.transportConfiguration?.type === TransportTypeEnum.TCP;
    if (commandType === CommandTypeEnum.CUSTOM) {
      if (isTcpDevice) {
        const value = values.tcpCommandValue;
        return value?.replaceAll(/\s/g, '');
      }
      return parseStringToJSON(values.commandValue!).json;
    } else {
      if (isTcpDevice) return Reflect.get(serviceCommand, CommandFieldsEnum.SERVICE_COMMAND);
      return {
        [service!]: serviceCommand,
      };
    }
  };

  const handleOk = async () => {
    await handleValidate();

    try {
      setModalProps({ loading: true, confirmLoading: true });

      const values = getFieldsValue() as CommandDeliveryFormFieldType;
      const { callType, commandType } = values;
      const serviceCommand = unref(thingsModelFormRef)?.getFieldsValue() || {};

      if (callType === CommandDeliveryWayEnum.TWO_WAY && !(await handleValidateDeviceActive())) {
        createMessage.warn('当前设备不在线');
        return;
      }

      const rpcCommands: RpcCommandType = {
        additionalInfo: {
          cmdType:
            commandType === CommandTypeEnum.CUSTOM
              ? CommandTypeEnum.CUSTOM
              : CommandTypeEnum.SERVICE,
        },
        method: RPCCommandMethodEnum.THINGSKIT,
        persistent: true,
        params: handleCommandParams(values, serviceCommand),
      };

      await commandIssuanceApi(callType, unref(props.deviceDetail)!.id?.id, rpcCommands);

      createMessage.success('命令下发成功');
    } finally {
      setModalProps({ loading: false, confirmLoading: false });
    }
  };
</script>
<style scoped lang="less"></style>