GrowCard.vue 15.2 KB
<template>
  <div>
    <!-- 首页基础信息 -->
    <div class="md:flex">
      <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666">
        <div class="flex" style="height: 100px">
          <div class="mr-4"
            ><img
              src="/src/assets/images/device-count.png"
              style="width: 5.625rem; height: 5.625rem"
          /></div>
          <div class="flex-auto">
            <div class="flex justify-between" style="align-items: center">
              <div style="font-size: 1.625rem; color: #333; font-weight: bold">
                <CountTo
                  v-if="growCardList?.deviceInfo?.sumCount"
                  :endVal="growCardList.deviceInfo.sumCount"
                />
                <CountTo v-else :endVal="0" />
              </div>
              <Tooltip>
                <template #title>
                  设备数 : {{ growCardList?.deviceInfo.sumCount }} 今日新增
                  {{ toThousands(growCardList?.deviceInfo?.todayAdd) }}
                </template>
                <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
              </Tooltip>
            </div>
            <div> 设备数 </div>
          </div>
        </div>
        <div class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.deviceInfo?.todayAdd) }}
        </div>
      </Card>
      <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666">
        <div class="flex" style="height: 100px">
          <div class="mr-4">
            <img
              v-if="!isAdmin(role)"
              src="/src/assets/images/alarm-count.png"
              style="width: 5.625rem; height: 5.625rem"
            />
            <img v-else src="/src/assets/images/zh.png" style="width: 5.625rem; height: 5.625rem" />
          </div>
          <div class="flex-auto">
            <div class="flex justify-between" style="align-items: center">
              <div
                v-if="!isAdmin(role)"
                style="font-size: 1.625rem; color: #333; font-weight: bold"
              >
                <CountTo
                  v-if="growCardList?.alarmInfo?.sumCount"
                  :end-val="growCardList.alarmInfo.sumCount"
                />
                <CountTo v-else :end-val="0" />
              </div>
              <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else>
                <CountTo
                  v-if="growCardList?.tenantInfo?.sumCount"
                  :end-val="growCardList.tenantInfo.sumCount"
                />
                <CountTo v-else :end-val="0" />
              </div>
              <Tooltip>
                <template #title>
                  {{
                    !isAdmin(role)
                      ? `告警数:${growCardList?.alarmInfo?.sumCount} 今日新增 ${toThousands(
                          growCardList?.alarmInfo?.todayAdd
                        )}`
                      : `租户总量:${growCardList?.tenantInfo?.sumCount} 今日新增 ${toThousands(
                          growCardList?.alarmInfo?.todayAdd
                        )}`
                  }}
                </template>
                <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
              </Tooltip>
            </div>
            <div> {{ !isAdmin(role) ? `告警数` : '租户总量' }}</div>
          </div>
        </div>
        <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.alarmInfo?.todayAdd) }}</div
        >
        <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.tenantInfo?.todayAdd) }}</div
        >
      </Card>
      <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4" style="color: #666">
        <div class="flex" style="height: 100px">
          <div class="mr-4">
            <img
              v-if="!isAdmin(role)"
              src="/src/assets/images/msg-count.png"
              style="width: 5.625rem; height: 5.625rem"
            />
            <img v-else src="/src/assets/images/kf.png" style="width: 5.625rem; height: 5.625rem" />
          </div>
          <div class="flex-auto">
            <div class="flex justify-between" style="align-items: center">
              <div
                v-if="!isAdmin(role)"
                style="font-size: 1.625rem; color: #333; font-weight: bold"
              >
                <CountTo
                  v-if="growCardList?.messageInfo?.messageCount"
                  :end-val="growCardList.messageInfo.messageCount"
                />
                <CountTo v-else :end-val="0" />
              </div>
              <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else>
                <CountTo
                  v-if="growCardList?.customerInfo?.sumCount"
                  :end-val="growCardList.customerInfo.sumCount"
                />
                <CountTo v-else :end-val="0" />
              </div>
              <Tooltip>
                <template #title>
                  {{
                    !isAdmin(role)
                      ? `消息数:${growCardList?.messageInfo?.messageCount} 今日新增 ${toThousands(
                          growCardList?.messageInfo?.todayMessageAdd
                        )}`
                      : `客户总量:${growCardList?.customerInfo?.sumCount} 今日新增 ${toThousands(
                          growCardList?.messageInfo?.todayMessageAdd
                        )}`
                  }}
                </template>
                <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
              </Tooltip>
            </div>
            <div> {{ !isAdmin(role) ? `消息数` : '客户总量' }}</div>
          </div>
        </div>
        <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.messageInfo?.todayMessageAdd) }}</div
        >
        <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.customerInfo?.todayAdd) }}</div
        >
      </Card>
      <Card
        v-if="!isAdmin(role)"
        size="small"
        class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-4"
        style="color: #666"
      >
        <div class="flex" style="height: 100px">
          <div class="mr-4">
            <img
              v-if="!isAdmin(role)"
              src="/src/assets/images/product.png"
              style="width: 5.625rem; height: 5.625rem"
            />
            <img
              v-else
              src="/src/assets/images/product.png"
              style="width: 5.625rem; height: 5.625rem"
            />
          </div>
          <div class="flex-auto">
            <div class="flex justify-between" style="align-items: center">
              <div
                v-if="!isAdmin(role)"
                style="font-size: 1.625rem; color: #333; font-weight: bold"
              >
                <CountTo
                  v-if="growCardList?.productInfo?.sumCount"
                  :end-val="growCardList.productInfo.sumCount"
                />
                <CountTo v-else :end-val="0" />
              </div>
              <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else>
                <CountTo
                  v-if="growCardList?.productInfo?.sumCount"
                  :end-val="growCardList.productInfo?.sumCount"
                />
                <CountTo v-else :end-val="0" />
              </div>
              <Tooltip>
                <template #title>
                  {{
                    !isAdmin(role)
                      ? `产品数:${growCardList?.productInfo?.sumCount} 今日新增 ${toThousands(
                          growCardList?.productInfo?.todayAdd
                        )}`
                      : `产品数:${growCardList?.customerInfo?.sumCount} 今日新增 ${toThousands(
                          growCardList?.productInfo?.todayAdd
                        )}`
                  }}
                </template>
                <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
              </Tooltip>
            </div>
            <div> {{ !isAdmin(role) ? `产品数` : '产品数' }}</div>
          </div>
        </div>
        <div v-if="!isAdmin(role)" class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.productInfo?.todayAdd) }}</div
        >
        <div v-else class="ml-2 pt-4" style="border-top: 2px solid #f0f2f5">
          今日新增 {{ toThousands(growCardList?.productInfo?.todayAdd) }}</div
        >
      </Card>
    </div>
    <!-- 首页饼图 -->
    <div class="md:flex mt-4" v-if="!isAdmin(role)">
      <Card
        size="small"
        class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
        style="color: #666; width: 50%"
        title="设备数量统计"
      >
        <a-row type="flex" justify="space-between" align="middle">
          <a-col :span="12">
            <PieChartDeviceSub
              v-if="seriesData.length > 0"
              :legendData="legendData"
              :seriesData="seriesData"
              :isCircle="false"
          /></a-col>
          <a-col :span="12">
            <a-row type="flex" justify="space-between" align="middle" style="row-gap: 30px">
              <a-col :offset="8" class="flex items-center">
                <span class="left-icon-d-color"></span>
                直连设备:
                <span class="bold-text">{{ growCardList?.deviceInfo?.directConnection ?? 0 }}</span
                >个</a-col
              >
              <a-col :offset="8" class="flex items-center">
                <span class="left-icon-g-color"></span>
                网关设备:
                <span class="bold-text">{{ growCardList?.deviceInfo?.gateWay ?? 0 }}</span
                >个</a-col
              >
              <a-col :offset="8" class="flex items-center">
                <span class="left-icon-s-color"></span>
                网关子设备:<span class="bold-text">{{
                  growCardList?.deviceInfo?.sensor ?? 0
                }}</span
                >个</a-col
              >
            </a-row>
          </a-col>
        </a-row>
      </Card>
      <Card
        size="small"
        class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-1"
        style="color: #666; width: 50%"
        title="设备状态统计"
      >
        <a-row type="flex" justify="space-between" align="middle">
          <a-col :span="12">
            <PieChartDeviceStatus
              v-if="seriesStatusData.length > 0"
              :seriesStatusData="seriesStatusData"
            />
            <div class="empty-box" v-else><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" /></div>
          </a-col>
          <a-col :span="12">
            <a-row type="flex" justify="space-between" align="middle" style="row-gap: 30px">
              <a-col :offset="8" class="flex items-center">
                <span class="right-icon-d-color"></span>
                待激活设备:
                <span class="bold-text">{{ growCardList?.deviceInfo?.inActive ?? 0 }}</span
                >个</a-col
              >
              <a-col :offset="8" class="flex items-center">
                <span class="right-icon-g-color"></span>
                在线设备:<span class="bold-text">{{ growCardList?.deviceInfo?.onLine ?? 0 }}</span
                >个</a-col
              >
              <a-col :offset="8" class="flex items-center">
                <span class="right-icon-s-color"></span>
                离线设备:<span class="bold-text">{{ growCardList?.deviceInfo?.offLine ?? 0 }}</span
                >个</a-col
              >
            </a-row>
          </a-col>
        </a-row>
      </Card>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { ref, onMounted, defineComponent, Ref } from 'vue';
  import { Card } from 'ant-design-vue';
  import { getHomeData } from '/@/api/dashboard';
  import { isAdmin } from '/@/enums/roleEnum';
  import { toThousands } from '/@/utils/fnUtils';
  import { CountTo } from '/@/components/CountTo/index';
  import { Tooltip } from 'ant-design-vue';
  import { CardList, seriesDataT } from './props';
  import PieChartDeviceSub from './PieChartDeviceSub.vue';
  import PieChartDeviceStatus from './PieChartDeviceStatus.vue';
  import { Empty } from 'ant-design-vue';

  defineProps<{
    role: string;
  }>();

  defineExpose({
    isAdmin,
    toThousands,
  });

  defineComponent({
    Card,
  });

  const legendData = ref(['网关设备', '直连设备', '网关子设备']);

  const seriesData: Ref<seriesDataT[]> = ref([]);

  const seriesStatusData: Ref<seriesDataT[]> = ref([]);

  const growCardList = ref<CardList>();

  const devicePieColor = [
    { key: 'directConnection', itemStyle: { color: '#5C7BD9' }, value: '直连设备' },
    { key: 'gateWay', itemStyle: { color: '#91CC75' }, value: '网关设备' },
    { key: 'sensor', itemStyle: { color: '#FAC859' }, value: '网关子设备' },
    { key: 'inActive', itemStyle: { color: '#5C7BD9' }, value: '待激活' },
    { key: 'onLine', itemStyle: { color: '#91CC75 ' }, value: '在线' },
    { key: 'offLine', itemStyle: { color: '#EC4040' }, value: '离线' },
  ];

  onMounted(async () => {
    const res = await getHomeData();
    growCardList.value = res;
    const { deviceInfo } = growCardList.value!;
    let data = Object.entries(deviceInfo).map(([key, value]) => {
      const name = devicePieColor?.find((f) => f.key === key)?.value;
      const itemStyle = devicePieColor?.find((f) => f.key === key)?.itemStyle;
      return { key, value, itemStyle, name };
    });
    seriesData.value = data.filter(
      (f) => f.key === 'directConnection' || f.key === 'gateWay' || f.key === 'sensor'
    );
    seriesStatusData.value = data.filter(
      (f) => f.key === 'inActive' || f.key === 'onLine' || f.key === 'offLine'
    );
  });
</script>
<style lang="less">
  .text {
    color: #333;
    display: flex;
    flex-wrap: nowrap;
  }

  .bold-text {
    font-weight: bold;
  }

  .base-left-icon-color {
    border-radius: 50%;
    width: 0.75rem;
    height: 0.75rem;
    display: block;
    position: relative;
    right: 0.5rem;
  }

  .left-icon-d-color :extend(.base-left-icon-color) {
    background-color: #5c7bd9 !important;
  }
  .left-icon-g-color :extend(.base-left-icon-color) {
    background-color: #91cc75 !important;
  }
  .left-icon-s-color :extend(.base-left-icon-color) {
    background-color: #fac859 !important;
  }
  .right-icon-d-color :extend(.base-left-icon-color) {
    background-color: #5c7bd9;
  }
  .right-icon-g-color :extend(.base-left-icon-color) {
    background-color: #91cc75;
  }
  .right-icon-s-color :extend(.base-left-icon-color) {
    background-color: #ec4040;
  }
</style>