[alert,webapp] 告警中心条件查询与搜索支持,支持批量已读未读

This commit is contained in:
tomsun28
2021-12-19 21:49:19 +08:00
parent 9b2638c233
commit d7a7c11ed9
11 changed files with 238 additions and 13 deletions

View File

@@ -3,7 +3,9 @@ export class Alert {
target!: string;
monitorId!: number;
monitorName!: string;
// 告警级别 0:高-emergency-紧急告警-红色 1:中-critical-严重告警-橙色 2:低-warning-警告告警-黄色
priority: number = 2;
// 告警状态: 0-正常告警(未读) 3-已读已知
status!: number;
content!: string;
times!: number;

View File

@@ -13,13 +13,43 @@
</nz-breadcrumb>
<nz-divider></nz-divider>
<button nz-button nzType="primary" (click)="onDeleteAlerts()">
<i nz-icon nzType="delete" nzTheme="outline"></i>
删除告警
</button>
<button nz-button nzType="primary" (click)="sync()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i>
</button>
<div>
<button nz-button nzType="primary" (click)="onDeleteAlerts()">
<i nz-icon nzType="delete" nzTheme="outline"></i>
删除告警
</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>
</button>
<button style="margin-right: 25px;float: right;" nz-button nzType="primary" (click)="onFilterSearchAlerts()">
搜索
</button>
<input style="margin-right: 5px;float: right;width:150px;border-radius: 9px;text-align: center;" nz-input
type="text" placeholder="搜索告警内容" nzSize="default" [(ngModel)]="filterContent" />
<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-select>
<nz-select style="margin-right: 10px;float: right;width: 120px;" nzAllowClear
[nzPlaceHolder]="'告警级别过滤'" [(ngModel)]="filterPriority">
<nz-option nzLabel="全部级别" nzValue="9"></nz-option>
<nz-option nzLabel="警告级别" nzValue="2"></nz-option>
<nz-option nzLabel="严重级别" nzValue="1"></nz-option>
<nz-option nzLabel="紧急级别" nzValue="0"></nz-option>
</nz-select>
</div>
<nz-table #fixedTable [nzData]="alerts"
[nzPageIndex]="pageIndex" [nzPageSize]="pageSize" [nzTotal]="total"
@@ -37,12 +67,13 @@
<th nzAlign="center">所属监控</th>
<th nzAlign="center">级别</th>
<th nzAlign="center">告警内容</th>
<th nzAlign="center">状态</th>
<th nzAlign="center">告警时间</th>
<th nzAlign="center" nzRight>操作</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of fixedTable.data">
<tr *ngFor="let data of fixedTable.data" [ngStyle]="{'background-color':data.status === 0 ? '#E1E7A89B' : 'inherit' }">
<td nzAlign="center" nzLeft [nzChecked]="checkedAlertIds.has(data.id)" (nzCheckedChange)="onItemChecked(data.id, $event)"></td>
<td nzAlign="center">{{ data.target }}</td>
<td nzAlign="center">
@@ -65,11 +96,20 @@
</nz-tag>
</td>
<td nzAlign="center">{{ data.content }}</td>
<td nzAlign="center">
{{ 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="标记已读">
<i nz-icon nzType="down-circle" nzTheme="outline"></i>
</button>
<button nz-button nzType="primary" (click)="onMarkUnReadOneAlert(data.id)" nz-tooltip nzTooltipTitle="标记未读">
<i nz-icon nzType="up-circle" nzTheme="outline"></i>
</button>
</td>
</tr>
</tbody>

View File

@@ -23,11 +23,40 @@ export class AlertCenterComponent implements OnInit {
alerts!: Alert[];
tableLoading: boolean = false;
checkedAlertIds = new Set<number>();
// 搜索过滤相关属性
filterStatus: number | undefined;
filterPriority: number | undefined;
filterContent: string | undefined;
ngOnInit(): void {
this.loadAlertsTable();
}
onFilterSearchAlerts() {
this.tableLoading = true;
let filterAlerts$ = this.alertSvc.searchAlerts(this.filterStatus, this.filterPriority,
this.filterContent, this.pageIndex - 1, this.pageSize)
.subscribe(message => {
filterAlerts$.unsubscribe();
this.tableLoading = false;
this.checkedAll = false;
this.checkedAlertIds.clear();
if (message.code === 0) {
let page = message.data;
this.alerts = page.content;
this.pageIndex = page.number + 1;
this.total = page.totalElements;
} else {
console.warn(message.msg);
}
}, error => {
this.tableLoading = false;
filterAlerts$.unsubscribe();
console.error(error.msg);
});
}
sync() {
this.loadAlertsTable();
}
@@ -51,6 +80,7 @@ export class AlertCenterComponent implements OnInit {
}, error => {
this.tableLoading = false;
alertsInit$.unsubscribe();
console.error(error.msg);
});
}
@@ -69,6 +99,35 @@ export class AlertCenterComponent implements OnInit {
});
}
onMarkReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning("未选中任何待标记项!","");
return;
}
this.modal.confirm({
nzTitle: '请确认是否批量标记已读!',
nzOkText: '确定',
nzCancelText: '取消',
nzOkDanger: true,
nzOkType: "primary",
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3)
});
}
onMarkUnReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning("未选中任何待标记项!","");
return;
}
this.modal.confirm({
nzTitle: '请确认是否批量标记未读!',
nzOkText: '确定',
nzCancelText: '取消',
nzOkDanger: true,
nzOkType: "primary",
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0)
});
}
onDeleteOneAlert(alertId: number) {
let alerts = new Set<number>();
alerts.add(alertId);
@@ -82,6 +141,32 @@ export class AlertCenterComponent implements OnInit {
});
}
onMarkReadOneAlert(alertId: number) {
let alerts = new Set<number>();
alerts.add(alertId);
this.modal.confirm({
nzTitle: '请确认是否标记已读!',
nzOkText: '确定',
nzCancelText: '取消',
nzOkDanger: true,
nzOkType: "primary",
nzOnOk: () => this.updateAlertsStatus(alerts, 3)
});
}
onMarkUnReadOneAlert(alertId: number) {
let alerts = new Set<number>();
alerts.add(alertId);
this.modal.confirm({
nzTitle: '请确认是否标记未读!',
nzOkText: '确定',
nzCancelText: '取消',
nzOkDanger: true,
nzOkType: "primary",
nzOnOk: () => this.updateAlertsStatus(alerts, 0)
});
}
deleteAlerts(alertIds: Set<number>) {
this.tableLoading = true;
const deleteAlerts$ = this.alertSvc.deleteAlerts(alertIds)
@@ -103,6 +188,27 @@ export class AlertCenterComponent implements OnInit {
);
}
updateAlertsStatus(alertIds: Set<number>, status: number) {
this.tableLoading = true;
const markAlertsStatus$ = this.alertSvc.applyAlertsStatus(alertIds, status)
.subscribe(message => {
markAlertsStatus$.unsubscribe();
if (message.code === 0) {
this.notifySvc.success("标记成功!", "");
this.loadAlertsTable();
} else {
this.tableLoading = false;
this.notifySvc.error("标记失败!", message.msg);
}
},
error => {
this.tableLoading = false;
markAlertsStatus$.unsubscribe();
this.notifySvc.error("标记失败!", error.msg)
}
);
}
// begin: 列表多选分页逻辑
checkedAll: boolean = false;
onAllChecked(checked: boolean) {
@@ -126,6 +232,4 @@ export class AlertCenterComponent implements OnInit {
this.loadAlertsTable();
}
// end: 列表多选分页逻辑
}

