DigitalDashBoard.vue 3.99 KB
<script lang="ts" setup>
  import { computed, onMounted, onUnmounted, ref, unref } from 'vue';
  import { Space, Tooltip } from 'ant-design-vue';
  import {
    DigitalComponentDefaultConfig,
    DigitalDashBoardLayout,
    DigitalDashBoardValue,
  } from './digitalDashBoard.config';
  import { dateUtil } from '/@/utils/dateUtil';
  import {
    fontSize,
    RadioRecord,
    DEFAULT_DATE_FORMAT,
    DEFAULT_RADIO_RECORD,
    DEFAULT_ANIMATION_INTERVAL,
  } from '../../detail/config/util';
  import { isNaN } from 'lodash';

  const props = defineProps<{
    layout: DigitalDashBoardLayout;
    value: DigitalDashBoardValue;
    radio?: RadioRecord;
    random?: boolean;
  }>();

  const changeValue = ref(0);

  const getPropsValue = computed(() => {
    return { value: unref(changeValue), ...DigitalComponentDefaultConfig, ...props.value };
  });

  const integerPart = computed(() => {
    let { value = 0 } = unref(getPropsValue);
    const { max = 5 } = props.layout;
    if (isNaN(value)) value = 0;
    let _value = Number(value).toFixed(2).split('.')[0];
    if (_value.length < max) _value = _value.padStart(5, '0');
    if (_value.length > max) _value = ''.padStart(5, '9');

    return _value;
  });

  const decimalPart = computed(() => {
    let { value = 0 } = unref(getPropsValue);
    const { keepNumber = 2 } = props.layout;
    if (isNaN(value)) value = 0;
    let _value = Number(value)?.toFixed(2).split('.')[1];
    if (_value.length < keepNumber) _value = _value.padStart(5, '0');

    if (_value.length > keepNumber) _value = ''.padStart(5, '0');

    return _value;
  });

  const getRadio = computed(() => {
    const { radio } = props.radio || DEFAULT_RADIO_RECORD;
    return radio;
  });

  let timeout: Nullable<number> = null;

  const handleRandom = () => {
    const newValue = Math.floor(Math.random() * 100);
    changeValue.value = newValue;
  };

  onMounted(() => {
    if (props.random)
      timeout = setInterval(handleRandom, DEFAULT_ANIMATION_INTERVAL) as unknown as number;
  });

  onUnmounted(() => {
    clearInterval(timeout as number);
    timeout = null;
  });
</script>

<template>
  <section class="w-full h-full">
    <div class="flex flex-col w-full h-full">
      <div class="flex-1 flex justify-center items-center">
        <div class="flex flex-col">
          <Space justify="end" class="justify-end" :size="getRadio * 15">
            <div
              v-for="number in integerPart"
              :key="number"
              class="border border-gray-400 p-2"
              :style="{
                color: getPropsValue.fontColor,
                fontSize: fontSize({ radio: getRadio, basic: 20 }),
              }"
            >
              {{ number }}
            </div>
          </Space>
          <Space justify="end" class="justify-end mt-2" :size="getRadio * 15">
            <div
              v-for="number in decimalPart"
              :key="number"
              class="border border-gray-400 p-1"
              :style="{
                color: getPropsValue.fontColor,
                fontSize: fontSize({ radio: getRadio, basic: 18 }),
              }"
            >
              {{ number }}
            </div>
          </Space>
        </div>
      </div>

      <div
        class="text-center truncate"
        :style="{ fontSize: fontSize({ radio: getRadio, basic: 18 }) }"
      >
        <span>{{ props.value.name || '电表' }}</span>
        <span class="px-1">({{ getPropsValue.unit }})</span>
      </div>
      <div
        class="text-center mt-1 text-gray-400 text-xs truncate"
        :style="{ fontSize: fontSize({ radio: getRadio, basic: 12, max: 16 }) }"
      >
        <Tooltip
          placement="topLeft"
          :title="dateUtil(props?.value?.updateTime || new Date()).format(DEFAULT_DATE_FORMAT)"
        >
          <span class="mr-1">更新时间:</span>
          <span>
            {{ dateUtil(props?.value?.updateTime || new Date()).format(DEFAULT_DATE_FORMAT) }}
          </span>
        </Tooltip>
      </div>
    </div>
    <div></div>
  </section>
</template>