index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. <template>
  2. <div class="dashboard-editor-container">
  3. <!-- 设备数量 -->
  4. <div class="layout-1">
  5. <el-row :gutter="8">
  6. <el-col class="gutter-row item item1" :span="4" >
  7. <a href="javascript:void(0);" @click="handleSearchByGrade(0)">
  8. <div class="gutter-box" :style="item1Style">
  9. <div class="today-add">
  10. <span>所有告警</span>
  11. </div>
  12. <div class="count">
  13. <div>
  14. <span class="number">
  15. <i class="el-icon-loading" v-if="showLoading"></i>
  16. <countTo v-else :startVal="startVal" :endVal="total" :duration="duration"></countTo>
  17. </span>
  18. </div>
  19. <span class="text">告警总数</span>
  20. </div>
  21. </div>
  22. </a>
  23. </el-col>
  24. <el-col class="gutter-row item item2" :span="4" >
  25. <a href="javascript:void(0);" @click="handleSearchByGrade(1)">
  26. <div class="gutter-box" :style="item2Style">
  27. <div class="today-add">
  28. <span >设备校准告警</span>
  29. <el-tooltip :enterable="false" effect="light" placement="top">
  30. <div slot="content">{{this.alarmGradeText[1]}}</div>
  31. <i class="el-icon-question"></i>
  32. </el-tooltip>
  33. </div>
  34. <div class="count">
  35. <span class="number">
  36. <i class="el-icon-loading" v-if="showLoading"></i>
  37. <countTo v-else :startVal="startVal" :endVal="alarmCount.first" :duration="duration"></countTo>
  38. </span>
  39. <span class="text">告警数量</span>
  40. </div>
  41. <div class="level-text">
  42. <span class="level-text-left">紧急程度:</span>
  43. <span class="level-text-right">非常紧急</span>
  44. </div>
  45. </div></a>
  46. </el-col>
  47. <el-col class="gutter-row item item3" :span="4" >
  48. <a href="javascript:void(0);" @click="handleSearchByGrade(2)">
  49. <div class="gutter-box" :style="item3Style">
  50. <div class="today-add">
  51. <span>硬件故障告警</span>
  52. <el-tooltip :enterable="false" effect="light" placement="top">
  53. <div slot="content">{{this.alarmGradeText[2]}}</div>
  54. <i class="el-icon-question"></i>
  55. </el-tooltip>
  56. </div>
  57. <div class="count">
  58. <span class="number">
  59. <i class="el-icon-loading" v-if="showLoading"></i>
  60. <countTo
  61. v-else
  62. :startVal="startVal"
  63. :endVal="alarmCount.second"
  64. :duration="duration"
  65. ></countTo>
  66. </span>
  67. <span class="text">告警数量</span>
  68. </div>
  69. <div class="level-text">
  70. <span class="level-text-left">紧急程度:</span>
  71. <span class="level-text-right">紧急</span>
  72. </div>
  73. </div></a>
  74. </el-col>
  75. <el-col class="gutter-row item item4" :span="4" >
  76. <a href="javascript:void(0);" @click="handleSearchByGrade(3)">
  77. <div class="gutter-box" :style="item4Style">
  78. <div class="today-add">
  79. <span>设备流量告警</span>
  80. <el-tooltip :enterable="false" effect="light" placement="top">
  81. <div slot="content">{{this.alarmGradeText[3]}}</div>
  82. <i class="el-icon-question"></i>
  83. </el-tooltip>
  84. </div>
  85. <div class="count">
  86. <span class="number">
  87. <i class="el-icon-loading" v-if="showLoading"></i>
  88. <countTo
  89. v-else
  90. :startVal="startVal"
  91. :endVal="alarmCount.third"
  92. :duration="duration"
  93. ></countTo>
  94. </span>
  95. <span class="text">告警数量</span>
  96. </div>
  97. <div class="level-text">
  98. <span class="level-text-left">紧急程度:</span>
  99. <span class="level-text-right">一般</span>
  100. </div>
  101. </div></a>
  102. </el-col>
  103. <el-col class="gutter-row item item5" :span="4" >
  104. <a href="javascript:void(0);" @click="handleSearchByGrade(4)">
  105. <div class="gutter-box" :style="item5Style">
  106. <div class="today-add">
  107. <span>其他告警</span>
  108. <el-tooltip :enterable="false" effect="light" placement="top">
  109. <div slot="content">{{this.alarmGradeText[4]}}</div>
  110. <i class="el-icon-question"></i>
  111. </el-tooltip>
  112. </div>
  113. <div class="count">
  114. <span class="number">
  115. <i class="el-icon-loading" v-if="showLoading"></i>
  116. <countTo
  117. v-else
  118. :startVal="startVal"
  119. :endVal="alarmCount.fourth"
  120. :duration="duration"
  121. ></countTo>
  122. </span>
  123. <span class="text">告警数量</span>
  124. </div>
  125. <div class="level-text">
  126. <span class="level-text-left">紧急程度:</span>
  127. <span class="level-text-right">较低</span>
  128. </div>
  129. </div></a>
  130. </el-col>
  131. </el-row>
  132. </div>
  133. <div class="layout-2 app-container">
  134. <!-- 搜索栏 -->
  135. <searchbar
  136. :url="url"
  137. @dataChange="setTableData"
  138. :searchReason="searchReason"
  139. />
  140. <el-table
  141. ref="multipleTable"
  142. :data="data"
  143. tooltip-effect="dark"
  144. style="width: 100%"
  145. v-loading="loading"
  146. border
  147. fit
  148. @selection-change="handleSelectMulti"
  149. :highlight-current-row="highlight"
  150. @row-click="rowClick"
  151. @cell-click="cellClick"
  152. >
  153. <el-table-column type="selection" align="center" width="55" />
  154. <!-- <el-table-column prop="alarm_reason" align="center" label="告警原因 ">
  155. <template slot-scope="data">
  156. <el-tooltip effect="light" :enterable="false" :disabled="data.row.sub_device_no ==null" :content="data.row.sub_device_no" placement="top">
  157. <el-tag effect="dark" :color='alarmGrade[data.row.grade]["color"]'>{{ data.row.alarm_reason }}</el-tag>
  158. </el-tooltip>
  159. </template>
  160. </el-table-column> -->
  161. <el-table-column prop="device_number" align="center" sortable label="设备编号" />
  162. <el-table-column prop="device_name" align="center" sortable label="设备名称" />
  163. <el-table-column prop="alarm_type" align="center" sortable label="告警类型 "/>
  164. <el-table-column prop="reason_text" align="center" sortable label="告警原因 "/>
  165. <el-table-column prop="start_time_text" align="center" sortable label="告警开始时间" />
  166. <!-- <el-table-column prop="end_time_text" align="center" width="160" label="告警结束时间" /> -->
  167. <!-- <el-table-column prop="state" align="center" label="告警状态" /> -->
  168. <el-table-column prop="comment" align="center" min-width="180" label="备注" />
  169. <el-table-column label="操作" width="130" align="center">
  170. <template slot-scope="record">
  171. <el-tooltip effect="light" :enterable="false" content="设备详情" placement="top">
  172. <el-button type="primary" icon="el-icon-view" @click="viewAlarmDetail(record.row.id)" />
  173. </el-tooltip>
  174. <!-- <el-tooltip effect="light" :enterable="false" content="历史心跳" placement="top">
  175. <el-button type="primary" icon="el-icon-data-line" @click="alarmAnalysis(record.row.asset_no)" />
  176. </el-tooltip> -->
  177. </template>
  178. </el-table-column>
  179. </el-table>
  180. <div class="selected-operate">
  181. <el-row>
  182. <el-col :span="8">
  183. <!-- <el-button
  184. :disabled="selectedIds.length<=0"
  185. type="info"
  186. @click="init()"
  187. >处理告警</el-button> -->
  188. <el-button
  189. :loading="downloadLoading"
  190. type="info"
  191. @click="exportAlarmList()"
  192. >导出</el-button>
  193. <el-button
  194. @click="clearSelectedIds()"
  195. >清空选中</el-button>
  196. </el-col>
  197. <el-col :span="16">
  198. <el-pagination
  199. background
  200. class="pagination-container"
  201. @size-change="handleSizeChange"
  202. @current-change="handleCurrentChange"
  203. :current-page="paginate.current"
  204. :page-sizes="paginate.sizes"
  205. :page-size="paginate.limit"
  206. :layout="paginate.layout"
  207. :total="paginate.total"
  208. />
  209. </el-col>
  210. </el-row>
  211. </div>
  212. <view-dialog
  213. :detailVisible="detailVisible"
  214. @sendVal="closeDialog"
  215. :alarmId="alarmId"
  216. />
  217. <analysis-dialog
  218. :analysisVisible="analysisVisible"
  219. @sendVal="closeDialog"
  220. :assetNo="assetNo"
  221. />
  222. <export-dialog
  223. :exportVisible="exportVisible"
  224. @sendVal="closeDialog"
  225. @exportCallback="exportAlarmByType"
  226. />
  227. </div>
  228. </div>
  229. </template>
  230. <script>
  231. import countTo from "vue-count-to";
  232. import rlListOperate from "@/layout/rl-list-operate/rlListOperate";
  233. import { parseTime } from '@/utils'
  234. import Searchbar from '../search/Searchbar';
  235. import viewDialog from "../component/viewDialog"
  236. import analysisDialog from "../component/analysisDialog"
  237. import exportAlarm from "../component/exportAlarm"
  238. import exportDialog from "../component/exportDialog"
  239. import { action } from '@/directive/permission/index.js'
  240. export default {
  241. name: "alarm_realtimeAlarm",
  242. mixins: [rlListOperate,exportAlarm],
  243. directives: { action },
  244. components: {
  245. countTo,
  246. Searchbar,
  247. viewDialog,
  248. analysisDialog,
  249. exportDialog
  250. },
  251. data() {
  252. return {
  253. duration: 3000,
  254. showLoading: true,
  255. showAddLoading: true,
  256. detailVisible:false,
  257. analysisVisible:false,
  258. exportVisible:false,
  259. alarmId:'',
  260. startVal: 0,
  261. assetNo:'',
  262. queryParam:{},
  263. alarmGrade:[],
  264. alarmGradeText:{
  265. 1:'计量器具校准失效提前告警',
  266. 2:'硬件故障告警',
  267. 3:'液压泵中流量卡的有效期管理跟报警提醒',
  268. 4:'其他告警提醒',
  269. },
  270. searchReason:[],
  271. alarmCount: {
  272. first: 13,
  273. second : 17,
  274. third: 22,
  275. fourth: 28,
  276. },
  277. item1Style: { "background-color": "#32c5d2" },
  278. item2Style: { "background-color": "#4caf50" },
  279. item3Style: { "background-color": "#7ba7bd" },
  280. item4Style: { "background-color": "#e7505a" },
  281. item5Style: { "background-color": "#e7505a" },
  282. url: "alarmRecords",
  283. };
  284. },
  285. computed: {
  286. total: function() {
  287. return (
  288. this.alarmCount.first +
  289. this.alarmCount.second +
  290. this.alarmCount.third +
  291. this.alarmCount.fourth
  292. );
  293. },
  294. online: function() {
  295. return this.statusCount.alarm + this.statusCount.normal;
  296. }
  297. },
  298. created(){
  299. },
  300. mounted() {
  301. this.alarmGradeCount([])
  302. this.initAlarmNotice()
  303. let alarmGrade = this.$appConfig["alarmGrade"];
  304. this.alarmGrade=alarmGrade
  305. this.item1Style = { "background-color": alarmGrade[0]["color"] };
  306. this.item2Style = { "background-color": alarmGrade[1]["color"] };
  307. this.item3Style = { "background-color": alarmGrade[2]["color"] };
  308. this.item4Style = { "background-color": alarmGrade[3]["color"] };
  309. this.item5Style = { "background-color": alarmGrade[4]["color"] };
  310. // Object.keys(alarmGrade).forEach((k) => {
  311. // console.log(alarmGrade[k])
  312. // })
  313. },
  314. methods: {
  315. async initAlarmNotice(){
  316. let that=this
  317. let gradeNotice=[]
  318. await this.$http.post("sysDictData/getOptions", { type: "alarmGradeNotice" }).then(resp => {
  319. Object.keys(resp.data).forEach((k) => {
  320. let item=resp.data[k]
  321. gradeNotice[item.value]=item.remark
  322. })
  323. });
  324. await this.$http.post("sysDictData/getOptions", { type: "AlarmReason" }).then(resp => {
  325. let gradeArr=[]
  326. Object.keys(resp.data).forEach((k) => {
  327. let item=resp.data[k]
  328. if(gradeArr[item.remark]){
  329. gradeArr[item.remark]+='或'+item.text
  330. }else{
  331. gradeArr[item.remark]=item.text
  332. }
  333. })
  334. let res=[]
  335. for (let i = 1; i <= 4; i++) {
  336. if(gradeNotice['grade'+i]){
  337. res[i]=gradeNotice['grade'+i]
  338. }else if(gradeArr[i]){
  339. res[i]=gradeArr[i]
  340. }else{
  341. res[i]='暂未定义'
  342. }
  343. }
  344. // that.alarmGradeText=res
  345. });
  346. },
  347. formatLoginTime(time) {
  348. return parseTime(time)
  349. },
  350. alarmGradeCount(alarm_reason){
  351. var self = this;
  352. var query =JSON.parse(JSON.stringify(this.queryParam))
  353. query.alarm_reason=alarm_reason
  354. query.grade = ''
  355. self.alarmCount.first = 45;
  356. self.alarmCount.second = 32;
  357. self.alarmCount.third = 42;
  358. self.alarmCount.fourth = 32;
  359. self.showLoading = false;
  360. // 查询状态数据
  361. // this.$http.get("alarm/alarmGradeCount/realtime",{ params: query }).then(function(resp) {
  362. // if (resp.code == 10000) {
  363. // self.alarmCount.first = resp.data[1];
  364. // self.alarmCount.second = resp.data[2];
  365. // self.alarmCount.third = resp.data[3];
  366. // self.alarmCount.fourth = resp.data[4];
  367. // self.showLoading = false;
  368. // }
  369. // });
  370. },
  371. /**
  372. * 监听搜索组件中查出的数据
  373. */
  374. setTableData(data,queryParam,paginate,isGradeSearch) {
  375. this.data = data
  376. this.queryParam = queryParam
  377. if(isGradeSearch){
  378. this.alarmGradeCount([])
  379. }else{
  380. this.alarmGradeCount(this.queryParam.alarm_reason)
  381. }
  382. this.paginate=paginate
  383. },
  384. viewAlarmDetail(alarm_id){
  385. this.alarmId=alarm_id;
  386. this.detailVisible=true;
  387. },
  388. alarmAnalysis(asset_no){
  389. this.assetNo=asset_no;
  390. this.analysisVisible=true;
  391. },
  392. closeDialog(){
  393. this.detailVisible=false;
  394. this.analysisVisible=false;
  395. this.exportVisible=false
  396. },
  397. handleSearchByGrade(level){
  398. let search_reason=[]
  399. if(level==0){
  400. search_reason['grade']=''
  401. search_reason['alarm_reason']=[]
  402. this.searchReason=search_reason
  403. return
  404. }
  405. search_reason['grade']=level
  406. let alarm_reason=[]
  407. this.$http.post("sysDictData/getOptions", { type: "AlarmReason" }).then(resp => {
  408. let level_arr=[]
  409. Object.keys(resp.data).forEach((k) => {
  410. let item=resp.data[k]
  411. level_arr.push(item.remark)
  412. if(item.remark==level){
  413. alarm_reason.push(item.value)
  414. }
  415. })
  416. if(level_arr.indexOf(level)<0){
  417. this.$http.post("sysDictData/getOptions", { type: "alarmGradeNotice" }).then(resp => {
  418. let key='grade'+level;
  419. Object.keys(resp.data).forEach((k) => {
  420. let gradeArr=resp.data[k]
  421. if(gradeArr.value==key){
  422. alarm_reason=gradeArr.text.split('&')
  423. }
  424. })
  425. search_reason['alarm_reason']=alarm_reason
  426. this.searchReason=search_reason
  427. });
  428. }else{
  429. search_reason['alarm_reason']=alarm_reason
  430. this.searchReason=search_reason
  431. }
  432. })
  433. },
  434. clearSelectedIds(){
  435. // this.selectedIds = []
  436. this.$refs.multipleTable.clearSelection();
  437. },
  438. exportAlarmList(){
  439. if(this.selectedIds.length<=0 ){
  440. this.exportExcelForAll(0);
  441. }else{
  442. this.exportVisible=true;
  443. }
  444. },
  445. exportAlarmByType(val){
  446. if(val=='all'){
  447. this.exportExcelForAll(0);
  448. }else{
  449. this.exportExcelBySelectIds(this.selectedIds);
  450. }
  451. this.exportVisible=false;
  452. }
  453. },
  454. };
  455. </script>
  456. <style lang='scss' scoped>
  457. @import "./alarm.scss";
  458. </style>