index.vue 5.33 KB
<script lang="ts" setup>
  import { ComponentPropsConfigType } from '../../../index.type';
  import { option } from './config';
  import { ref, unref } from 'vue';
  import { SvgIcon } from '/@/components/Icon';
  import { computed } from 'vue';
  import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  import { useReceiveMessage } from '../../../hook/useReceiveMessage';
  import { useReceiveValue } from '../../../hook/useReceiveValue';
  import { useMultipleDataFetch } from '../../../hook/socket/useSocket';
  import { MultipleDataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
  import { useComponentScale } from '../../../hook/useComponentScale';
  import { useDeviceProfileQueryContext } from '/@/views/visual/palette/hooks/useDeviceProfileQueryContext';
  import { buildUUID } from '/@/utils/uuid';
  import { useI18n } from '/@/hooks/web/useI18n';

  const props = defineProps<{
    config: ComponentPropsConfigType<typeof option>;
  }>();
  const { t } = useI18n();

  const time = ref<Nullable<number>>(null);

  const { getDeviceProfileTslByIdWithIdentifier } = useDeviceProfileQueryContext();

  const getDesign = computed(() => {
    const { persetOption = {}, option } = props.config;
    const { dataSource = [] } = option || {};
    const {
      unit: persetUnit,
      fontColor: persetFontColor,
      icon: persetIcon,
      iconColor: persetIconColor,
      valueSize: persetValueSize,
      fontSize: persetFontSize,
    } = persetOption || {};

    return {
      dataSource: dataSource.map((item) => {
        const { fontColor, icon, iconColor, unit, valueSize, fontSize, customIcon, defaultCustom } =
          item.componentInfo;
        const { attribute, attributeRename, deviceName, deviceRename, deviceId, deviceProfileId } =
          item;
        const tsl = getDeviceProfileTslByIdWithIdentifier?.(deviceProfileId, attribute);
        return {
          unit: unit ?? persetUnit,
          fontColor: fontColor ?? persetFontColor,
          icon: icon ?? persetIcon,
          iconColor: iconColor ?? persetIconColor,
          attribute,
          deviceName: deviceRename || deviceName,
          attributeName: attributeRename || tsl?.functionName,
          id: deviceId,
          valueSize: valueSize || persetValueSize || 20,
          fontSize: fontSize || persetFontSize || 14,
          defaultCustom: defaultCustom || 'default',
          customIcon: customIcon || [],
        };
      }),
    };
  });

  const defaultSvgList = ref([
    {
      id: buildUUID(),
      value: 26.2,
      deviceName: t('business.deviceText'),
      attributeName: t('business.attributeText'),
      icon: 'zongfushe',
      unit: '℃',
      iconColor: '#367BFF',
      fontColor: '#357CFB',
      fontSize: 16,
      valueSize: 16,
      defaultCustom: 'default',
      customIcon: [],
    },
    {
      id: buildUUID(),
      value: 53.7,
      deviceName: t('business.deviceText'),
      attributeName: t('business.attributeText'),
      icon: 'guangzhaoqiangdu',
      unit: '%RH',
      iconColor: '#FFA000',
      fontColor: '#FFA000',
      fontSize: 16,
      valueSize: 16,
      defaultCustom: 'default',
      customIcon: [],
    },
  ]);

  const { forEachGroupMessage } = useReceiveMessage();
  const { getNumberValue } = useReceiveValue();

  const updateSvgList = ref(
    props.config.option.dataSource ? unref(getDesign).dataSource : defaultSvgList
  );

  const updateFn: MultipleDataFetchUpdateFn = (message, deviceId, attribute) => {
    forEachGroupMessage(message, deviceId, attribute, (attribute, value, timespan) => {
      updateSvgList.value.forEach((item) => {
        if (item.id === deviceId && item.attribute === attribute && value) {
          item.value = getNumberValue(value);
          time.value = timespan;
        }
      });
    });
  };

  useMultipleDataFetch(props, updateFn);
  const { getRatio } = useComponentScale(props);
</script>

<template>
  <main class="w-full h-full flex flex-col justify-evenly items-center">
    <DeviceName :config="config" />
    <div
      style="width: 86%"
      v-for="item in updateSvgList"
      :key="item.id"
      class="flex justify-between items-center mt-2"
    >
      <div class="flex items-center">
        <!-- <SvgIcon
          :name="item.icon!"
          prefix="iconfont"
          :size="getRatio ? 30 * getRatio : 30"
          :style="{ color: item.iconColor }"
        /> -->
        <SvgIcon
          v-if="item.defaultCustom !== 'custom'"
          :name="item.icon!"
          prefix="iconfont"
          :size="getRatio ? getRatio * 30 : 30"
          :style="{ color: item.iconColor }"
        />
        <img
          v-else
          :src="item.customIcon[0]?.url"
          :style="{ width: getRatio ? getRatio * 30 + 'px' : '30px' }"
          :alt="item.customIcon[0]?.name"
        />
        <div
          class="text-gray-500 ml-6"
          :style="{ fontSize: (getRatio ? getRatio * item.fontSize : item.fontSize) + 'px' }"
          >{{
            item.deviceName + '-' + item.attributeName || t('visual.board.temperatureText')
          }}</div
        >
      </div>

      <span
        :style="{
          color: item.fontColor,
          fontSize: (getRatio ? getRatio * item.valueSize : item.valueSize) + 'px',
        }"
      >
        <span> {{ (item as any).value || 0 }}</span>
        <span>{{ item.unit }} </span>
      </span>
    </div>
  </main>
</template>