Commit 1612a2ca1037943cfe1871f0a24309bef3ad2dd9

Authored by fengtao
1 parent 747c2cf7

feat:首页新增饼状图和调整部分样式

1 1 <template>
  2 + <!-- 首页基础信息 -->
2 3 <div class="md:flex">
3 4 <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4" style="color: #666">
4 5 <div class="flex" style="height: 100px">
... ... @@ -131,8 +132,12 @@
131 132 今日新增 {{ toThousands(growCardList?.customerInfo?.todayAdd) }}</div
132 133 >
133 134 </Card>
134   -
135   - <Card size="small" class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-4" style="color: #666">
  135 + <Card
  136 + v-if="!isAdmin(role)"
  137 + size="small"
  138 + class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-4"
  139 + style="color: #666"
  140 + >
136 141 <div class="flex" style="height: 100px">
137 142 <div class="mr-4">
138 143 <img
... ... @@ -188,50 +193,143 @@
188 193 >
189 194 </Card>
190 195 </div>
  196 + <!-- 首页饼图 -->
  197 + <div class="md:flex mt-4" v-if="!isAdmin(role)">
  198 + <Card
  199 + size="small"
  200 + class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
  201 + style="color: #666; width: 50%"
  202 + >
  203 + <div class="flex container">
  204 + <div class="mr-4 flex chart-top">
  205 + <PieChartDeviceSub :legendData="legendData" :seriesData="seriesData" :isCircle="true" />
  206 + </div>
  207 + <div class="ml-20 flex justify-around right-text">
  208 + <div class="text">
  209 + 直连设备:{{ growCardList?.deviceInfo?.directConnection ?? 0 }}个
  210 + </div>
  211 + <div class="text"> 网关设备:{{ growCardList?.deviceInfo?.gateWay ?? 0 }}个 </div>
  212 + <div class="text"> 网关子设备:{{ growCardList?.deviceInfo?.sensor ?? 0 }}个 </div>
  213 + </div>
  214 + </div>
  215 + </Card>
  216 + <Card
  217 + size="small"
  218 + class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-1"
  219 + style="color: #666; width: 50%"
  220 + >
  221 + <div class="flex container">
  222 + <div class="mr-4 flex chart-top">
  223 + <PieChartDeviceSub
  224 + :legendData="legendStatusData"
  225 + :seriesData="seriesStatusData"
  226 + :isCircle="false"
  227 + />
  228 + </div>
  229 + <div class="ml-20 flex justify-around right-text">
  230 + <div class="text"> 待激活设备:{{ growCardList?.deviceInfo?.inActive ?? 0 }}个 </div>
  231 + <div class="text"> 在线设备:{{ growCardList?.deviceInfo?.onLine ?? 0 }}个 </div>
  232 + <div class="text"> 离线设备:{{ growCardList?.deviceInfo?.offLine ?? 0 }}个 </div>
  233 + </div>
  234 + </div>
  235 + </Card>
  236 + </div>
191 237 </template>
192 238 <script lang="ts" setup>
193   - import { ref, onMounted, defineComponent } from 'vue';
  239 + import { ref, onMounted, defineComponent, Ref } from 'vue';
194 240 import { Card } from 'ant-design-vue';
195 241 import { getHomeData } from '/@/api/dashboard';
196 242 import { isAdmin } from '/@/enums/roleEnum';
197 243 import { toThousands } from '/@/utils/fnUtils';
198 244 import { CountTo } from '/@/components/CountTo/index';
199 245 import { Tooltip } from 'ant-design-vue';
  246 + import { CardList, seriesDataT } from './props';
  247 + import PieChartDeviceSub from './PieChartDeviceSub.vue';
200 248
201 249 defineProps<{
202 250 role: string;
203 251 }>();
  252 +
204 253 defineExpose({
205 254 isAdmin,
206 255 toThousands,
207 256 });
  257 +
208 258 defineComponent({
209 259 Card,
210 260 });
211   - interface CardList {
212   - deviceInfo: {
213   - sumCount: number;
214   - onLine: number;
215   - offLine: number;
216   - inActive: number;
217   - todayAdd: number;
218   - };
219   - tenantInfo?: { sumCount: number; todayAdd: number };
220   - customerInfo?: { sumCount: number; todayAdd: number };
221   - alarmInfo?: {
222   - sumCount: number;
223   - todayAdd: number;
224   - };
225   - messageInfo?: {
226   - dataPointsCount: number;
227   - messageCount: number;
228   - todayDataPointsAdd: number;
229   - todayMessageAdd: number;
230   - };
231   - }
  261 +
  262 + const legendData = ref(['网关设备', '直连设备', '网关子设备']);
  263 +
  264 + const seriesData: Ref<seriesDataT[]> = ref([]);
  265 +
  266 + const legendStatusData = ref(['待激活', '在线', '离线']);
  267 +
  268 + const seriesStatusData: Ref<seriesDataT[]> = ref([]);
  269 +
