dashboard.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. <template>
  2. <div class="home-container">
  3. <el-row :gutter="15" class="home-card-one mb15">
  4. <el-col :xs="24" :sm="12" :md="12" :lg="6" :xl="6" v-for="(v, k) in homeOne" :key="k" :class="{ 'home-media home-media-lg': k > 1, 'home-media-sm': k === 1 }">
  5. <div class="home-card-item flex">
  6. <div class="flex-margin flex w100" :class="` home-one-animation${k}`">
  7. <div class="flex-auto">
  8. <span class="font30">{{ v.num1 }}</span>
  9. <span class="ml5 font16" :style="{ color: v.color1 }"> {{ v.num2 }}</span>
  10. <div class="mt10">{{ v.num3 }}</div>
  11. </div>
  12. <div class="home-card-item-icon flex" :style="{ background: `var(${v.color2})` }">
  13. <i class="iconfont flex-margin font32" :class="v.num4" :style="{ color: `var(${v.color3})` }"></i>
  14. </div>
  15. </div>
  16. </div>
  17. </el-col>
  18. </el-row>
  19. <el-row :gutter="15" class="home-card-two mb15">
  20. <el-col :xs="24" :sm="14" :md="14" :lg="16" :xl="16">
  21. <div class="home-card-item">
  22. <div style="height: 100%" ref="homeLineRef"></div>
  23. </div>
  24. </el-col>
  25. <el-col :xs="24" :sm="10" :md="10" :lg="8" :xl="8" class="home-media">
  26. <div class="home-card-item">
  27. <div style="height: 100%" ref="homePieRef"></div>
  28. </div>
  29. </el-col>
  30. </el-row>
  31. <el-row :gutter="15" class="home-card-three">
  32. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  33. <div class="home-card-item" style="height: auto;">
  34. <div class="home-card-item-title">
  35. <span>告警信息列表</span>
  36. <el-button size="small" text type="primary" @click="toMore()">更多信息</el-button>
  37. </div>
  38. <el-table :data="tableData.data" style="width: 100%" v-loading="loading">
  39. <el-table-column label="ID" align="center" prop="id" width="60" v-col="'ID'" />
  40. <el-table-column label="告警类型" prop="type" :show-overflow-tooltip="true" v-col="'type'">
  41. <template #default="scope">
  42. <span v-if="scope.row.type == 1">规则告警</span>
  43. <span v-else>设备自主告警</span>
  44. </template>
  45. </el-table-column>
  46. <el-table-column label="规则名称" prop="ruleName" :show-overflow-tooltip="true" v-col="'ruleName'" />
  47. <el-table-column label="规则级别" prop="alarmLevel" :show-overflow-tooltip="true" v-col="'alarmLevel'">
  48. <template #default="scope">
  49. {{ scope.row.alarmLevel.name }}
  50. </template>
  51. </el-table-column>
  52. <el-table-column label="产品标识" prop="productKey" :show-overflow-tooltip="true" v-col="'productKey'" />
  53. <el-table-column label="设备标识" prop="deviceKey" :show-overflow-tooltip="true" v-col="'deviceKey'" />
  54. <el-table-column prop="status" label="告警状态" width="100" align="center" v-col="'status'">
  55. <template #default="scope">
  56. <el-tag type="success" size="small" v-if="scope.row.status">已处理</el-tag>
  57. <el-tag type="info" size="small" v-else>未处理</el-tag>
  58. </template>
  59. </el-table-column>
  60. <el-table-column prop="createdAt" label="告警时间" align="center" width="180" v-col="'createdAt'"></el-table-column>
  61. <el-table-column label="操作" width="150" align="center" fixed="right" v-col="'handle'">
  62. <template #default="scope">
  63. <el-button v-auth="'detail'" size="small" text type="primary" @click="onOpenDetailDic(scope.row)">详情</el-button>
  64. <el-button v-auth="'edit'" size="small" text type="warning" @click="onOpenEditDic(scope.row)" v-if="scope.row.status == 0">处理</el-button>
  65. </template>
  66. </el-table-column>
  67. </el-table>
  68. </div>
  69. </el-col>
  70. </el-row>
  71. <EditDic ref="editDicRef" @dataList="getAlarmList" />
  72. <DetailDic ref="detailRef" @dataList="getAlarmList" />
  73. </div>
  74. </template>
  75. <script lang="ts">
  76. import { toRefs, reactive, defineComponent, onMounted, ref, watch, nextTick, onActivated } from 'vue';
  77. import * as echarts from 'echarts';
  78. import { useRouter } from 'vue-router';
  79. import { useStore } from '/@/store/index';
  80. import api from '/@/api/datahub';
  81. import EditDic from '../alarm/log/component/edit.vue';
  82. import DetailDic from '../alarm/log/component/detail.vue';
  83. let global: any = {
  84. homeChartOne: null,
  85. homeChartTwo: null,
  86. homeCharThree: null,
  87. dispose: [null, '', undefined]
  88. };
  89. export default defineComponent({
  90. name: 'home',
  91. components: { EditDic, DetailDic },
  92. setup() {
  93. const editDicRef = ref();
  94. const detailRef = ref();
  95. const homeLineRef = ref();
  96. const homePieRef = ref();
  97. const homeBarRef = ref();
  98. const store = useStore();
  99. const router = useRouter();
  100. const state = reactive({
  101. loading: false,
  102. tableData: {
  103. data: [],
  104. total: 0,
  105. loading: false,
  106. param: {
  107. pageNum: 1,
  108. pageSize: 10,
  109. status: '',
  110. dateRange: [],
  111. },
  112. },
  113. homeOne: [
  114. {
  115. num1: '0',
  116. num2: '0',
  117. num3: '产品数',
  118. num4: 'icon-zidingyibuju',
  119. color1: '#6690F9',
  120. color2: '--el-color-warning-lighter',
  121. color3: '--el-color-warning',
  122. },
  123. {
  124. num1: '0',
  125. num2: '离线 0',
  126. num3: '设备数',
  127. num4: 'icon-putong',
  128. color1: '#FF6462',
  129. color2: '--next-color-primary-lighter',
  130. color3: '--el-color-primary',
  131. },
  132. {
  133. num1: '0',
  134. num2: '0',
  135. num3: '今日设备消息量',
  136. num4: 'icon-shidu',
  137. color1: '#6690F9',
  138. color2: '--el-color-success-lighter',
  139. color3: '--el-color-success',
  140. },
  141. {
  142. num1: '0',
  143. num2: '0',
  144. num3: '设备报警量',
  145. num4: 'icon-zaosheng',
  146. color1: '#6690F9',
  147. color2: '--el-color-warning-lighter',
  148. color3: '--el-color-warning',
  149. },
  150. ],
  151. myCharts: [],
  152. charts: {
  153. theme: '',
  154. bgColor: '',
  155. color: '#303133',
  156. },
  157. lineChartXAxisDat: [],
  158. lineChartMsgTotalData: [],
  159. lineChartAlarmTotalData: [],
  160. pieChartLegend: [],
  161. pieChartData: []
  162. });
  163. // 折线图
  164. const initLineChart = () => {
  165. if (!global.dispose.some((b: any) => b === global.homeChartOne)) global.homeChartOne.dispose();
  166. global.homeChartOne = <any>echarts.init(homeLineRef.value, state.charts.theme);
  167. const option = {
  168. backgroundColor: state.charts.bgColor,
  169. title: {
  170. text: '设备消息',
  171. x: 'left',
  172. textStyle: { fontSize: '15', color: state.charts.color },
  173. },
  174. grid: { top: 70, right: 20, bottom: 30, left: 30 },
  175. tooltip: { trigger: 'axis' },
  176. legend: { data: ['消息量', '预警量'], right: 0 },
  177. xAxis: {
  178. data: state.lineChartXAxisData
  179. },
  180. yAxis: [
  181. {
  182. type: 'value',
  183. name: '条数',
  184. splitLine: { show: true, lineStyle: { type: 'dashed', color: '#f5f5f5' } },
  185. axisLabel: {
  186. margin: 2,
  187. formatter: function (value, index) {
  188. if (value >= 10000 && value < 10000000) {
  189. value = value / 10000 + "W";
  190. } else if (value >= 10000000) {
  191. value = value / 10000000 + "KW";
  192. }
  193. return value;
  194. }
  195. },
  196. },
  197. ],
  198. series: [
  199. {
  200. name: '消息量',
  201. type: 'line',
  202. symbolSize: 6,
  203. symbol: 'circle',
  204. smooth: true,
  205. data: state.lineChartMsgTotalData,
  206. lineStyle: { color: '#fe9a8b' },
  207. itemStyle: { color: '#fe9a8b', borderColor: '#fe9a8b' },
  208. areaStyle: {
  209. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  210. { offset: 0, color: '#fe9a8bb3' },
  211. { offset: 1, color: '#fe9a8b03' },
  212. ]),
  213. },
  214. },
  215. {
  216. name: '预警量',
  217. type: 'line',
  218. symbolSize: 6,
  219. symbol: 'circle',
  220. smooth: true,
  221. data: state.lineChartAlarmTotalData,
  222. lineStyle: { color: '#9E87FF' },
  223. itemStyle: { color: '#9E87FF', borderColor: '#9E87FF' },
  224. areaStyle: {
  225. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  226. { offset: 0, color: '#9E87FFb3' },
  227. { offset: 1, color: '#9E87FF03' },
  228. ]),
  229. },
  230. emphasis: {
  231. itemStyle: {
  232. color: {
  233. type: 'radial',
  234. x: 0.5,
  235. y: 0.5,
  236. r: 0.5,
  237. colorStops: [
  238. { offset: 0, color: '#9E87FF' },
  239. { offset: 0.4, color: '#9E87FF' },
  240. { offset: 0.5, color: '#fff' },
  241. { offset: 0.7, color: '#fff' },
  242. { offset: 0.8, color: '#fff' },
  243. { offset: 1, color: '#fff' },
  244. ],
  245. },
  246. borderColor: '#9E87FF',
  247. borderWidth: 2,
  248. },
  249. },
  250. },
  251. ],
  252. };
  253. (<any>global.homeChartOne).setOption(option);
  254. (<any>state.myCharts).push(global.homeChartOne);
  255. };
  256. // 饼图
  257. const initPieChart = () => {
  258. if (!global.dispose.some((b: any) => b === global.homeChartTwo)) global.homeChartTwo.dispose();
  259. global.homeChartTwo = <any>echarts.init(homePieRef.value, state.charts.theme);
  260. var getname = state.pieChartLegend;
  261. var getvalue = state.pieChartData;
  262. var data = [];
  263. for (var i = 0; i < getname.length; i++) {
  264. data.push({ name: getname[i], value: getvalue[i] });
  265. }
  266. const colorList = ['#51A3FC', '#36C78B', '#FEC279', '#968AF5', '#FF0000'];
  267. const option = {
  268. backgroundColor: state.charts.bgColor,
  269. title: {
  270. text: '预警类型',
  271. x: 'left',
  272. textStyle: { fontSize: '15', color: state.charts.color },
  273. },
  274. tooltip: { trigger: 'item', formatter: '{b} <br/> {c}%' },
  275. graphic: {
  276. elements: [
  277. {
  278. type: 'image',
  279. z: -1,
  280. style: {
  281. image: store.state.themeConfig.themeConfig.isIsDark
  282. ? ''
  283. : 'data:image/png;base64,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',
  284. width: 230,
  285. height: 230,
  286. },
  287. left: '16.5%',
  288. top: 'center',
  289. },
  290. ],
  291. },
  292. legend: {
  293. type: 'scroll',
  294. orient: 'vertical',
  295. right: '0%',
  296. left: '65%',
  297. top: 'center',
  298. itemWidth: 14,
  299. itemHeight: 14,
  300. data: getname,
  301. textStyle: {
  302. rich: {
  303. name: {
  304. fontSize: 14,
  305. fontWeight: 400,
  306. width: 200,
  307. height: 35,
  308. padding: [0, 0, 0, 60],
  309. color: state.charts.color,
  310. },
  311. rate: {
  312. fontSize: 15,
  313. fontWeight: 500,
  314. height: 35,
  315. width: 40,
  316. padding: [0, 0, 0, 30],
  317. color: state.charts.color,
  318. },
  319. },
  320. },
  321. },
  322. series: [
  323. {
  324. type: 'pie',
  325. radius: ['82', store.state.themeConfig.themeConfig.isIsDark ? '50' : '102'],
  326. center: ['32%', '50%'],
  327. itemStyle: {
  328. color: function (params: any) {
  329. return colorList[params.dataIndex];
  330. },
  331. },
  332. label: { show: false },
  333. labelLine: { show: false },
  334. data: data,
  335. },
  336. ],
  337. };
  338. (<any>global.homeChartTwo).setOption(option);
  339. (<any>state.myCharts).push(global.homeChartTwo);
  340. };
  341. // 批量设置 echarts resize
  342. const initEchartsResizeFun = () => {
  343. nextTick(() => {
  344. for (let i = 0; i < state.myCharts.length; i++) {
  345. setTimeout(() => {
  346. (<any>state.myCharts[i]).resize();
  347. }, i * 1000);
  348. }
  349. });
  350. };
  351. // 批量设置 echarts resize
  352. const initEchartsResize = () => {
  353. window.addEventListener('resize', initEchartsResizeFun);
  354. };
  355. const getOverviewData = () => {
  356. api.iotManage.getOverviewData().then((res: any) => {
  357. const { overview, device, alarmLevel } = res;
  358. // overview
  359. // "deviceTotal": 8, //设备总量
  360. // "deviceOffline": 4, //离线设备数量
  361. // "productTotal": 6, //产品总量
  362. // "productAdded": 0, //今日产品增量
  363. // "msgTotal": 107246, //设备消息总量
  364. // "msgAdded": 7391, //今日设备消息增量
  365. // "alarmTotal": 43, //设备报警总量
  366. // "alarmAdded": 0 //今日设备报警增量
  367. state.homeOne[0].num1 = overview.productTotal;
  368. state.homeOne[0].num2 = `+${overview.productAdded}`;
  369. state.homeOne[1].num1 = overview.deviceTotal;
  370. state.homeOne[1].num2 = `离线 ${overview.deviceOffline}`;
  371. state.homeOne[2].num1 = overview.msgTotal;
  372. state.homeOne[2].num2 = `+${overview.msgAdded}`;
  373. state.homeOne[3].num1 = overview.alarmTotal;
  374. state.homeOne[3].num2 = `${overview.alarmAdded}`;
  375. // device
  376. // msgTotal 设备消息量月度统计
  377. // alarmTotal 设备告警量月度统计
  378. state.lineChartMsgTotalData = [];
  379. state.lineChartAlarmTotalData = [];
  380. state.lineChartXAxisData = Object.keys(device.msgTotal).map((item: any) => {
  381. state.lineChartMsgTotalData.push(device.msgTotal[item]);
  382. state.lineChartAlarmTotalData.push(device.alarmTotal[item]);
  383. return `${item}月`
  384. })
  385. // alarmLevel
  386. // "level": 4, //级别
  387. // "name": "一般", //级别名称
  388. // "num": 43, //该级别日志数量
  389. // "ratio": 100 //该级别日志数量占比(百分比)
  390. state.pieChartLegend = [];
  391. alarmLevel && alarmLevel.map((item: any) => {
  392. state.pieChartLegend.push(item.name)
  393. state.pieChartData.push(item.ratio)
  394. })
  395. })
  396. };
  397. const getAlarmList = () => {
  398. api.iotManage.getAlarmList(state.tableData.param).then((res: any) => {
  399. state.tableData.data = res.list;
  400. state.tableData.total = res.Total;
  401. })
  402. }
  403. //打开详情页
  404. const onOpenDetailDic = (row: any) => {
  405. detailRef.value.openDialog(row);
  406. };
  407. // 打开修改产品弹窗
  408. const onOpenEditDic = (row: any) => {
  409. editDicRef.value.openDialog(row);
  410. };
  411. // 告警信息-更多信息
  412. const toMore = () => {
  413. router.push({ path: '/monitor/notice' });
  414. };
  415. // 页面加载时
  416. onMounted(() => {
  417. initEchartsResize();
  418. getOverviewData();
  419. getAlarmList();
  420. });
  421. // 由于页面缓存原因,keep-alive
  422. onActivated(() => {
  423. initEchartsResizeFun();
  424. });
  425. // 监听 vuex 中的 tagsview 开启全屏变化,重新 resize 图表,防止不出现/大小不变等
  426. watch(
  427. () => store.state.tagsViewRoutes.isTagsViewCurrenFull,
  428. () => {
  429. initEchartsResizeFun();
  430. }
  431. );
  432. // 监听 vuex 中是否开启深色主题
  433. watch(
  434. () => store.state.themeConfig.themeConfig.isIsDark,
  435. (isIsDark) => {
  436. nextTick(() => {
  437. state.charts.theme = isIsDark ? 'dark' : '';
  438. state.charts.bgColor = isIsDark ? 'transparent' : '';
  439. state.charts.color = isIsDark ? '#dadada' : '#303133';
  440. setTimeout(() => {
  441. initLineChart();
  442. }, 500);
  443. setTimeout(() => {
  444. initPieChart();
  445. }, 700);
  446. });
  447. },
  448. {
  449. deep: true,
  450. immediate: true,
  451. }
  452. );
  453. return {
  454. homeLineRef,
  455. homePieRef,
  456. homeBarRef,
  457. detailRef,
  458. editDicRef,
  459. toMore,
  460. onOpenEditDic,
  461. getAlarmList,
  462. onOpenDetailDic,
  463. getOverviewData,
  464. ...toRefs(state),
  465. };
  466. },
  467. });
  468. </script>
  469. <style scoped lang="scss">
  470. $homeNavLengh: 8;
  471. .home-container {
  472. overflow: hidden;
  473. .home-card-one,
  474. .home-card-two,
  475. .home-card-three {
  476. .home-card-item,
  477. .home-card-top {
  478. width: 100%;
  479. height: 130px;
  480. border-radius: 4px;
  481. transition: all ease 0.3s;
  482. padding: 20px;
  483. overflow: hidden;
  484. background: var(--el-color-white);
  485. color: var(--el-text-color-primary);
  486. border: 1px solid var(--next-border-color-light);
  487. &:hover {
  488. box-shadow: 0 2px 12px var(--next-color-dark-hover);
  489. transition: all ease 0.3s;
  490. }
  491. &-icon {
  492. width: 70px;
  493. height: 70px;
  494. border-radius: 100%;
  495. flex-shrink: 1;
  496. i {
  497. color: var(--el-text-color-placeholder);
  498. }
  499. }
  500. &-title {
  501. font-size: 15px;
  502. font-weight: bold;
  503. height: 30px;
  504. }
  505. }
  506. }
  507. .home-card-three {
  508. .home-card-item-title {
  509. display: flex;
  510. justify-content: space-between;
  511. // span:nth-child(2) {
  512. // color: #409eff;
  513. // }
  514. }
  515. }
  516. .home-card-one {
  517. @for $i from 0 through 3 {
  518. .home-one-animation#{$i} {
  519. opacity: 0;
  520. animation-name: error-num;
  521. animation-duration: 0.5s;
  522. animation-fill-mode: forwards;
  523. animation-delay: calc($i/10) + s;
  524. }
  525. }
  526. }
  527. .home-card-two,
  528. .home-card-three {
  529. .home-card-item {
  530. height: 300px;
  531. }
  532. .home-card-top {
  533. height: 250px;
  534. .box-card {
  535. padding: 15px 20px 20px 10px;
  536. p {
  537. margin-bottom: 10px;
  538. }
  539. &-item {
  540. margin-bottom: 10px;
  541. }
  542. }
  543. }
  544. .home-card-item,
  545. .home-card-top {
  546. width: 100%;
  547. overflow: hidden;
  548. .home-monitor {
  549. height: 100%;
  550. .flex-warp-item {
  551. width: 25%;
  552. height: 111px;
  553. display: flex;
  554. .flex-warp-item-box {
  555. margin: auto;
  556. text-align: center;
  557. color: var(--el-text-color-primary);
  558. display: flex;
  559. border-radius: 5px;
  560. background: var(--next-bg-color);
  561. cursor: pointer;
  562. transition: all 0.3s ease;
  563. &:hover {
  564. background: var(--el-color-primary-light-9);
  565. transition: all 0.3s ease;
  566. }
  567. }
  568. @for $i from 0 through $homeNavLengh {
  569. .home-animation#{$i} {
  570. opacity: 0;
  571. animation-name: error-num;
  572. animation-duration: 0.5s;
  573. animation-fill-mode: forwards;
  574. animation-delay: calc($i/10) + s;
  575. }
  576. }
  577. }
  578. }
  579. }
  580. }
  581. .text-info {
  582. color: #23c6c8;
  583. }
  584. .text-danger {
  585. color: #ed5565;
  586. }
  587. .git-res {
  588. margin-top: 20px;
  589. }
  590. .git-res .el-link {
  591. margin-right: 30px;
  592. }
  593. ul,
  594. li {
  595. padding: 0;
  596. margin: 0;
  597. list-style: none
  598. }
  599. .product {
  600. margin-top: 50px;
  601. h3 {
  602. margin-bottom: 15px;
  603. }
  604. }
  605. .product li {
  606. margin-bottom: 20px;
  607. float: left;
  608. width: 150px;
  609. }
  610. .box-card.xx {
  611. margin-top: 20px;
  612. }
  613. }
  614. </style>