config.vue 6.02 KB
<script setup lang="ts">
import { Button, Divider } from 'ant-design-vue'
import { nextTick, onMounted, ref, unref } from 'vue'
import { getOrganization } from '@/api/device'
import { getCameraList } from '@/api/video'
import { BasicForm, useForm } from '@/components/Form'
import { ComponentEnum, FormLayoutEnum } from '@/components/Form/src/enum'
import { ContentDataFieldsEnum, ContentDataFieldsNameEnum } from '@/enums/datasource'
import { useParseParams } from '@/core/LoadData'
import { useNodeData } from '@/core/Library/hook/useNodeData'
import type { ConfigComponentProps } from '@/core/Library/types'
import { createPublicFormContext } from '@/core/Library/components/PublicForm/usePublicFormContext'
import type { NodeDataDataSourceJsonType, VideoOptionType } from '@/api/node/model'
import { useMessage } from '@/hooks/web/useMessage'
import { useSavePageContent } from '@/core/Library/hook/useSavePageContent'
import { VideoAccessModeEnum } from '@/enums/videoEnum'
import type { VideoItemRecordType } from '@/api/video/model'

const props = defineProps<ConfigComponentProps>()
const { organizationId } = useParseParams()
const nodeDataActinType = useNodeData({ cell: props.cell!, immediate: false })

const { getNodeData, getNodeAllData, saveNodeAllData } = nodeDataActinType

enum VideoFormFieldsEnum {
  VIDEO_ID = 'id',
  VIDEO_URL = 'videoUrl',
  ACCESS_MODE = 'accessMode',
  VIDEO_FLAG = 'videoComponentFlag',
  CHANNEL_ID = 'channelId',
  DEVICE_ID = 'deviceId',
  PLAY_PROTOCOL = 'playProtocol',
}

enum VideoFormFieldsNameEnum {
  VIDEO_ID = '视频流',
  ACCESS_MODE = 'ACCESS_MODE',
  VIDEO_URL = '视频地址',
  CHANNEL_ID = '通道号',
  DEVICE_ID = '设备id',
  PLAY_PROTOCOL = '播放协议',
}

const loading = ref(false)

const [register, { getFieldsValue, validate, setFieldsValue }] = useForm({
  schemas: [
    {
      field: ContentDataFieldsEnum.ORG_ID,
      label: ContentDataFieldsNameEnum.ORG_ID,
      component: ComponentEnum.API_TREE_SELECT,
      required: true,
      componentProps: ({ formModel }) => {
        return {
          api: getOrganization,
          params: organizationId,
          labelField: 'name',
          valueField: 'id',
          onChange() {
            formModel[VideoFormFieldsEnum.VIDEO_ID] = null
            formModel[VideoFormFieldsEnum.CHANNEL_ID] = null
            formModel[VideoFormFieldsEnum.DEVICE_ID] = null
            formModel[VideoFormFieldsEnum.PLAY_PROTOCOL] = null
          },
        }
      },
    },
    {
      field: VideoFormFieldsEnum.VIDEO_ID,
      label: VideoFormFieldsNameEnum.VIDEO_ID,
      component: ComponentEnum.API_SELECT,
      required: true,
      componentProps: ({ formModel }) => {
        return {
          api: async (params: Record<'organizationId', string>) => {
            if (!params.organizationId) return []
            return await getCameraList(params)
          },
          params: {
            organizationId: formModel[ContentDataFieldsEnum.ORG_ID],
          },
          fieldNames: { label: 'name', value: 'id' },
          resultField: 'data',
          onSelect(_: string, option: VideoItemRecordType) {
            const accessMode = option?.accessMode
            formModel[VideoFormFieldsEnum.ACCESS_MODE] = accessMode
            formModel[VideoFormFieldsEnum.VIDEO_URL] = option?.videoUrl
            formModel[VideoFormFieldsEnum.CHANNEL_ID] = accessMode === VideoAccessModeEnum.GBT28181 ? option?.params?.channelNo : null
            formModel[VideoFormFieldsEnum.DEVICE_ID] = accessMode === VideoAccessModeEnum.GBT28181 ? option?.params?.deviceId : null
            formModel[VideoFormFieldsEnum.VIDEO_FLAG] = true
            formModel[VideoFormFieldsEnum.PLAY_PROTOCOL] = option?.playProtocol
          },
        }
      },
    },
    {
      field: VideoFormFieldsEnum.ACCESS_MODE,
      label: VideoFormFieldsNameEnum.ACCESS_MODE,
      component: ComponentEnum.INPUT,
      ifShow: false,
    },
    {
      field: VideoFormFieldsEnum.DEVICE_ID,
      label: VideoFormFieldsNameEnum.DEVICE_ID,
      component: ComponentEnum.INPUT,
      ifShow: false,
    },
    {
      field: VideoFormFieldsEnum.CHANNEL_ID,
      label: VideoFormFieldsNameEnum.CHANNEL_ID,
      component: ComponentEnum.INPUT,
      ifShow: false,
    },
    {
      field: VideoFormFieldsEnum.VIDEO_URL,
      label: VideoFormFieldsNameEnum.VIDEO_URL,
      component: ComponentEnum.INPUT,
      ifShow: false,
    },
    {
      field: VideoFormFieldsEnum.VIDEO_FLAG,
      label: VideoFormFieldsEnum.VIDEO_FLAG,
      component: ComponentEnum.INPUT,
      ifShow: false,
    },
    {
      field: VideoFormFieldsEnum.PLAY_PROTOCOL,
      label: VideoFormFieldsNameEnum.PLAY_PROTOCOL,
      component: ComponentEnum.INPUT_NUMBER,
      ifShow: false,
    },
  ],

  showActionButtonGroup: false,
  layout: FormLayoutEnum.HORIZONTAL,
  labelWidth: 70,
})

const handleSetFormValues = async () => {
  const { dataSourceJson } = unref(getNodeData) || {}
  const { videoOption } = dataSourceJson || {}
  await nextTick()
  setFieldsValue(videoOption || {})
}
const { createMessage } = useMessage()
const { savePageContent } = useSavePageContent()
const handleSubmit = async () => {
  try {
    loading.value = true
    await validate()
    const values = getFieldsValue()
    await saveNodeAllData({ dataSourceJson: { videoOption: values as unknown as VideoOptionType } as unknown as NodeDataDataSourceJsonType })
    createMessage.success('操作成功~')
    savePageContent()
  }
  finally {
    loading.value = false
  }
}

onMounted(async () => {
  await getNodeAllData()
  handleSetFormValues()
})
createPublicFormContext(nodeDataActinType)
</script>

<template>
  <main class="w-full h-full flex flex-col">
    <div class="px-4 form-container">
      <Divider orientation="left">
        视频绑定
      </Divider>
      <BasicForm @register="register" />
      <Button type="primary" class="w-full" :loading="loading" @click="handleSubmit">
        保存
      </Button>
    </div>
  </main>
</template>

<style lang="less" scoped>
.form-container {
  @apply text-sm;

  :deep(.ant-divider) {
    @apply text-sm;
  }
}
</style>