index.vue 3.49 KB
<script lang="ts" setup>
  import {
    ComponentPropsConfigType,
    MultipleDataFetchUpdateFn,
  } from '/@/views/visual/packages/index.type';
  import { option } from './config';
  import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket';
  import { SvgIcon } from '/@/components/Icon';
  import { Switch } from 'ant-design-vue';
  import { computed, ref } from 'vue';
  import { useComponentScale } from '../../../hook/useComponentScale';
  import { useSendCommand } from '../../../hook/useSendCommand';
  import { unref } from 'vue';
  import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';

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

  const checked = ref(false);

  const svgList = ref<any>([
    {
      value: 26.2,
      name: 'wendu',
      icon: 'zongfushe',
      unit: 'kw',
      iconColor: '#367BFF',
      fontColor: '#357CFB',
      checked: false,
      id: 0,
    },
    {
      value: 53.7,
      name: 'shidu',
      icon: 'guangzhaoqiangdu',
      unit: '℃',
      iconColor: '#FFA000',
      fontColor: '#FFA000',
      checked: true,
      id: 1,
    },
  ]);

  const getDesign = computed(() => {
    const { persetOption = {}, option } = props.config;
    const { dataSource = [] } = option || {};
    const {
      unit: persetUnit,
      fontColor: persetFontColor,
      icon: persetIcon,
      iconColor: persetIconColor,
    } = persetOption || {};
    return {
      dataSource: dataSource.map((item) => {
        const { fontColor, icon, iconColor, unit } = item.componentInfo;
        const { attribute, attributeRename } = item;
        return {
          unit: unit ?? persetUnit,
          fontColor: fontColor ?? persetFontColor,
          icon: icon ?? persetIcon,
          iconColor: iconColor ?? persetIconColor,
          attribute: attribute || attributeRename,
          attributeRename,
        };
      }),
    };
  });

  const { sendCommand, loading } = useSendCommand();
  const handleChange = async (index: number) => {
    const flag = await sendCommand(props.config.option, unref(checked));
    if (!flag) svgList[index].checked = !svgList[index].checked;
  };

  const updateFn: MultipleDataFetchUpdateFn = (message) => {
    const { data = {} } = message;
    const { dataSource } = unref(getDesign);
    svgList.value.length = 0;
    svgList.value = dataSource.map((item) => {
      const { icon, iconColor, unit, fontColor, attribute } = item || {};
      const [latest] = data[attribute] || [];
      const [_timespan, value] = latest || [];
      return {
        value: Number(value),
        name: attribute,
        icon,
        unit,
        iconColor,
        fontColor,
      };
    });
  };

  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, index) in svgList"
      :key="item.id"
      class="flex justify-between items-center"
    >
      <div class="flex items-center">
        <SvgIcon
          :name="item.icon!"
          prefix="iconfont"
          :size="getRatio ? 30 * getRatio : 30"
          :style="{ color: item.iconColor }"
        />

        <div class="text-gray-500 text-lg truncate ml-6">{{ item.attribute || '温度' }}</div>
      </div>

      <Switch v-model:checked="item.checked" :loading="loading" @change="handleChange(index)" />
    </div>
  </main>
</template>