| 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> | 
... | ... |  |