Commit 8b8e41b099a9b9faff1ee992c81c84fc1457e874

Authored by ww
1 parent 416ae516

perf: 优化首页统计块展示

1 1 import { BasicPageParams } from './../model/baseModel';
  2 +import { HomeStatisticsRecordType } from './model';
2 3 import { defHttp } from '/@/utils/http/axios';
3 4 enum HomeEnum {
4 5 home = '/homepage/left/top',
... ... @@ -9,7 +10,7 @@ enum HomeEnum {
9 10 }
10 11
11 12 export const getHomeData = () => {
12   - return defHttp.get({
  13 + return defHttp.get<HomeStatisticsRecordType>({
13 14 url: HomeEnum.home,
14 15 });
15 16 };
... ...
1   -<template>
2   - <div>
3   - <!-- 首页基础信息 -->
4   - <div class="md:flex">
5   - <Card
6   - v-if="!isAdmin(role)"
7   - size="small"
8   - class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
9   - style="color: #666"
10   - >
11   - <div class="flex" style="height: 100px">
12   - <div class="mr-4">
13   - <img
14   - v-if="!isAdmin(role)"
15   - src="/src/assets/images/product.png"
16   - style="width: 5.625rem; height: 5.625rem"
17   - />
18   - <img
19   - v-else
20   - src="/src/assets/images/product.png"
21   - style="width: 5.625rem; height: 5.625rem"
22   - />
23   - </div>
24   - <div class="flex-auto">
25   - <div class="flex justify-between" style="align-items: center">
26   - <div
27   - v-if="!isAdmin(role)"
28   - style="font-size: 1.625rem; color: #333; font-weight: bold"
29   - >
30   - <CountTo
31   - v-if="growCardList?.productInfo?.sumCount"
32   - :end-val="growCardList.productInfo.sumCount"
33   - />
34   - <CountTo v-else :end-val="0" />
35   - </div>
36   - <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else>
37   - <CountTo
38   - v-if="growCardList?.productInfo?.sumCount"
39   - :end-val="growCardList.productInfo?.sumCount"
40   - />
41   - <CountTo v-else :end-val="0" />
42   - </div>
43   - <Tooltip>
44   - <template #title>
45   - {{
46   - !isAdmin(role)
47   - ? `产品数:${growCardList?.productInfo?.sumCount} 今日新增 ${toThousands(
48   - growCardList?.productInfo?.todayAdd
49   - )}`
50   - : `产品数:${growCardList?.customerInfo?.sumCount} 今日新增 ${toThousands(
51   - growCardList?.productInfo?.todayAdd
52   - )}`
53   - }}
54   - </template>
55   - <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
56   - </Tooltip>
57   - </div>
58   - <div> {{ !isAdmin(role) ? `产品数` : '产品数' }}</div>
59   - </div>
60   - </div>
61   - <div v-if="!isAdmin(role)" class="pt-4" style="border-top: 2px solid #f0f2f5">
62   - 今日新增 {{ toThousands(growCardList?.productInfo?.todayAdd) }}</div
63   - >
64   - <div v-else class="pt-4" style="border-top: 2px solid #f0f2f5">
65   - 今日新增 {{ toThousands(growCardList?.productInfo?.todayAdd) }}</div
66   - >
67   - </Card>
68   - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4" style="color: #666">
69   - <div class="flex" style="height: 100px">
70   - <div class="mr-4"
71   - ><img
72   - src="/src/assets/images/device-count.png"
73   - style="width: 5.625rem; height: 5.625rem"
74   - /></div>
75   - <div class="flex-auto">
76   - <div class="flex justify-between" style="align-items: center">
77   - <div style="font-size: 1.625rem; color: #333; font-weight: bold">
78   - <CountTo
79   - v-if="growCardList?.deviceInfo?.sumCount"
80   - :endVal="growCardList.deviceInfo.sumCount"
81   - />
82   - <CountTo v-else :endVal="0" />
83   - </div>
84   - <Tooltip>
85   - <template #title>
86   - 设备数 : {{ growCardList?.deviceInfo.sumCount }} 今日新增
87   - {{ toThousands(growCardList?.deviceInfo?.todayAdd) }}
88   - </template>
89   - <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
90   - </Tooltip>
91   - </div>
92   - <div> 设备数 </div>
93   - </div>
94   - </div>
95   - <div class="pt-4" style="border-top: 2px solid #f0f2f5">
96   - 今日新增 {{ toThousands(growCardList?.deviceInfo?.todayAdd) }}
97   - </div>
98   - </Card>
99   - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-4" style="color: #666">
100   - <div class="flex" style="height: 100px">
101   - <div class="mr-4">
102   - <img
103   - v-if="!isAdmin(role)"
104   - src="/src/assets/images/alarm-count.png"
105   - style="width: 5.625rem; height: 5.625rem"
106   - />
107   - <img v-else src="/src/assets/images/zh.png" style="width: 5.625rem; height: 5.625rem" />
108   - </div>
109   - <div class="flex-auto">
110   - <div class="flex justify-between" style="align-items: center">
111   - <div
112   - v-if="!isAdmin(role)"
113   - style="font-size: 1.625rem; color: #333; font-weight: bold"
114   - >
115   - <CountTo
116   - v-if="growCardList?.alarmInfo?.sumCount"
117   - :end-val="growCardList.alarmInfo.sumCount"
118   - />
119   - <CountTo v-else :end-val="0" />
120   - </div>
121   - <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else>
122   - <CountTo
123   - v-if="growCardList?.tenantInfo?.sumCount"
124   - :end-val="growCardList.tenantInfo.sumCount"
125   - />
126   - <CountTo v-else :end-val="0" />
127   - </div>
128   - <Tooltip>
129   - <template #title>
130   - {{
131   - !isAdmin(role)
132   - ? `告警数:${growCardList?.alarmInfo?.sumCount} 今日新增 ${toThousands(
133   - growCardList?.alarmInfo?.todayAdd
134   - )}`
135   - : `租户总量:${growCardList?.tenantInfo?.sumCount} 今日新增 ${toThousands(
136   - growCardList?.tenantInfo?.todayAdd
137   - )}`
138   - }}
139   - </template>
140   - <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
141   - </Tooltip>
142   - </div>
143   - <div> {{ !isAdmin(role) ? `告警数` : '租户总量' }}</div>
144   - </div>
145   - </div>
146   - <div v-if="!isAdmin(role)" class="pt-4" style="border-top: 2px solid #f0f2f5">
147   - 今日新增 {{ toThousands(growCardList?.alarmInfo?.todayAdd) }}</div
148   - >
149   - <div v-else class="pt-4" style="border-top: 2px solid #f0f2f5">
150   - 今日新增 {{ toThousands(growCardList?.tenantInfo?.todayAdd) }}</div
151   - >
152   - </Card>
153   - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-4" style="color: #666">
154   - <div class="flex" style="height: 100px">
155   - <div class="mr-4">
156   - <img
157   - v-if="!isAdmin(role)"
158   - src="/src/assets/images/msg-count.png"
159   - style="width: 5.625rem; height: 5.625rem"
160   - />
161   - <img v-else src="/src/assets/images/kf.png" style="width: 5.625rem; height: 5.625rem" />
162   - </div>
163   - <div class="flex-auto">
164   - <div class="flex justify-between" style="align-items: center">
165   - <div
166   - v-if="!isAdmin(role)"
167   - style="font-size: 1.625rem; color: #333; font-weight: bold"
168   - >
169   - <CountTo
170   - v-if="growCardList?.messageInfo?.messageCount"
171   - :end-val="growCardList.messageInfo.messageCount"
172   - />
173   - <CountTo v-else :end-val="0" />
174   - </div>
175   - <div style="font-size: 1.625rem; color: #333; font-weight: bold" v-else>
176   - <CountTo
177   - v-if="growCardList?.customerInfo?.sumCount"
178   - :end-val="growCardList.customerInfo.sumCount"
179   - />
180   - <CountTo v-else :end-val="0" />
181   - </div>
182   - <Tooltip>
183   - <template #title>
184   - {{
185   - !isAdmin(role)
186   - ? `今日消息数:${
187   - growCardList?.messageInfo?.todayMessageAdd
188   - } 今日消息点数 ${toThousands(
189   - growCardList?.messageInfo?.todayDataPointsAdd
190   - )}`
191   - : `客户总量:${growCardList?.customerInfo?.sumCount} 今日新增 ${toThousands(
192   - growCardList?.customerInfo?.todayAdd
193   - )}`
194   - }}
195   - </template>
196   - <img
197   - v-if="isAdmin(role)"
198   - src="/src/assets/images/tip.png"
199   - style="width: 1.125rem; height: 1.125rem"
200   - />
201   - </Tooltip>
202   - </div>
203   - <div> {{ !isAdmin(role) ? `消息数` : '客户总量' }}</div>
204   - </div>
205   - <div class="flex-auto" v-if="!isAdmin(role)">
206   - <div class="flex justify-between" style="align-items: center">
207   - <div
208   - v-if="!isAdmin(role)"
209   - style="font-size: 1.625rem; color: #333; font-weight: bold"
210   - >
211   - <CountTo
212   - v-if="growCardList?.messageInfo?.dataPointsCount"
213   - :end-val="growCardList.messageInfo.dataPointsCount"
214   - />
215   - <CountTo v-else :end-val="0" />
216   - </div>
217   - <Tooltip>
218   - <template #title>
219   - {{
220   - !isAdmin(role)
221   - ? `今日消息数:${
222   - growCardList?.messageInfo?.todayMessageAdd
223   - } 今日消息点数 ${toThousands(
224   - growCardList?.messageInfo?.todayDataPointsAdd
225   - )}`
226   - : `客户总量:${growCardList?.customerInfo?.sumCount} 今日新增 ${toThousands(
227   - growCardList?.customerInfo?.todayAdd
228   - )}`
229   - }}
230   - </template>
231   - <img src="/src/assets/images/tip.png" style="width: 1.125rem; height: 1.125rem" />
232   - </Tooltip>
233   - </div>
234   - <div> {{ !isAdmin(role) ? `消息点数` : '' }}</div>
235   - </div>
236   - </div>
237   - <div class="flex justify-between" style="border-top: 2px solid #f0f2f5">
238   - <div v-if="!isAdmin(role)" class="pt-4">
239   - 今日消息数 {{ toThousands(growCardList?.messageInfo?.todayMessageAdd) }}</div
240   - >
241   - <div v-if="!isAdmin(role)" class="pt-4">
242   - 今日消息点数 {{ toThousands(growCardList?.messageInfo?.todayDataPointsAdd) }}</div
243   - >
244   - <div v-else class="pt-4">
245   - 近30日新增 {{ toThousands(growCardList?.customerInfo?.todayAdd) }}</div
246   - >
247   - </div>
248   - </Card>
249   - </div>
250   - <!-- 首页饼图 -->
251   - <div class="md:flex mt-4" v-if="!isAdmin(role)">
252   - <Card
253   - size="small"
254   - class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
255   - style="color: #666; width: 50%"
256   - title="设备数量统计"
257   - >
258   - <a-row type="flex" justify="space-between" align="middle">
259   - <a-col :span="12">
260   - <PieChartDeviceSub
261   - v-if="seriesData.length > 0"
262   - :legendData="legendData"
263   - :seriesData="seriesData"
264   - :isCircle="false"
265   - /></a-col>
266   - <a-col :span="12">
267   - <a-row type="flex" justify="space-between" align="middle" style="row-gap: 30px">
268   - <a-col :offset="8" class="flex items-center">
269   - <span class="left-icon-d-color"></span>
270   - 直连设备:
271   - <span class="bold-text">{{ growCardList?.deviceInfo?.directConnection ?? 0 }}</span
272   - >个</a-col
273   - >
274   - <a-col :offset="8" class="flex items-center">
275   - <span class="left-icon-g-color"></span>
276   - 网关设备:
277   - <span class="bold-text">{{ growCardList?.deviceInfo?.gateWay ?? 0 }}</span
278   - >个</a-col
279   - >
280   - <a-col :offset="8" class="flex items-center">
281   - <span class="left-icon-s-color"></span>
282   - 网关子设备:<span class="bold-text">{{
283   - growCardList?.deviceInfo?.sensor ?? 0
284   - }}</span
285   - >个</a-col
286   - >
287   - </a-row>
288   - </a-col>
289   - </a-row>
290   - </Card>
291   - <Card
292   - size="small"
293   - class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-1"
294   - style="color: #666; width: 50%"
295   - title="设备状态统计"
296   - >
297   - <a-row type="flex" justify="space-between" align="middle">
298   - <a-col :span="12">
299   - <PieChartDeviceStatus
300   - v-if="seriesStatusData.length > 0"
301   - :seriesStatusData="seriesStatusData"
302   - />
303   - <div class="empty-box" v-else><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" /></div>
304   - </a-col>
305   - <a-col :span="12">
306   - <a-row type="flex" justify="space-between" align="middle" style="row-gap: 30px">
307   - <a-col :offset="8" class="flex items-center">
308   - <span class="right-icon-d-color"></span>
309   - 待激活设备:
310   - <span class="bold-text">{{ growCardList?.deviceInfo?.inActive ?? 0 }}</span
311   - >个</a-col
312   - >
313   - <a-col :offset="8" class="flex items-center">
314   - <span class="right-icon-g-color"></span>
315   - 在线设备:<span class="bold-text">{{ growCardList?.deviceInfo?.onLine ?? 0 }}</span
316   - >个</a-col
317   - >
318   - <a-col :offset="8" class="flex items-center">
319   - <span class="right-icon-s-color"></span>
320   - 离线设备:<span class="bold-text">{{ growCardList?.deviceInfo?.offLine ?? 0 }}</span
321   - >个</a-col
322   - >
323   - </a-row>
324   - </a-col>
325   - </a-row>
326   - </Card>
327   - </div>
328   - </div>
329   -</template>
330   -<script lang="ts" setup>
331   - import { ref, onMounted, defineComponent, Ref } from 'vue';
332   - import { Card } from 'ant-design-vue';
333   - import { getHomeData } from '/@/api/dashboard';
334   - import { isAdmin } from '/@/enums/roleEnum';
335   - import { toThousands } from '/@/utils/fnUtils';
336   - import { CountTo } from '/@/components/CountTo/index';
337   - import { Tooltip } from 'ant-design-vue';
338   - import { CardList, seriesDataT } from './props';
339   - import PieChartDeviceSub from './PieChartDeviceSub.vue';
340   - import PieChartDeviceStatus from './PieChartDeviceStatus.vue';
341   - import { Empty } from 'ant-design-vue';
342   -
343   - defineProps<{
344   - role: string;
345   - }>();
346   -
347   - defineExpose({
348   - isAdmin,
349   - toThousands,
350   - });
351   -
352   - defineComponent({
353   - Card,
354   - });
355   -
356   - const legendData = ref(['网关设备', '直连设备', '网关子设备']);
357   -
358   - const seriesData: Ref<seriesDataT[]> = ref([]);
359   -
360   - const seriesStatusData: Ref<seriesDataT[]> = ref([]);
361   -
362   - const growCardList = ref<CardList>();
363   -
364   - const devicePieColor = [
365   - { key: 'directConnection', itemStyle: { color: '#5C7BD9' }, value: '直连设备' },
366   - { key: 'gateWay', itemStyle: { color: '#91CC75' }, value: '网关设备' },
367   - { key: 'sensor', itemStyle: { color: '#FAC859' }, value: '网关子设备' },
368   - { key: 'inActive', itemStyle: { color: '#5C7BD9' }, value: '待激活' },
369   - { key: 'onLine', itemStyle: { color: '#91CC75 ' }, value: '在线' },
370   - { key: 'offLine', itemStyle: { color: '#EC4040' }, value: '离线' },
371   - ];
372   -
373   - onMounted(async () => {
374   - const res = await getHomeData();
375   - growCardList.value = res;
376   - const { deviceInfo } = growCardList.value!;
377   - let data = Object.entries(deviceInfo).map(([key, value]) => {
378   - const name = devicePieColor?.find((f) => f.key === key)?.value;
379   - const itemStyle = devicePieColor?.find((f) => f.key === key)?.itemStyle;
380   - return { key, value, itemStyle, name };
381   - });
382   - seriesData.value = data.filter(
383   - (f) => f.key === 'directConnection' || f.key === 'gateWay' || f.key === 'sensor'
384   - );
385   - seriesStatusData.value = data.filter(
386   - (f) => f.key === 'inActive' || f.key === 'onLine' || f.key === 'offLine'
387   - );
388   - });
389   -</script>
390   -<style lang="less">
391   - .text {
392   - color: #333;
393   - display: flex;
394   - flex-wrap: nowrap;
395   - }
396   -
397   - .bold-text {
398   - font-weight: bold;
399   - }
400   -
401   - .base-left-icon-color {
402   - border-radius: 50%;
403   - width: 0.75rem;
404   - height: 0.75rem;
405   - display: block;
406   - position: relative;
407   - right: 0.5rem;
408   - }
409   -
410   - .left-icon-d-color :extend(.base-left-icon-color) {
411   - background-color: #5c7bd9 !important;
412   - }
413   - .left-icon-g-color :extend(.base-left-icon-color) {
414   - background-color: #91cc75 !important;
415   - }
416   - .left-icon-s-color :extend(.base-left-icon-color) {
417   - background-color: #fac859 !important;
418   - }
419   - .right-icon-d-color :extend(.base-left-icon-color) {
420   - background-color: #5c7bd9;
421   - }
422   - .right-icon-g-color :extend(.base-left-icon-color) {
423   - background-color: #91cc75;
424   - }
425   - .right-icon-s-color :extend(.base-left-icon-color) {
426   - background-color: #ec4040;
427   - }
428   -</style>
  1 +<template>
  2 + <div>
  3 + <!-- 首页基础信息 -->
  4 + <section class="flex gap-4">
  5 + <StatisticalCard
  6 + :style="{ width: `${100 / statisticalPanelList.length}%` }"
  7 + v-for="(item, index) in statisticalPanelList"
  8 + :key="index"
  9 + :value="item"
  10 + />
  11 + </section>
  12 + <!-- 首页饼图 -->
  13 + <div class="md:flex mt-4" v-if="!isAdmin(role)">
  14 + <Card
  15 + size="small"
  16 + class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
  17 + style="color: #666; width: 50%"
  18 + title="设备数量统计"
  19 + >
  20 + <a-row type="flex" justify="space-between" align="middle">
  21 + <a-col :span="12">
  22 + <PieChartDeviceSub
  23 + v-if="seriesData.length > 0"
  24 + :legendData="legendData"
  25 + :seriesData="seriesData"
  26 + :isCircle="false"
  27 + /></a-col>
  28 + <a-col :span="12">
  29 + <a-row type="flex" justify="space-between" align="middle" style="row-gap: 30px">
  30 + <a-col :offset="8" class="flex items-center">
  31 + <span class="left-icon-d-color"></span>
  32 + 直连设备:
  33 + <span class="bold-text">{{ growCardList?.deviceInfo?.directConnection ?? 0 }}</span
  34 + >个</a-col
  35 + >
  36 + <a-col :offset="8" class="flex items-center">
  37 + <span class="left-icon-g-color"></span>
  38 + 网关设备:
  39 + <span class="bold-text">{{ growCardList?.deviceInfo?.gateWay ?? 0 }}</span
  40 + >个</a-col
  41 + >
  42 + <a-col :offset="8" class="flex items-center">
  43 + <span class="left-icon-s-color"></span>
  44 + 网关子设备:<span class="bold-text">{{
  45 + growCardList?.deviceInfo?.sensor ?? 0
  46 + }}</span
  47 + >个</a-col
  48 + >
  49 + </a-row>
  50 + </a-col>
  51 + </a-row>
  52 + </Card>
  53 + <Card
  54 + size="small"
  55 + class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-1"
  56 + style="color: #666; width: 50%"
  57 + title="设备状态统计"
  58 + >
  59 + <a-row type="flex" justify="space-between" align="middle">
  60 + <a-col :span="12">
  61 + <PieChartDeviceStatus
  62 + v-if="seriesStatusData.length > 0"
  63 + :seriesStatusData="seriesStatusData"
  64 + />
  65 + <div class="empty-box" v-else><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" /></div>
  66 + </a-col>
  67 + <a-col :span="12">
  68 + <a-row type="flex" justify="space-between" align="middle" style="row-gap: 30px">
  69 + <a-col :offset="8" class="flex items-center">
  70 + <span class="right-icon-d-color"></span>
  71 + 待激活设备:
  72 + <span class="bold-text">{{ growCardList?.deviceInfo?.inActive ?? 0 }}</span
  73 + >个</a-col
  74 + >
  75 + <a-col :offset="8" class="flex items-center">
  76 + <span class="right-icon-g-color"></span>
  77 + 在线设备:<span class="bold-text">{{ growCardList?.deviceInfo?.onLine ?? 0 }}</span
  78 + >个</a-col
  79 + >
  80 + <a-col :offset="8" class="flex items-center">
  81 + <span class="right-icon-s-color"></span>
  82 + 离线设备:<span class="bold-text">{{ growCardList?.deviceInfo?.offLine ?? 0 }}</span
  83 + >个</a-col
  84 + >
  85 + </a-row>
  86 + </a-col>
  87 + </a-row>
  88 + </Card>
  89 + </div>
  90 + </div>
  91 +</template>
  92 +<script lang="ts" setup>
  93 + import { ref, onMounted, defineComponent, Ref } from 'vue';
  94 + import { Card } from 'ant-design-vue';
  95 + import { getHomeData } from '/@/api/dashboard';
  96 + import { isAdmin } from '/@/enums/roleEnum';
  97 + import { toThousands } from '/@/utils/fnUtils';
  98 + import { CardList, seriesDataT } from './props';
  99 + import PieChartDeviceSub from './PieChartDeviceSub.vue';
  100 + import PieChartDeviceStatus from './PieChartDeviceStatus.vue';
  101 + import { Empty } from 'ant-design-vue';
  102 + import StatisticalCard from './StatisticalCard.vue';
  103 + import { HomeStatisticsRecordType } from '/@/api/dashboard/model';
  104 + import { useRole } from '/@/hooks/business/useRole';
  105 + import { unref } from 'vue';
  106 +
  107 + interface RecordType {
  108 + value: number;
  109 + label: string;
  110 + }
  111 +
  112 + interface StatisticalItemType {
  113 + images: string;
  114 + totals: RecordType[];
  115 + tooltips: RecordType[];
  116 + todayTotals: RecordType[];
  117 + }
  118 +
  119 + defineProps<{
  120 + role: string;
  121 + }>();
  122 +
  123 + defineExpose({
  124 + isAdmin,
  125 + toThousands,
  126 + });
  127 +
  128 + defineComponent({
  129 + Card,
  130 + });
  131 +
  132 + const legendData = ref(['网关设备', '直连设备', '网关子设备']);
  133 +
  134 + const seriesData: Ref<seriesDataT[]> = ref([]);
  135 +
  136 + const seriesStatusData: Ref<seriesDataT[]> = ref([]);
  137 +
  138 + const growCardList = ref<CardList>();
  139 +
  140 + const statisticalPanelList = ref<StatisticalItemType[]>([]);
  141 +
  142 + const devicePieColor = [
  143 + { key: 'directConnection', itemStyle: { color: '#5C7BD9' }, value: '直连设备' },
  144 + { key: 'gateWay', itemStyle: { color: '#91CC75' }, value: '网关设备' },
  145 + { key: 'sensor', itemStyle: { color: '#FAC859' }, value: '网关子设备' },
  146 + { key: 'inActive', itemStyle: { color: '#5C7BD9' }, value: '待激活' },
  147 + { key: 'onLine', itemStyle: { color: '#91CC75 ' }, value: '在线' },
  148 + { key: 'offLine', itemStyle: { color: '#EC4040' }, value: '离线' },
  149 + ];
  150 +
  151 + const { isSysadmin, isPlatformAdmin } = useRole();
  152 + const handleTransformStatisticalInfo = (record: HomeStatisticsRecordType) => {
  153 + const { deviceInfo, productInfo, alarmInfo, messageInfo, customerInfo, tenantInfo } = record;
  154 +
  155 + const productTotal: StatisticalItemType = {
  156 + images: '/src/assets/images/product.png',
  157 + totals: [{ label: '产品数', value: productInfo?.sumCount }],
  158 + tooltips: [
  159 + { label: '产品数', value: productInfo?.sumCount },
  160 + { label: '今日新增', value: productInfo?.todayAdd },
  161 + ],
  162 + todayTotals: [{ label: '今日新增', value: productInfo?.todayAdd }],
  163 + };
  164 +
  165 + const deviceTotal: StatisticalItemType = {
  166 + images: '/src/assets/images/device-count.png',
  167 + totals: [{ label: '设备数', value: deviceInfo?.sumCount }],
  168 + tooltips: [
  169 + { label: '设备数', value: deviceInfo?.sumCount },
  170 + { label: '今日新增', value: deviceInfo?.todayAdd },
  171 + ],
  172 + todayTotals: [{ label: '今日新增', value: deviceInfo?.todayAdd }],
  173 + };
  174 +
  175 + const alarmTotal: StatisticalItemType = {
  176 + images: '/src/assets/images/alarm-count.png',
  177 + totals: [{ label: '告警数', value: alarmInfo?.sumCount }],
  178 + tooltips: [
  179 + { label: '告警数', value: alarmInfo?.sumCount },
  180 + { label: '今日新增', value: alarmInfo?.todayAdd },
  181 + ],
  182 + todayTotals: [{ label: '今日新增', value: alarmInfo?.todayAdd }],
  183 + };
  184 +
  185 + const messageTotal: StatisticalItemType = {
  186 + images: '/src/assets/images/msg-count.png',
  187 + totals: [
  188 + { label: '消息数', value: messageInfo?.messageCount },
  189 + { label: '消息点数', value: messageInfo?.dataPointsCount },
  190 + ],
  191 + tooltips: [
  192 + { label: '今日消息数', value: messageInfo?.todayMessageAdd },
  193 + { label: '今日消息点数', value: messageInfo?.todayDataPointsAdd },
  194 + ],
  195 + todayTotals: [
  196 + { label: '今日消息数', value: messageInfo?.todayMessageAdd },
  197 + { label: '今日消息点数', value: messageInfo?.todayDataPointsAdd },
  198 + ],
  199 + };
  200 +
  201 + const tenantTotal: StatisticalItemType = {
  202 + images: '/src/assets/images/zh.png',
  203 + totals: [{ label: '租户总量', value: tenantInfo?.sumCount }],
  204 + tooltips: [
  205 + { label: '租户总量', value: tenantInfo?.sumCount },
  206 + { label: '今日新增', value: tenantInfo?.todayAdd },
  207 + ],
  208 + todayTotals: [{ label: '今日新增', value: tenantInfo?.todayAdd }],
  209 + };
  210 +
  211 + const customerTotal: StatisticalItemType = {
  212 + images: '/src/assets/images/kf.png',
  213 + totals: [{ label: '客户总量', value: customerInfo?.sumCount }],
  214 + tooltips: [
  215 + { label: '客户总量', value: customerInfo?.sumCount },
  216 + { label: '今日新增', value: customerInfo?.todayAdd },
  217 + ],
  218 + todayTotals: [{ label: '今日新增', value: customerInfo?.todayAdd }],
  219 + };
  220 +
  221 + if (unref(isSysadmin) || unref(isPlatformAdmin)) {
  222 + statisticalPanelList.value = [deviceTotal, tenantTotal, customerTotal];
  223 + } else {
  224 + statisticalPanelList.value = [productTotal, deviceTotal, alarmTotal, messageTotal];
  225 + }
  226 + };
  227 +
  228 + onMounted(async () => {
  229 + const res = await getHomeData();
  230 + growCardList.value = res;
  231 + handleTransformStatisticalInfo(res);
  232 + const { deviceInfo } = growCardList.value!;
  233 + let data = Object.entries(deviceInfo).map(([key, value]) => {
  234 + const name = devicePieColor?.find((f) => f.key === key)?.value;
  235 + const itemStyle = devicePieColor?.find((f) => f.key === key)?.itemStyle;
  236 + return { key, value, itemStyle, name };
  237 + });
  238 + seriesData.value = data.filter(
  239 + (f) => f.key === 'directConnection' || f.key === 'gateWay' || f.key === 'sensor'
  240 + );
  241 + seriesStatusData.value = data.filter(
  242 + (f) => f.key === 'inActive' || f.key === 'onLine' || f.key === 'offLine'
  243 + );
  244 + });
  245 +</script>
  246 +<style lang="less">
  247 + .text {
  248 + color: #333;
  249 + display: flex;
  250 + flex-wrap: nowrap;
  251 + }
  252 +
  253 + .bold-text {
  254 + font-weight: bold;
  255 + }
  256 +
  257 + .base-left-icon-color {
  258 + border-radius: 50%;
  259 + width: 0.75rem;
  260 + height: 0.75rem;
  261 + display: block;
  262 + position: relative;
  263 + right: 0.5rem;
  264 + }
  265 +
  266 + .left-icon-d-color :extend(.base-left-icon-color) {
  267 + background-color: #5c7bd9 !important;
  268 + }
  269 + .left-icon-g-color :extend(.base-left-icon-color) {
  270 + background-color: #91cc75 !important;
  271 + }
  272 + .left-icon-s-color :extend(.base-left-icon-color) {
  273 + background-color: #fac859 !important;
  274 + }
  275 + .right-icon-d-color :extend(.base-left-icon-color) {
  276 + background-color: #5c7bd9;
  277 + }
  278 + .right-icon-g-color :extend(.base-left-icon-color) {
  279 + background-color: #91cc75;
  280 + }
  281 + .right-icon-s-color :extend(.base-left-icon-color) {
  282 + background-color: #ec4040;
  283 + }
  284 +</style>
... ...