warn.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. <template>
  2. <div class="app-container power-index-content">
  3. <el-row :gutter="10">
  4. <el-col :span="4" :xs="24">
  5. <div class="head-container">
  6. <el-input v-model="areaName" placeholder="请输入服务区名称" clearable size="small"
  7. prefix-icon="el-icon-search"
  8. style="margin-bottom: 20px"/>
  9. </div>
  10. <div class="head-container">
  11. <el-tree ref="tree" :data="areaOptions" :default-expand-all="true" :expand-on-click-node="false"
  12. :filter-node-method="filterNode" node-key="id" highlight-current @node-click="handleNodeClick"/>
  13. </div>
  14. </el-col>
  15. <el-col :span="20" :xs="24">
  16. <el-row :gutter="20">
  17. <el-col :span="12">
  18. <DeviceWaring :areaCode="areaCode"/>
  19. </el-col>
  20. <el-col :span="12">
  21. <LineChartBlock title="历史告警变化" :opt-cfg="devcWarningHis">
  22. <template v-slot:filters>
  23. <SwitchTag
  24. :ds="[{ val: 'year', text: '按年' }, { val: 'month', text: '按月' }, { val: 'day', text: '按日' }]"
  25. :defTag="dateType" :tagClick="onDateTypeSwitch"/>
  26. </template>
  27. </LineChartBlock>
  28. </el-col>
  29. </el-row>
  30. <el-row type="flex" :gutter="20" style="margin-top: 20px">
  31. <el-col :span="12">
  32. <BlockTable title="实时告警" :table-data="realTimeTableData">
  33. <template v-slot:columns>
  34. <el-table-column type="index" label="序号" align="center"/>
  35. <el-table-column prop="subSystemName" label="子系统" align="center"/>
  36. <el-table-column prop="objName" label="对象名称" align="center"/>
  37. <el-table-column prop="alarmMsg" label="描述" align="center"/>
  38. <el-table-column prop="alarmTime" label="时间" align="center"/>
  39. <el-table-column label="操作" align="center" width="100">
  40. <template slot-scope="scope">
  41. <el-dropdown @command="(cmd) => handleCommand(cmd, scope.row)"
  42. v-if="![ALARM_STATE.dissolved.value, ALARM_STATE.dissolved.value].includes(scope.row.alarmState)">
  43. <span class="el-dropdown-link">
  44. <dict-tag :options="dict.type.alarm_state" :value="scope.row.alarmState"></dict-tag>
  45. <i class="el-icon-arrow-down el-icon--right"></i>
  46. </span>
  47. <el-dropdown-menu slot="dropdown">
  48. <el-dropdown-item :command="ALARM_STATE.disposing.code"
  49. v-if="scope.row.alarmState === ALARM_STATE.new.value">开始处理
  50. </el-dropdown-item>
  51. <el-dropdown-item :command="ALARM_STATE.disposed.code">已处理</el-dropdown-item>
  52. <el-dropdown-item :command="ALARM_STATE.dissolved.code">已消散</el-dropdown-item>
  53. </el-dropdown-menu>
  54. </el-dropdown>
  55. </template>
  56. </el-table-column>
  57. </template>
  58. </BlockTable>
  59. </el-col>
  60. <el-col :span="12">
  61. <BarChartBlock title="告警统计报表" :opt-cfg="subSysIndex">
  62. <template v-slot:filters>
  63. <SwitchTag
  64. :ds="[{ val: 'year', text: '按年' }, { val: 'month', text: '按月' }, { val: 'day', text: '按日' }]"
  65. :defTag="dateType" :tagClick="onSubSysDateTypeSwitch"/>
  66. </template>
  67. </BarChartBlock>
  68. </el-col>
  69. </el-row>
  70. </el-col>
  71. </el-row>
  72. </div>
  73. </template>
  74. <script>
  75. import {
  76. fetchAlarmIndexDay,
  77. fetchAlarmIndexMonth,
  78. fetchAlarmIndexYear,
  79. fetchSubSysIndexDay,
  80. fetchSubSysIndexMonth,
  81. fetchSubSysIndexYear,
  82. listAlarmInfo,
  83. updateAlarmInfo,
  84. } from '@/api/alarm/alarm-info';
  85. import {ApiCode} from '@/api/apiEmums';
  86. import Block from '@/components/Block/block.vue';
  87. import BlockTable from '@/components/Block/BlockTable/index.vue';
  88. import BarChartBlock from '@/components/Block/charts/BarChartBlock.vue';
  89. import PieChartBlock from '@/components/Block/charts/PieChartBlock.vue';
  90. import {ALARM_STATE} from '@/enums/alarm';
  91. import {DateTool} from '@/utils/DateTool';
  92. import DeviceWaring from '@/views/devmgr/warn/DevcWarning/index.vue';
  93. import dayjs from 'dayjs';
  94. import {areaTreeSelect} from '@/api/basecfg/area'
  95. import LineChartBlock from '../../../components/Block/charts/LineChartBlock.vue';
  96. import SwitchTag from '../../../components/SwitchTag/index.vue';
  97. export default {
  98. dicts: ['alarm_type', 'alarm_state'],
  99. components: {
  100. Tag,
  101. BlockTable,
  102. DeviceWaring,
  103. Block,
  104. BarChartBlock,
  105. PieChartBlock,
  106. LineChartBlock,
  107. SwitchTag,
  108. },
  109. data() {
  110. return {
  111. startRecTime: '',
  112. endRecTime: '',
  113. areaName: undefined,
  114. areaOptions: [],
  115. ALARM_STATE,
  116. dateType: {val: 'year'},
  117. areaCode: '',
  118. devcWarningHis: {
  119. unit: ' ',
  120. xAxis: {
  121. type: 'category',
  122. data: [],
  123. },
  124. series: [],
  125. },
  126. subSysIndex: {
  127. unit: ' ',
  128. xAxis: {
  129. type: 'category',
  130. data: [],
  131. },
  132. series: [],
  133. },
  134. realTimeTableData: [],
  135. };
  136. },
  137. watch: {
  138. // 根据名称筛选区域树
  139. areaName(val) {
  140. this.$refs.tree.filter(val)
  141. }
  142. },
  143. async mounted() {
  144. await this.getAreaTreeByTag('0', 1)
  145. this.queryCharts()
  146. this.getRecentSevenDays();
  147. },
  148. methods: {
  149. /**计算近7天的时间范围*/
  150. getRecentSevenDays() {
  151. const endRecTime = dayjs(); // 当前时间
  152. const startRecTime = endRecTime.subtract(7, 'days'); // 7天前的时间
  153. this.startRecTime = startRecTime.format('YYYY-MM-DD HH:mm:ss');
  154. this.endRecTime = endRecTime.format('YYYY-MM-DD HH:mm:ss');
  155. },
  156. /** 查询区域树结构 */
  157. async getAreaTreeByTag(areaCode, layer) {
  158. await areaTreeSelect(areaCode, layer).then(response => {
  159. this.areaOptions = [{
  160. id: '-1',
  161. label: '全部',
  162. children: []
  163. }].concat(response.data)
  164. this.areaCode = '-1'
  165. })
  166. },
  167. // 筛选节点
  168. filterNode(value, data) {
  169. if (!value) return true
  170. return data.label.indexOf(value) !== -1
  171. },
  172. handleNodeClick(data, node) {
  173. this.areaCode = data.id
  174. this.queryCharts()
  175. },
  176. async onDateTypeSwitch(item) {
  177. if (item.val === 'day') {
  178. const xaxis = DateTool.getTime(60);
  179. const {data} = await fetchAlarmIndexDay({
  180. areaCode: this.areaCode,
  181. });
  182. const series = this.toSeries(data, xaxis);
  183. this.devcWarningHis.xAxis.data = xaxis;
  184. this.devcWarningHis.series = series;
  185. return;
  186. }
  187. if (item.val === 'month') {
  188. const xaxis = DateTool.getDayOfRange(
  189. dayjs().subtract(1, 'month'), dayjs(), DateTool.DateFormat.YYYY_MM_DD);
  190. const {data} = await fetchAlarmIndexMonth({areaCode: this.areaCode});
  191. const series = this.toSeries(data, xaxis);
  192. this.devcWarningHis.xAxis.data = xaxis;
  193. this.devcWarningHis.series = series;
  194. return;
  195. }
  196. const xaxis = DateTool.getMonthsOfYearAgo();
  197. const {data} = await fetchAlarmIndexYear({areaCode: this.areaCode});
  198. const series = this.toSeries(data, xaxis);
  199. this.devcWarningHis.xAxis.data = xaxis;
  200. this.devcWarningHis.series = series;
  201. },
  202. async onSubSysDateTypeSwitch(item) {
  203. if (item.val === 'day') {
  204. const xaxis = DateTool.getTime(60);
  205. const {data} = await fetchSubSysIndexDay({
  206. areaCode: this.areaCode,
  207. });
  208. const series = this.subSysIndexToSeries(data, xaxis);
  209. this.subSysIndex.xAxis.data = xaxis;
  210. this.subSysIndex.series = series;
  211. return;
  212. }
  213. if (item.val === 'month') {
  214. const xaxis = DateTool.getDayOfRange(
  215. dayjs().subtract(1, 'month'), dayjs(), DateTool.DateFormat.YYYY_MM_DD);
  216. const {data} = await fetchSubSysIndexMonth({areaCode: this.areaCode});
  217. const series = this.subSysIndexToSeries(data, xaxis);
  218. this.subSysIndex.xAxis.data = xaxis;
  219. this.subSysIndex.series = series;
  220. return;
  221. }
  222. const xaxis = DateTool.getMonthsOfYearAgo();
  223. const {data} = await fetchSubSysIndexYear({areaCode: this.areaCode});
  224. const series = this.subSysIndexToSeries(data, xaxis);
  225. this.subSysIndex.xAxis.data = xaxis;
  226. this.subSysIndex.series = series;
  227. },
  228. toSeries(data, xaxis) {
  229. const dayGroup = _.groupBy(data, 'alarmType');
  230. const series = [];
  231. Object.keys(dayGroup).forEach((alarmType) => {
  232. let ds = {};
  233. let typeName = this.selectDictLabel(this.dict.type.alarm_type, alarmType);
  234. dayGroup[alarmType].forEach(item => {
  235. ds[item.dateIndex] = item.cnt;
  236. });
  237. let seriesData = [];
  238. xaxis.forEach((item) => seriesData.push(ds[item] || 0));
  239. series.push({
  240. name: typeName,
  241. type: 'line',
  242. smooth: true,
  243. data: seriesData,
  244. });
  245. });
  246. return series;
  247. },
  248. subSysIndexToSeries(data, xaxis) {
  249. const dayGroup = _.groupBy(data, 'systemCode');
  250. const series = [];
  251. Object.keys(dayGroup).forEach((subSysCode) => {
  252. let ds = {};
  253. let systemName = dayGroup[subSysCode][0].systemName;
  254. dayGroup[subSysCode].forEach(item => {
  255. ds[item.dateIndex] = item.cnt;
  256. });
  257. let seriesData = [];
  258. xaxis.forEach((item) => seriesData.push(ds[item] || 0));
  259. series.push({
  260. name: systemName,
  261. type: 'bar',
  262. data: seriesData,
  263. });
  264. });
  265. return series;
  266. },
  267. queryCharts() {
  268. this.onDateTypeSwitch(this.dateType);
  269. this.onSubSysDateTypeSwitch(this.dateType);
  270. this.getRealTimeAlarm();
  271. },
  272. async getRealTimeAlarm() {
  273. let result = [];
  274. const {
  275. code,
  276. rows,
  277. } = await listAlarmInfo({
  278. pageNum: 1,
  279. pageSize: 10,
  280. areaCode: this.areaCode,
  281. alarmStateList: [
  282. ALARM_STATE.new.value, ALARM_STATE.disposing.value,
  283. ],
  284. startRecTime: this.startRecTime,
  285. endRecTime: this.endRecTime,
  286. });
  287. if (ApiCode.SUCCESS === code && rows && rows.length > 0) {
  288. result = rows;
  289. }
  290. this.realTimeTableData = result;
  291. },
  292. async handleCommand(command, data) {
  293. await updateAlarmInfo({
  294. id: data.id,
  295. alarmState: ALARM_STATE[command].value,
  296. });
  297. await this.getRealTimeAlarm();
  298. },
  299. },
  300. };
  301. </script>
  302. <style src="./index.scss" scoped lang="scss"/>