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