GBTDrawer.vue 4.2 KB
<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    :destroy-on-close="true"
    title="新增GBT28181"
    width="30%"
    @ok="handleSubmit"
    wrapClassName="camera-configration-drawer"
  >
    <BasicForm @register="registerForm">
      <!-- 表单设备通道插槽 -->
      <template #deviceChannelsSlot="{ model }">
        <span class="hidden">{{ handleSelectOrg(model['organizationId']) }}</span>
        <SelectDevice ref="selectDeviceRef" :selectOptions="selectDeviceOptions" />
      </template>
    </BasicForm>
  </BasicDrawer>
</template>

<script lang="ts" setup name="GBTDrawer">
  import { ref, nextTick, onMounted, watch } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getStreamingMediaList, createGPTPostApi } from '/@/api/camera/cameraManager';
  import SelectDevice from './SelectDevice.vue';
  import { formGBTSchema, StreamInterface } from '../config.data';
  import { getMeetTheConditionsDevice } from '/@/api/dataBoard';
  import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';

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

  const streamConfigOptions = ref<StreamInterface[]>([]);

  const selectDeviceOptions = ref<StreamInterface[]>([]);

  const orgId = ref('');

  const selectDeviceRef = ref<InstanceType<typeof SelectDevice>>();

  const { createMessage } = useMessage();

  const [registerForm, { validate, resetFields }] = useForm({
    labelWidth: 120,
    schemas: formGBTSchema,
    showActionButtonGroup: false,
  });

  const getStreamingMediaLists = async () => {
    const rest = await getStreamingMediaList({});
    streamConfigOptions.value = rest?.map(({ host: label, id: value, type }) => ({
      label,
      value,
      type,
    }));
  };

  onMounted(() => getStreamingMediaLists());

  const handleSelectOrg = (e) => (orgId.value = e);

  const getDeviceListByOrg = async (organizationId) => {
    const values = await getMeetTheConditionsDevice({
      organizationId,
      transportType: TransportTypeEnum.GBT28181,
    });
    selectDeviceOptions.value = values
      ? values.map((item) => ({
          label: item.alias || item.name,
          value: item.tbDeviceId,
          id: item.id,
          deviceProfileId: item.deviceProfileId,
        }))
      : [];
  };

  watch(
    () => orgId.value,
    (newValue) => {
      if (newValue) {
        //获取设备
        selectDeviceRef.value?.resetValue();
        getDeviceListByOrg(newValue);
      }
    },
    {
      immediate: true,
    }
  );

  const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
    await resetFields();
    await nextTick();
    selectDeviceRef.value?.resetValue();
    const { record } = data || {};
    // 批量新增不需要回显
    return record;
  });

  //验证视频通道号
  const validateChannelNos = (gptDeviceDTOS) => {
    gptDeviceDTOS.some((deviceDTO) => {
      const channelNo = deviceDTO['channelNos'];
      const ChannelNoRegexp = /^\d{1,20}$/;
      if (!ChannelNoRegexp.test(channelNo)) {
        createMessage.error('输入内容只能是数字,且不能超过20位');
        throw Error('输入内容只能是数字,且不能超过20位');
      }
    });
  };

  const handleSubmit = async () => {
    try {
      setDrawerProps({ confirmLoading: true });
      const values = await validate();
      if (!values) return;
      const gptDeviceDTOS = selectDeviceRef.value?.getDeviceChannels();
      if (Array.isArray(gptDeviceDTOS) && gptDeviceDTOS.length == 0)
        return createMessage.error('请填写设备通道号');
      validateChannelNos(gptDeviceDTOS);
      const mergeValues = {
        ...values,
        accessMode: 2,
        gptDeviceDTOS,
      };
      await createGPTPostApi(mergeValues);
      createMessage.success('批量新增成功');
      closeDrawer();
      emits('success');
    } finally {
      setDrawerProps({ confirmLoading: false });
    }
  };
</script>

<style lang="less" scoped>
  .camera-configration-drawer {
    .ant-input-number {
      width: 100% !important;
    }
  }
</style>