config.data.ts 9 KB
import { BasicColumn, FormSchema } from '/@/components/Table';
import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/Form/index';

import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules';
import { h } from 'vue';
import SnHelpMessage from './SnHelpMessage.vue';
import SnHelpMessage1 from './SnHelpMessage1.vue';
import { OrgTreeSelect } from '../../common/OrgTreeSelect';
import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
import { createImgPreview } from '/@/components/Preview';
import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
import { findDictItemByCode } from '/@/api/system/dict';
import { DictEnum } from '/@/enums/dictEnum';

useComponentRegister('OrgTreeSelect', OrgTreeSelect);

export enum CameraPermission {
  PREVIEW = 'api:yt:video:get',
  CREATE = 'api:yt:video:post',
  UPDATE = 'api:yt:video:update',
  DELETE = 'api:yt:video:delete',
}

export enum AccessMode {
  ManuallyEnter = 0,
  Streaming = 1,
}

export enum PlayProtocol {
  HTTP = 0,
  HTTPS = 1,
}

export enum StreamType {
  MASTER = 0,
  CHILD = 1,
  THIRD = 2,
}

export enum PageMode {
  SPLIT_SCREEN_MODE = 'splitScreen',
  LIST_MODE = 'listMode',
  FULL_SCREEN_MODE = 'fullScreenMode',
}

export enum MediaType {
  MP4 = 'mp4',
  M3U8 = 'm3u8',
}

export enum ArticulationEnumType {
  HIGH_DEFINITION = 1,
  SMOOTH = 2,
}
export enum ArticulationEnumNameType {
  HIGH_DEFINITION = '高清',
  SMOOTH = '流畅',
}
// 表格列数据
export const columns: BasicColumn[] = [
  {
    title: '封面',
    dataIndex: 'avatar',
    width: 80,
    slots: { customRender: 'img' },
  },
  {
    title: '名字',
    dataIndex: 'name',
    width: 120,
  },
  {
    title: '摄像头编号/监控点编号',
    dataIndex: 'sn',
    width: 220,
  },
  {
    title: '视频流',
    dataIndex: 'videoUrl',
    width: 120,
  },
  {
    title: '所属组织',
    dataIndex: 'organizationName',
    width: 160,
  },
  {
    title: '获取方式',
    dataIndex: 'accessMode',
    width: 100,
    slots: { customRender: 'accessMode' },
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    width: 140,
  },
];

// 查询字段
export const searchFormSchema: FormSchema[] = [
  {
    field: 'name',
    label: '摄像头名字',
    component: 'Input',
    colProps: { span: 8 },
    componentProps: {
      maxLength: 36,
      placeholder: '请输入摄像头名字',
    },
  },
];

export enum VideoPlatformEnum {
  // 海康
  SCI = 0,
  // 萤石云
  FLUORITE = 1,
}