232 270 const growCardList = ref<CardList>();
  271 +
233 272 onMounted(async () => {
234 273 const res = await getHomeData();
235 274 growCardList.value = res;
  275 + const devObj = growCardList.value?.deviceInfo;
  276 + for (let o in devObj) {
  277 + if (o === 'directConnection' || o === 'gateWay' || o === 'sensor') {
  278 + seriesData.value.push({
  279 + value:
  280 + o === 'directConnection'
  281 + ? devObj?.directConnection
  282 + : o === 'gateWay'
  283 + ? devObj?.gateWay
  284 + : devObj?.sensor,
  285 + name: o === 'directConnection' ? '直连设备' : o === 'gateWay' ? '网关设备' : '网关子设备',
  286 + itemStyle:
  287 + o === 'directConnection'
  288 + ? { color: '#5AEEED' }
  289 + : o === 'gateWay'
  290 + ? { color: '#0B55F1' }
  291 + : { color: '#00C678' },
  292 + });
  293 + }
  294 + if (o === 'inActive' || o === 'onLine' || o === 'offLine') {
  295 + seriesStatusData.value.push({
  296 + value:
  297 + o === 'inActive' ? devObj?.inActive : o === 'onLine' ? devObj?.onLine : devObj?.offLine,
  298 + name: o === 'inActive' ? '待激活' : o === 'onLine' ? '在线' : '离线',
  299 + itemStyle:
  300 + o === 'inActive'
  301 + ? { color: '#F9C900' }
  302 + : o === 'onLine'
  303 + ? { color: '#5AEEED' }
  304 + : { color: '#FF9C4A' },
  305 + });
  306 + }
  307 + }
236 308 });
237 309 </script>
  310 +<style lang="css">
  311 + .right-text {
  312 + width: 40%;
  313 + flex-direction: column;
  314 + height: 240px;
  315 + margin: 10px 0 10px 50px;
  316 + }
  317 +
  318 + .text {
  319 + color: #333;
  320 + font-weight: bold;
  321 + display: flex;
  322 + flex-wrap: nowrap;
  323 + }
  324 +
  325 + .chart-top {
  326 + width: 60%;
  327 + height: 300px;
  328 + align-items: center;
  329 + margin-top: -30px;
  330 + }
  331 +
  332 + .container {
  333 + width: 100%;
  334 + }
  335 +</style>
