Showing
6 changed files
with
172 additions
and
177 deletions
| 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> | ... | ... |
src/views/dashboard/workbench/components/PieChartDevice.vue
deleted
100644 → 0
| 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); | ... | ... |