messageHandler.ts 2.87 KB
import { isNull } from 'lodash-es'
import type { App } from 'vue'
import type { SubscriptionUpdateMsg } from '../type/message'
import { DataDynamicEffectHandler } from './dataDynamicEffectHandler'
import { useObjectModelValue } from './useObjectModelValue'
import type { CommandSource, LightboxModeWebsocketService } from '.'
import type { ActTypeEnum } from '@/enums/datasource'
import { DataSourceTypeEnum } from '@/enums/datasource'
import { getAppInstanceId } from '@/utils/draw'
import type { RenderComponentExposeType } from '@/core/Library/types'
import { useLatestMessageValue } from '@/core/Library/hook/useLatestMessageValue'
import type { NodeDataDataSourceJsonType } from '@/api/node/model'

export class MessageHandler {
  constructor(public service: LightboxModeWebsocketService) {
  }

  get nodeUtils() {
    return this.service.nodeUtils
  }

  distribute(message: SubscriptionUpdateMsg) {
    const { subscriptionId } = message
    const telemetrySubscriber = this.service.subscribersMap.get(subscriptionId)

    if (!telemetrySubscriber) return

    const { commandSource } = telemetrySubscriber
    const { dataType } = commandSource
    if (dataType === DataSourceTypeEnum.DATASOURCE)
      this.updateDataSource(commandSource, message)
    else if (dataType === DataSourceTypeEnum.ACT)
      this.updateDataDynamicEffect(commandSource, message)
  }

  updateDataSource(commandSource: CommandSource, message: SubscriptionUpdateMsg) {
    try {
      const { node } = commandSource
      const cell = this.nodeUtils.getCellById(node)
      if (!cell) return
      const instanceId = getAppInstanceId(cell)
      const instance = window?.VueInstanceMap?.[instanceId] as App
      if (instance && (instance._instance?.exposed as RenderComponentExposeType)?.onMessage)
        (instance._instance?.exposed as RenderComponentExposeType)?.onMessage?.(commandSource, message)
      else
        this.defaultHandler(commandSource, message)
    }
    catch (error) {
      console.error(error)
    }
  }

  defaultHandler(commandSource: CommandSource, message: SubscriptionUpdateMsg) {
    const { data, node } = commandSource
    const { attr, deviceProfileId } = data as NodeDataDataSourceJsonType

    let { latestValue } = useLatestMessageValue(message.data, attr as string)
    if (isNull(latestValue)) return
    latestValue = useObjectModelValue(deviceProfileId, attr as string, latestValue)
    const cell = this.nodeUtils.getCellById(node)

    const cellValue = cell.getValue() as Element
    cellValue.setAttribute('label', latestValue)
    this.nodeUtils.updateCellValue(cell, cellValue)
  }

  updateDataDynamicEffect(commandSource: CommandSource, message: SubscriptionUpdateMsg) {
    const { type } = commandSource
    const handler = new DataDynamicEffectHandler(this.service)

    if (!type) return
    if (handler[type as ActTypeEnum])
      handler[type as ActTypeEnum]?.(commandSource, message)
  }
}