... ...
1   -<template>
2   - <div class="md:flex mt-4">
3   - <Card
4   - size="small"
5   - class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:mr-4"
6   - style="color: #666; width: 50%"
7   - >
8   - <div class="flex container">
9   - <div class="mr-4 flex chart-top">
10   - <PieChartDeviceSub
11   - :legendData="legendData"
12   - :seriesData="seriesData"
13   - :radisData="radisData"
14   - />
15   - </div>
16   - <div class="ml-20 flex justify-around right-text">
17   - <div class="text"> 直连设备:4个 </div>
18   - <div class="text"> 网关设备:1个 </div>
19   - <div class="text"> 网关子设备:6个 </div>
20   - </div>
21   - </div>
22   - </Card>
23   - <Card
24   - size="small"
25   - class="md:w-1/3 w-full !md:mt-0 !mt-4 !md:ml-1"
26   - style="color: #666; width: 50%"
27   - >
28   - <div class="flex container">
29   - <div class="mr-4 flex chart-top">
30   - <PieChartDeviceSub
31   - :legendData="legendStatusData"
32   - :seriesData="seriesStatusData"
33   - :radisData="radisStatusData"
34   - />
35   - </div>
36   - <div class="ml-20 flex justify-around right-text">
37   - <div class="text"> 待激活设备:2个 </div>
38   - <div class="text"> 在线设备:1个 </div>
39   - <div class="text"> 离线设备:4个 </div>
40   - </div>
41   - </div>
42   - </Card>
43   - </div>
44   -</template>
45   -<script lang="ts" setup>
46   - import { ref, onMounted, defineComponent, Ref } from 'vue';
47   - import { Card } from 'ant-design-vue';
48   - import { getHomeData } from '/@/api/dashboard';
49   - import { isAdmin } from '/@/enums/roleEnum';
50   - import { toThousands } from '/@/utils/fnUtils';
51   - import PieChartDeviceSub from './PieChartDeviceSub.vue';
52   -
53   - defineProps<{
54   - role: string;
55   - }>();
56   - defineExpose({
57   - isAdmin,
58   - toThousands,
59   - });
60   - defineComponent({
61   - Card,
62   - });
63   - interface CardList {
64   - deviceInfo: {
65   - sumCount: number;
66   - onLine: number;
67   - offLine: number;
68   - inActive: number;
69   - todayAdd: number;
70   - };
71   - tenantInfo?: { sumCount: number; todayAdd: number };
72   - customerInfo?: { sumCount: number; todayAdd: number };
73   - alarmInfo?: {
74   - sumCount: number;
75   - todayAdd: number;
76   - };
77   - messageInfo?: {
78   - dataPointsCount: number;
79   - messageCount: number;
80   - todayDataPointsAdd: number;
81   - todayMessageAdd: number;
82   - };
83   - }
84   - type seriesDataT = {
85   - value: number;
86   - name: string;
87   - itemStyle: object;
88   - };
89   - const radisData: any = ref('70%');
90   - const radisStatusData = ref<string[]>(['40%', '70%']);
91   - const growCardList = ref<CardList>();
92   - const legendData = ref(['gateway', 'directly', 'sub-device']);
93   - const seriesData: Ref<seriesDataT[]> = ref([
94   - { value: 1048, name: 'gateway', itemStyle: { color: '#3079FF' } },
95   - { value: 735, name: 'directly', itemStyle: { color: '#36cbcb' } },
96   - { value: 580, name: 'sub-device', itemStyle: { color: '#4ecb73' } },
97   - ]);
98   - const legendStatusData = ref(['inactive', 'online', 'offline']);
99   - const seriesStatusData: Ref<seriesDataT[]> = ref([
100   - { value: 1048, name: 'inactive', itemStyle: { color: '#3079FF' } },
101   - { value: 735, name: 'online', itemStyle: { color: '#36cbcb' } },
102   - { value: 580, name: 'offline', itemStyle: { color: '#4ecb73' } },
103   - ]);
104   - onMounted(async () => {
105   - const res = await getHomeData();
106   - growCardList.value = res;
107   - });
108   -</script>
109   -
110   -<style lang="css">
111   - .right-text {
112   - width: 40%;
113   - flex-direction: column;
114   - height: 240px;
115   - margin: 10px 0 10px 50px;
116   - }
117   -
118   - .text {
119   - color: #333;
120   - font-weight: bold;
121   - display: flex;
122   - flex-wrap: nowrap;
123   - }
124   -
125   - .chart-top {
126   - width: 60%;
127   - height: 300px;
128   - align-items: center;
129   - margin-top: -30px;
130   - }
131   -
132   - .container {
133   - width: 100%;
134   - }
135   -</style>
... ... @@ -8,6 +8,7 @@
8 8 import { defineComponent, PropType, ref, Ref, onMounted, toRefs } from 'vue';
9 9 import { useECharts } from '/@/hooks/web/useECharts';
10 10 import { Empty } from 'ant-design-vue';
  11 + import { seriesDataT } from './props';
