index.vue 3.41 KB
<script lang="ts" setup>
  import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
  import { option } from './config';
  import { useComponentScale } from '/@/views/visual/packages/hook/useComponentScale';
  import { computed } from 'vue';
  import { ref, onMounted, unref } from 'vue';
  import { useIntervalFn } from '@vueuse/core';
  import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
  import { useReceiveValue } from '../../../hook/useReceiveValue';
  import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime';
  import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
  import { useDataFetch } from '../../../hook/socket/useSocket';

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

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

  const getDesign = computed(() => {
    const { persetOption = {}, option } = props.config;
    const {
      openColor: persetOpenColor,
      closeColor: persetCloseColor,
      showDeviceName: persetShowDeviceName,
      showTime: persetShowTime,
      fontSize: persetFontSize,
    } = persetOption || {};
    const { componentInfo, attribute, attributeName, attributeRename } = option;

    const { openColor, closeColor, showDeviceName, showTime, fontSize } = componentInfo || {};
    return {
      openColor: openColor ?? persetOpenColor,
      closeColor: closeColor ?? persetCloseColor,
      showDeviceName: showDeviceName ?? persetShowDeviceName,
      attribute: attributeRename || attributeName || attribute,
      showTime: showTime ?? persetShowTime,
      fontSize: fontSize || persetFontSize || 14,
    };
  });

  const randomFn = () => {
    useIntervalFn(() => {
      isOpenClose.value = !unref(isOpenClose);
    }, 2000);
  };
  const { getNumberValue } = useReceiveValue();
  const updateFn: DataFetchUpdateFn = (message, attribute) => {
    const { data = {} } = message;
    const [latest] = data[attribute] || [];
    if (!latest.length) return;
    const [timespan, value] = latest;
    time.value = timespan;
    isOpenClose.value = Boolean(getNumberValue(value));
  };

  onMounted(() => {
    !props.config.option.uuid && randomFn();
  });

  useDataFetch(props, updateFn);

  const { getScale } = useComponentScale(props);
</script>

<template>
  <main
    :style="getScale"
    class="w-full h-full flex flex-col justify-center items-center"
    :class="!getDesign.showTime && 'p-5'"
  >
    <DeviceName :config="config" class="text-center" />

    <div class="flex-1 flex justify-center items-center flex-col" :style="getScale">
      <div
        :style="{
          '--open-color': getDesign.openColor,
          '--close-color': getDesign.closeColor,
        }"
        :class="isOpenClose ? 'switch_open' : 'switch_close'"
      ></div>
      <div class="text-gray-500 truncate" :style="{ fontSize: getDesign.fontSize + 'px' }">{{
        getDesign.attribute
      }}</div>
    </div>
    <UpdateTime v-if="getDesign.showTime" :time="time" />
  </main>
</template>
<style lang="less" scoped>
  .switch_open {
    background: var(--open-color);
    box-shadow: var(--open-color) 0 0 10px 3px;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    margin: 10px 0;
  }

  .switch_close {
    background-color: var(--close-color);
    box-shadow: none;
    width: 42.023px;
    height: 42.023px;
    border-radius: 50%;
    margin: 10px 0;
  }
</style>