View File

@@ -7,6 +7,8 @@ import {Alert} from "../pojo/Alert";
const alerts_uri = '/alerts';
const alerts_status_uri = '/alerts/status';
@Injectable({
providedIn: 'root'
})
@@ -29,6 +31,31 @@ export class AlertService {
return this.http.get<Message<Page<Alert>>>(alerts_uri, options);
}
public searchAlerts(status: number | undefined, priority: number | undefined, content: string | undefined,
pageIndex: number, pageSize: number) : Observable<Message<Page<Alert>>> {
pageIndex = pageIndex ? pageIndex : 0;
pageSize = pageSize ? pageSize : 8;
// 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象
let httpParams = new HttpParams();
httpParams = httpParams.appendAll({
'sort': 'id',
'order': 'desc',
'pageIndex': pageIndex,
'pageSize': pageSize
});
if (status != undefined && status != 9) {
httpParams = httpParams.append('status', status);
}
if (priority != undefined && priority != 9) {
httpParams = httpParams.append('priority', priority);
}
if (content != undefined && content != '' && content.trim() != '') {
httpParams = httpParams.append('content', content.trim());
}
const options = { params: httpParams };
return this.http.get<Message<Page<Alert>>>(alerts_uri, options);
}
public deleteAlerts(alertIds: Set<number>) : Observable<Message<any>> {
let httpParams = new HttpParams();
alertIds.forEach(alertId => {
@@ -40,4 +67,15 @@ export class AlertService {
return this.http.delete<Message<any>>(alerts_uri, options);
}
public applyAlertsStatus(alertIds: Set<number>, status: number) : Observable<Message<any>> {
let httpParams = new HttpParams();
alertIds.forEach(alertId => {
// 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象
// append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value
httpParams = httpParams.append('ids', alertId);
})
const options = { params: httpParams };
return this.http.put<Message<any>>(`${alerts_status_uri}/${status}`, null, options);
}
}