Explorar o código

[web-app] 告警配置列表-告警定义关联监控功能

tomsun28 %!s(int64=4) %!d(string=hai) anos
pai
achega
a2c480e5ae

+ 8 - 0
web-app/src/app/pojo/AlertDefineBind.ts

@@ -0,0 +1,8 @@
+export class AlertDefineBind {
+  id!: number;
+  alertDefineId!: number;
+  monitorId!: number;
+  monitorName!: string;
+  gmtCreate!: number;
+  gmtUpdate!: number;
+}

+ 61 - 6
web-app/src/app/routes/alert/alert-setting/alert-setting.component.html

@@ -82,6 +82,9 @@
     </td>
     <td nzAlign="center">{{ data.gmtUpdate? data.gmtUpdate : data.gmtCreate }}</td>
     <td nzAlign="center" nzRight>
+      <button nz-button nzType="primary" (click)="onOpenConnectModal(data.id, data.app)">
+        <i nz-icon nzType="link" nzTheme="outline"></i>
+      </button>
       <button nz-button nzType="primary" (click)="onEditOneAlertDefine(data.id)">
         <i nz-icon nzType="edit" nzTheme="outline"></i>
       </button>
@@ -97,15 +100,15 @@
   总量 {{ total }}
 </ng-template>
 
-
+<!-- 新增或修改告警定义弹出框 -->
 <nz-modal
-  [(nzVisible)]="isModalVisible"
-  [nzTitle]="isModalAdd?'新增告警阈值' : '修改告警阈值'"
-  (nzOnCancel)="onModalCancel()"
-  (nzOnOk)="onModalOk()"
+  [(nzVisible)]="isManageModalVisible"
+  [nzTitle]="isManageModalAdd?'新增告警阈值' : '修改告警阈值'"
+  (nzOnCancel)="onManageModalCancel()"
+  (nzOnOk)="onManageModalOk()"
   nzMaskClosable="false"
   nzWidth="60%"
-  [nzOkLoading]="isModalOkLoading"
+  [nzOkLoading]="isManageModalOkLoading"
 >
   <div *nzModalContent class = "-inner-content">
     <form nz-form>
@@ -177,3 +180,55 @@
     </form>
   </div>
 </nz-modal>
+
+<!-- 关联告警定义与监控关系弹出框 -->
+
+<nz-modal
+  [(nzVisible)]="isConnectModalVisible"
+  nzTitle="告警定义关联监控"
+  (nzOnCancel)="onConnectModalCancel()"
+  (nzOnOk)="onConnectModalOk()"
+  nzMaskClosable="false"
+  nzWidth="60%"
+  [nzOkLoading]="isConnectModalOkLoading"
+>
+  <nz-transfer
+    *nzModalContent
+    [nzDataSource]="transferData"
+    nzShowSearch="true"
+    nzShowSelectAll="false"
+    [nzRenderList]="[renderList, renderList]"
+    (nzChange)="change($event)"
+  >
+    <ng-template
+      #renderList
+      let-items
+      let-direction="direction"
+      let-stat="stat"
+      let-onItemSelectAll="onItemSelectAll"
+      let-onItemSelect="onItemSelect"
+    >
+      <nz-table #t [nzData]="$asTransferItems(items)" nzSize="small">
+        <thead>
+        <tr>
+          <th
+            [nzChecked]="stat.checkAll"
+            [nzIndeterminate]="stat.checkHalf"
+            (nzCheckedChange)="onItemSelectAll($event)"
+          ></th>
+          <th>监控</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr *ngFor="let data of t.data" (click)="onItemSelect(data)">
+          <td
+            [nzChecked]="!!data.checked"
+            (nzCheckedChange)="onItemSelect(data)"
+          ></td>
+          <td>{{ data.name }}</td>
+        </tr>
+        </tbody>
+      </nz-table>
+    </ng-template>
+  </nz-transfer>
+</nz-modal>

+ 108 - 19
web-app/src/app/routes/alert/alert-setting/alert-setting.component.ts

@@ -6,8 +6,14 @@ import {NzNotificationService} from "ng-zorro-antd/notification";
 import {NzMessageService} from "ng-zorro-antd/message";
 import {AlertDefineService} from "../../../service/alert-define.service";
 import {AlertDefine} from "../../../pojo/AlertDefine";
-import {finalize} from "rxjs/operators";
+import {finalize, map} from "rxjs/operators";
 import {AppDefineService} from "../../../service/app-define.service";