// 弹框配置项
export const formSchema: QFormSchema[] = [
  {
    field: 'avatar',
    label: '视频封面',
    component: 'ApiUpload',
    changeEvent: 'update:fileList',
    valueField: 'fileList',
    componentProps: () => {
      return {
        listType: 'picture-card',
        maxFileLimit: 1,
        accept: '.png,.jpg,.jpeg,.gif',
        api: async (file: File) => {
          try {
            const formData = new FormData();
            formData.set('file', file);
            const { fileStaticUri, fileName } = await uploadThumbnail(formData);
            return {
              uid: fileStaticUri,
              name: fileName,
              url: fileStaticUri,
            } as FileItem;
          } catch (error) {
            return {};
          }
        },
        onPreview: (fileList: FileItem) => {
          createImgPreview({ imageList: [fileList.url!] });
        },
      };
    },
  },
  {
    field: 'name',
    label: '视频名字',
    required: true,
    component: 'Input',
    componentProps: {
      placeholder: '请输入视频名字',
      maxLength: 30,
    },
    rules: [...CameraMaxLength, { required: true, message: '视频名是必填项' }],
  },
  {
    field: 'organizationId',
    label: '所属组织',
    required: true,
    component: 'OrgTreeSelect',
  },
  {
    label: '视频流获取方式',
    field: 'accessMode',
    component: 'RadioGroup',
    rules: [{ required: true, message: '视频流获取方式为必选项', type: 'number' }],
    defaultValue: AccessMode.ManuallyEnter,
    componentProps({ formActionType }) {
      return {
        defaultValue: AccessMode.ManuallyEnter,
        placeholder: '请选择视频流获取方式',
        options: [
          { label: '手动输入', value: AccessMode.ManuallyEnter },
          { label: '流媒体获取', value: AccessMode.Streaming },
        ],
        onChange() {
          formActionType.setFieldsValue({
            brand: null,
            sn: null,
            videoUrl: null,
            videoPlatformId: null,
          });
        },
      };
    },
  },
  {
    field: 'brand',
    label: '视频厂家',
    component: 'Input',
    ifShow({ values }) {
      return values.accessMode === AccessMode.ManuallyEnter;
    },
    componentProps: {
      maxLength: 36,
      placeholder: '请输入视频厂家',
    },
  },
  {
    field: 'sn',
    label: '摄像头编号',
    required: true,
    component: 'Input',
    rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
    ifShow({ values }) {
      return values.accessMode === AccessMode.ManuallyEnter;
    },
    componentProps: {
      maxLength: 36,
      placeholder: '请输入摄像头编号',
    },
  },
  {
    field: 'videoUrl',
    label: '视频流',
    component: 'Input',
    required: true,
    ifShow({ values }) {
      return values.accessMode === AccessMode.ManuallyEnter;
    },
    componentProps: {
      placeholder: '请输入视频流',
      maxLength: 255,
    },
    rules: [{ required: true, message: '视频流是必填项' }, ...CameraVideoUrl],
  },
  {
    field: 'videoType',
    label: '流媒体平台',
    component: 'ApiRadioGroup',
    required: true,
    defaultValue: VideoPlatformEnum.SCI,
    ifShow: ({ values }) => values.accessMode === AccessMode.Streaming,
    componentProps: {
      api: async (params) => {
        const values = await findDictItemByCode(params);
        return values.map((item) => ({ label: item.itemText, value: Number(item.itemValue) }));
      },
      params: {
        dictCode: DictEnum.STREAMING_MEDIA_TYPE,
      },
      getPopupContainer: () => document.body,
      placeholder: `请选择平台类型`,
    },
  },
  {
    field: 'videoPlatformId',
    label: '流媒体配置',
    component: 'Select',
    ifShow({ values }) {
      return values.accessMode === AccessMode.Streaming;
    },
    slot: 'videoPlatformIdSlot',
    componentProps: {
      placeholder: '请选择流媒体配置',
    },
  },
  {
    field: 'streamType',
    label: '码流',
    component: 'RadioGroup',
    defaultValue: StreamType.MASTER,
    ifShow({ values }) {
      return (
        values.accessMode === AccessMode.Streaming &&
        values.videoType !== VideoPlatformEnum.FLUORITE
      );
    },
    componentProps: {
      placeholder: '请选择码流',
      defaultValue: StreamType.MASTER,
      options: [
        { label: '主码流', value: StreamType.MASTER },
        { label: '子码流', value: StreamType.CHILD },
        { label: '第三码流', value: StreamType.THIRD },
      ],
    },
  },
  {
    field: 'articulation',
    label: '清晰度',
    component: 'RadioGroup',
    defaultValue: ArticulationEnumType.HIGH_DEFINITION,
    ifShow: ({ model }) =>
      model.accessMode === AccessMode.Streaming && model.videoType === VideoPlatformEnum.FLUORITE,
    componentProps: () => {
      return {
        options: [
          {
            label: ArticulationEnumNameType.HIGH_DEFINITION,
            value: ArticulationEnumType.HIGH_DEFINITION,
          },
          {
            label: ArticulationEnumNameType.SMOOTH,
            value: ArticulationEnumType.SMOOTH,
          },
        ],
      };
    },
  },
  {
    field: 'playProtocol',
    label: '播放协议',
    component: 'RadioGroup',
    defaultValue: PlayProtocol.HTTPS,
    ifShow({ values }) {
      return (
        values.accessMode === AccessMode.Streaming &&
        values.videoType !== VideoPlatformEnum.FLUORITE
      );
    },
    helpMessage: ['平台使用https的hls协议,需联系海康开放平台专家支持。'],
    componentProps: {
      placeholder: '请选择播放协议',
      defaultValue: PlayProtocol.HTTPS,
      options: [{ label: 'https', value: PlayProtocol.HTTPS }],
    },
  },
  {
    field: 'sn',
    label: h(SnHelpMessage) as any,
    component: 'Input',
    rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
    ifShow({ values }) {
      return (
        values.accessMode === AccessMode.Streaming &&
        values.videoType !== VideoPlatformEnum.FLUORITE
      );
    },
    componentProps: {
      placeholder: '请输入监控点编号',
    },
  },
  {
    field: 'sn',
    label: h(SnHelpMessage1) as any,
    component: 'Input',
    rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
    ifShow({ values }) {
      return (
        values.accessMode === AccessMode.Streaming &&
        values.videoType === VideoPlatformEnum.FLUORITE
      );
    },
    componentProps: {
      placeholder: '请输入监控点编号',
    },
  },
];