Bläddra i källkod

[webapp] 通知红标,近期未处理告警展示

tomsun28 4 år sedan
förälder
incheckning
0bc7d4751a

+ 1 - 1
alerter/src/main/java/com/usthe/alert/pojo/entity/Alert.java

@@ -67,7 +67,7 @@ public class Alert {
     @Length(max = 1024)
     private String content;
 
-    @ApiModelProperty(value = "告警状态: 0-正常告警(未读) 1-阈值触发但未达到告警次数 2-恢复告警 3-已读已知",
+    @ApiModelProperty(value = "告警状态: 0-正常告警(待处理) 1-阈值触发但未达到告警次数 2-恢复告警 3-已处理",
             example = "1", accessMode = READ_WRITE, position = 7)
     @Min(0)
     @Max(2)

+ 1 - 1
manager/src/main/resources/db/schema.sql

@@ -116,7 +116,7 @@ CREATE TABLE  alert
     alert_define_id  bigint           not null comment '告警关联的告警定义ID',
     priority         tinyint          not null default 0 comment '告警级别 0:高-emergency-紧急告警-红色 1:中-critical-严重告警-橙色 2:低-warning-警告告警-黄色',
     content          varchar(255)     not null comment '告警通知实际内容',
-    status           tinyint          not null default 0 comment '告警状态: 0-正常告警(未读) 1-阈值触发但未达到告警次数 2-恢复告警 3-已读已知',
+    status           tinyint          not null default 0 comment '告警状态: 0-正常告警(待处理) 1-阈值触发但未达到告警次数 2-恢复告警 3-已处理',
     times            int              not null comment '触发次数,即达到告警定义的触发阈值次数要求后才会发告警',
     gmt_create       timestamp        default current_timestamp comment 'create time',
     primary key (id)

+ 51 - 87
web-app/src/app/layout/basic/widgets/notify.component.ts

@@ -1,8 +1,11 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
-import { NoticeIconList, NoticeIconSelect, NoticeItem } from '@delon/abc/notice-icon';
-import { add, formatDistanceToNow, parse } from 'date-fns';
+import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core';
+import {NoticeIconSelect, NoticeItem } from '@delon/abc/notice-icon';
 import { NzI18nService } from 'ng-zorro-antd/i18n';
 import { NzMessageService } from 'ng-zorro-antd/message';
+import {AlertService} from "../../../service/alert.service";
+import {ALAIN_I18N_TOKEN} from "@delon/theme";
+import {I18NService} from "@core";
+import {Router} from "@angular/router";
 
 @Component({
   selector: 'header-notify',
@@ -13,53 +16,35 @@ import { NzMessageService } from 'ng-zorro-antd/message';
       [loading]="loading"
       btnClass="alain-default__nav-item"
       btnIconClass="alain-default__nav-item-icon"
-      (select)="select($event)"
-      (clear)="clear($event)"
+      (clear)="gotoAlertCenter($event)"
       (popoverVisibleChange)="loadData()"
     ></notice-icon>
   `,
   changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class HeaderNotifyComponent {
+export class HeaderNotifyComponent implements OnInit{
+
   data: NoticeItem[] = [
     {
-      title: '告警通知',
+      title: '近期未处理告警',
       list: [],
-      emptyText: '暂无告警通知',
+      emptyText: '暂无未处理告警',
       emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
-      clearText: '清空告警'
+      clearText: '进入告警中心'
     }
   ];
-  count = 5;
+  count = 0;
   loading = false;
 
-  constructor(private msg: NzMessageService, private nzI18n: NzI18nService, private cdr: ChangeDetectorRef) {}
-
-  private updateNoticeData(notices: NoticeIconList[]): NoticeItem[] {
-    const data = this.data.slice();
-    data.forEach(i => (i.list = []));
+  constructor(private msg: NzMessageService,
+              private nzI18n: NzI18nService,
+              private router: Router,
+              @Inject(ALAIN_I18N_TOKEN)  private i18nSvc: I18NService,
+              private alertSvc: AlertService,
+              private cdr: ChangeDetectorRef) {}
 
-    notices.forEach(item => {
-      const newItem = { ...item } as NoticeIconList;
-      if (typeof newItem.datetime === 'string') {
-        newItem.datetime = parse(newItem.datetime, 'yyyy-MM-dd', new Date());
-      }
-      if (newItem.datetime) {
-        newItem.datetime = formatDistanceToNow(newItem.datetime as Date, { locale: this.nzI18n.getDateLocale() });
-      }
-      if (newItem.extra && newItem.status) {
-        newItem.color = (
-          {
-            todo: undefined,
-            processing: 'blue',
-            urgent: 'red',
-            doing: 'gold'
-          } as { [key: string]: string | undefined }
-        )[newItem.status];
-      }
-      data.find(w => w.title === newItem.type)!.list.push(newItem);
-    });
-    return data;
+  ngOnInit(): void {
+    this.loadData();
   }
 
   loadData(): void {
@@ -67,60 +52,39 @@ export class HeaderNotifyComponent {
       return;
     }
     this.loading = true;
-    setTimeout(() => {
-      const now = new Date();
-      this.data = this.updateNoticeData([
-        {
-          id: '000000001',
-          avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
-          title: '监控-MYSQL_192.135.34.2-发出2级告警',
-          datetime: add(now, { days: 10 }),
-          type: '告警通知'
-        },
-        {
-          id: '000000002',
-          avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
-          title: '监控-MYSQL_192.135.44.2-发出1级告警',
-          datetime: add(now, { days: -3 }),
-          type: '告警通知'
-        },
-        {
-          id: '000000003',
-          avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
-          title: '监控-WEBSITE_www.baidu.com-发出4级告警',
-          datetime: add(now, { months: -3 }),
-          read: true,
-          type: '告警通知'
-        },
-        {
-          id: '000000004',
-          avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
-          title: '监控-REDIS_192.34.55.3-发出4级告警',
-          datetime: add(now, { years: -1 }),
-          type: '告警通知'
-        },
-        {
-          id: '000000005',
-          avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
-          title: '监控-REDIS_192.34.55.6-发出4级告警',
-          datetime: '2020-08-07',
-          type: '告警通知'
+    let loadAlerts$ = this.alertSvc.searchAlerts(0, undefined,undefined, 0, 5)
+      .subscribe(message => {
+        loadAlerts$.unsubscribe();
+        if (message.code === 0) {
+          let page = message.data;
+          let alerts = page.content;
+          this.data[0].list = [];
+          alerts.forEach(alert => {
+            let item = {
+                id: alert.id,
+                avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
+                title: '监控-' + alert.monitorName +'-发出' + this.i18nSvc.fanyi(`alert.priority.${alert.priority}`),
+                datetime: alert.gmtCreate,
+                color: 'blue',
+                type: '近期未处理告警'
+              }
+            this.data[0].list.push(item);
+          })
+          this.count = page.totalElements;
+        } else {
+          console.warn(message.msg);
         }
-      ]);
-
-      this.loading = false;
-      this.cdr.detectChanges();
-    }, 500);
+        this.loading = false;
+        this.cdr.detectChanges();
+      }, error => {
+        loadAlerts$.unsubscribe();
+        console.error(error.msg);
+        this.loading = false;
+      })
   }
 
-  clear(type: string): void {
-    this.loading = true;
-    setTimeout(() => {
-      this.data = this.updateNoticeData([]);
-      this.loading = false;
-      this.cdr.detectChanges();
-    }, 500);
-    this.msg.success(`已清空 ${type}`);
+  gotoAlertCenter(type: string): void {
+    this.router.navigateByUrl(`/alert/center`);
   }
 
   select(res: NoticeIconSelect): void {

+ 7 - 9
web-app/src/app/layout/basic/widgets/user.component.ts

@@ -1,7 +1,7 @@
-import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
+import { ChangeDetectionStrategy, Component } from '@angular/core';
 import { Router } from '@angular/router';
-import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
 import { SettingsService, User } from '@delon/theme';
+import {LocalStorageService} from "../../../service/local-storage.service";
 
 @Component({
   selector: 'header-user',
@@ -20,10 +20,6 @@ import { SettingsService, User } from '@delon/theme';
           <i nz-icon nzType="setting" class="mr-sm"></i>
           {{ 'menu.account.settings' | i18n }}
         </div>
-        <div nz-menu-item routerLink="/exception/trigger">
-          <i nz-icon nzType="close-circle" class="mr-sm"></i>
-          {{ 'menu.account.trigger' | i18n }}
-        </div>
         <li nz-menu-divider></li>
         <div nz-menu-item (click)="logout()">
           <i nz-icon nzType="logout" class="mr-sm"></i>
@@ -39,10 +35,12 @@ export class HeaderUserComponent {
     return this.settings.user;
   }
 
-  constructor(private settings: SettingsService, private router: Router, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {}
+  constructor(private settings: SettingsService,
+              private router: Router,
+              private localStorageSvc : LocalStorageService) {}
 
   logout(): void {
-    this.tokenService.clear();
-    this.router.navigateByUrl(this.tokenService.login_url!);
+    this.localStorageSvc.clear();
+    this.router.navigateByUrl('/passport/login');
   }
 }

+ 1 - 1
web-app/src/app/pojo/Alert.ts

@@ -5,7 +5,7 @@ export class Alert {
   monitorName!: string;
   // 告警级别 0:高-emergency-紧急告警-红色 1:中-critical-严重告警-橙色 2:低-warning-警告告警-黄色
   priority: number = 2;
-  // 告警状态: 0-正常告警(未读)  3-已读已知
+  // 告警状态: 0-正常告警(待处理) 1-阈值触发但未达到告警次数 2-恢复告警 3-已处理
   status!: number;
   content!: string;
   times!: number;

+ 7 - 7
web-app/src/app/routes/alert/alert-center/alert-center.component.html

@@ -20,11 +20,11 @@
   </button>
   <button nz-button nzType="primary" (click)="onMarkReadAlerts()">
     <i nz-icon nzType="down-circle" nzTheme="outline"></i>
-    标记已
+    标记已处理
   </button>
   <button nz-button nzType="primary" (click)="onMarkUnReadAlerts()">
     <i nz-icon nzType="up-circle" nzTheme="outline"></i>
-    标记未
+    标记未处理
   </button>
   <button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
     <i nz-icon nzType="sync" nzTheme="outline"></i>
@@ -38,8 +38,8 @@
   <nz-select style="margin-right: 10px;float: right;width: 120px;" nzAllowClear
              [nzPlaceHolder]="'告警状态过滤'" [(ngModel)]="filterStatus">
     <nz-option nzLabel="全部状态" nzValue="9"></nz-option>
-    <nz-option nzLabel="未读告警" nzValue="0"></nz-option>
-    <nz-option nzLabel="已读告警" nzValue="3"></nz-option>
+    <nz-option nzLabel="未处理" nzValue="0"></nz-option>
+    <nz-option nzLabel="已处理" nzValue="3"></nz-option>
   </nz-select>
   <nz-select style="margin-right: 10px;float: right;width: 120px;" nzAllowClear
              [nzPlaceHolder]="'告警级别过滤'" [(ngModel)]="filterPriority">
@@ -97,17 +97,17 @@
     </td>
     <td nzAlign="center">{{ data.content }}</td>
     <td nzAlign="center">
-      {{ data.status === 0 ? '未读' : '已读' }}
+      {{ data.status === 0 ? '未处理' : '已处理' }}
     </td>
     <td nzAlign="center">{{ data.gmtCreate }}</td>
     <td nzAlign="center" nzRight>
       <button nz-button nzType="primary" (click)="onDeleteOneAlert(data.id)" nz-tooltip nzTooltipTitle="删除告警">
         <i nz-icon nzType="delete" nzTheme="outline"></i>
       </button>
-      <button nz-button nzType="primary" (click)="onMarkReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记已">
+      <button nz-button nzType="primary" (click)="onMarkReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记已处理">
         <i nz-icon nzType="down-circle" nzTheme="outline"></i>
       </button>
-      <button nz-button nzType="primary" (click)="onMarkUnReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记未">
+      <button nz-button nzType="primary" (click)="onMarkUnReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记未处理">
         <i nz-icon nzType="up-circle" nzTheme="outline"></i>
       </button>
     </td>

+ 1 - 3
web-app/src/app/routes/exception/exception-routing.module.ts

@@ -2,13 +2,11 @@ import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
 
 import { ExceptionComponent } from './exception.component';
-import { ExceptionTriggerComponent } from './trigger.component';
 
 const routes: Routes = [
   { path: '403', component: ExceptionComponent, data: { type: 403 } },
   { path: '404', component: ExceptionComponent, data: { type: 404 } },
-  { path: '500', component: ExceptionComponent, data: { type: 500 } },
-  { path: 'trigger', component: ExceptionTriggerComponent }
+  { path: '500', component: ExceptionComponent, data: { type: 500 } }
 ];
 
 @NgModule({

+ 1 - 2
web-app/src/app/routes/exception/exception.module.ts

@@ -6,10 +6,9 @@ import { NzCardModule } from 'ng-zorro-antd/card';
 
 import { ExceptionRoutingModule } from './exception-routing.module';
 import { ExceptionComponent } from './exception.component';
-import { ExceptionTriggerComponent } from './trigger.component';
 
 @NgModule({
   imports: [CommonModule, DelonExceptionModule, NzButtonModule, NzCardModule, ExceptionRoutingModule],
-  declarations: [ExceptionComponent, ExceptionTriggerComponent]
+  declarations: [ExceptionComponent]
 })
 export class ExceptionModule {}

+ 0 - 35
web-app/src/app/routes/exception/trigger.component.ts

@@ -1,35 +0,0 @@
-import { Component, Inject } from '@angular/core';
-import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
-import { _HttpClient } from '@delon/theme';
-
-@Component({
-  selector: 'exception-trigger',
-  template: `
-    <div class="pt-lg">
-      <nz-card>
-        <button *ngFor="let t of types" (click)="go(t)" nz-button nzDanger>触发{{ t }}</button>
-        <button nz-button nzType="link" (click)="refresh()">触发刷新Token</button>
-      </nz-card>
-    </div>
-  `
-})
-export class ExceptionTriggerComponent {
-  types = [401, 403, 404, 500];
-
-  constructor(private http: _HttpClient, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {}
-
-  go(type: number): void {
-    this.http.get(`/api/${type}`).subscribe();
-  }
-
-  refresh(): void {
-    this.tokenService.set({ token: 'invalid-token' });
-    // 必须提供一个后端地址,无法通过 Mock 来模拟
-    this.http.post(`https://localhost:5001/auth`).subscribe(
-      res => console.warn('成功', res),
-      err => {
-        console.log('最后结果失败', err);
-      }
-    );
-  }
-}

+ 1 - 1
web-app/src/app/routes/passport/lock/lock.component.html

@@ -7,7 +7,7 @@
       <nz-form-item>
         <nz-form-control [nzErrorTip]="'validation.password.required' | i18n">
           <nz-input-group nzSuffixIcon="lock">
-            <input type="password" nz-input formControlName="password" />
+            <input type="password" nz-input formControlName="password" placeholder="输入任意解锁"/>
           </nz-input-group>
         </nz-form-control>
       </nz-form-item>

+ 1 - 8
web-app/src/app/routes/passport/lock/lock.component.ts

@@ -1,7 +1,6 @@
-import { Component, Inject } from '@angular/core';
+import { Component } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { Router } from '@angular/router';
-import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
 import { SettingsService, User } from '@delon/theme';
 
 @Component({
@@ -18,7 +17,6 @@ export class UserLockComponent {
 
   constructor(
     fb: FormBuilder,
-    @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
     private settings: SettingsService,
     private router: Router
   ) {
@@ -33,11 +31,6 @@ export class UserLockComponent {
       this.f.controls[i].updateValueAndValidity();
     }
     if (this.f.valid) {
-      console.log('Valid!');
-      console.log(this.f.value);
-      this.tokenService.set({
-        token: '123'
-      });
       this.router.navigate(['dashboard']);
     }
   }

+ 4 - 0
web-app/src/app/service/local-storage.service.ts

@@ -35,4 +35,8 @@ export class LocalStorageService {
     return this.putData(Authorization, token);
   }
 
+  public clear() {
+    localStorage.clear();
+  }
+
 }

+ 15 - 0
web-app/src/assets/tmp/i18n/zh-CN.json

@@ -55,6 +55,21 @@
       "redis": "Redis"
     }
   },
+  "alert": {
+    "": "告警",
+    "status": {
+      "": "告警状态",
+      "0": "待处理",
+      "2": "已恢复",
+      "3": "已处理"
+    },
+    "priority": {
+      "": "告警级别",
+      "0": "紧急告警",
+      "1": "严重告警",
+      "2": "警告告警"
+    }
+  },
   "app.lock": "锁屏",
   "app.login.message-invalid-credentials": "账户或密码错误(admin/ant.design)",
   "app.login.message-invalid-verification-code": "验证码错误",