+import {TransferChange, TransferItem} from "ng-zorro-antd/transfer";
+import {zip} from "rxjs";
+import {MonitorService} from "../../../service/monitor.service";
+import {Message} from "../../../pojo/Message";
+import {AlertDefineBind} from "../../../pojo/AlertDefineBind";
+import {Monitor} from "../../../pojo/Monitor";
 
 @Component({
   selector: 'app-alert-setting',
@@ -23,6 +29,7 @@ export class AlertSettingComponent implements OnInit {
               private notifySvc: NzNotificationService,
               private msg: NzMessageService,
               private appDefineSvc: AppDefineService,
+              private monitorSvc: MonitorService,
               private alertDefineSvc: AlertDefineService) { }
 
   pageIndex: number = 1;
@@ -76,9 +83,9 @@ export class AlertSettingComponent implements OnInit {
 
   onNewAlertDefine() {
     this.define = new AlertDefine();
-    this.isModalAdd = true;
-    this.isModalVisible = true;
-    this.isModalOkLoading = false;
+    this.isManageModalAdd = true;
+    this.isManageModalVisible = true;
+    this.isManageModalOkLoading = false;
   }
 
   onEditOneAlertDefine(alertDefineId: number) {
@@ -105,9 +112,9 @@ export class AlertSettingComponent implements OnInit {
   }
 
   editAlertDefine(alertDefineId: number) {
-    this.isModalAdd = false;
-    this.isModalVisible = true;
-    this.isModalOkLoading = false;
+    this.isManageModalAdd = false;
+    this.isManageModalVisible = true;
+    this.isManageModalOkLoading = false;
     // 查询告警定义信息
     const getDefine$ = this.alertDefineSvc.getAlertDefine(alertDefineId)
       .pipe(finalize(() => {
@@ -207,28 +214,28 @@ export class AlertSettingComponent implements OnInit {
 
 
   // start 新增修改告警定义model
-  isModalVisible = false;
-  isModalOkLoading = false;
-  isModalAdd = true;
+  isManageModalVisible = false;
+  isManageModalOkLoading = false;
+  isManageModalAdd = true;
   define!: AlertDefine;
   cascadeValues: string[] = [];
-  onModalCancel() {
-    this.isModalVisible = false;
+  onManageModalCancel() {
+    this.isManageModalVisible = false;
   }
-  onModalOk() {
-    this.isModalOkLoading = true;
+  onManageModalOk() {
+    this.isManageModalOkLoading = true;
     this.define.app = this.cascadeValues[0];
     this.define.metric = this.cascadeValues[1];
     this.define.field = this.cascadeValues[2];
-    if (this.isModalAdd) {
+    if (this.isManageModalAdd) {
       const modalOk$ = this.alertDefineSvc.newAlertDefine(this.define)
         .pipe(finalize(() => {
           modalOk$.unsubscribe();
-          this.isModalOkLoading = false;
+          this.isManageModalOkLoading = false;
         }))
         .subscribe(message => {
           if (message.code === 0) {
-            this.isModalVisible = false;
+            this.isManageModalVisible = false;
             this.notifySvc.success("新增成功!", "");
             this.loadAlertDefineTable();
           } else {
@@ -241,11 +248,11 @@ export class AlertSettingComponent implements OnInit {
       const modalOk$ = this.alertDefineSvc.editAlertDefine(this.define)
         .pipe(finalize(() => {
           modalOk$.unsubscribe();
-          this.isModalOkLoading = false;
+          this.isManageModalOkLoading = false;
         }))
         .subscribe(message => {
           if (message.code === 0) {
-            this.isModalVisible = false;
+            this.isManageModalVisible = false;
             this.notifySvc.success("修改成功!", "");
             this.loadAlertDefineTable();
           } else {
@@ -256,4 +263,86 @@ export class AlertSettingComponent implements OnInit {
         })
     }
   }
+  // end 新增修改告警定义model
+
+  // start 告警定义与监控关联model
+  isConnectModalVisible = false;
+  isConnectModalOkLoading = false;
+  transferData: TransferItem[] = [];
+  currentAlertDefineId!: number;
+  $asTransferItems = (data: unknown): TransferItem[] => data as TransferItem[];
+  onOpenConnectModal(alertDefineId: number, app: string) {
+    this.isConnectModalVisible = true;
+    this.currentAlertDefineId = alertDefineId;
+    zip(this.alertDefineSvc.getAlertDefineMonitorsBind(alertDefineId), this.monitorSvc.getMonitorsByApp(app))
+      .pipe(
+        map(([defineBindData, monitorData]: [Message<AlertDefineBind[]>, Message<Monitor[]>]) => {
+          let bindRecode: Record<number, string> = {};
+          if (defineBindData.data != undefined) {
+            defineBindData.data.forEach(bind => {
+              bindRecode[bind.monitorId] = bind.monitorName;
+            })
+          }
+          let listTmp: any[] = [];
+          if (monitorData.data != undefined) {
+            monitorData.data.forEach(monitor => {
+              listTmp.push({
+                id: monitor.id,
+                name: monitor.name,
+                key: monitor.id,
+                direction: bindRecode[monitor.id] == undefined ? 'left' : 'right'
+              })
+            })
+          }
+          return listTmp;
+        })
+      ).subscribe(list => this.transferData = list);
+  }
+  onConnectModalCancel() {
+    this.isConnectModalVisible = false;
+  }
+  onConnectModalOk() {
+    this.isConnectModalOkLoading = true;
+    let defineBinds: AlertDefineBind[] = [];
+    this.transferData.forEach(item => {
+      if (item.direction == 'right') {
+        let bind = new AlertDefineBind();
+        bind.alertDefineId = this.currentAlertDefineId;
+        bind.monitorId = item.id;
+        bind.monitorName = item.name;
+        defineBinds.push(bind);
+      }
+    })
+    const applyBind$ = this.alertDefineSvc.applyAlertDefineMonitorsBind(this.currentAlertDefineId, defineBinds)
+      .pipe(finalize(() => {
+        applyBind$.unsubscribe();
+      }))
+      .subscribe(message => {
+        this.isConnectModalOkLoading = false;
+        if (message.code === 0) {
+          this.notifySvc.success("应用成功!", "");
+          this.isConnectModalVisible = false;
+          this.loadAlertDefineTable();
+        } else {
+          this.notifySvc.error("应用失败!", message.msg);
+        }
+      }, error => {
+        this.notifySvc.error("应用失败!", error.msg);
+      })
+  }
+  change(ret: TransferChange): void {
+    const listKeys = ret.list.map(l => l.key);
+    const hasOwnKey = (e: TransferItem): boolean => e.hasOwnProperty('key');
+    this.transferData = this.transferData.map(e => {
+      if (listKeys.includes(e.key) && hasOwnKey(e)) {
+        if (ret.to === 'left') {
+          delete e.hide;
+        } else if (ret.to === 'right') {
+          e.hide = false;
+        }
+      }
+      return e;
+    });
+  }
+  // end 告警定义与监控关联model
 }

+ 2 - 0
web-app/src/app/routes/alert/alert.module.ts

@@ -10,6 +10,7 @@ import {NzTagModule} from "ng-zorro-antd/tag";
 import {NzRadioModule} from "ng-zorro-antd/radio";
 import {NzSwitchModule} from "ng-zorro-antd/switch";
 import {NzCascaderModule} from "ng-zorro-antd/cascader";
+import {NzTransferModule} from "ng-zorro-antd/transfer";
 
 const COMPONENTS: Type<void>[] = [
   AlertCenterComponent,
@@ -27,6 +28,7 @@ const COMPONENTS: Type<void>[] = [
     NzRadioModule,
     NzSwitchModule,
     NzCascaderModule,
+    NzTransferModule,
   ],
   declarations: COMPONENTS,
 })

+ 7 - 7
web-app/src/app/service/alert-define.service.ts

@@ -4,6 +4,7 @@ import {Observable} from "rxjs";
 import {Message} from "../pojo/Message";
 import {Page} from "../pojo/Page";
 import {AlertDefine} from "../pojo/AlertDefine";
+import {AlertDefineBind} from "../pojo/AlertDefineBind";
 
 const alert_define_uri = "/alert/define";
 const alert_defines_uri = "/alert/defines";
@@ -27,14 +28,13 @@ export class AlertDefineService {
     return this.http.get<Message<AlertDefine>>(`${alert_define_uri}/${alertDefineId}`);
   }
 
-  /**
-   * 应用告警定义与监控关联
-   * @param alertDefineId 告警定义ID
-   * @param monitorMap 关联的监控ID-监控名称
-   */
   public applyAlertDefineMonitorsBind(alertDefineId: number,
-                                      monitorMap: Record<number, string>): Observable<Message<AlertDefine>> {
-    return this.http.post<Message<AlertDefine>>(`${alert_define_uri}/${alertDefineId}/monitors`, monitorMap);
+                                      binds: AlertDefineBind[]): Observable<Message<any>> {
+    return this.http.post<Message<any>>(`${alert_define_uri}/${alertDefineId}/monitors`, binds);
+  }
+
+  public getAlertDefineMonitorsBind(alertDefineId: number) : Observable<Message<AlertDefineBind[]>> {
+    return this.http.get<Message<AlertDefineBind[]>>(`${alert_define_uri}/${alertDefineId}/monitors`);
   }
 
   public deleteAlertDefines(alertDefineIds: Set<number>) : Observable<Message<any>> {

+ 4 - 0
web-app/src/app/service/monitor.service.ts

@@ -69,6 +69,10 @@ export class MonitorService {
     return this.http.get<Message<any>>(`${monitor_uri}/${monitorId}`);
   }
 
+  public getMonitorsByApp(app: string) : Observable<Message<Monitor[]>> {
+    return this.http.get<Message<Monitor[]>>(`${monitors_uri}/${app}`);
+  }
+
   public getMonitors(app: string, pageIndex: number, pageSize: number) : Observable<Message<Page<Monitor>>> {
     app = app.trim();
     pageIndex = pageIndex ? pageIndex : 0;