11 12
12 13 export default defineComponent({
13 14 components: { Empty },
... ... @@ -28,19 +29,17 @@
28 29 type: Array,
29 30 default: () => [],
30 31 },
31   - radisData: {
32   - type: Array || String,
33   - default: () => ['40%', '70%'] || '70%',
  32 + isCircle: {
  33 + type: Boolean,
  34 + default: true,
34 35 },
35 36 },
36 37 setup(props) {
37   - const { legendData, seriesData, radisData } = toRefs(props);
38   - const dataSeries = ref<any>([]);
39   - const legendDatas = ref<any>([]);
40   - const radisDatas = ref<any>([]);
41   - dataSeries.value = seriesData.value;
42   - legendDatas.value = legendData.value;
43   - radisDatas.value = radisData.value;
  38 + const { legendData, seriesData } = toRefs(props);
  39 + const dataSeries: Ref<seriesDataT[]> = ref([]);
  40 + const legendDatas: Ref<seriesDataT[]> = ref([]);
  41 + dataSeries.value = seriesData.value as unknown as seriesDataT[];
  42 + legendDatas.value = legendData.value as unknown as seriesDataT[];
44 43
45 44 const chartRef = ref<HTMLDivElement | null>(null);
46 45 const { setOptions, resize } = useECharts(chartRef as Ref<HTMLDivElement>);
... ... @@ -60,8 +59,9 @@
60 59 },
61 60 series: [
62 61 {
  62 + avoidLabelOverlap: false,
63 63 type: 'pie',
64   - radius: radisDatas.value,
  64 + radius: props.isCircle ? '60%' : ['40%', '60%'],
65 65 data: dataSeries.value,
66 66 emphasis: {
67 67 itemStyle: {
... ... @@ -70,6 +70,12 @@
70 70 shadowColor: 'rgba(0, 0, 0, 0.5)',
71 71 },
72 72 },
  73 + labelLine: {
  74 + normal: {
  75 + show: true,
  76 + length2: 1,
  77 + },
  78 + },
73 79 },
74 80 ],
75 81 });
... ...
... ... @@ -243,7 +243,6 @@
243 243 }
244 244 } else {
245 245 if (data) {
246   - console.log('消息数', data);
247 246 if (data) {
248 247 const { transportDataPointsCountHourly, transportMsgCountHourly } =
249 248 data.data[0].latest.TIME_SERIES;
... ... @@ -259,9 +258,7 @@
259 258 transportDataPointsCountHourly?.ts,
260 259 transportDataPointsCountHourly?.value,
261 260 ]);
262   - console.log('state.dataPointList', state.dataPointList);
263 261 state.messageList.push([transportMsgCountHourly?.ts, transportMsgCountHourly?.value]);
264   - console.log('state.messageList', state.messageList);
265 262 }
266 263 }
267 264 if (update) {
... ... @@ -276,8 +273,6 @@
276 273 }
277 274 state.dataPointList = newArray;
278 275 state.messageList = newArray1;
279   - console.log('newArray', state.dataPointList);
280   - console.log('newArray1', state.messageList);
281 276 }
282 277 }
283 278 },
... ...
... ... @@ -13,3 +13,33 @@ export const basicProps = {
13 13 default: '280px',
14 14 },
15 15 };
  16 +
  17 +export interface CardList {
  18 + deviceInfo: {
  19 + sumCount: number;
  20 + onLine: number;
  21 + offLine: number;
  22 + inActive: number;
  23 + todayAdd: number;
  24 + directConnection: number;
  25 + gateWay: number;
  26 + sensor: number;
  27 + };
  28 + tenantInfo?: { sumCount: number; todayAdd: number };
  29 + customerInfo?: { sumCount: number; todayAdd: number };
  30 + alarmInfo?: {
  31 + sumCount: number;
  32 + todayAdd: number;
  33 + };
  34 + messageInfo?: {
  35 + dataPointsCount: number;
  36 + messageCount: number;
  37 + todayDataPointsAdd: number;
  38 + todayMessageAdd: number;
  39 + };
  40 +}
  41 +export type seriesDataT = {
  42 + value: number | undefined;
  43 + name: string;
  44 + itemStyle: object;
  45 +};
... ...
... ... @@ -2,7 +2,6 @@
2 2 <div class="p-4 md:flex">
3 3 <div class="md:w-7/10 w-full !mr-4 enter-y">
4 4 <GrowCard :loading="loading" class="enter-y" :role="role" />
5   - <PieChartDevice :loading="loading" class="enter-y" :role="role" />
6 5 <SiteAnalysisMessage class="!my-4 enter-y" :loading="loading" :role="role" />
7 6 <SiteAnalysis class="!my-4 enter-y" :loading="loading" :role="role" />
8 7 <div class="md:flex enter-y" v-if="!isAdmin(role)">
... ... @@ -31,15 +30,17 @@
31 30 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
32 31 import { getAuthCache } from '/@/utils/auth';
33 32 import { isAdmin } from '/@/enums/roleEnum';
34   - import PieChartDevice from './components/PieChartDevice.vue';
35 33
36 34 defineExpose({
37 35 isAdmin,
38 36 });
39 37
40 38 const userInfo: any = getAuthCache(USER_INFO_KEY);
  39 +
41 40 const role: string = userInfo?.roles[0];
  41 +
42 42 const loading = ref(true);
  43 +
43 44 setTimeout(() => {
44 45 loading.value = false;
45 46 }, 1500);
... ...