AlarmList.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <template>
  2. <div>
  3. <div class="box box-primary">
  4. <div class="box-header">
  5. <h4 class="text-primary text-center">报警列表</h4>
  6. </div>
  7. <div class="box-body">
  8. <form class="form-inline" autocomplete="off" spellcheck="false">
  9. <div class="form-group form-group-sm">
  10. <label>搜索</label>
  11. <input type="text" class="form-control" placeholder="关键字" v-model.trim="q" @keydown.enter.prevent ref="q">
  12. </div>
  13. <span class="hidden-xs">&nbsp;&nbsp;</span>
  14. <div class="form-group form-group-sm">
  15. <label>报警级别</label>
  16. <select class="form-control" v-model.trim="priority">
  17. <option value="">全部</option>
  18. <option value="1">一级警情</option>
  19. <option value="2">二级警情</option>
  20. <option value="3">三级警情</option>
  21. <option value="4">四级警情</option>
  22. </select>
  23. </div>
  24. <span class="hidden-xs">&nbsp;&nbsp;</span>
  25. <div class="form-group form-group-sm">
  26. <label>报警方式</label>
  27. <select class="form-control" v-model.trim="method">
  28. <option value="">全部</option>
  29. <option value="1">电话报警</option>
  30. <option value="2">设备报警</option>
  31. <option value="3">短信报警</option>
  32. <option value="4">GPS报警</option>
  33. <option value="5">视频报警</option>
  34. <option value="6">设备故障报警</option>
  35. <option value="7">其他报警</option>
  36. </select>
  37. </div>
  38. <span class="hidden-xs">&nbsp;&nbsp;</span>
  39. <div class="form-group">
  40. <div class="input-group input-group-sm">
  41. <DatePicker class="form-control input-group-sm" clearBtn :day.sync="starttime" ref="startDatePicker" placeholder="开始日期"></DatePicker>
  42. <div class="input-group-btn">
  43. <button type="button" class="btn btn-sm btn-default" @click.prevent="showStartDatePicker">
  44. <i class="fa fa-calendar"></i>
  45. </button>
  46. </div>
  47. </div>
  48. </div>
  49. <span class="hidden-xs">&nbsp;-&nbsp;</span>
  50. <div class="form-group">
  51. <div class="input-group input-group-sm">
  52. <DatePicker class="form-control input-group-sm" clearBtn :day.sync="endtime" ref="endDatePicker" placeholder="结束日期"></DatePicker>
  53. <div class="input-group-btn">
  54. <button type="button" class="btn btn-sm btn-default" @click.prevent="showEndDatePicker">
  55. <i class="fa fa-calendar"></i>
  56. </button>
  57. </div>
  58. </div>
  59. </div>
  60. <div class="form-group form-group-sm pull-right" v-if="hasAnyRole(serverInfo, userInfo, '管理员') && hasAllChannel(serverInfo, userInfo)">
  61. <div class="input-group input-group-sm">
  62. <button type="button" class="btn btn-sm btn-danger" @click.prevent="clearAlarm">
  63. <i class="fa fa-remove"></i> 清空
  64. </button>
  65. </div>
  66. </div>
  67. </form>
  68. <br>
  69. <div class="clearfix"></div>
  70. <el-table :data="alarms" stripe :default-sort="{prop: 'Time', order: 'descending'}" @sort-change="sortChange" v-loading="loading" element-loading-text="加载中...">
  71. <el-table-column prop="DeviceID" label="报警设备" min-width="200" :formatter="formatDevice" show-overflow-tooltip></el-table-column>
  72. <el-table-column prop="ChannelID" label="报警通道" min-width="200" :formatter="formatChannel" show-overflow-tooltip></el-table-column>
  73. <el-table-column label="操作" min-width="100" v-if="isMobile()">
  74. <template slot-scope="props">
  75. <div class="btn-group btn-group-xs">
  76. <button type="button" class="btn btn-danger" @click.prevent="removeAlarm(props.row)" v-if="hasAnyRole(serverInfo, userInfo, '管理员')">
  77. <i class="fa fa-remove"></i> 删除
  78. </button>
  79. </div>
  80. </template>
  81. </el-table-column>
  82. <el-table-column prop="AlarmPriority" label="报警级别" min-width="100" :formatter="formatPriority" show-overflow-tooltip sortable="custom"></el-table-column>
  83. <el-table-column prop="AlarmMethod" label="报警方式" min-width="100" :formatter="formatMethod" show-overflow-tooltip></el-table-column>
  84. <el-table-column prop="AlarmType" label="报警类型" min-width="100" :formatter="formatType" show-overflow-tooltip></el-table-column>
  85. <el-table-column prop="Time" label="报警时间" min-width="160" sortable="custom"></el-table-column>
  86. <!-- <el-table-column prop="RecordLink" label="关联录像" min-width="150" show-overflow-tooltip>
  87. <template slot-scope="props">
  88. <a href="props.RecordLink" v-if="props.RecordLink" target="_blank">{{props.RecordLink}}</a>
  89. <span v-else>-</span>
  90. </template>
  91. </el-table-column> -->
  92. <!-- <el-table-column prop="Description" label="描述" min-width="200" show-overflow-tooltip></el-table-column> -->
  93. <el-table-column label="操作" min-width="100" fixed="right" v-if="!isMobile()">
  94. <template slot-scope="props">
  95. <div class="btn-group btn-group-xs">
  96. <button type="button" class="btn btn-danger" @click.prevent="removeAlarm(props.row)" v-if="hasAnyRole(serverInfo, userInfo, '管理员')">
  97. <i class="fa fa-remove"></i> 删除
  98. </button>
  99. </div>
  100. </template>
  101. </el-table-column>
  102. </el-table>
  103. </div>
  104. <div class="box-footer" v-if="total > 0">
  105. <el-pagination layout="total,prev,pager,next" :pager-count="isMobile() ? 3 : 5" class="pull-right" :total="total" :page-size.sync="pageSize" :current-page.sync="currentPage"></el-pagination>
  106. </div>
  107. </div>
  108. <div class="alert text-center" v-if="alarmPublishToRedis && serverInfo.IsDemo">
  109. <small>
  110. <strong><i class="fa fa-info-circle"></i> 提示 : </strong>
  111. 已开启报警消息发布到 Redis, 可向 Redis 订阅 alarm 消息以获取实时报警 > SUBSCRIBE alarm; 消息内容为报警信息 JSON 序列化字符串
  112. </small>
  113. </div>
  114. </div>
  115. </template>
  116. <script>
  117. import _ from "lodash";
  118. import DatePicker from "components/DatePicker.vue";
  119. import { mapState } from "vuex";
  120. import moment from 'moment';
  121. export default {
  122. props: {
  123. },
  124. data() {
  125. return {
  126. q: "",
  127. priority: "",
  128. method: "",
  129. starttime: "",
  130. endtime: "",
  131. total: 0,
  132. pageSize: 10,
  133. currentPage: 1,
  134. sort: "Time",
  135. order: "desc",
  136. loading: false,
  137. timer: 0,
  138. alarms: [],
  139. alarmPublishToRedis: false,
  140. };
  141. },
  142. computed: {
  143. ...mapState(['userInfo', 'serverInfo']),
  144. },
  145. components: {
  146. DatePicker
  147. },
  148. mounted() {
  149. // this.timer = setInterval(() => {
  150. // this.getAlarms();
  151. // }, 3000);
  152. },
  153. beforeDestroy() {
  154. if (this.timer) {
  155. clearInterval(this.timer);
  156. this.timer = 0;
  157. }
  158. },
  159. methods: {
  160. ready(){
  161. this.$watch('q', function(newVal, oldVal) {
  162. this.doDelaySearch();
  163. });
  164. this.$watch('starttime', function(newVal, oldVal) {
  165. this.doSearch();
  166. });
  167. this.$watch('endtime', function(newVal, oldVal) {
  168. this.doSearch();
  169. });
  170. this.$watch('priority', function(newVal, oldVal) {
  171. this.doSearch();
  172. });
  173. this.$watch('method', function(newVal, oldVal) {
  174. this.doSearch();
  175. });
  176. this.$watch('currentPage', function(newVal, oldVal) {
  177. this.doSearch(newVal);
  178. });
  179. },
  180. doSearch(page = 1) {
  181. var query = {};
  182. if (this.q) query["q"] = this.q;
  183. if (this.starttime) query["starttime"] = this.starttime;
  184. if (this.endtime) query["endtime"] = this.endtime;
  185. if (this.priority) query["priority"] = this.priority;
  186. if (this.method) query["method"] = this.method;
  187. this.$router.replace({
  188. path: `/alarms/${page}`,
  189. query: query
  190. });
  191. },
  192. doDelaySearch: _.debounce(function() {
  193. this.doSearch();
  194. }, 500),
  195. getAlarms() {
  196. $.get("/api/v1/alarm/list", {
  197. q: this.q,
  198. start: (this.currentPage -1) * this.pageSize,
  199. limit: this.pageSize,
  200. starttime: this.starttime ? moment(this.starttime, "YYYYMMDD").startOf('day').format("YYYY-MM-DDTHH:mm:ss") : "",
  201. endtime: this.endtime ? moment(this.endtime, "YYYYMMDD").endOf('day').format("YYYY-MM-DDTHH:mm:ss") : "",
  202. priority: this.priority,
  203. method: this.method,
  204. sort: this.sort,
  205. order: this.order
  206. })
  207. .then(ret => {
  208. this.total = ret.AlarmCount;
  209. this.alarms = ret.AlarmList;
  210. this.alarmPublishToRedis = ret.AlarmPublishToRedis;
  211. })
  212. .always(() => {
  213. });
  214. },
  215. sortChange(data) {
  216. this.sort = data.prop;
  217. this.order = data.order == "ascending" ? "asc" : "desc";
  218. this.getAlarms();
  219. },
  220. formatName(row, col, cell) {
  221. if (cell) return cell;
  222. return "-";
  223. },
  224. formatDevice(row, col, cell) {
  225. // if (row.DeviceName) {
  226. // return row.DeviceName;
  227. // }
  228. if (row.DeviceID) {
  229. return row.DeviceID;
  230. }
  231. return "-";
  232. },
  233. formatChannel(row, rol, cell) {
  234. // if (row.ChannelName) {
  235. // return row.ChannelName;
  236. // }
  237. if (row.ChannelID) {
  238. return row.ChannelID;
  239. }
  240. return "-";
  241. },
  242. formatPriority(row, col, cell) {
  243. if (row.AlarmPriorityName){
  244. return row.AlarmPriorityName;
  245. }
  246. if (row.AlarmPriority) {
  247. return row.AlarmPriority;
  248. }
  249. return "-";
  250. },
  251. formatMethod(row, col, cell) {
  252. if (row.AlarmMethodName) {
  253. return row.AlarmMethodName;
  254. }
  255. if (row.AlarmMethod) {
  256. return row.AlarmMethod;
  257. }
  258. return "-";
  259. },
  260. formatType(row, col, cell) {
  261. if (row.AlarmTypeName) {
  262. return row.AlarmTypeName;
  263. }
  264. if (row.AlarmType) {
  265. return row.AlarmType;
  266. }
  267. return "-";
  268. },
  269. showStartDatePicker() {
  270. $(this.$refs.startDatePicker.$el).focus();
  271. },
  272. showEndDatePicker() {
  273. $(this.$refs.endDatePicker.$el).focus();
  274. },
  275. removeAlarm(row) {
  276. this.$confirm(`确认删除`, "提示").then(() => {
  277. $.get("/api/v1/alarm/remove", {
  278. id: row.ID
  279. }).always(() => {
  280. this.getAlarms();
  281. });
  282. }).catch(() => {});
  283. },
  284. clearAlarm() {
  285. this.$confirm('确认全部删除', "提示").then(() => {
  286. $.get("/api/v1/alarm/clear", {}).then(() => {
  287. this.getAlarms();
  288. })
  289. }).catch(() => {});
  290. }
  291. },
  292. beforeRouteEnter(to, from, next) {
  293. next(vm => {
  294. vm.q = to.query.q || "";
  295. vm.starttime = to.query.starttime || "";
  296. vm.endtime = to.query.endtime || "";
  297. vm.priority = to.query.priority || "";
  298. vm.method = to.query.method || "";
  299. vm.currentPage = parseInt(to.params.page) || 1;
  300. vm.ready();
  301. });
  302. },
  303. beforeRouteUpdate(to, from, next) {
  304. next();
  305. this.$nextTick(() => {
  306. this.q = to.query.q || "";
  307. this.starttime = to.query.starttime || "";
  308. this.endtime = to.query.endtime || "";
  309. this.priority = to.query.priority || "";
  310. this.method = to.query.method || "";
  311. this.currentPage = parseInt(to.params.page) || 1;
  312. this.alarms = [];
  313. this.getAlarms();
  314. });
  315. }
  316. };
  317. </script>