[webapp] 批量处理eslint格式告警

This commit is contained in:
tomsun28
2021-12-23 15:59:49 +08:00
parent a22548a06d
commit e846de5b20
72 changed files with 1724 additions and 2170 deletions

View File

@@ -19,7 +19,7 @@ const LANG = {
ng: ngLang, ng: ngLang,
zorro: zorroLang, zorro: zorroLang,
date: dateLang, date: dateLang,
delon: delonLang, delon: delonLang
}; };
// register angular // register angular
import { registerLocaleData } from '@angular/common'; import { registerLocaleData } from '@angular/common';
@@ -28,31 +28,28 @@ const LANG_PROVIDES = [
{ provide: LOCALE_ID, useValue: LANG.abbr }, { provide: LOCALE_ID, useValue: LANG.abbr },
{ provide: NZ_I18N, useValue: LANG.zorro }, { provide: NZ_I18N, useValue: LANG.zorro },
{ provide: NZ_DATE_LOCALE, useValue: LANG.date }, { provide: NZ_DATE_LOCALE, useValue: LANG.date },
{ provide: DELON_LOCALE, useValue: LANG.delon }, { provide: DELON_LOCALE, useValue: LANG.delon }
]; ];
// #endregion // #endregion
// #region i18n services // #region i18n services
import { ALAIN_I18N_TOKEN } from '@delon/theme'; import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { I18NService } from '@core'; import { I18NService } from '@core';
const I18NSERVICE_PROVIDES = [ const I18NSERVICE_PROVIDES = [{ provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false }];
{ provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false }
];
// #region // #region
// #region JSON Schema form (using @delon/form) // #region JSON Schema form (using @delon/form)
import { JsonSchemaModule } from '@shared'; import { JsonSchemaModule } from '@shared';
const FORM_MODULES = [ JsonSchemaModule ]; const FORM_MODULES = [JsonSchemaModule];
// #endregion // #endregion
// #region Http Interceptors // #region Http Interceptors
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { DefaultInterceptor } from '@core'; import { DefaultInterceptor } from '@core';
import { SimpleInterceptor } from '@delon/auth'; import { SimpleInterceptor } from '@delon/auth';
const INTERCEPTOR_PROVIDES = [ const INTERCEPTOR_PROVIDES = [
// { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true}, // { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true},
{ provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true} { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true }
]; ];
// #endregion // #endregion
@@ -87,9 +84,7 @@ import { ReactiveFormsModule } from '@angular/forms';
import { NgxEchartsModule } from 'ngx-echarts'; import { NgxEchartsModule } from 'ngx-echarts';
@NgModule({ @NgModule({
declarations: [ declarations: [AppComponent],
AppComponent
],
imports: [ imports: [
BrowserModule, BrowserModule,
BrowserAnimationsModule, BrowserAnimationsModule,
@@ -109,12 +104,7 @@ import { NgxEchartsModule } from 'ngx-echarts';
echarts: () => import('echarts') echarts: () => import('echarts')
}) })
], ],
providers: [ providers: [...LANG_PROVIDES, ...INTERCEPTOR_PROVIDES, ...I18NSERVICE_PROVIDES, ...APP_INIT_PROVIDES],
...LANG_PROVIDES,
...INTERCEPTOR_PROVIDES,
...I18NSERVICE_PROVIDES,
...APP_INIT_PROVIDES
],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule {}

View File

@@ -1,15 +1,13 @@
import { NgModule, Optional, SkipSelf } from '@angular/core'; import { NgModule, Optional, SkipSelf } from '@angular/core';
import { throwIfAlreadyLoaded } from './module-import-guard';
import { I18NService } from './i18n/i18n.service'; import { I18NService } from './i18n/i18n.service';
import { throwIfAlreadyLoaded } from './module-import-guard';
@NgModule({ @NgModule({
providers: [ providers: [I18NService]
I18NService
]
}) })
export class CoreModule { export class CoreModule {
constructor( @Optional() @SkipSelf() parentModule: CoreModule) { constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
throwIfAlreadyLoaded(parentModule, 'CoreModule'); throwIfAlreadyLoaded(parentModule, 'CoreModule');
} }
} }

View File

@@ -1,24 +1,24 @@
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree} from "@angular/router"; import { Injectable } from '@angular/core';
import {Observable} from "rxjs"; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import {Injectable} from "@angular/core"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {LocalStorageService} from "../../service/local-storage.service"; import { Observable } from 'rxjs';
import {NzNotificationService} from "ng-zorro-antd/notification";
import { LocalStorageService } from '../../service/local-storage.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class DetectAuthGuard implements CanActivate { export class DetectAuthGuard implements CanActivate {
constructor(private localStorageSvc: LocalStorageService, private notifySvc: NzNotificationService, private router: Router) {}
constructor(private localStorageSvc : LocalStorageService, canActivate(
private notifySvc: NzNotificationService, route: ActivatedRouteSnapshot,
private router: Router) { } state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
let activate = this.localStorageSvc.hasAuthorizationToken(); let activate = this.localStorageSvc.hasAuthorizationToken();
if (!activate) { if (!activate) {
setTimeout(() => { setTimeout(() => {
this.notifySvc.warning('请先登陆!','') this.notifySvc.warning('请先登陆!', '');
this.router.navigateByUrl('/passport/login'); this.router.navigateByUrl('/passport/login');
}); });
} }

View File

@@ -1,10 +1,10 @@
// 请参考https://ng-alain.com/docs/i18n // 请参考https://ng-alain.com/docs/i18n
import {Platform} from '@angular/cdk/platform'; import { Platform } from '@angular/cdk/platform';
import {registerLocaleData} from '@angular/common'; import { registerLocaleData } from '@angular/common';
import ngEn from '@angular/common/locales/en'; import ngEn from '@angular/common/locales/en';
import ngZh from '@angular/common/locales/zh'; import ngZh from '@angular/common/locales/zh';
import ngZhTw from '@angular/common/locales/zh-Hant'; import ngZhTw from '@angular/common/locales/zh-Hant';
import {Injectable} from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
_HttpClient, _HttpClient,
AlainI18nBaseService, AlainI18nBaseService,
@@ -14,13 +14,14 @@ import {
zh_CN as delonZhCn, zh_CN as delonZhCn,
zh_TW as delonZhTw zh_TW as delonZhTw
} from '@delon/theme'; } from '@delon/theme';
import {AlainConfigService} from '@delon/util/config'; import { AlainConfigService } from '@delon/util/config';
import {enUS as dfEn, zhCN as dfZhCn, zhTW as dfZhTw} from 'date-fns/locale'; import { enUS as dfEn, zhCN as dfZhCn, zhTW as dfZhTw } from 'date-fns/locale';
import {NzSafeAny} from 'ng-zorro-antd/core/types'; import { NzSafeAny } from 'ng-zorro-antd/core/types';
import {en_US as zorroEnUS, NzI18nService, zh_CN as zorroZhCN, zh_TW as zorroZhTW} from 'ng-zorro-antd/i18n'; import { en_US as zorroEnUS, NzI18nService, zh_CN as zorroZhCN, zh_TW as zorroZhTW } from 'ng-zorro-antd/i18n';
import {Observable, zip} from 'rxjs'; import { Observable, zip } from 'rxjs';
import {map} from "rxjs/operators"; import { map } from 'rxjs/operators';
import {Message} from "../../pojo/Message";
import { Message } from '../../pojo/Message';
interface LangConfigData { interface LangConfigData {
abbr: string; abbr: string;
@@ -94,16 +95,15 @@ export class I18NService extends AlainI18nBaseService {
} }
loadLangData(lang: string): Observable<NzSafeAny> { loadLangData(lang: string): Observable<NzSafeAny> {
return zip(this.http.get(`http://localhost:4200/assets/tmp/i18n/${lang}.json`),this.http.get(`/i18n/${lang}`)) return zip(this.http.get(`./assets/i18n/${lang}.json`), this.http.get(`/i18n/${lang}`)).pipe(
.pipe(
map(([langLocalData, langRemoteData]: [Record<string, string>, Message<any>]) => { map(([langLocalData, langRemoteData]: [Record<string, string>, Message<any>]) => {
let remote:Record<string, string> = langRemoteData.data; let remote: Record<string, string> = langRemoteData.data;
Object.keys(remote).forEach(key => { Object.keys(remote).forEach(key => {
langLocalData[key] = remote[key]; langLocalData[key] = remote[key];
}); });
return langLocalData; return langLocalData;
}) })
) );
} }
use(lang: string, data: Record<string, unknown>): void { use(lang: string, data: Record<string, unknown>): void {

View File

@@ -4,7 +4,8 @@ import {
HttpHandler, HttpHandler,
HttpHeaders, HttpHeaders,
HttpInterceptor, HttpInterceptor,
HttpRequest, HttpResponse, HttpRequest,
HttpResponse,
HttpResponseBase HttpResponseBase
} from '@angular/common/http'; } from '@angular/common/http';
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
@@ -14,7 +15,8 @@ import { environment } from '@env/environment';
import { NzNotificationService } from 'ng-zorro-antd/notification'; import { NzNotificationService } from 'ng-zorro-antd/notification';
import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { catchError, filter, mergeMap, switchMap, take } from 'rxjs/operators'; import { catchError, filter, mergeMap, switchMap, take } from 'rxjs/operators';
import {LocalStorageService} from "../../service/local-storage.service";
import { LocalStorageService } from '../../service/local-storage.service';
const CODE_MESSAGE: { [key: number]: string } = { const CODE_MESSAGE: { [key: number]: string } = {
200: '服务器成功返回请求的数据。', 200: '服务器成功返回请求的数据。',
@@ -44,7 +46,7 @@ export class DefaultInterceptor implements HttpInterceptor {
private refreshToking = false; private refreshToking = false;
private refreshToken$: BehaviorSubject<any> = new BehaviorSubject<any>(null); private refreshToken$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(private injector: Injector, private storageSvc: LocalStorageService) { } constructor(private injector: Injector, private storageSvc: LocalStorageService) {}
private get notification(): NzNotificationService { private get notification(): NzNotificationService {
return this.injector.get(NzNotificationService); return this.injector.get(NzNotificationService);
@@ -71,8 +73,7 @@ export class DefaultInterceptor implements HttpInterceptor {
*/ */
private refreshTokenRequest(): Observable<any> { private refreshTokenRequest(): Observable<any> {
const refreshToken = this.storageSvc.getRefreshToken(); const refreshToken = this.storageSvc.getRefreshToken();
return this.http.post(`/account/auth/refresh`, null, null, return this.http.post(`/account/auth/refresh`, null, null, { headers: { Authorization: `Bearer ${refreshToken}` } });
{ headers: { Authorization: `Bearer ${refreshToken}` }});
} }
// #region 刷新Token方式一使用 401 重新刷新 Token // #region 刷新Token方式一使用 401 重新刷新 Token
@@ -124,12 +125,11 @@ export class DefaultInterceptor implements HttpInterceptor {
let token = this.storageSvc.getAuthorizationToken(); let token = this.storageSvc.getAuthorizationToken();
return req.clone({ return req.clone({
setHeaders: { setHeaders: {
'Authorization': `Bearer ${token}` Authorization: `Bearer ${token}`
} }
}); });
} }
private toLogin(): void { private toLogin(): void {
this.notification.error(`未登录或登录已过期,请重新登录。`, ``); this.notification.error(`未登录或登录已过期,请重新登录。`, ``);
this.goTo('/passport/login'); this.goTo('/passport/login');
@@ -150,14 +150,13 @@ export class DefaultInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let url = req.url; let url = req.url;
if (!url.startsWith('https://') && !url.startsWith('http://')) { if (!url.startsWith('https://') && !url.startsWith('http://') && !url.startsWith('.')) {
const { baseUrl } = environment.api; const { baseUrl } = environment.api;
url = baseUrl + (baseUrl.endsWith('/') && url.startsWith('/') ? url.substring(1) : url); url = baseUrl + (baseUrl.endsWith('/') && url.startsWith('/') ? url.substring(1) : url);
} }
const newReq = req.clone({ url, setHeaders: this.fillHeaders(req.headers) }); const newReq = req.clone({ url, setHeaders: this.fillHeaders(req.headers) });
return next.handle(newReq).pipe( return next.handle(newReq).pipe(
mergeMap(httpEvent => { mergeMap(httpEvent => {
if (httpEvent instanceof HttpResponseBase) { if (httpEvent instanceof HttpResponseBase) {
// todo 处理成功状态响应 // todo 处理成功状态响应
@@ -192,7 +191,7 @@ export class DefaultInterceptor implements HttpInterceptor {
break; break;
} }
this.checkStatus(err); this.checkStatus(err);
console.warn(`${err.status} == ${err.message}`) console.warn(`${err.status} == ${err.message}`);
return throwError(err); return throwError(err);
}) })
); );

View File

@@ -1,17 +1,17 @@
import { HttpClient } from '@angular/common/http';
import { Injectable, Inject } from '@angular/core'; import { Injectable, Inject } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http'; import { ACLService } from '@delon/acl';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { ALAIN_I18N_TOKEN, MenuService, SettingsService, TitleService } from '@delon/theme'; import { ALAIN_I18N_TOKEN, MenuService, SettingsService, TitleService } from '@delon/theme';
import { ACLService } from '@delon/acl';
import { I18NService } from '../i18n/i18n.service';
import { Observable, zip, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import type { NzSafeAny } from 'ng-zorro-antd/core/types'; import type { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzIconService } from 'ng-zorro-antd/icon'; import { NzIconService } from 'ng-zorro-antd/icon';
import { Observable, zip, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ICONS } from '../../../style-icons'; import { ICONS } from '../../../style-icons';
import { ICONS_AUTO } from '../../../style-icons-auto'; import { ICONS_AUTO } from '../../../style-icons-auto';
import { I18NService } from '../i18n/i18n.service';
/** /**
* Used for application startup * Used for application startup
* Generally used to get the basic data of the application, like: Menu Data, User Data, etc. * Generally used to get the basic data of the application, like: Menu Data, User Data, etc.
@@ -32,10 +32,9 @@ export class StartupService {
iconSrv.addIcon(...ICONS_AUTO, ...ICONS); iconSrv.addIcon(...ICONS_AUTO, ...ICONS);
} }
private viaHttp(): Observable<void> { private viaHttp(): Observable<void> {
const defaultLang = this.i18n.defaultLang; const defaultLang = this.i18n.defaultLang;
return zip(this.i18n.loadLangData(defaultLang), this.httpClient.get('http://localhost:4200/assets/tmp/app-data.json')).pipe( return zip(this.i18n.loadLangData(defaultLang), this.httpClient.get('./assets/app-data.json')).pipe(
catchError((res: NzSafeAny) => { catchError((res: NzSafeAny) => {
console.warn(`StartupService.load: Network request failed`, res); console.warn(`StartupService.load: Network request failed`, res);
setTimeout(() => this.router.navigateByUrl(`/exception/500`)); setTimeout(() => this.router.navigateByUrl(`/exception/500`));
@@ -60,19 +59,6 @@ export class StartupService {
); );
} }
private viaMockI18n(): Observable<void> {
const defaultLang = this.i18n.defaultLang;
return this.i18n.loadLangData(defaultLang).pipe(
map((langData: NzSafeAny) => {
this.i18n.use(defaultLang, langData);
this.viaMock();
})
);
}
private viaMock(): Observable<void> { private viaMock(): Observable<void> {
// const tokenData = this.tokenService.get(); // const tokenData = this.tokenService.get();
// if (!tokenData.token) { // if (!tokenData.token) {

View File

@@ -1,21 +1,12 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { MenuFoldOutline, MenuUnfoldOutline, FormOutline, DashboardOutline } from '@ant-design/icons-angular/icons';
import { NZ_ICONS, NzIconModule } from 'ng-zorro-antd/icon'; import { NZ_ICONS, NzIconModule } from 'ng-zorro-antd/icon';
import {
MenuFoldOutline,
MenuUnfoldOutline,
FormOutline,
DashboardOutline
} from '@ant-design/icons-angular/icons';
const icons = [MenuFoldOutline, MenuUnfoldOutline, DashboardOutline, FormOutline]; const icons = [MenuFoldOutline, MenuUnfoldOutline, DashboardOutline, FormOutline];
@NgModule({ @NgModule({
imports: [NzIconModule], imports: [NzIconModule],
exports: [NzIconModule], exports: [NzIconModule],
providers: [ providers: [{ provide: NZ_ICONS, useValue: icons }]
{ provide: NZ_ICONS, useValue: icons }
]
}) })
export class IconsProviderModule { export class IconsProviderModule {}
}

View File

@@ -50,19 +50,13 @@ import { environment } from '@env/environment';
<header-user></header-user> <header-user></header-user>
</layout-default-header-item> </layout-default-header-item>
<ng-template #asideUserTpl> <ng-template #asideUserTpl>
<div nz-dropdown nzTrigger="click" [nzDropdownMenu]="userMenu" class="alain-default__aside-user"> <div nz-dropdown nzTrigger="click" class="alain-default__aside-user">
<nz-avatar class="alain-default__aside-user-avatar" [nzSrc]="user.avatar"></nz-avatar> <nz-avatar class="alain-default__aside-user-avatar" [nzSrc]="avatar"></nz-avatar>
<div class="alain-default__aside-user-info"> <div class="alain-default__aside-user-info">
<strong>{{ user.name }}</strong> <strong>{{ user.name }}</strong>
<p class="mb0">{{ user.email }}</p> <p class="mb0">{{ user.email }}</p>
</div> </div>
</div> </div>
<nz-dropdown-menu #userMenu="nzDropdownMenu">
<ul nz-menu>
<li nz-menu-item routerLink="/pro/account/center">{{ 'menu.account.center' | i18n }}</li>
<li nz-menu-item routerLink="/pro/account/settings">{{ 'menu.account.settings' | i18n }}</li>
</ul>
</nz-dropdown-menu>
</ng-template> </ng-template>
<ng-template #contentTpl> <ng-template #contentTpl>
<router-outlet></router-outlet> <router-outlet></router-outlet>
@@ -71,13 +65,14 @@ import { environment } from '@env/environment';
<setting-drawer *ngIf="showSettingDrawer"></setting-drawer> <setting-drawer *ngIf="showSettingDrawer"></setting-drawer>
<theme-btn></theme-btn> <theme-btn></theme-btn>
`, `
}) })
export class LayoutBasicComponent { export class LayoutBasicComponent {
options: LayoutDefaultOptions = { options: LayoutDefaultOptions = {
logoExpanded: `./assets/brand_white.svg`, logoExpanded: `./assets/brand_white.svg`,
logoCollapsed: `./assets/logo.svg`, logoCollapsed: `./assets/logo.svg`
}; };
avatar: string = `./assets/logo.svg`;
searchToggleStatus = false; searchToggleStatus = false;
showSettingDrawer = !environment.production; showSettingDrawer = !environment.production;
get user(): User { get user(): User {

View File

@@ -1,11 +1,12 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit} from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
import {NoticeIconSelect, NoticeItem } from '@delon/abc/notice-icon'; import { Router } from '@angular/router';
import { I18NService } from '@core';
import { NoticeIconSelect, NoticeItem } from '@delon/abc/notice-icon';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { NzI18nService } from 'ng-zorro-antd/i18n'; import { NzI18nService } from 'ng-zorro-antd/i18n';
import { NzMessageService } from 'ng-zorro-antd/message'; import { NzMessageService } from 'ng-zorro-antd/message';
import {AlertService} from "../../../service/alert.service";
import {ALAIN_I18N_TOKEN} from "@delon/theme"; import { AlertService } from '../../../service/alert.service';
import {I18NService} from "@core";
import {Router} from "@angular/router";
@Component({ @Component({
selector: 'header-notify', selector: 'header-notify',
@@ -22,8 +23,7 @@ import {Router} from "@angular/router";
`, `,
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class HeaderNotifyComponent implements OnInit{ export class HeaderNotifyComponent implements OnInit {
data: NoticeItem[] = [ data: NoticeItem[] = [
{ {
title: '近期未处理告警', title: '近期未处理告警',
@@ -36,12 +36,14 @@ export class HeaderNotifyComponent implements OnInit{
count = 0; count = 0;
loading = false; loading = false;
constructor(private msg: NzMessageService, constructor(
private msg: NzMessageService,
private nzI18n: NzI18nService, private nzI18n: NzI18nService,
private router: Router, private router: Router,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService,
private alertSvc: AlertService, private alertSvc: AlertService,
private cdr: ChangeDetectorRef) {} private cdr: ChangeDetectorRef
) {}
ngOnInit(): void { ngOnInit(): void {
this.loadData(); this.loadData();
@@ -52,8 +54,8 @@ export class HeaderNotifyComponent implements OnInit{
return; return;
} }
this.loading = true; this.loading = true;
let loadAlerts$ = this.alertSvc.searchAlerts(0, undefined,undefined, 0, 5) let loadAlerts$ = this.alertSvc.searchAlerts(0, undefined, undefined, 0, 5).subscribe(
.subscribe(message => { message => {
loadAlerts$.unsubscribe(); loadAlerts$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
let page = message.data; let page = message.data;
@@ -63,24 +65,26 @@ export class HeaderNotifyComponent implements OnInit{
let item = { let item = {
id: alert.id, id: alert.id,
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
title: '监控-' + alert.monitorName +'-发出' + this.i18nSvc.fanyi(`alert.priority.${alert.priority}`), title: `监控-${alert.monitorName}-发出${this.i18nSvc.fanyi(`alert.priority.${alert.priority}`)}`,
datetime: alert.gmtCreate, datetime: alert.gmtCreate,
color: 'blue', color: 'blue',
type: '近期未处理告警' type: '近期未处理告警'
} };
this.data[0].list.push(item); this.data[0].list.push(item);
}) });
this.count = page.totalElements; this.count = page.totalElements;
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
this.loading = false; this.loading = false;
this.cdr.detectChanges(); this.cdr.detectChanges();
}, error => { },
error => {
loadAlerts$.unsubscribe(); loadAlerts$.unsubscribe();
console.error(error.msg); console.error(error.msg);
this.loading = false; this.loading = false;
}) }
);
} }
gotoAlertCenter(type: string): void { gotoAlertCenter(type: string): void {

View File

@@ -12,8 +12,9 @@ import {
} from '@angular/core'; } from '@angular/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
import {MonitorService} from "../../../service/monitor.service";
import {Monitor} from "../../../pojo/Monitor"; import { Monitor } from '../../../pojo/Monitor';
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'header-search', selector: 'header-search',
@@ -40,7 +41,7 @@ import {Monitor} from "../../../pojo/Monitor";
<nz-auto-option *ngFor="let option of options" [nzValue]="option.id" [nzLabel]="option.name"> <nz-auto-option *ngFor="let option of options" [nzValue]="option.id" [nzLabel]="option.name">
<a [routerLink]="['/monitors/' + option.id]"> <a [routerLink]="['/monitors/' + option.id]">
监控名称: {{ option.name }} 监控名称: {{ option.name }}
<span style="left:50% ; position: absolute;">监控Host: {{option.host}}</span> <span style="left:50% ; position: absolute;">监控Host: {{ option.host }}</span>
<span style="right: 10px; position: absolute;"><i nz-icon nzType="arrow-right" nzTheme="outline"></i></span> <span style="right: 10px; position: absolute;"><i nz-icon nzType="arrow-right" nzTheme="outline"></i></span>
</a> </a>
</nz-auto-option> </nz-auto-option>
@@ -73,9 +74,7 @@ export class HeaderSearchComponent implements AfterViewInit, OnDestroy {
} }
@Output() readonly toggleChangeChange = new EventEmitter<boolean>(); @Output() readonly toggleChangeChange = new EventEmitter<boolean>();
constructor(private el: ElementRef<HTMLElement>, constructor(private el: ElementRef<HTMLElement>, private cdr: ChangeDetectorRef, private monitorSvc: MonitorService) {}
private cdr: ChangeDetectorRef,
private monitorSvc : MonitorService) {}
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.qIpt = this.el.nativeElement.querySelector('.ant-input') as HTMLInputElement; this.qIpt = this.el.nativeElement.querySelector('.ant-input') as HTMLInputElement;
@@ -91,8 +90,8 @@ export class HeaderSearchComponent implements AfterViewInit, OnDestroy {
) )
.subscribe(value => { .subscribe(value => {
// 远程加载搜索数据 // 远程加载搜索数据
let searchMonitors$ = this.monitorSvc.searchMonitors(value, value, 0, 10) let searchMonitors$ = this.monitorSvc.searchMonitors(value, value, 0, 10).subscribe(
.subscribe(message => { message => {
this.loading = false; this.loading = false;
searchMonitors$.unsubscribe(); searchMonitors$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
@@ -102,11 +101,13 @@ export class HeaderSearchComponent implements AfterViewInit, OnDestroy {
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
}, error => { },
error => {
this.loading = false; this.loading = false;
searchMonitors$.unsubscribe(); searchMonitors$.unsubscribe();
console.error(error.msg); console.error(error.msg);
}) }
);
}); });
} }

View File

@@ -1,7 +1,8 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'; import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { SettingsService, User } from '@delon/theme'; import { SettingsService, User } from '@delon/theme';
import {LocalStorageService} from "../../../service/local-storage.service";
import { LocalStorageService } from '../../../service/local-storage.service';
@Component({ @Component({
selector: 'header-user', selector: 'header-user',
@@ -12,14 +13,6 @@ import {LocalStorageService} from "../../../service/local-storage.service";
</div> </div>
<nz-dropdown-menu #userMenu="nzDropdownMenu"> <nz-dropdown-menu #userMenu="nzDropdownMenu">
<div nz-menu class="width-sm"> <div nz-menu class="width-sm">
<div nz-menu-item routerLink="/pro/account/center">
<i nz-icon nzType="user" class="mr-sm"></i>
{{ 'menu.account.center' | i18n }}
</div>
<div nz-menu-item routerLink="/pro/account/settings">
<i nz-icon nzType="setting" class="mr-sm"></i>
{{ 'menu.account.settings' | i18n }}
</div>
<li nz-menu-divider></li> <li nz-menu-divider></li>
<div nz-menu-item (click)="logout()"> <div nz-menu-item (click)="logout()">
<i nz-icon nzType="logout" class="mr-sm"></i> <i nz-icon nzType="logout" class="mr-sm"></i>
@@ -35,9 +28,7 @@ export class HeaderUserComponent {
return this.settings.user; return this.settings.user;
} }
constructor(private settings: SettingsService, constructor(private settings: SettingsService, private router: Router, private localStorageSvc: LocalStorageService) {}
private router: Router,
private localStorageSvc : LocalStorageService) {}
logout(): void { logout(): void {
this.localStorageSvc.clear(); this.localStorageSvc.clear();

View File

@@ -25,7 +25,7 @@ import { HeaderFullScreenComponent } from './basic/widgets/fullscreen.component'
import { HeaderI18nComponent } from './basic/widgets/i18n.component'; import { HeaderI18nComponent } from './basic/widgets/i18n.component';
import { HeaderSearchComponent } from './basic/widgets/search.component'; import { HeaderSearchComponent } from './basic/widgets/search.component';
import { HeaderUserComponent } from './basic/widgets/user.component'; import { HeaderUserComponent } from './basic/widgets/user.component';
import {HeaderNotifyComponent} from "./basic/widgets/notify.component"; import { HeaderNotifyComponent } from './basic/widgets/notify.component';
import { LayoutBlankComponent } from './blank/blank.component'; import { LayoutBlankComponent } from './blank/blank.component';
const COMPONENTS = [LayoutBasicComponent, LayoutBlankComponent]; const COMPONENTS = [LayoutBasicComponent, LayoutBlankComponent];
@@ -41,9 +41,7 @@ const HEADER_COMPONENTS = [
// passport // passport
import { LayoutPassportComponent } from './passport/passport.component'; import { LayoutPassportComponent } from './passport/passport.component';
const PASSPORT = [ const PASSPORT = [LayoutPassportComponent];
LayoutPassportComponent
];
@NgModule({ @NgModule({
imports: [ imports: [
@@ -64,9 +62,9 @@ const PASSPORT = [
NzSpinModule, NzSpinModule,
NzBadgeModule, NzBadgeModule,
NzAvatarModule, NzAvatarModule,
NzIconModule, NzIconModule
], ],
declarations: [...COMPONENTS, ...HEADER_COMPONENTS, ...PASSPORT], declarations: [...COMPONENTS, ...HEADER_COMPONENTS, ...PASSPORT],
exports: [...COMPONENTS, ...PASSPORT], exports: [...COMPONENTS, ...PASSPORT]
}) })
export class LayoutModule { } export class LayoutModule {}

View File

@@ -3,7 +3,7 @@
<div class="wrap"> <div class="wrap">
<div class="top"> <div class="top">
<div class="head"> <div class="head">
<img class="logo" src="./assets/logo.svg" alt=""> <img class="logo" src="./assets/logo.svg" alt="" />
<span class="title">探云</span> <span class="title">探云</span>
</div> </div>
<div class="desc">易用友好的高性能监控云服务</div> <div class="desc">易用友好的高性能监控云服务</div>

View File

@@ -9,16 +9,8 @@ import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
export class LayoutPassportComponent implements OnInit { export class LayoutPassportComponent implements OnInit {
links = [ links = [
{ {
title: '帮助', title: '欢迎使用TanCloud探云-监控云服务-tancloud.cn',
href: '' href: 'https://tancloud.cn'
},
{
title: '隐私',
href: ''
},
{
title: '条款',
href: ''
} }
]; ];

View File

@@ -1,4 +1,3 @@
export class Page<T> { export class Page<T> {
content!: T[]; content!: T[];
// 集合总页数 // 集合总页数

View File

@@ -30,36 +30,53 @@
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<button style="margin-right: 25px;float: right;" nz-button nzType="primary" (click)="onFilterSearchAlerts()"> <button style="margin-right: 25px; float: right" nz-button nzType="primary" (click)="onFilterSearchAlerts()"> 搜索 </button>
搜索 <input
</button> style="margin-right: 5px; float: right; width: 150px; border-radius: 9px; text-align: center"
<input style="margin-right: 5px;float: right;width:150px;border-radius: 9px;text-align: center;" nz-input nz-input
type="text" placeholder="搜索告警内容" nzSize="default" [(ngModel)]="filterContent" /> type="text"
<nz-select style="margin-right: 10px;float: right;width: 120px;" nzAllowClear placeholder="搜索告警内容"
[nzPlaceHolder]="'告警状态过滤'" [(ngModel)]="filterStatus"> 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="9"></nz-option>
<nz-option nzLabel="未处理" nzValue="0"></nz-option> <nz-option nzLabel="未处理" nzValue="0"></nz-option>
<nz-option nzLabel="已处理" nzValue="3"></nz-option> <nz-option nzLabel="已处理" nzValue="3"></nz-option>
</nz-select> </nz-select>
<nz-select style="margin-right: 10px;float: right;width: 120px;" nzAllowClear <nz-select
[nzPlaceHolder]="'告警级别过滤'" [(ngModel)]="filterPriority"> style="margin-right: 10px; float: right; width: 120px"
nzAllowClear
[nzPlaceHolder]="'告警级别过滤'"
[(ngModel)]="filterPriority"
>
<nz-option nzLabel="全部级别" nzValue="9"></nz-option> <nz-option nzLabel="全部级别" nzValue="9"></nz-option>
<nz-option nzLabel="警告级别" nzValue="2"></nz-option> <nz-option nzLabel="警告级别" nzValue="2"></nz-option>
<nz-option nzLabel="严重级别" nzValue="1"></nz-option> <nz-option nzLabel="严重级别" nzValue="1"></nz-option>
<nz-option nzLabel="紧急级别" nzValue="0"></nz-option> <nz-option nzLabel="紧急级别" nzValue="0"></nz-option>
</nz-select> </nz-select>
</div> </div>
<nz-table #fixedTable [nzData]="alerts" <nz-table
[nzPageIndex]="pageIndex" [nzPageSize]="pageSize" [nzTotal]="total" #fixedTable
nzFrontPagination ="false" [nzData]="alerts"
[nzLoading] = "tableLoading" [nzPageIndex]="pageIndex"
[nzPageSize]="pageSize"
[nzTotal]="total"
nzFrontPagination="false"
[nzLoading]="tableLoading"
nzShowSizeChanger nzShowSizeChanger
[nzShowTotal]="rangeTemplate" [nzShowTotal]="rangeTemplate"
[nzPageSizeOptions]="[8,15,25]" [nzPageSizeOptions]="[8, 15, 25]"
(nzQueryParams)="onTablePageChange($event)" (nzQueryParams)="onTablePageChange($event)"
nzShowPagination = "true" [nzScroll]="{ x: '1150px', y: '1240px' }"> nzShowPagination="true"
[nzScroll]="{ x: '1150px', y: '1240px' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="60px" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="60px" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
@@ -73,7 +90,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let data of fixedTable.data" [ngStyle]="{'background-color':data.status === 0 ? '#E1E7A89B' : 'inherit' }"> <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" nzLeft [nzChecked]="checkedAlertIds.has(data.id)" (nzCheckedChange)="onItemChecked(data.id, $event)"></td>
<td nzAlign="center">{{ data.target }}</td> <td nzAlign="center">{{ data.target }}</td>
<td nzAlign="center"> <td nzAlign="center">
@@ -115,6 +132,4 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>
总量 {{ total }}
</ng-template>

View File

@@ -8,9 +8,8 @@ describe('AlertCenterComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ AlertCenterComponent ] declarations: [AlertCenterComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,21 +1,18 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {NzTableQueryParams} from "ng-zorro-antd/table"; import { NzModalService } from 'ng-zorro-antd/modal';
import {Alert} from "../../../pojo/Alert"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {NzNotificationService} from "ng-zorro-antd/notification"; import { NzTableQueryParams } from 'ng-zorro-antd/table';
import {AlertService} from "../../../service/alert.service";
import {NzModalService} from "ng-zorro-antd/modal"; import { Alert } from '../../../pojo/Alert';
import { AlertService } from '../../../service/alert.service';
@Component({ @Component({
selector: 'app-alert-center', selector: 'app-alert-center',
templateUrl: './alert-center.component.html', templateUrl: './alert-center.component.html',
styles: [ styles: []
]
}) })
export class AlertCenterComponent implements OnInit { export class AlertCenterComponent implements OnInit {
constructor(private notifySvc: NzNotificationService, private modal: NzModalService, private alertSvc: AlertService) {}
constructor(private notifySvc: NzNotificationService,
private modal: NzModalService,
private alertSvc: AlertService) { }
pageIndex: number = 1; pageIndex: number = 1;
pageSize: number = 8; pageSize: number = 8;
@@ -34,9 +31,10 @@ export class AlertCenterComponent implements OnInit {
onFilterSearchAlerts() { onFilterSearchAlerts() {
this.tableLoading = true; this.tableLoading = true;
let filterAlerts$ = this.alertSvc.searchAlerts(this.filterStatus, this.filterPriority, let filterAlerts$ = this.alertSvc
this.filterContent, this.pageIndex - 1, this.pageSize) .searchAlerts(this.filterStatus, this.filterPriority, this.filterContent, this.pageIndex - 1, this.pageSize)
.subscribe(message => { .subscribe(
message => {
filterAlerts$.unsubscribe(); filterAlerts$.unsubscribe();
this.tableLoading = false; this.tableLoading = false;
this.checkedAll = false; this.checkedAll = false;
@@ -49,12 +47,13 @@ export class AlertCenterComponent implements OnInit {
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
}, error => { },
error => {
this.tableLoading = false; this.tableLoading = false;
filterAlerts$.unsubscribe(); filterAlerts$.unsubscribe();
console.error(error.msg); console.error(error.msg);
}); }
);
} }
sync() { sync() {
@@ -63,8 +62,8 @@ export class AlertCenterComponent implements OnInit {
loadAlertsTable() { loadAlertsTable() {
this.tableLoading = true; this.tableLoading = true;
let alertsInit$ = this.alertSvc.getAlerts(this.pageIndex - 1, this.pageSize) let alertsInit$ = this.alertSvc.getAlerts(this.pageIndex - 1, this.pageSize).subscribe(
.subscribe(message => { message => {
this.tableLoading = false; this.tableLoading = false;
this.checkedAll = false; this.checkedAll = false;
this.checkedAlertIds.clear(); this.checkedAlertIds.clear();
@@ -77,16 +76,18 @@ export class AlertCenterComponent implements OnInit {
console.warn(message.msg); console.warn(message.msg);
} }
alertsInit$.unsubscribe(); alertsInit$.unsubscribe();
}, error => { },
error => {
this.tableLoading = false; this.tableLoading = false;
alertsInit$.unsubscribe(); alertsInit$.unsubscribe();
console.error(error.msg); console.error(error.msg);
}); }
);
} }
onDeleteAlerts() { onDeleteAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning("未选中任何待删除项!",""); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -94,14 +95,14 @@ export class AlertCenterComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteAlerts(this.checkedAlertIds) nzOnOk: () => this.deleteAlerts(this.checkedAlertIds)
}); });
} }
onMarkReadAlerts() { onMarkReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning("未选中任何待标记项!",""); this.notifySvc.warning('未选中任何待标记项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -109,13 +110,13 @@ export class AlertCenterComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3) nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 3)
}); });
} }
onMarkUnReadAlerts() { onMarkUnReadAlerts() {
if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) { if (this.checkedAlertIds == null || this.checkedAlertIds.size === 0) {
this.notifySvc.warning("未选中任何待标记项!",""); this.notifySvc.warning('未选中任何待标记项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -123,7 +124,7 @@ export class AlertCenterComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0) nzOnOk: () => this.updateAlertsStatus(this.checkedAlertIds, 0)
}); });
} }
@@ -136,7 +137,7 @@ export class AlertCenterComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteAlerts(alerts) nzOnOk: () => this.deleteAlerts(alerts)
}); });
} }
@@ -149,7 +150,7 @@ export class AlertCenterComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(alerts, 3) nzOnOk: () => this.updateAlertsStatus(alerts, 3)
}); });
} }
@@ -162,49 +163,49 @@ export class AlertCenterComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.updateAlertsStatus(alerts, 0) nzOnOk: () => this.updateAlertsStatus(alerts, 0)
}); });
} }
deleteAlerts(alertIds: Set<number>) { deleteAlerts(alertIds: Set<number>) {
this.tableLoading = true; this.tableLoading = true;
const deleteAlerts$ = this.alertSvc.deleteAlerts(alertIds) const deleteAlerts$ = this.alertSvc.deleteAlerts(alertIds).subscribe(
.subscribe(message => { message => {
deleteAlerts$.unsubscribe(); deleteAlerts$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("删除成功!", ""); this.notifySvc.success('删除成功!', '');
this.loadAlertsTable(); this.loadAlertsTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error("删除失败!", message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteAlerts$.unsubscribe(); deleteAlerts$.unsubscribe();
this.notifySvc.error("删除失败!", error.msg) this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
updateAlertsStatus(alertIds: Set<number>, status: number) { updateAlertsStatus(alertIds: Set<number>, status: number) {
this.tableLoading = true; this.tableLoading = true;
const markAlertsStatus$ = this.alertSvc.applyAlertsStatus(alertIds, status) const markAlertsStatus$ = this.alertSvc.applyAlertsStatus(alertIds, status).subscribe(
.subscribe(message => { message => {
markAlertsStatus$.unsubscribe(); markAlertsStatus$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("标记成功!", ""); this.notifySvc.success('标记成功!', '');
this.loadAlertsTable(); this.loadAlertsTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error("标记失败!", message.msg); this.notifySvc.error('标记失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
markAlertsStatus$.unsubscribe(); markAlertsStatus$.unsubscribe();
this.notifySvc.error("标记失败!", error.msg) this.notifySvc.error('标记失败!', error.msg);
} }
); );
} }

View File

@@ -22,10 +22,13 @@
<button nz-button nzType="primary" (click)="syncReceiver()" nz-tooltip nzTooltipTitle="刷新"> <button nz-button nzType="primary" (click)="syncReceiver()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table #fixedTable [nzData]="receivers" <nz-table
nzFrontPagination ="false" #fixedTable
[nzLoading] = "receiverTableLoading" [nzData]="receivers"
[nzScroll]="{ x: '1150px', y: '1240px' }"> nzFrontPagination="false"
[nzLoading]="receiverTableLoading"
[nzScroll]="{ x: '1150px', y: '1240px' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center">接收人</th> <th nzAlign="center">接收人</th>
@@ -38,7 +41,7 @@
<tbody> <tbody>
<tr *ngFor="let data of fixedTable.data"> <tr *ngFor="let data of fixedTable.data">
<td nzAlign="center"> <td nzAlign="center">
<span>{{ data.name}}</span> <span>{{ data.name }}</span>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.type == 0" nzColor="orange"> <nz-tag *ngIf="data.type == 0" nzColor="orange">
@@ -59,12 +62,12 @@
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<span *ngIf="data.type == 0">{{data.phone}}</span> <span *ngIf="data.type == 0">{{ data.phone }}</span>
<span *ngIf="data.type == 1">{{data.email}}</span> <span *ngIf="data.type == 1">{{ data.email }}</span>
<span *ngIf="data.type == 2">{{data.hookUrl}}</span> <span *ngIf="data.type == 2">{{ data.hookUrl }}</span>
<span *ngIf="data.type == 3">{{data.wechatId}}</span> <span *ngIf="data.type == 3">{{ data.wechatId }}</span>
</td> </td>
<td nzAlign="center">{{ data.gmtUpdate? data.gmtUpdate : data.gmtCreate }}</td> <td nzAlign="center">{{ data.gmtUpdate ? data.gmtUpdate : data.gmtCreate }}</td>
<td nzAlign="center" nzRight> <td nzAlign="center" nzRight>
<button nz-button nzType="primary" (click)="onEditOneNoticeReceiver(data)" nz-tooltip nzTooltipTitle="修改接收人"> <button nz-button nzType="primary" (click)="onEditOneNoticeReceiver(data)" nz-tooltip nzTooltipTitle="修改接收人">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
@@ -85,10 +88,13 @@
<button nz-button nzType="primary" (click)="syncRule()" nz-tooltip nzTooltipTitle="刷新"> <button nz-button nzType="primary" (click)="syncRule()" nz-tooltip nzTooltipTitle="刷新">
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table #ruleFixedTable [nzData]="rules" <nz-table
nzFrontPagination ="false" #ruleFixedTable
[nzLoading] = "ruleTableLoading" [nzData]="rules"
[nzScroll]="{ x: '1150px', y: '1240px' }"> nzFrontPagination="false"
[nzLoading]="ruleTableLoading"
[nzScroll]="{ x: '1150px', y: '1240px' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center">策略名称</th> <th nzAlign="center">策略名称</th>
@@ -102,10 +108,10 @@
<tbody> <tbody>
<tr *ngFor="let data of ruleFixedTable.data"> <tr *ngFor="let data of ruleFixedTable.data">
<td nzAlign="center"> <td nzAlign="center">
<span>{{ data.name}}</span> <span>{{ data.name }}</span>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<span>{{ data.receiverName}}</span> <span>{{ data.receiverName }}</span>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.filterAll" nzColor="green"> <nz-tag *ngIf="data.filterAll" nzColor="green">
@@ -123,7 +129,7 @@
<span>关闭</span> <span>关闭</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.gmtUpdate? data.gmtUpdate : data.gmtCreate }}</td> <td nzAlign="center">{{ data.gmtUpdate ? data.gmtUpdate : data.gmtCreate }}</td>
<td nzAlign="center" nzRight> <td nzAlign="center" nzRight>
<button nz-button nzType="primary" (click)="onEditOneNoticeRule(data)" nz-tooltip nzTooltipTitle="修改告警策略"> <button nz-button nzType="primary" (click)="onEditOneNoticeRule(data)" nz-tooltip nzTooltipTitle="修改告警策略">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
@@ -138,37 +144,28 @@
</nz-tab> </nz-tab>
</nz-tabset> </nz-tabset>
<!-- 新增或修改通知接收人弹出框 --> <!-- 新增或修改通知接收人弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageReceiverModalVisible" [(nzVisible)]="isManageReceiverModalVisible"
[nzTitle]="isManageReceiverModalAdd?'新增接收人' : '修改接收人'" [nzTitle]="isManageReceiverModalAdd ? '新增接收人' : '修改接收人'"
(nzOnCancel)="onManageReceiverModalCancel()" (nzOnCancel)="onManageReceiverModalCancel()"
(nzOnOk)="onManageReceiverModalOk()" (nzOnOk)="onManageReceiverModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
nzWidth="60%" nzWidth="60%"
[nzOkLoading]="isManageReceiverModalOkLoading" [nzOkLoading]="isManageReceiverModalOkLoading"
> >
<div *nzModalContent class = "-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form> <form nz-form>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'name' nzRequired="true">接收人名称</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true">接收人名称</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="receiver.name" nz-input name="name" type="text" id="name"> <input [(ngModel)]="receiver.name" nz-input name="name" type="text" id="name" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" <nz-form-label nzSpan="7" nzRequired="true" nzFor="type">通知方式 </nz-form-label>
nzRequired="true"
nzFor= "type">通知方式
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-select <nz-select [(ngModel)]="receiver.type" nzAllowClear nzPlaceHolder="Choose" name="type" id="type">
[(ngModel)]="receiver.type"
nzAllowClear
nzPlaceHolder="Choose"
name="type" id="type"
>
<nz-option [nzValue]="0" nzDisabled nzLabel="短信"></nz-option> <nz-option [nzValue]="0" nzDisabled nzLabel="短信"></nz-option>
<nz-option [nzValue]="1" nzLabel="邮箱"></nz-option> <nz-option [nzValue]="1" nzLabel="邮箱"></nz-option>
<nz-option [nzValue]="2" nzLabel="WebHook"></nz-option> <nz-option [nzValue]="2" nzLabel="WebHook"></nz-option>
@@ -177,29 +174,29 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item *ngIf="receiver.type === 0"> <nz-form-item *ngIf="receiver.type === 0">
<nz-form-label [nzSpan]="7" nzFor= 'phone' [nzRequired]="receiver.type === 0">手机号</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="phone" [nzRequired]="receiver.type === 0">手机号</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="receiver.phone" nz-input name="phone" type="tel" id="phone"> <input [(ngModel)]="receiver.phone" nz-input name="phone" type="tel" id="phone" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item *ngIf="receiver.type === 1"> <nz-form-item *ngIf="receiver.type === 1">
<nz-form-label [nzSpan]="7" nzFor= 'email' [nzRequired]="receiver.type === 1">邮箱</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="email" [nzRequired]="receiver.type === 1">邮箱</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="receiver.email" nz-input name="email" type="email" id="email"> <input [(ngModel)]="receiver.email" nz-input name="email" type="email" id="email" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item *ngIf="receiver.type === 2"> <nz-form-item *ngIf="receiver.type === 2">
<nz-form-label [nzSpan]="7" nzFor= 'hookUrl' [nzRequired]="receiver.type === 2">URL地址</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="hookUrl" [nzRequired]="receiver.type === 2">URL地址</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="receiver.hookUrl" nz-input name="hookUrl" type="url" id="hookUrl"> <input [(ngModel)]="receiver.hookUrl" nz-input name="hookUrl" type="url" id="hookUrl" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item *ngIf="receiver.type === 3"> <nz-form-item *ngIf="receiver.type === 3">
<nz-form-label [nzSpan]="7" nzFor= 'wechatId' [nzRequired]="receiver.type === 3">微信OPENID</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="wechatId" [nzRequired]="receiver.type === 3">微信OPENID</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="receiver.wechatId" nz-input name="wechatId" type="text" id="wechatId"> <input [(ngModel)]="receiver.wechatId" nz-input name="wechatId" type="text" id="wechatId" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
</form> </form>
</div> </div>
</nz-modal> </nz-modal>
@@ -207,29 +204,29 @@
<!-- 新增或修改通知策略弹出框 --> <!-- 新增或修改通知策略弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageRuleModalVisible" [(nzVisible)]="isManageRuleModalVisible"
[nzTitle]="isManageRuleModalAdd?'新增策略' : '修改策略'" [nzTitle]="isManageRuleModalAdd ? '新增策略' : '修改策略'"
(nzOnCancel)="onManageRuleModalCancel()" (nzOnCancel)="onManageRuleModalCancel()"
(nzOnOk)="onManageRuleModalOk()" (nzOnOk)="onManageRuleModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
nzWidth="60%" nzWidth="60%"
[nzOkLoading]="isManageRuleModalOkLoading" [nzOkLoading]="isManageRuleModalOkLoading"
> >
<div *nzModalContent class = "-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form> <form nz-form>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'rule_name' nzRequired="true">策略名称</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="rule_name" nzRequired="true">策略名称</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="rule.name" nz-input name="rule_name" type="text" id="rule_name"> <input [(ngModel)]="rule.name" nz-input name="rule_name" type="text" id="rule_name" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "filterAll">转发所有</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="filterAll">转发所有</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="rule.filterAll" disabled name="filterAll" id="filterAll"></nz-switch> <nz-switch [(ngModel)]="rule.filterAll" disabled name="filterAll" id="filterAll"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "receiver">接收人</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="receiver">接收人</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-select <nz-select
[(ngModel)]="rule.receiverId" [(ngModel)]="rule.receiverId"
@@ -238,17 +235,18 @@
nzShowSearch nzShowSearch
nzAllowClear nzAllowClear
nzPlaceHolder="Select a person" nzPlaceHolder="Select a person"
name="receiver" id="receiver" name="receiver"
id="receiver"
> >
</nz-select> </nz-select>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "enable">是否启用</nz-form-label> <nz-form-label nzSpan="7" nzRequired="true" nzFor="enable">是否启用</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="rule.enable" name="enable" id="enable"></nz-switch> <nz-switch [(ngModel)]="rule.enable" name="enable" id="enable"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
</form> </form>
</div> </div>
</nz-modal> </nz-modal>

View File

@@ -8,9 +8,8 @@ describe('AlertNoticeComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ AlertNoticeComponent ] declarations: [AlertNoticeComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,24 +1,25 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {NzNotificationService} from "ng-zorro-antd/notification"; import { NzModalService } from 'ng-zorro-antd/modal';
import {NoticeReceiverService} from "../../../service/notice-receiver.service"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {NoticeRuleService} from "../../../service/notice-rule.service"; import { finalize } from 'rxjs/operators';
import {NoticeReceiver} from "../../../pojo/NoticeReceiver";
import {finalize} from "rxjs/operators"; import { NoticeReceiver } from '../../../pojo/NoticeReceiver';
import {NoticeRule} from "../../../pojo/NoticeRule"; import { NoticeRule } from '../../../pojo/NoticeRule';
import {NzModalService} from "ng-zorro-antd/modal"; import { NoticeReceiverService } from '../../../service/notice-receiver.service';
import { NoticeRuleService } from '../../../service/notice-rule.service';
@Component({ @Component({
selector: 'app-alert-notice', selector: 'app-alert-notice',
templateUrl: './alert-notice.component.html', templateUrl: './alert-notice.component.html',
styles: [ styles: []
]
}) })
export class AlertNoticeComponent implements OnInit { export class AlertNoticeComponent implements OnInit {
constructor(
constructor(private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private noticeReceiverSvc: NoticeReceiverService, private noticeReceiverSvc: NoticeReceiverService,
private modal: NzModalService, private modal: NzModalService,
private noticeRuleSvc : NoticeRuleService) { } private noticeRuleSvc: NoticeRuleService
) {}
receivers!: NoticeReceiver[]; receivers!: NoticeReceiver[];
receiverTableLoading: boolean = true; receiverTableLoading: boolean = true;
@@ -38,8 +39,8 @@ export class AlertNoticeComponent implements OnInit {
loadReceiversTable() { loadReceiversTable() {
this.receiverTableLoading = true; this.receiverTableLoading = true;
let receiverInit$ = this.noticeReceiverSvc.getReceivers() let receiverInit$ = this.noticeReceiverSvc.getReceivers().subscribe(
.subscribe(message => { message => {
this.receiverTableLoading = false; this.receiverTableLoading = false;
if (message.code === 0) { if (message.code === 0) {
this.receivers = message.data; this.receivers = message.data;
@@ -47,16 +48,18 @@ export class AlertNoticeComponent implements OnInit {
console.warn(message.msg); console.warn(message.msg);
} }
receiverInit$.unsubscribe(); receiverInit$.unsubscribe();
}, error => { },
error => {
console.error(error.msg); console.error(error.msg);
this.receiverTableLoading = false; this.receiverTableLoading = false;
receiverInit$.unsubscribe(); receiverInit$.unsubscribe();
}); }
);
} }
loadRulesTable() { loadRulesTable() {
this.ruleTableLoading = true; this.ruleTableLoading = true;
let rulesInit$ = this.noticeRuleSvc.getNoticeRules() let rulesInit$ = this.noticeRuleSvc.getNoticeRules().subscribe(
.subscribe(message => { message => {
this.ruleTableLoading = false; this.ruleTableLoading = false;
if (message.code === 0) { if (message.code === 0) {
this.rules = message.data; this.rules = message.data;
@@ -64,71 +67,85 @@ export class AlertNoticeComponent implements OnInit {
console.warn(message.msg); console.warn(message.msg);
} }
rulesInit$.unsubscribe(); rulesInit$.unsubscribe();
}, error => { },
error => {
console.error(error.msg); console.error(error.msg);
this.ruleTableLoading = false; this.ruleTableLoading = false;
rulesInit$.unsubscribe(); rulesInit$.unsubscribe();
}); }
);
} }
onDeleteOneNoticeReceiver(receiveId : number) { onDeleteOneNoticeReceiver(receiveId: number) {
this.modal.confirm({ this.modal.confirm({
nzTitle: '请确认是否删除!', nzTitle: '请确认是否删除!',
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteOneNoticeReceiver(receiveId) nzOnOk: () => this.deleteOneNoticeReceiver(receiveId)
}); });
} }
deleteOneNoticeReceiver(receiveId : number) { deleteOneNoticeReceiver(receiveId: number) {
const deleteReceiver$ = this.noticeReceiverSvc.deleteReceiver(receiveId) const deleteReceiver$ = this.noticeReceiverSvc
.pipe(finalize(() => { .deleteReceiver(receiveId)
.pipe(
finalize(() => {
deleteReceiver$.unsubscribe(); deleteReceiver$.unsubscribe();
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("删除成功!", ""); this.notifySvc.success('删除成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error("删除失败!", message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("删除失败!", error.msg); error => {
}) this.notifySvc.error('删除失败!', error.msg);
}
);
} }
onDeleteOneNoticeRule(ruleId : number) { onDeleteOneNoticeRule(ruleId: number) {
this.modal.confirm({ this.modal.confirm({
nzTitle: '请确认是否删除!', nzTitle: '请确认是否删除!',
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteOneNoticeRule(ruleId) nzOnOk: () => this.deleteOneNoticeRule(ruleId)
}); });
} }
deleteOneNoticeRule(ruleId : number) { deleteOneNoticeRule(ruleId: number) {
const deleteRule$ = this.noticeRuleSvc.deleteNoticeRule(ruleId) const deleteRule$ = this.noticeRuleSvc
.pipe(finalize(() => { .deleteNoticeRule(ruleId)
.pipe(
finalize(() => {
deleteRule$.unsubscribe(); deleteRule$.unsubscribe();
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("删除成功!", ""); this.notifySvc.success('删除成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error("删除失败!", message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("删除失败!", error.msg); error => {
}) this.notifySvc.error('删除失败!', error.msg);
}
);
} }
// start 新增或修改通知接收人弹出框 // start 新增或修改通知接收人弹出框
isManageReceiverModalVisible : boolean = false; isManageReceiverModalVisible: boolean = false;
isManageReceiverModalAdd: boolean = true; isManageReceiverModalAdd: boolean = true;
isManageReceiverModalOkLoading: boolean = false; isManageReceiverModalOkLoading: boolean = false;
receiver!: NoticeReceiver; receiver!: NoticeReceiver;
@@ -138,7 +155,7 @@ export class AlertNoticeComponent implements OnInit {
this.isManageReceiverModalVisible = true; this.isManageReceiverModalVisible = true;
this.isManageReceiverModalAdd = true; this.isManageReceiverModalAdd = true;
} }
onEditOneNoticeReceiver(receiver : NoticeReceiver) { onEditOneNoticeReceiver(receiver: NoticeReceiver) {
this.receiver = receiver; this.receiver = receiver;
this.isManageReceiverModalVisible = true; this.isManageReceiverModalVisible = true;
this.isManageReceiverModalAdd = false; this.isManageReceiverModalAdd = false;
@@ -150,44 +167,56 @@ export class AlertNoticeComponent implements OnInit {
onManageReceiverModalOk() { onManageReceiverModalOk() {
this.isManageReceiverModalOkLoading = true; this.isManageReceiverModalOkLoading = true;
if (this.isManageReceiverModalAdd) { if (this.isManageReceiverModalAdd) {
const modalOk$ = this.noticeReceiverSvc.newReceiver(this.receiver) const modalOk$ = this.noticeReceiverSvc
.pipe(finalize(() => { .newReceiver(this.receiver)
.pipe(
finalize(() => {
modalOk$.unsubscribe(); modalOk$.unsubscribe();
this.isManageReceiverModalOkLoading = false; this.isManageReceiverModalOkLoading = false;
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageReceiverModalVisible = false; this.isManageReceiverModalVisible = false;
this.notifySvc.success("新增成功!", ""); this.notifySvc.success('新增成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error("新增失败!", message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("新增失败!", error.msg); error => {
}) this.notifySvc.error('新增失败!', error.msg);
}
);
} else { } else {
const modalOk$ = this.noticeReceiverSvc.editReceiver(this.receiver) const modalOk$ = this.noticeReceiverSvc
.pipe(finalize(() => { .editReceiver(this.receiver)
.pipe(
finalize(() => {
modalOk$.unsubscribe(); modalOk$.unsubscribe();
this.isManageReceiverModalOkLoading = false; this.isManageReceiverModalOkLoading = false;
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageReceiverModalVisible = false; this.isManageReceiverModalVisible = false;
this.notifySvc.success("修改成功!", ""); this.notifySvc.success('修改成功!', '');
this.loadReceiversTable(); this.loadReceiversTable();
} else { } else {
this.notifySvc.error("修改失败!", message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("修改失败!", error.msg); error => {
}) this.notifySvc.error('修改失败!', error.msg);
}
);
} }
} }
// start 新增或修改通知策略弹出框 // start 新增或修改通知策略弹出框
isManageRuleModalVisible : boolean = false; isManageRuleModalVisible: boolean = false;
isManageRuleModalAdd: boolean = true; isManageRuleModalAdd: boolean = true;
isManageRuleModalOkLoading: boolean = false; isManageRuleModalOkLoading: boolean = false;
rule!: NoticeRule; rule!: NoticeRule;
@@ -199,43 +228,53 @@ export class AlertNoticeComponent implements OnInit {
this.isManageRuleModalAdd = true; this.isManageRuleModalAdd = true;
} }
onEditOneNoticeRule(rule : NoticeRule) { onEditOneNoticeRule(rule: NoticeRule) {
this.rule = rule; this.rule = rule;
this.isManageRuleModalVisible = true; this.isManageRuleModalVisible = true;
this.isManageRuleModalAdd = false; this.isManageRuleModalAdd = false;
this.receiversOption.push({ this.receiversOption.push({
value: rule.receiverId, value: rule.receiverId,
label: rule.receiverName label: rule.receiverName
}) });
} }
loadReceiversOption() { loadReceiversOption() {
let receiverOption$ = this.noticeReceiverSvc.getReceivers() let receiverOption$ = this.noticeReceiverSvc.getReceivers().subscribe(
.subscribe(message => { message => {
if (message.code === 0) { if (message.code === 0) {
let data = message.data; let data = message.data;
this.receiversOption = []; this.receiversOption = [];
data.forEach(item => { data.forEach(item => {
let label = item.name + '-'; let label = `${item.name}-`;
switch (item.type) { switch (item.type) {
case 0: label = label + 'Phone';break; case 0:
case 1: label = label + 'Email';break; label = `${label}Phone`;
case 2: label = label + 'WebHook';break; break;
case 3: label = label + 'WeChat';break; case 1:
label = `${label}Email`;
break;
case 2:
label = `${label}WebHook`;
break;
case 3:
label = `${label}WeChat`;
break;
} }
this.receiversOption.push({ this.receiversOption.push({
value: item.id, value: item.id,
label: label label: label
}); });
}) });
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
receiverOption$.unsubscribe(); receiverOption$.unsubscribe();
}, error => { },
error => {
console.error(error.msg); console.error(error.msg);
receiverOption$.unsubscribe(); receiverOption$.unsubscribe();
}); }
);
} }
onManageRuleModalCancel() { onManageRuleModalCancel() {
@@ -250,40 +289,51 @@ export class AlertNoticeComponent implements OnInit {
}); });
this.isManageRuleModalOkLoading = true; this.isManageRuleModalOkLoading = true;
if (this.isManageRuleModalAdd) { if (this.isManageRuleModalAdd) {
const modalOk$ = this.noticeRuleSvc.newNoticeRule(this.rule) const modalOk$ = this.noticeRuleSvc
.pipe(finalize(() => { .newNoticeRule(this.rule)
.pipe(
finalize(() => {
modalOk$.unsubscribe(); modalOk$.unsubscribe();
this.isManageRuleModalOkLoading = false; this.isManageRuleModalOkLoading = false;
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageRuleModalVisible = false; this.isManageRuleModalVisible = false;
this.notifySvc.success("新增成功!", ""); this.notifySvc.success('新增成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error("新增失败!", message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("新增失败!", error.msg); error => {
}) this.notifySvc.error('新增失败!', error.msg);
}
);
} else { } else {
const modalOk$ = this.noticeRuleSvc.editNoticeRule(this.rule) const modalOk$ = this.noticeRuleSvc
.pipe(finalize(() => { .editNoticeRule(this.rule)
.pipe(
finalize(() => {
modalOk$.unsubscribe(); modalOk$.unsubscribe();
this.isManageRuleModalOkLoading = false; this.isManageRuleModalOkLoading = false;
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageRuleModalVisible = false; this.isManageRuleModalVisible = false;
this.notifySvc.success("修改成功!", ""); this.notifySvc.success('修改成功!', '');
this.loadRulesTable(); this.loadRulesTable();
} else { } else {
this.notifySvc.error("修改失败!", message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("修改失败!", error.msg); error => {
}) this.notifySvc.error('修改失败!', error.msg);
}
);
} }
} }
} }

View File

@@ -1,8 +1,9 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import {AlertCenterComponent} from "./alert-center/alert-center.component";
import {AlertSettingComponent} from "./alert-setting/alert-setting.component"; import { AlertCenterComponent } from './alert-center/alert-center.component';
import {AlertNoticeComponent} from "./alert-notice/alert-notice.component"; import { AlertNoticeComponent } from './alert-notice/alert-notice.component';
import { AlertSettingComponent } from './alert-setting/alert-setting.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: AlertCenterComponent }, { path: '', component: AlertCenterComponent },
@@ -16,4 +17,4 @@ const routes: Routes = [
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(routes)],
exports: [RouterModule] exports: [RouterModule]
}) })
export class AlertRoutingModule { } export class AlertRoutingModule {}

View File

@@ -17,7 +17,7 @@
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
新增阈值 新增阈值
</button> </button>
<button nz-button nzType="primary" (click)="onEditAlertDefine()" > <button nz-button nzType="primary" (click)="onEditAlertDefine()">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
编辑 编辑
</button> </button>
@@ -29,15 +29,21 @@
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table #fixedTable [nzData]="defines" <nz-table
[nzPageIndex]="pageIndex" [nzPageSize]="pageSize" [nzTotal]="total" #fixedTable
nzFrontPagination ="false" [nzData]="defines"
[nzLoading] = "tableLoading" [nzPageIndex]="pageIndex"
[nzPageSize]="pageSize"
[nzTotal]="total"
nzFrontPagination="false"
[nzLoading]="tableLoading"
nzShowSizeChanger nzShowSizeChanger
[nzShowTotal]="rangeTemplate" [nzShowTotal]="rangeTemplate"
[nzPageSizeOptions]="[8,15,25]" [nzPageSizeOptions]="[8, 15, 25]"
(nzQueryParams)="onTablePageChange($event)" (nzQueryParams)="onTablePageChange($event)"
nzShowPagination = "true" [nzScroll]="{ x: '1150px', y: '1240px' }"> nzShowPagination="true"
[nzScroll]="{ x: '1150px', y: '1240px' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="60px" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="60px" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
@@ -58,7 +64,7 @@
<span>{{ data.app + '.' + data.metric + '.' + data.field }}</span> <span>{{ data.app + '.' + data.metric + '.' + data.field }}</span>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<span>{{ data.expr}}</span> <span>{{ data.expr }}</span>
</td> </td>
<td nzAlign="center"> <td nzAlign="center">
<nz-tag *ngIf="data.priority == 0" nzColor="red"> <nz-tag *ngIf="data.priority == 0" nzColor="red">
@@ -84,7 +90,7 @@
<span></span> <span></span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.gmtUpdate? data.gmtUpdate : data.gmtCreate }}</td> <td nzAlign="center">{{ data.gmtUpdate ? data.gmtUpdate : data.gmtCreate }}</td>
<td nzAlign="center" nzRight> <td nzAlign="center" nzRight>
<button nz-button nzType="primary" (click)="onOpenConnectModal(data.id, data.app)" nz-tooltip nzTooltipTitle="配置关联监控"> <button nz-button nzType="primary" (click)="onOpenConnectModal(data.id, data.app)" nz-tooltip nzTooltipTitle="配置关联监控">
<i nz-icon nzType="link" nzTheme="outline"></i> <i nz-icon nzType="link" nzTheme="outline"></i>
@@ -100,39 +106,33 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>
总量 {{ total }}
</ng-template>
<!-- 新增或修改告警定义弹出框 --> <!-- 新增或修改告警定义弹出框 -->
<nz-modal <nz-modal
[(nzVisible)]="isManageModalVisible" [(nzVisible)]="isManageModalVisible"
[nzTitle]="isManageModalAdd?'新增告警阈值' : '修改告警阈值'" [nzTitle]="isManageModalAdd ? '新增告警阈值' : '修改告警阈值'"
(nzOnCancel)="onManageModalCancel()" (nzOnCancel)="onManageModalCancel()"
(nzOnOk)="onManageModalOk()" (nzOnOk)="onManageModalOk()"
nzMaskClosable="false" nzMaskClosable="false"
nzWidth="60%" nzWidth="60%"
[nzOkLoading]="isManageModalOkLoading" [nzOkLoading]="isManageModalOkLoading"
> >
<div *nzModalContent class = "-inner-content"> <div *nzModalContent class="-inner-content">
<form nz-form> <form nz-form>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'target' nzRequired="true">指标对象</nz-form-label> <nz-form-label [nzSpan]="7" nzFor="target" nzRequired="true">指标对象</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-cascader name="target" id="target" [nzOptions]="appHierarchies" [(ngModel)]="cascadeValues"> <nz-cascader name="target" id="target" [nzOptions]="appHierarchies" [(ngModel)]="cascadeValues"> </nz-cascader>
</nz-cascader>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="8" nzOffset="7"> <nz-col [nzSpan]="8" nzOffset="7">
<nz-collapse> <nz-collapse>
<nz-collapse-panel <nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的阈值触发表达式环境变量与操作符">
[nzActive] = "isManageModalAdd"
nzHeader="支持的阈值触发表达式环境变量与操作符"
>
<nz-list nzSize="small" nzSplit="false"> <nz-list nzSize="small" nzSplit="false">
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>{{cascadeValues[2]}} : 选中的指标对象</code> <code>{{ cascadeValues[2] }} : 选中的指标对象</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>instance : 所属行实例值</code> <code>instance : 所属行实例值</code>
@@ -146,29 +146,39 @@
</nz-col> </nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'expr' nzRequired="true" nzTooltipTitle="根据此表达式来计算判断是否触发阈值,表达式环境变量和操作符见上方"> <nz-form-label
[nzSpan]="7"
nzFor="expr"
nzRequired="true"
nzTooltipTitle="根据此表达式来计算判断是否触发阈值,表达式环境变量和操作符见上方"
>
阈值触发表达式 阈值触发表达式
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="define.expr" rows="3" nz-input <textarea
name="expr" id="expr" placeholder="根据此表达式计算判断是否触发阈值.&#10;示例: equals&#40;instance,&quot;cpu1&quot;&#41; &amp;&amp; usage&gt;40"> [(ngModel)]="define.expr"
rows="3"
nz-input
name="expr"
id="expr"
placeholder='根据此表达式计算判断是否触发阈值.&#10;示例: equals&#40;instance,"cpu1"&#41; &amp;&amp; usage&gt;40'
>
</textarea> </textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "priority" <nz-form-label
nzTooltipTitle="触发阈值的告警级别,从低到高依次为:警告-warning严重-critical紧急-emergency"> nzSpan="7"
nzRequired="true"
nzFor="priority"
nzTooltipTitle="触发阈值的告警级别,从低到高依次为:警告-warning严重-critical紧急-emergency"
>
告警级别 告警级别
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-select <nz-select [(ngModel)]="define.priority" nzAllowClear nzPlaceHolder="Choose" name="priority" id="priority">
[(ngModel)]="define.priority"
nzAllowClear
nzPlaceHolder="Choose"
name="priority" id="priority"
>
<nz-option [nzValue]="0" nzLabel="紧急告警"></nz-option> <nz-option [nzValue]="0" nzLabel="紧急告警"></nz-option>
<nz-option [nzValue]="1" nzLabel="严重告警"></nz-option> <nz-option [nzValue]="1" nzLabel="严重告警"></nz-option>
<nz-option [nzValue]="2" nzLabel="警告告警"></nz-option> <nz-option [nzValue]="2" nzLabel="警告告警"></nz-option>
@@ -176,28 +186,24 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "duration" nzTooltipTitle="设置触发阈值多少次之后才会发送告警"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="duration" nzTooltipTitle="设置触发阈值多少次之后才会发送告警">
触发次数 触发次数
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-input-number [(ngModel)]="define.times" [nzMin]="1" [nzMax]="10" [nzStep]="1" <nz-input-number [(ngModel)]="define.times" [nzMin]="1" [nzMax]="10" [nzStep]="1" name="duration" id="duration">
name="duration" id="duration">
</nz-input-number> </nz-input-number>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="8" nzOffset="7"> <nz-col [nzSpan]="8" nzOffset="7">
<nz-collapse> <nz-collapse>
<nz-collapse-panel <nz-collapse-panel [nzActive]="isManageModalAdd" nzHeader="支持的通知模版环境变量">
[nzActive] = "isManageModalAdd"
nzHeader="支持的通知模版环境变量"
>
<nz-list nzSize="small" nzSplit="false"> <nz-list nzSize="small" nzSplit="false">
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>&#36;&#40;metric&#41; : 选中的指标对象名称</code> <code>&#36;&#40;metric&#41; : 选中的指标对象名称</code>
</nz-list-item> </nz-list-item>
<nz-list-item *ngIf="cascadeValues.length == 3"> <nz-list-item *ngIf="cascadeValues.length == 3">
<code>&#36;&#40;{{cascadeValues[2]}}&#41; : 选中的指标对象值</code> <code>&#36;&#40;{{ cascadeValues[2] }}&#41; : 选中的指标对象值</code>
</nz-list-item> </nz-list-item>
<nz-list-item> <nz-list-item>
<code>&#36;&#40;instance&#41; : 所在行实例值</code> <code>&#36;&#40;instance&#41; : 所在行实例值</code>
@@ -214,33 +220,37 @@
</nz-col> </nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'template' nzRequired="true" nzTooltipTitle="告警触发后发送的通知信息模版,模版环境变量见上方"> <nz-form-label [nzSpan]="7" nzFor="template" nzRequired="true" nzTooltipTitle="告警触发后发送的通知信息模版,模版环境变量见上方">
通知模版 通知模版
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="200"> <nz-textarea-count [nzMaxCharacterCount]="200">
<textarea [(ngModel)]="define.template" rows="3" nz-input <textarea
name="template" id="template" placeholder="请输入告警的通知模版.&#10;示例: ${app}.${metrics}.${metric}'s value is too high"> [(ngModel)]="define.template"
rows="3"
nz-input
name="template"
id="template"
placeholder="请输入告警的通知模版.&#10;示例: ${app}.${metrics}.${metric}'s value is too high"
>
</textarea> </textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "preset" nzTooltipTitle="此告警阈值配置是否应用于全局所有此类型监控"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="preset" nzTooltipTitle="此告警阈值配置是否应用于全局所有此类型监控">
全局默认 全局默认
</nz-form-label> </nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="define.preset" name="preset" id="preset"></nz-switch> <nz-switch [(ngModel)]="define.preset" name="preset" id="preset"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzRequired="true" nzFor= "enable" nzTooltipTitle="此告警阈值配置开启生效或关闭"> <nz-form-label nzSpan="7" nzRequired="true" nzFor="enable" nzTooltipTitle="此告警阈值配置开启生效或关闭"> 启用告警 </nz-form-label>
启用告警
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="define.enable" name="enable" id="enable"></nz-switch> <nz-switch [(ngModel)]="define.enable" name="enable" id="enable"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
</form> </form>
</div> </div>
</nz-modal> </nz-modal>
@@ -275,18 +285,14 @@
<nz-table #t [nzData]="$asTransferItems(items)" nzSize="small"> <nz-table #t [nzData]="$asTransferItems(items)" nzSize="small">
<thead> <thead>
<tr> <tr>
<th [nzChecked]="stat.checkAll" [nzIndeterminate]="stat.checkHalf" <th [nzChecked]="stat.checkAll" [nzIndeterminate]="stat.checkHalf" (nzCheckedChange)="onItemSelectAll($event)"></th>
(nzCheckedChange)="onItemSelectAll($event)"></th> <th *ngIf="direction == 'left'">未关联监控</th>
<th *ngIf="direction=='left'">关联监控</th> <th *ngIf="direction == 'right'">关联监控</th>
<th *ngIf="direction=='right'">已关联监控</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let data of t.data" (click)="onItemSelect(data)"> <tr *ngFor="let data of t.data" (click)="onItemSelect(data)">
<td <td [nzChecked]="!!data.checked" (nzCheckedChange)="onItemSelect(data)"></td>
[nzChecked]="!!data.checked"
(nzCheckedChange)="onItemSelect(data)"
></td>
<td>{{ data.name }}</td> <td>{{ data.name }}</td>
</tr> </tr>
</tbody> </tbody>

View File

@@ -8,9 +8,8 @@ describe('AlertSettingComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ AlertSettingComponent ] declarations: [AlertSettingComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,31 +1,32 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {NzTableQueryParams} from "ng-zorro-antd/table"; import { NzModalService } from 'ng-zorro-antd/modal';
import {NzModalService} from "ng-zorro-antd/modal"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {NzNotificationService} from "ng-zorro-antd/notification"; import { NzTableQueryParams } from 'ng-zorro-antd/table';
import {AlertDefineService} from "../../../service/alert-define.service"; import { TransferChange, TransferItem } from 'ng-zorro-antd/transfer';
import {AlertDefine} from "../../../pojo/AlertDefine"; import { zip } from 'rxjs';
import {finalize, map} 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 { AlertDefine } from '../../../pojo/AlertDefine';
import {zip} from "rxjs"; import { AlertDefineBind } from '../../../pojo/AlertDefineBind';
import {MonitorService} from "../../../service/monitor.service"; import { Message } from '../../../pojo/Message';
import {Message} from "../../../pojo/Message"; import { Monitor } from '../../../pojo/Monitor';
import {AlertDefineBind} from "../../../pojo/AlertDefineBind"; import { AlertDefineService } from '../../../service/alert-define.service';
import {Monitor} from "../../../pojo/Monitor"; import { AppDefineService } from '../../../service/app-define.service';
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'app-alert-setting', selector: 'app-alert-setting',
templateUrl: './alert-setting.component.html', templateUrl: './alert-setting.component.html',
styles: [ styles: []
]
}) })
export class AlertSettingComponent implements OnInit { export class AlertSettingComponent implements OnInit {
constructor(
constructor(private modal: NzModalService, private modal: NzModalService,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private appDefineSvc: AppDefineService, private appDefineSvc: AppDefineService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService,
private alertDefineSvc: AlertDefineService) { } private alertDefineSvc: AlertDefineService
) {}
pageIndex: number = 1; pageIndex: number = 1;
pageSize: number = 8; pageSize: number = 8;
@@ -39,19 +40,25 @@ export class AlertSettingComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.loadAlertDefineTable(); this.loadAlertDefineTable();
// 查询监控层级 // 查询监控层级
const getHierarchy$ = this.appDefineSvc.getAppHierarchy() const getHierarchy$ = this.appDefineSvc
.pipe(finalize(() => { .getAppHierarchy()
.pipe(
finalize(() => {
getHierarchy$.unsubscribe(); getHierarchy$.unsubscribe();
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.appHierarchies = message.data; this.appHierarchies = message.data;
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
}, error => { },
error => {
console.warn(error.msg); console.warn(error.msg);
}) }
);
} }
sync() { sync() {
@@ -60,8 +67,8 @@ export class AlertSettingComponent implements OnInit {
loadAlertDefineTable() { loadAlertDefineTable() {
this.tableLoading = true; this.tableLoading = true;
let alertDefineInit$ = this.alertDefineSvc.getAlertDefines(this.pageIndex - 1, this.pageSize) let alertDefineInit$ = this.alertDefineSvc.getAlertDefines(this.pageIndex - 1, this.pageSize).subscribe(
.subscribe(message => { message => {
this.tableLoading = false; this.tableLoading = false;
this.checkedAll = false; this.checkedAll = false;
this.checkedDefineIds.clear(); this.checkedDefineIds.clear();
@@ -74,10 +81,12 @@ export class AlertSettingComponent implements OnInit {
console.warn(message.msg); console.warn(message.msg);
} }
alertDefineInit$.unsubscribe(); alertDefineInit$.unsubscribe();
}, error => { },
error => {
this.tableLoading = false; this.tableLoading = false;
alertDefineInit$.unsubscribe(); alertDefineInit$.unsubscribe();
}); }
);
} }
onNewAlertDefine() { onNewAlertDefine() {
@@ -89,7 +98,7 @@ export class AlertSettingComponent implements OnInit {
onEditOneAlertDefine(alertDefineId: number) { onEditOneAlertDefine(alertDefineId: number) {
if (alertDefineId == null) { if (alertDefineId == null) {
this.notifySvc.warning("未选中任何待编辑项!",""); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
this.editAlertDefine(alertDefineId); this.editAlertDefine(alertDefineId);
@@ -98,15 +107,15 @@ export class AlertSettingComponent implements OnInit {
onEditAlertDefine() { onEditAlertDefine() {
// 编辑时只能选中一个 // 编辑时只能选中一个
if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) { if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) {
this.notifySvc.warning("未选中任何待编辑项!",""); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
if (this.checkedDefineIds.size > 1) { if (this.checkedDefineIds.size > 1) {
this.notifySvc.warning("只能对一个选中项进行编辑!",""); this.notifySvc.warning('只能对一个选中项进行编辑!', '');
return; return;
} }
let alertDefineId = 0; let alertDefineId = 0;
this.checkedDefineIds.forEach(item => alertDefineId = item); this.checkedDefineIds.forEach(item => (alertDefineId = item));
this.editAlertDefine(alertDefineId); this.editAlertDefine(alertDefineId);
} }
@@ -115,25 +124,31 @@ export class AlertSettingComponent implements OnInit {
this.isManageModalVisible = true; this.isManageModalVisible = true;
this.isManageModalOkLoading = false; this.isManageModalOkLoading = false;
// 查询告警定义信息 // 查询告警定义信息
const getDefine$ = this.alertDefineSvc.getAlertDefine(alertDefineId) const getDefine$ = this.alertDefineSvc
.pipe(finalize(() => { .getAlertDefine(alertDefineId)
.pipe(
finalize(() => {
getDefine$.unsubscribe(); getDefine$.unsubscribe();
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.define = message.data; this.define = message.data;
this.cascadeValues = [this.define.app, this.define.metric, this.define.field]; this.cascadeValues = [this.define.app, this.define.metric, this.define.field];
} else { } else {
this.notifySvc.error("查询此监控定义详情失败!",message.msg); this.notifySvc.error('查询此监控定义详情失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("查询此监控定义详情失败!",error.msg); error => {
}) this.notifySvc.error('查询此监控定义详情失败!', error.msg);
}
);
} }
onDeleteAlertDefines() { onDeleteAlertDefines() {
if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) { if (this.checkedDefineIds == null || this.checkedDefineIds.size === 0) {
this.notifySvc.warning("未选中任何待删除项!",""); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -141,7 +156,7 @@ export class AlertSettingComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteAlertDefines(this.checkedDefineIds) nzOnOk: () => this.deleteAlertDefines(this.checkedDefineIds)
}); });
} }
@@ -154,33 +169,34 @@ export class AlertSettingComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteAlertDefines(defineIds) nzOnOk: () => this.deleteAlertDefines(defineIds)
}); });
} }
deleteAlertDefines(defineIds: Set<number>) { deleteAlertDefines(defineIds: Set<number>) {
if (defineIds == null || defineIds.size == 0) { if (defineIds == null || defineIds.size == 0) {
this.notifySvc.warning("未选中任何待删除项!",""); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.tableLoading = true; this.tableLoading = true;
const deleteDefines$ = this.alertDefineSvc.deleteAlertDefines(defineIds) const deleteDefines$ = this.alertDefineSvc.deleteAlertDefines(defineIds).subscribe(
.subscribe(message => { message => {
deleteDefines$.unsubscribe(); deleteDefines$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("删除成功!", ""); this.notifySvc.success('删除成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error("删除失败!", message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, error => { },
error => {
this.tableLoading = false; this.tableLoading = false;
deleteDefines$.unsubscribe(); deleteDefines$.unsubscribe();
this.notifySvc.error("删除失败!", error.msg) this.notifySvc.error('删除失败!', error.msg);
}) }
);
} }
// begin: 列表多选分页逻辑 // begin: 列表多选分页逻辑
@@ -201,6 +217,7 @@ export class AlertSettingComponent implements OnInit {
} }
/** /**
* 分页回调 * 分页回调
*
* @param params 页码信息 * @param params 页码信息
*/ */
onTablePageChange(params: NzTableQueryParams) { onTablePageChange(params: NzTableQueryParams) {
@@ -211,7 +228,6 @@ export class AlertSettingComponent implements OnInit {
} }
// end: 列表多选逻辑 // end: 列表多选逻辑
// start 新增修改告警定义model // start 新增修改告警定义model
isManageModalVisible = false; isManageModalVisible = false;
isManageModalOkLoading = false; isManageModalOkLoading = false;
@@ -227,39 +243,51 @@ export class AlertSettingComponent implements OnInit {
this.define.metric = this.cascadeValues[1]; this.define.metric = this.cascadeValues[1];
this.define.field = this.cascadeValues[2]; this.define.field = this.cascadeValues[2];
if (this.isManageModalAdd) { if (this.isManageModalAdd) {
const modalOk$ = this.alertDefineSvc.newAlertDefine(this.define) const modalOk$ = this.alertDefineSvc
.pipe(finalize(() => { .newAlertDefine(this.define)
.pipe(
finalize(() => {
modalOk$.unsubscribe(); modalOk$.unsubscribe();
this.isManageModalOkLoading = false; this.isManageModalOkLoading = false;
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageModalVisible = false; this.isManageModalVisible = false;
this.notifySvc.success("新增成功!", ""); this.notifySvc.success('新增成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error("新增失败!", message.msg); this.notifySvc.error('新增失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("新增失败!", error.msg); error => {
}) this.notifySvc.error('新增失败!', error.msg);
}
);
} else { } else {
const modalOk$ = this.alertDefineSvc.editAlertDefine(this.define) const modalOk$ = this.alertDefineSvc
.pipe(finalize(() => { .editAlertDefine(this.define)
.pipe(
finalize(() => {
modalOk$.unsubscribe(); modalOk$.unsubscribe();
this.isManageModalOkLoading = false; this.isManageModalOkLoading = false;
})) })
.subscribe(message => { )
.subscribe(
message => {
if (message.code === 0) { if (message.code === 0) {
this.isManageModalVisible = false; this.isManageModalVisible = false;
this.notifySvc.success("修改成功!", ""); this.notifySvc.success('修改成功!', '');
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error("修改失败!", message.msg); this.notifySvc.error('修改失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("修改失败!", error.msg); error => {
}) this.notifySvc.error('修改失败!', error.msg);
}
);
} }
} }
// end 新增修改告警定义model // end 新增修改告警定义model
@@ -280,7 +308,7 @@ export class AlertSettingComponent implements OnInit {
if (defineBindData.data != undefined) { if (defineBindData.data != undefined) {
defineBindData.data.forEach(bind => { defineBindData.data.forEach(bind => {
bindRecode[bind.monitorId] = bind.monitorName; bindRecode[bind.monitorId] = bind.monitorName;
}) });
} }
let listTmp: any[] = []; let listTmp: any[] = [];
if (monitorData.data != undefined) { if (monitorData.data != undefined) {
@@ -290,12 +318,13 @@ export class AlertSettingComponent implements OnInit {
name: monitor.name, name: monitor.name,
key: monitor.id, key: monitor.id,
direction: bindRecode[monitor.id] == undefined ? 'left' : 'right' direction: bindRecode[monitor.id] == undefined ? 'left' : 'right'
}) });
}) });
} }
return listTmp; return listTmp;
}) })
).subscribe(list => this.transferData = list); )
.subscribe(list => (this.transferData = list));
} }
onConnectModalCancel() { onConnectModalCancel() {
this.isConnectModalVisible = false; this.isConnectModalVisible = false;
@@ -311,23 +340,29 @@ export class AlertSettingComponent implements OnInit {
bind.monitorName = item.name; bind.monitorName = item.name;
defineBinds.push(bind); defineBinds.push(bind);
} }
}) });
const applyBind$ = this.alertDefineSvc.applyAlertDefineMonitorsBind(this.currentAlertDefineId, defineBinds) const applyBind$ = this.alertDefineSvc
.pipe(finalize(() => { .applyAlertDefineMonitorsBind(this.currentAlertDefineId, defineBinds)
.pipe(
finalize(() => {
applyBind$.unsubscribe(); applyBind$.unsubscribe();
})) })
.subscribe(message => { )
.subscribe(
message => {
this.isConnectModalOkLoading = false; this.isConnectModalOkLoading = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("应用成功!", ""); this.notifySvc.success('应用成功!', '');
this.isConnectModalVisible = false; this.isConnectModalVisible = false;
this.loadAlertDefineTable(); this.loadAlertDefineTable();
} else { } else {
this.notifySvc.error("应用失败!", message.msg); this.notifySvc.error('应用失败!', message.msg);
} }
}, error => { },
this.notifySvc.error("应用失败!", error.msg); error => {
}) this.notifySvc.error('应用失败!', error.msg);
}
);
} }
change(ret: TransferChange): void { change(ret: TransferChange): void {
const listKeys = ret.list.map(l => l.key); const listKeys = ret.list.map(l => l.key);
@@ -344,5 +379,4 @@ export class AlertSettingComponent implements OnInit {
}); });
} }
// end 告警定义与监控关联model // end 告警定义与监控关联model
} }

View File

@@ -1,24 +1,21 @@
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';
import { AlertRoutingModule } from './alert-routing.module'; import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
import {NzBreadCrumbModule} from "ng-zorro-antd/breadcrumb"; import { NzCascaderModule } from 'ng-zorro-antd/cascader';
import {NzDividerModule} from "ng-zorro-antd/divider"; import { NzCollapseModule } from 'ng-zorro-antd/collapse';
import {AlertCenterComponent} from "./alert-center/alert-center.component"; import { NzDividerModule } from 'ng-zorro-antd/divider';
import {AlertSettingComponent} from "./alert-setting/alert-setting.component"; import { NzListModule } from 'ng-zorro-antd/list';
import {AlertNoticeComponent} from "./alert-notice/alert-notice.component"; import { NzRadioModule } from 'ng-zorro-antd/radio';
import {NzTagModule} from "ng-zorro-antd/tag"; import { NzSwitchModule } from 'ng-zorro-antd/switch';
import {NzRadioModule} from "ng-zorro-antd/radio"; import { NzTagModule } from 'ng-zorro-antd/tag';
import {NzSwitchModule} from "ng-zorro-antd/switch"; import { NzTransferModule } from 'ng-zorro-antd/transfer';
import {NzCascaderModule} from "ng-zorro-antd/cascader";
import {NzTransferModule} from "ng-zorro-antd/transfer";
import {NzCollapseModule} from "ng-zorro-antd/collapse";
import {NzListModule} from "ng-zorro-antd/list";
const COMPONENTS: Type<void>[] = [ import { AlertCenterComponent } from './alert-center/alert-center.component';
AlertCenterComponent, import { AlertNoticeComponent } from './alert-notice/alert-notice.component';
AlertSettingComponent, import { AlertRoutingModule } from './alert-routing.module';
AlertNoticeComponent import { AlertSettingComponent } from './alert-setting/alert-setting.component';
];
const COMPONENTS: Array<Type<void>> = [AlertCenterComponent, AlertSettingComponent, AlertNoticeComponent];
@NgModule({ @NgModule({
imports: [ imports: [
@@ -34,6 +31,6 @@ const COMPONENTS: Type<void>[] = [
NzCollapseModule, NzCollapseModule,
NzListModule NzListModule
], ],
declarations: COMPONENTS, declarations: COMPONENTS
}) })
export class AlertModule { } export class AlertModule {}

View File

@@ -1,18 +1,7 @@
import {ThemeOption} from "ngx-echarts"; import { ThemeOption } from 'ngx-echarts';
export const CoolTheme: ThemeOption = { export const CoolTheme: ThemeOption = {
color: [ color: ['#b21ab4', '#6f0099', '#2a2073', '#0b5ea8', '#17aecc', '#b3b3ff', '#eb99ff', '#fae6ff', '#e6f2ff', '#eeeeee'],
'#b21ab4',
'#6f0099',
'#2a2073',
'#0b5ea8',
'#17aecc',
'#b3b3ff',
'#eb99ff',
'#fae6ff',
'#e6f2ff',
'#eeeeee'
],
title: { title: {
textStyle: { textStyle: {

View File

@@ -1,6 +1,13 @@
<br/> <br />
<div nz-row [nzGutter]="24" style="margin-top: 10px"> <div nz-row [nzGutter]="24" style="margin-top: 10px">
<div nz-col nzXs="18" nzSm="18" nzMd="18" nzLg="18" nzOffset="1"> <div nz-col nzXs="18" nzSm="18" nzMd="18" nzLg="18" nzOffset="1">
<div echarts [options]="appsCountEChartOption" theme='default' [autoResize]= 'true' [loading]="appsCountLoading" (chartClick)="onChartClick($event)"></div> <div
echarts
[options]="appsCountEChartOption"
theme="default"
[autoResize]="true"
[loading]="appsCountLoading"
(chartClick)="onChartClick($event)"
></div>
</div> </div>
</div> </div>

View File

@@ -1,17 +1,11 @@
import { import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, OnInit } from '@angular/core';
ChangeDetectionStrategy, import { Router } from '@angular/router';
ChangeDetectorRef, import { I18NService } from '@core';
Component, import { ALAIN_I18N_TOKEN } from '@delon/theme';
Inject,
OnDestroy,
OnInit
} from '@angular/core';
import {NzMessageService} from "ng-zorro-antd/message";
import {MonitorService} from "../../service/monitor.service";
import { EChartsOption } from 'echarts'; import { EChartsOption } from 'echarts';
import {I18NService} from "@core"; import { NzMessageService } from 'ng-zorro-antd/message';
import {ALAIN_I18N_TOKEN} from "@delon/theme";
import {Router} from "@angular/router"; import { MonitorService } from '../../service/monitor.service';
@Component({ @Component({
selector: 'app-dashboard', selector: 'app-dashboard',
@@ -20,12 +14,13 @@ import {Router} from "@angular/router";
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class DashboardComponent implements OnInit, OnDestroy { export class DashboardComponent implements OnInit, OnDestroy {
constructor(
constructor(private msg: NzMessageService, private msg: NzMessageService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService,
@Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService, @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService,
private router: Router, private router: Router,
private cdr: ChangeDetectorRef){} private cdr: ChangeDetectorRef
) {}
interval$!: number; interval$!: number;
appsCountLoading: boolean = true; appsCountLoading: boolean = true;
@@ -45,8 +40,8 @@ export class DashboardComponent implements OnInit, OnDestroy {
} }
refresh(): void { refresh(): void {
let dashboard$ = this.monitorSvc.getAppsMonitorSummary() let dashboard$ = this.monitorSvc.getAppsMonitorSummary().subscribe(
.subscribe(message => { message => {
dashboard$.unsubscribe(); dashboard$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
// {app:'linux',size: 12} // {app:'linux',size: 12}
@@ -54,7 +49,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
this.appsCountTableData = []; this.appsCountTableData = [];
let total = 0; let total = 0;
apps.forEach(app => { apps.forEach(app => {
let appName = this.i18nSvc.fanyi('monitor.app.' + app.app); let appName = this.i18nSvc.fanyi(`monitor.app.${app.app}`);
this.appsCountTableData.push({ this.appsCountTableData.push({
// 自定义属性 // 自定义属性
app: app.app, app: app.app,
@@ -62,7 +57,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
name: appName, name: appName,
value: app.size value: app.size
}); });
total = total + app.size? app.size : 0; total = total + app.size ? app.size : 0;
}); });
this.appsCountEChartOption = { this.appsCountEChartOption = {
@@ -94,14 +89,12 @@ export class DashboardComponent implements OnInit, OnDestroy {
fontSize: 15, fontSize: 15,
color: '#ffffff', color: '#ffffff',
fontStyle: 'oblique', fontStyle: 'oblique',
formatter: '{a}:{c}', formatter: '{a}:{c}'
}, },
labelLine: { labelLine: {
show: false show: false
}, },
data: [ data: [{ value: total, name: '监控总量' }]
{ value: total, name: '监控总量' },
]
}, },
{ {
name: '纳管数量分布', name: '纳管数量分布',
@@ -148,10 +141,12 @@ export class DashboardComponent implements OnInit, OnDestroy {
}; };
this.cdr.detectChanges(); this.cdr.detectChanges();
} }
}, error => { },
error => {
console.error(error); console.error(error);
dashboard$.unsubscribe(); dashboard$.unsubscribe();
}); }
);
} }
onChartClick(click: any) { onChartClick(click: any) {

View File

@@ -1,21 +1,19 @@
<nz-card *ngIf="isTable" nzHoverable style="height:auto;margin-left: 14px;" [nzBordered]="true" <nz-card *ngIf="isTable" nzHoverable style="height: auto; margin-left: 14px" [nzBordered]="true" [nzTitle]="monitor_metrics_card_title">
[nzTitle]="monitor_metrics_card_title" >
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows"> <nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead> <thead>
<tr> <tr>
<th style="text-align: center" *ngFor="let field of fields">{{field.name}}</th> <th style="text-align: center" *ngFor="let field of fields">{{ field.name }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let valueRow of smallTable.data"> <tr *ngFor="let valueRow of smallTable.data">
<td *ngFor="let value of valueRow.values">{{ value.origin}}</td> <td *ngFor="let value of valueRow.values">{{ value.origin }}</td>
</tr> </tr>
</tbody> </tbody>
</nz-table> </nz-table>
</nz-card> </nz-card>
<nz-card *ngIf="!isTable" nzHoverable style="height:auto;margin-left: 14px;" [nzBordered]="true" <nz-card *ngIf="!isTable" nzHoverable style="height: auto; margin-left: 14px" [nzBordered]="true" [nzTitle]="monitor_metrics_card_title">
[nzTitle]="monitor_metrics_card_title" >
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows"> <nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead> <thead>
<tr> <tr>
@@ -24,19 +22,21 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let field of fields;let i = index;"> <tr *ngFor="let field of fields; let i = index">
<td>{{field.name}}</td> <td>{{ field.name }}</td>
<td>{{rowValues[i].origin + ' ' + (field.unit? field.unit : '')}}</td> <td>{{ rowValues[i].origin + ' ' + (field.unit ? field.unit : '') }}</td>
</tr> </tr>
</tbody> </tbody>
</nz-table> </nz-table>
</nz-card> </nz-card>
<ng-template #monitor_metrics_card_title> <ng-template #monitor_metrics_card_title>
<p style="font-size: small; text-align: center; margin-bottom: 3px; color: #0c0c0c">{{metrics}}</p> <p style="font-size: small; text-align: center; margin-bottom: 3px; color: #0c0c0c">{{ metrics }}</p>
<div> <div>
<a nz-popover [nzPopoverContent]="'最近采集时间 ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')"> <i nz-icon nzType="field-time" nzTheme="outline"></i></a> <a nz-popover [nzPopoverContent]="'最近采集时间 ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')">
<i style="font-size: 0.3px; font-weight: normal;color: rgba(84,83,83,0.89)">采集时间:{{time | _date: "HH:mm:ss"}}</i> <i nz-icon nzType="field-time" nzTheme="outline"></i
></a>
<i style="font-size: 0.3px; font-weight: normal; color: rgba(84, 83, 83, 0.89)">采集时间:{{ time | _date: 'HH:mm:ss' }}</i>
</div> </div>
</ng-template> </ng-template>

View File

@@ -8,9 +8,8 @@ describe('MonitorDataChartComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ MonitorDataChartComponent ] declarations: [MonitorDataChartComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,5 +1,6 @@
import {Component, Input, OnInit} from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import {MonitorService} from "../../../service/monitor.service";
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'app-monitor-data-chart', selector: 'app-monitor-data-chart',
@@ -7,9 +8,10 @@ import {MonitorService} from "../../../service/monitor.service";
styleUrls: ['./monitor-data-chart.component.less'] styleUrls: ['./monitor-data-chart.component.less']
}) })
export class MonitorDataChartComponent implements OnInit { export class MonitorDataChartComponent implements OnInit {
@Input() @Input()
get monitorId(): number { return this._monitorId; } get monitorId(): number {
return this._monitorId;
}
set monitorId(monitorId: number) { set monitorId(monitorId: number) {
this._monitorId = monitorId; this._monitorId = monitorId;
this.loadData(); this.loadData();
@@ -24,13 +26,13 @@ export class MonitorDataChartComponent implements OnInit {
rowValues!: any[]; rowValues!: any[];
isTable: boolean = true; isTable: boolean = true;
constructor(private monitorSvc: MonitorService) { } constructor(private monitorSvc: MonitorService) {}
ngOnInit(): void {} ngOnInit(): void {}
loadData() { loadData() {
// 读取实时指标数据 // 读取实时指标数据
let metricData$ = this.monitorSvc.getMonitorMetricsData(this.monitorId, this.metrics) let metricData$ = this.monitorSvc.getMonitorMetricsData(this.monitorId, this.metrics).subscribe(
.subscribe(message => { message => {
metricData$.unsubscribe(); metricData$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.time = message.data.time; this.time = message.data.time;
@@ -43,9 +45,10 @@ export class MonitorDataChartComponent implements OnInit {
} else { } else {
console.error(message.msg); console.error(message.msg);
} }
}, error => { },
error => {
metricData$.unsubscribe(); metricData$.unsubscribe();
})
} }
);
}
} }

View File

@@ -7,40 +7,50 @@
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{app: app ? app : ''}"> <a [routerLink]="['/monitors']" [queryParams]="{ app: app ? app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>监控列表</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="pie-chart"></i> <i nz-icon nzType="pie-chart"></i>
<span>{{'monitor.app.' + app | i18n}} 监控详情</span> <span>{{ 'monitor.app.' + app | i18n }} 监控详情</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-layout> <nz-layout>
<nz-sider nzWidth="19%" nzTheme="light"> <nz-sider nzWidth="19%" nzTheme="light">
<nz-card nzHoverable style="width:100%;height:100%" [nzBordered]="true" [nzTitle]="monitor_basic_card_title" > <nz-card nzHoverable style="width: 100%; height: 100%" [nzBordered]="true" [nzTitle]="monitor_basic_card_title">
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">ID</p></div> <div nz-col nzSpan="8"><p style="text-align: right">ID</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitorId}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitorId }}</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">名称</p></div> <div nz-col nzSpan="8"><p style="text-align: right">名称</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitor?.name}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.name }}</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">HOST</p></div> <div nz-col nzSpan="8"><p style="text-align: right">HOST</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitor?.host}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.host }}</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">端口</p></div> <div nz-col nzSpan="8"><p style="text-align: right">端口</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{port}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ port }}</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">描述</p></div> <div nz-col nzSpan="8"><p style="text-align: right">描述</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitor?.description}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.description }}</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">状态</p></div> <div nz-col nzSpan="8"><p style="text-align: right">状态</p></div>
@@ -69,15 +79,21 @@
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">采集间隔</p></div> <div nz-col nzSpan="8"><p style="text-align: right">采集间隔</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitor?.intervals}}s</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.intervals }}s</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">创建时间</p></div> <div nz-col nzSpan="8"><p style="text-align: right">创建时间</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitor?.gmtCreate}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.gmtCreate }}</p></div
>
</div> </div>
<div nz-row nzGutter="16"> <div nz-row nzGutter="16">
<div nz-col nzSpan="8"><p style="text-align: right">最近更新时间</p></div> <div nz-col nzSpan="8"><p style="text-align: right">最近更新时间</p></div>
<div nz-col nzSpan="16"><p style="text-align: left">{{monitor?.gmtUpdate}}</p></div> <div nz-col nzSpan="16"
><p style="text-align: left">{{ monitor?.gmtUpdate }}</p></div
>
</div> </div>
</nz-card> </nz-card>
</nz-sider> </nz-sider>
@@ -89,7 +105,7 @@
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i> <i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
监控数据报告详情 监控数据报告详情
</ng-template> </ng-template>
<div style="display: flex;justify-content:flex-start;flex-wrap: wrap;"> <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let metric of metrics; let i = index"> <div *ngFor="let metric of metrics; let i = index">
<app-monitor-data-chart [metrics]="metric" [monitorId]="monitorId"></app-monitor-data-chart> <app-monitor-data-chart [metrics]="metric" [monitorId]="monitorId"></app-monitor-data-chart>
</div> </div>

View File

@@ -8,9 +8,8 @@ describe('MonitorDetailComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ MonitorDetailComponent ] declarations: [MonitorDetailComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,10 +1,11 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {MonitorService} from "../../../service/monitor.service"; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import {ActivatedRoute, ParamMap, Router} from "@angular/router"; import { TitleService } from '@delon/theme';
import {TitleService} from "@delon/theme"; import { switchMap } from 'rxjs/operators';
import {switchMap} from "rxjs/operators";
import {Param} from "../../../pojo/Param"; import { Monitor } from '../../../pojo/Monitor';
import {Monitor} from "../../../pojo/Monitor"; import { Param } from '../../../pojo/Param';
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'app-monitor-detail', selector: 'app-monitor-detail',
@@ -12,12 +13,8 @@ import {Monitor} from "../../../pojo/Monitor";
styleUrls: ['./monitor-detail.component.less'] styleUrls: ['./monitor-detail.component.less']
}) })
export class MonitorDetailComponent implements OnInit { export class MonitorDetailComponent implements OnInit {
constructor(private monitorSvc: MonitorService, private route: ActivatedRoute, private router: Router, private titleSvc: TitleService) {}
constructor(private monitorSvc: MonitorService, isSpinning: boolean = false;
private route: ActivatedRoute,
private router: Router,
private titleSvc: TitleService) { }
isSpinning: boolean = false
monitorId!: number; monitorId!: number;
app: string | undefined; app: string | undefined;
monitor: Monitor | undefined; monitor: Monitor | undefined;
@@ -26,15 +23,18 @@ export class MonitorDetailComponent implements OnInit {
metrics!: string[]; metrics!: string[];
ngOnInit(): void { ngOnInit(): void {
this.route.paramMap.pipe( this.route.paramMap
.pipe(
switchMap((paramMap: ParamMap) => { switchMap((paramMap: ParamMap) => {
this.isSpinning = true; this.isSpinning = true;
let id = paramMap.get("monitorId"); let id = paramMap.get('monitorId');
this.monitorId = Number(id); this.monitorId = Number(id);
// 查询监控指标组结构信息 // 查询监控指标组结构信息
return this.monitorSvc.getMonitor(this.monitorId); return this.monitorSvc.getMonitor(this.monitorId);
}) })
).subscribe(message => { )
.subscribe(
message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.monitor = message.data.monitor; this.monitor = message.data.monitor;
@@ -45,13 +45,15 @@ export class MonitorDetailComponent implements OnInit {
if (param.field === 'port') { if (param.field === 'port') {
this.port = Number(param.value); this.port = Number(param.value);
} }
}) });
this.metrics = message.data.metrics; this.metrics = message.data.metrics;
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
}, error => { },
error => {
this.isSpinning = false; this.isSpinning = false;
}); }
);
} }
} }

View File

@@ -7,56 +7,59 @@
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{app: monitor.app ? monitor.app : ''}"> <a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>监控列表</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="edit"></i> <i nz-icon nzType="edit"></i>
<span>修改 {{'monitor.app.' + monitor.app | i18n}} 监控</span> <span>修改 {{ 'monitor.app.' + monitor.app | i18n }} 监控</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-spin [nzSpinning]="isSpinning"> <nz-spin [nzSpinning]="isSpinning">
<div class = "-inner-content"> <div class="-inner-content">
<form nz-form> <form nz-form>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'host' nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> <nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> 监控Host </nz-form-label>
监控Host
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" placeholder="请输入域名或IP"> <input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" placeholder="请输入域名或IP" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'name' nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性"> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性">
监控名称 监控名称
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="monitor.name" nz-input name="name" type="text" id="name" placeholder="监控名称需要保证唯一性"> <input [(ngModel)]="monitor.name" nz-input name="name" type="text" id="name" placeholder="监控名称需要保证唯一性" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item *ngFor="let paramDefine of paramDefines; let i = index"> <nz-form-item *ngFor="let paramDefine of paramDefines; let i = index">
<nz-form-label *ngIf="paramDefine.field !== 'host' && paramDefine.type ==='text'" <nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
nzSpan="7" nzSpan="7"
[nzRequired]="paramDefine.required" [nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}} [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.field !== 'host' && paramDefine.type ==='text'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'" nzSpan="8">
<input nz-input [(ngModel)]="params[i].value" [name]="paramDefine.field" <input
[type]="paramDefine.type" [id]="paramDefine.field" nz-input
[placeholder]="paramDefine.placeholder? paramDefine.placeholder : ''"> [(ngModel)]="params[i].value"
[name]="paramDefine.field"
[type]="paramDefine.type"
[id]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'password'" <nz-form-label *ngIf="paramDefine.type === 'password'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
nzSpan="7" >{{ paramDefine.name }}
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8">
<nz-input-group [nzSuffix]="suffixTemplate"> <nz-input-group [nzSuffix]="suffixTemplate">
@@ -67,7 +70,7 @@
[(ngModel)]="params[i].value" [(ngModel)]="params[i].value"
[id]="paramDefine.field" [id]="paramDefine.field"
[name]="paramDefine.field" [name]="paramDefine.field"
[placeholder]="paramDefine.placeholder? paramDefine.placeholder : ''" [placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/> />
</nz-input-group> </nz-input-group>
<ng-template #suffixTemplate> <ng-template #suffixTemplate>
@@ -75,11 +78,8 @@
</ng-template> </ng-template>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
<nz-form-label *ngIf="paramDefine.type === 'number'" >{{ paramDefine.name }}
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8">
<nz-input-number <nz-input-number
@@ -87,83 +87,64 @@
[nzMin]="-1000" [nzMin]="-1000"
[nzMax]="65535" [nzMax]="65535"
[nzStep]="1" [nzStep]="1"
[nzPlaceHolder]="paramDefine.placeholder? paramDefine.placeholder : ''" [nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
[name]="paramDefine.field" [id]="paramDefine.field" [name]="paramDefine.field"
[id]="paramDefine.field"
></nz-input-number> ></nz-input-number>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'boolean'" <nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
nzSpan="7" >{{ paramDefine.name }}
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8">
<nz-switch [(ngModel)]="params[i].value" [name]="paramDefine.field" [id]="paramDefine.field"></nz-switch> <nz-switch [(ngModel)]="params[i].value" [name]="paramDefine.field" [id]="paramDefine.field"></nz-switch>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'radio'" <nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
nzSpan="7" >{{ paramDefine.name }}
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8">
<nz-radio-group [(ngModel)]="params[i].value" nzButtonStyle="solid" <nz-radio-group [(ngModel)]="params[i].value" nzButtonStyle="solid" [name]="paramDefine.field" [id]="paramDefine.field">
[name]="paramDefine.field" [id]="paramDefine.field">
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options"> <label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
{{optionItem.label}} {{ optionItem.label }}
</label> </label>
</nz-radio-group> </nz-radio-group>
</nz-form-control> </nz-form-control>
</nz-form-item>
</nz-form-item >
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor= "intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> <nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
采集间隔
</nz-form-label>
<nz-form-control nzSpan="10"> <nz-form-control nzSpan="10">
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="10000" [nzStep]="8" <nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="10000" [nzStep]="8" name="intervals" id="intervals">
name="intervals" id="intervals">
</nz-input-number> </nz-input-number>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor= "detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> <nz-form-label nzSpan="7" nzFor="detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> 是否探测 </nz-form-label>
是否探测
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch> <nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'description' nzTooltipTitle="更多标识和描述此监控的备注信息"> <nz-form-label [nzSpan]="7" nzFor="description" nzTooltipTitle="更多标识和描述此监控的备注信息"> 描述备注 </nz-form-label>
描述备注
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea> <textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<div nz-row> <div nz-row>
<div nz-col nzSpan="8" nzOffset="9"> <div nz-col nzSpan="8" nzOffset="9">
<button nz-button nzType="primary" type="submit" (click)="onDetect()"> <button nz-button nzType="primary" type="submit" (click)="onDetect()"> 探测 </button>
探测 <button nz-button nzType="primary" type="submit" (click)="onSubmit()"> 确定 </button>
</button> <button nz-button nzType="primary" type="reset" (click)="onCancel()"> 取消 </button>
<button nz-button nzType="primary" type="submit" (click)="onSubmit()">
确定
</button>
<button nz-button nzType="primary" type="reset" (click)="onCancel()">
取消
</button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</nz-spin> </nz-spin>

View File

@@ -8,9 +8,8 @@ describe('MonitorModifyComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ MonitorEditComponent ] declarations: [MonitorEditComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,31 +1,32 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {switchMap} from "rxjs/operators"; import { FormGroup } from '@angular/forms';
import {ActivatedRoute, ParamMap, Router} from "@angular/router"; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import {Param} from "../../../pojo/Param"; import { TitleService } from '@delon/theme';
import {AppDefineService} from "../../../service/app-define.service"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {MonitorService} from "../../../service/monitor.service"; import { throwError } from 'rxjs';
import {NzNotificationService} from "ng-zorro-antd/notification"; import { switchMap } from 'rxjs/operators';
import {ParamDefine} from "../../../pojo/ParamDefine";
import {Monitor} from "../../../pojo/Monitor"; import { Message } from '../../../pojo/Message';
import {FormGroup} from "@angular/forms"; import { Monitor } from '../../../pojo/Monitor';
import {Message} from "../../../pojo/Message"; import { Param } from '../../../pojo/Param';
import {throwError} from "rxjs"; import { ParamDefine } from '../../../pojo/ParamDefine';
import {TitleService} from "@delon/theme"; import { AppDefineService } from '../../../service/app-define.service';
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'app-monitor-modify', selector: 'app-monitor-modify',
templateUrl: './monitor-edit.component.html', templateUrl: './monitor-edit.component.html',
styles: [ styles: []
]
}) })
export class MonitorEditComponent implements OnInit { export class MonitorEditComponent implements OnInit {
constructor(
constructor(private appDefineSvc: AppDefineService, private appDefineSvc: AppDefineService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private titleSvc: TitleService, private titleSvc: TitleService,
private notifySvc: NzNotificationService,) { } private notifySvc: NzNotificationService
) {}
paramDefines!: ParamDefine[]; paramDefines!: ParamDefine[];
params!: Param[]; params!: Param[];
@@ -34,36 +35,41 @@ export class MonitorEditComponent implements OnInit {
profileForm: FormGroup = new FormGroup({}); profileForm: FormGroup = new FormGroup({});
detected: boolean = true; detected: boolean = true;
passwordVisible: boolean = false; passwordVisible: boolean = false;
isSpinning:boolean = false isSpinning: boolean = false;
ngOnInit(): void { ngOnInit(): void {
this.route.paramMap.pipe( this.route.paramMap
.pipe(
switchMap((paramMap: ParamMap) => { switchMap((paramMap: ParamMap) => {
this.isSpinning = false; this.isSpinning = false;
this.passwordVisible = false; this.passwordVisible = false;
let id = paramMap.get("monitorId"); let id = paramMap.get('monitorId');
this.monitor.id = Number(id); this.monitor.id = Number(id);
// 查询监控信息 // 查询监控信息
return this.monitorSvc.getMonitor(this.monitor.id); return this.monitorSvc.getMonitor(this.monitor.id);
}) })
).pipe(switchMap((message: Message<any>) => { )
.pipe(
switchMap((message: Message<any>) => {
if (message.code === 0) { if (message.code === 0) {
this.monitor = message.data.monitor; this.monitor = message.data.monitor;
this.titleSvc.setTitleByI18n('monitor.app.' + this.monitor.app) this.titleSvc.setTitleByI18n(`monitor.app.${this.monitor.app}`);
if (message.data.params != null) { if (message.data.params != null) {
message.data.params.forEach((item: Param) => { message.data.params.forEach((item: Param) => {
this.paramValueMap.set(item.field, item) this.paramValueMap.set(item.field, item);
}); });
} }
this.params = message.data.params; this.params = message.data.params;
this.detected = message.data.detected? message.data.detected : true; this.detected = message.data.detected ? message.data.detected : true;
} else { } else {
console.warn(message.msg); console.warn(message.msg);
this.notifySvc.error("查询异常,此监控不存在", message.msg); this.notifySvc.error('查询异常,此监控不存在', message.msg);
return throwError("查询此监控异常"); return throwError('查询此监控异常');
} }
return this.appDefineSvc.getAppParamsDefine(this.monitor.app); return this.appDefineSvc.getAppParamsDefine(this.monitor.app);
})).subscribe(message => { })
)
.subscribe(message => {
if (message.code === 0) { if (message.code === 0) {
this.paramDefines = message.data; this.paramDefines = message.data;
this.params = []; this.params = [];
@@ -71,15 +77,15 @@ export class MonitorEditComponent implements OnInit {
let param = this.paramValueMap.get(define.field); let param = this.paramValueMap.get(define.field);
if (param === undefined) { if (param === undefined) {
param = new Param(); param = new Param();
param.type = define.type === "number" ? 0 : 1; param.type = define.type === 'number' ? 0 : 1;
if (define.type === "boolean") { if (define.type === 'boolean') {
param.value = false; param.value = false;
} }
if (param.field === "host") { if (param.field === 'host') {
param.value = this.monitor.host; param.value = this.monitor.host;
} }
} else { } else {
if (define.type === "boolean") { if (define.type === 'boolean') {
if (param.value != null) { if (param.value != null) {
param.value = param.value.toLowerCase() == 'true'; param.value = param.value.toLowerCase() == 'true';
} else { } else {
@@ -88,7 +94,7 @@ export class MonitorEditComponent implements OnInit {
} }
} }
this.params.push(param); this.params.push(param);
}) });
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
@@ -98,65 +104,65 @@ export class MonitorEditComponent implements OnInit {
onSubmit() { onSubmit() {
// todo 暂时单独设置host属性值 // todo 暂时单独设置host属性值
this.params.forEach(param => { this.params.forEach(param => {
if (param.field === "host") { if (param.field === 'host') {
param.value = this.monitor.host; param.value = this.monitor.host;
} }
}); });
let addMonitor = { let addMonitor = {
"detected": this.detected, detected: this.detected,
"monitor": this.monitor, monitor: this.monitor,
"params": this.params params: this.params
}; };
this.isSpinning = true; this.isSpinning = true;
this.monitorSvc.editMonitor(addMonitor) this.monitorSvc.editMonitor(addMonitor).subscribe(
.subscribe(message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("修改监控成功", ""); this.notifySvc.success('修改监控成功', '');
this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`) this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`);
} else { } else {
this.notifySvc.error("修改监控失败", message.msg); this.notifySvc.error('修改监控失败', message.msg);
}}, }
},
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error("修改监控失败", error.error.msg); this.notifySvc.error('修改监控失败', error.error.msg);
} }
) );
} }
onDetect() { onDetect() {
// todo 暂时单独设置host属性值 // todo 暂时单独设置host属性值
this.params.forEach(param => { this.params.forEach(param => {
if (param.field === "host") { if (param.field === 'host') {
param.value = this.monitor.host; param.value = this.monitor.host;
} }
}); });
let detectMonitor = { let detectMonitor = {
"detected": this.detected, detected: this.detected,
"monitor": this.monitor, monitor: this.monitor,
"params": this.params params: this.params
}; };
this.isSpinning = true; this.isSpinning = true;
this.monitorSvc.detectMonitor(detectMonitor) this.monitorSvc.detectMonitor(detectMonitor).subscribe(
.subscribe(message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("探测成功", ""); this.notifySvc.success('探测成功', '');
} else { } else {
this.notifySvc.error("探测失败", message.msg); this.notifySvc.error('探测失败', message.msg);
} }
}, },
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error("探测异常", error.error.msg); this.notifySvc.error('探测异常', error.error.msg);
} }
) );
} }
onCancel() { onCancel() {
let app = this.monitor.app; let app = this.monitor.app;
app = app ? app : ''; app = app ? app : '';
this.router.navigateByUrl(`/monitors?app=${app}`) this.router.navigateByUrl(`/monitors?app=${app}`);
} }
} }

View File

@@ -8,17 +8,17 @@
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>{{'monitor.app.' + app | i18n}} 监控列表</span> <span>{{ 'monitor.app.' + app | i18n }} 监控列表</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<button nz-button nzType="primary"> <button nz-button nzType="primary">
<a routerLink="/monitors/new" [queryParams]="{app: app}"> <a routerLink="/monitors/new" [queryParams]="{ app: app }">
<i nz-icon nzType="appstore-add" nzTheme="outline"></i> <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
新增 {{'monitor.app.' + app | i18n}} 新增 {{ 'monitor.app.' + app | i18n }}
</a> </a>
</button> </button>
<button nz-button nzType="primary" (click)="onEditMonitor()" > <button nz-button nzType="primary" (click)="onEditMonitor()">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
编辑 编辑
</button> </button>
@@ -38,15 +38,21 @@
<i nz-icon nzType="sync" nzTheme="outline"></i> <i nz-icon nzType="sync" nzTheme="outline"></i>
</button> </button>
<nz-table #fixedTable [nzData]="monitors" <nz-table
[nzPageIndex]="pageIndex" [nzPageSize]="pageSize" [nzTotal]="total" #fixedTable
nzFrontPagination ="false" [nzData]="monitors"
[nzLoading] = "tableLoading" [nzPageIndex]="pageIndex"
[nzPageSize]="pageSize"
[nzTotal]="total"
nzFrontPagination="false"
[nzLoading]="tableLoading"
nzShowSizeChanger nzShowSizeChanger
[nzShowTotal]="rangeTemplate" [nzShowTotal]="rangeTemplate"
[nzPageSizeOptions]="[8,15,25]" [nzPageSizeOptions]="[8, 15, 25]"
(nzQueryParams)="onTablePageChange($event)" (nzQueryParams)="onTablePageChange($event)"
nzShowPagination = "true" [nzScroll]="{ x: '1150px', y: '1240px' }"> nzShowPagination="true"
[nzScroll]="{ x: '1150px', y: '1240px' }"
>
<thead> <thead>
<tr> <tr>
<th nzAlign="center" nzLeft nzWidth="60px" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th> <th nzAlign="center" nzLeft nzWidth="60px" [(nzChecked)]="checkedAll" (nzCheckedChange)="onAllChecked($event)"></th>
@@ -95,7 +101,7 @@
<span>{{ 'monitor.app.' + data.app | i18n }}</span> <span>{{ 'monitor.app.' + data.app | i18n }}</span>
</nz-tag> </nz-tag>
</td> </td>
<td nzAlign="center">{{ data.gmtUpdate? data.gmtUpdate : data.gmtCreate }}</td> <td nzAlign="center">{{ data.gmtUpdate ? data.gmtUpdate : data.gmtCreate }}</td>
<td nzAlign="center" nzRight> <td nzAlign="center" nzRight>
<button nz-button nzType="primary" (click)="onEditOneMonitor(data.id)" nz-tooltip nzTooltipTitle="修改监控"> <button nz-button nzType="primary" (click)="onEditOneMonitor(data.id)" nz-tooltip nzTooltipTitle="修改监控">
<i nz-icon nzType="edit" nzTheme="outline"></i> <i nz-icon nzType="edit" nzTheme="outline"></i>
@@ -114,6 +120,4 @@
</tbody> </tbody>
</nz-table> </nz-table>
<ng-template #rangeTemplate> <ng-template #rangeTemplate> 总量 {{ total }} </ng-template>
总量 {{ total }}
</ng-template>

View File

@@ -8,9 +8,8 @@ describe('MonitorListComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ MonitorListComponent ] declarations: [MonitorListComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,26 +1,27 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router"; import { ActivatedRoute, Router } from '@angular/router';
import {MonitorService} from "../../../service/monitor.service"; import { NzMessageService } from 'ng-zorro-antd/message';
import {Monitor} from "../../../pojo/Monitor"; import { NzModalService } from 'ng-zorro-antd/modal';
import {NzModalService} from "ng-zorro-antd/modal"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {NzNotificationService} from "ng-zorro-antd/notification"; import { NzTableQueryParams } from 'ng-zorro-antd/table';
import {NzMessageService} from "ng-zorro-antd/message";
import {NzTableQueryParams} from "ng-zorro-antd/table"; import { Monitor } from '../../../pojo/Monitor';
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'app-monitor-list', selector: 'app-monitor-list',
templateUrl: './monitor-list.component.html', templateUrl: './monitor-list.component.html',
styles: [ styles: []
]
}) })
export class MonitorListComponent implements OnInit { export class MonitorListComponent implements OnInit {
constructor(
constructor(private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private modal: NzModalService, private modal: NzModalService,
private notifySvc: NzNotificationService, private notifySvc: NzNotificationService,
private msg: NzMessageService, private msg: NzMessageService,
private monitorSvc: MonitorService) { } private monitorSvc: MonitorService
) {}
app!: string; app!: string;
pageIndex: number = 1; pageIndex: number = 1;
@@ -31,9 +32,8 @@ export class MonitorListComponent implements OnInit {
checkedMonitorIds = new Set<number>(); checkedMonitorIds = new Set<number>();
ngOnInit(): void { ngOnInit(): void {
this.route.queryParamMap this.route.queryParamMap.subscribe(paramMap => {
.subscribe(paramMap => { this.app = paramMap.get('app') || '';
this.app = paramMap.get("app") || '';
this.pageIndex = 1; this.pageIndex = 1;
this.pageSize = 8; this.pageSize = 8;
this.checkedMonitorIds = new Set<number>(); this.checkedMonitorIds = new Set<number>();
@@ -48,8 +48,8 @@ export class MonitorListComponent implements OnInit {
loadMonitorTable() { loadMonitorTable() {
this.tableLoading = true; this.tableLoading = true;
let monitorInit$ = this.monitorSvc.getMonitors(this.app, this.pageIndex - 1, this.pageSize) let monitorInit$ = this.monitorSvc.getMonitors(this.app, this.pageIndex - 1, this.pageSize).subscribe(
.subscribe(message => { message => {
this.tableLoading = false; this.tableLoading = false;
this.checkedAll = false; this.checkedAll = false;
this.checkedMonitorIds.clear(); this.checkedMonitorIds.clear();
@@ -66,12 +66,13 @@ export class MonitorListComponent implements OnInit {
error => { error => {
this.tableLoading = false; this.tableLoading = false;
monitorInit$.unsubscribe(); monitorInit$.unsubscribe();
}); }
);
} }
onEditOneMonitor(monitorId: number) { onEditOneMonitor(monitorId: number) {
if (monitorId == null) { if (monitorId == null) {
this.notifySvc.warning("未选中任何待编辑项!",""); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
this.router.navigateByUrl(`/monitors/${monitorId}/edit`); this.router.navigateByUrl(`/monitors/${monitorId}/edit`);
@@ -82,15 +83,15 @@ export class MonitorListComponent implements OnInit {
onEditMonitor() { onEditMonitor() {
// 编辑时只能选中一个监控 // 编辑时只能选中一个监控
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning("未选中任何待编辑项!",""); this.notifySvc.warning('未选中任何待编辑项!', '');
return; return;
} }
if (this.checkedMonitorIds.size > 1) { if (this.checkedMonitorIds.size > 1) {
this.notifySvc.warning("只能对一个选中项进行编辑!",""); this.notifySvc.warning('只能对一个选中项进行编辑!', '');
return; return;
} }
let monitorId = 0; let monitorId = 0;
this.checkedMonitorIds.forEach(item => monitorId = item); this.checkedMonitorIds.forEach(item => (monitorId = item));
this.router.navigateByUrl(`/monitors/${monitorId}/edit`); this.router.navigateByUrl(`/monitors/${monitorId}/edit`);
} }
@@ -102,14 +103,14 @@ export class MonitorListComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteMonitors(monitors) nzOnOk: () => this.deleteMonitors(monitors)
}); });
} }
onDeleteMonitors() { onDeleteMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning("未选中任何待删除项!",""); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -117,40 +118,39 @@ export class MonitorListComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.deleteMonitors(this.checkedMonitorIds) nzOnOk: () => this.deleteMonitors(this.checkedMonitorIds)
}); });
} }
deleteMonitors(monitors: Set<number>) { deleteMonitors(monitors: Set<number>) {
if (monitors == null || monitors.size == 0) { if (monitors == null || monitors.size == 0) {
this.notifySvc.warning("未选中任何待删除项!",""); this.notifySvc.warning('未选中任何待删除项!', '');
return; return;
} }
this.tableLoading = true; this.tableLoading = true;
const deleteMonitors$ = this.monitorSvc.deleteMonitors(monitors) const deleteMonitors$ = this.monitorSvc.deleteMonitors(monitors).subscribe(
.subscribe(message => { message => {
deleteMonitors$.unsubscribe(); deleteMonitors$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("删除成功!", ""); this.notifySvc.success('删除成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error("删除失败!", message.msg); this.notifySvc.error('删除失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
deleteMonitors$.unsubscribe(); deleteMonitors$.unsubscribe();
this.notifySvc.error("删除失败!", error.msg) this.notifySvc.error('删除失败!', error.msg);
} }
); );
} }
onCancelManageMonitors() { onCancelManageMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning("未选中任何待取消项!",""); this.notifySvc.warning('未选中任何待取消项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -158,7 +158,7 @@ export class MonitorListComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.cancelManageMonitors(this.checkedMonitorIds) nzOnOk: () => this.cancelManageMonitors(this.checkedMonitorIds)
}); });
} }
@@ -171,35 +171,35 @@ export class MonitorListComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.cancelManageMonitors(monitors) nzOnOk: () => this.cancelManageMonitors(monitors)
}); });
} }
cancelManageMonitors(monitors: Set<number>) { cancelManageMonitors(monitors: Set<number>) {
this.tableLoading = true; this.tableLoading = true;
const cancelManage$ = this.monitorSvc.cancelManageMonitors(monitors) const cancelManage$ = this.monitorSvc.cancelManageMonitors(monitors).subscribe(
.subscribe(message => { message => {
cancelManage$.unsubscribe(); cancelManage$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("取消纳管成功!", ""); this.notifySvc.success('取消纳管成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error("取消纳管失败!", message.msg); this.notifySvc.error('取消纳管失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
cancelManage$.unsubscribe(); cancelManage$.unsubscribe();
this.notifySvc.error("取消纳管失败!", error.msg) this.notifySvc.error('取消纳管失败!', error.msg);
} }
); );
} }
onEnableManageMonitors() { onEnableManageMonitors() {
if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) { if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
this.notifySvc.warning("未选中任何待启用纳管项!",""); this.notifySvc.warning('未选中任何待启用纳管项!', '');
return; return;
} }
this.modal.confirm({ this.modal.confirm({
@@ -207,7 +207,7 @@ export class MonitorListComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.enableManageMonitors(this.checkedMonitorIds) nzOnOk: () => this.enableManageMonitors(this.checkedMonitorIds)
}); });
} }
@@ -220,28 +220,28 @@ export class MonitorListComponent implements OnInit {
nzOkText: '确定', nzOkText: '确定',
nzCancelText: '取消', nzCancelText: '取消',
nzOkDanger: true, nzOkDanger: true,
nzOkType: "primary", nzOkType: 'primary',
nzOnOk: () => this.enableManageMonitors(monitors) nzOnOk: () => this.enableManageMonitors(monitors)
}); });
} }
enableManageMonitors(monitors: Set<number>) { enableManageMonitors(monitors: Set<number>) {
this.tableLoading = true; this.tableLoading = true;
const enableManage$ = this.monitorSvc.enableManageMonitors(monitors) const enableManage$ = this.monitorSvc.enableManageMonitors(monitors).subscribe(
.subscribe(message => { message => {
enableManage$.unsubscribe(); enableManage$.unsubscribe();
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("启用纳管成功!", ""); this.notifySvc.success('启用纳管成功!', '');
this.loadMonitorTable(); this.loadMonitorTable();
} else { } else {
this.tableLoading = false; this.tableLoading = false;
this.notifySvc.error("启用纳管失败!", message.msg); this.notifySvc.error('启用纳管失败!', message.msg);
} }
}, },
error => { error => {
this.tableLoading = false; this.tableLoading = false;
enableManage$.unsubscribe(); enableManage$.unsubscribe();
this.notifySvc.error("启用纳管失败!", error.msg) this.notifySvc.error('启用纳管失败!', error.msg);
} }
); );
} }
@@ -266,6 +266,7 @@ export class MonitorListComponent implements OnInit {
/** /**
* 分页回调 * 分页回调
*
* @param params 页码信息 * @param params 页码信息
*/ */
onTablePageChange(params: NzTableQueryParams) { onTablePageChange(params: NzTableQueryParams) {
@@ -274,5 +275,4 @@ export class MonitorListComponent implements OnInit {
this.pageSize = pageSize; this.pageSize = pageSize;
this.loadMonitorTable(); this.loadMonitorTable();
} }
} }

View File

@@ -7,57 +7,67 @@
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<a [routerLink]="['/monitors']" [queryParams]="{app: monitor.app ? monitor.app : ''}"> <a [routerLink]="['/monitors']" [queryParams]="{ app: monitor.app ? monitor.app : '' }">
<i nz-icon nzType="monitor"></i> <i nz-icon nzType="monitor"></i>
<span>监控列表</span> <span>监控列表</span>
</a> </a>
</nz-breadcrumb-item> </nz-breadcrumb-item>
<nz-breadcrumb-item> <nz-breadcrumb-item>
<i nz-icon nzType="plus-circle"></i> <i nz-icon nzType="plus-circle"></i>
<span>新增 {{'monitor.app.' + monitor.app | i18n}} 监控</span> <span>新增 {{ 'monitor.app.' + monitor.app | i18n }} 监控</span>
</nz-breadcrumb-item> </nz-breadcrumb-item>
</nz-breadcrumb> </nz-breadcrumb>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-spin [nzSpinning]="isSpinning"> <nz-spin [nzSpinning]="isSpinning">
<div class = "-inner-content"> <div class="-inner-content">
<form nz-form> <form nz-form>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'host' nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> <nz-form-label [nzSpan]="7" nzFor="host" nzRequired="true" nzTooltipTitle="被监控的对端IP或域名"> 监控Host </nz-form-label>
监控Host
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host" <input
placeholder="请输入域名或IP" (ngModelChange)="onHostChange($event)"> [(ngModel)]="monitor.host"
nz-input
name="host"
type="text"
id="host"
placeholder="请输入域名或IP"
(ngModelChange)="onHostChange($event)"
/>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'name' nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性"> <nz-form-label [nzSpan]="7" nzFor="name" nzRequired="true" nzTooltipTitle="标识此监控的名称,名称需要保证唯一性">
监控名称 监控名称
</nz-form-label> </nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<input [(ngModel)]="monitor.name" nz-input name="name" type="text" id="name" placeholder="监控名称需要保证唯一性"> <input [(ngModel)]="monitor.name" nz-input name="name" type="text" id="name" placeholder="监控名称需要保证唯一性" />
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item *ngFor="let paramDefine of paramDefines; let i = index"> <nz-form-item *ngFor="let paramDefine of paramDefines; let i = index">
<nz-form-label *ngIf="paramDefine.field !== 'host' && paramDefine.type ==='text'" <nz-form-label
*ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'"
nzSpan="7" nzSpan="7"
[nzRequired]="paramDefine.required" [nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}} [nzFor]="paramDefine.field"
>{{ paramDefine.name }}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.field !== 'host' && paramDefine.type ==='text'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.field !== 'host' && paramDefine.type === 'text'" nzSpan="8">
<input nz-input [(ngModel)]="params[i].value" [name]="paramDefine.field" <input
[type]="paramDefine.type" [id]="paramDefine.field" nz-input
[placeholder]="paramDefine.placeholder? paramDefine.placeholder : ''"> [(ngModel)]="params[i].value"
[name]="paramDefine.field"
[type]="paramDefine.type"
[id]="paramDefine.field"
[placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'password'" <nz-form-label *ngIf="paramDefine.type === 'password'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
nzSpan="7" >{{ paramDefine.name }}
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="8">
<nz-input-group [nzSuffix]="suffixTemplate"> <nz-input-group [nzSuffix]="suffixTemplate">
@@ -68,7 +78,7 @@
[(ngModel)]="params[i].value" [(ngModel)]="params[i].value"
[id]="paramDefine.field" [id]="paramDefine.field"
[name]="paramDefine.field" [name]="paramDefine.field"
[placeholder]="paramDefine.placeholder? paramDefine.placeholder : ''" [placeholder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
/> />
</nz-input-group> </nz-input-group>
<ng-template #suffixTemplate> <ng-template #suffixTemplate>
@@ -76,11 +86,8 @@
</ng-template> </ng-template>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'number'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
<nz-form-label *ngIf="paramDefine.type === 'number'" >{{ paramDefine.name }}
nzSpan="7"
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="8">
<nz-input-number <nz-input-number
@@ -88,83 +95,64 @@
[nzMin]="-1000" [nzMin]="-1000"
[nzMax]="65535" [nzMax]="65535"
[nzStep]="1" [nzStep]="1"
[nzPlaceHolder]="paramDefine.placeholder? paramDefine.placeholder : ''" [nzPlaceHolder]="paramDefine.placeholder ? paramDefine.placeholder : ''"
[name]="paramDefine.field" [id]="paramDefine.field" [name]="paramDefine.field"
[id]="paramDefine.field"
></nz-input-number> ></nz-input-number>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'boolean'" <nz-form-label *ngIf="paramDefine.type === 'boolean'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
nzSpan="7" >{{ paramDefine.name }}
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="8">
<nz-switch [(ngModel)]="params[i].value" [name]="paramDefine.field" [id]="paramDefine.field"></nz-switch> <nz-switch [(ngModel)]="params[i].value" [name]="paramDefine.field" [id]="paramDefine.field"></nz-switch>
</nz-form-control> </nz-form-control>
<nz-form-label *ngIf="paramDefine.type === 'radio'" <nz-form-label *ngIf="paramDefine.type === 'radio'" nzSpan="7" [nzRequired]="paramDefine.required" [nzFor]="paramDefine.field"
nzSpan="7" >{{ paramDefine.name }}
[nzRequired]="paramDefine.required"
[nzFor]= "paramDefine.field">{{paramDefine.name}}
</nz-form-label> </nz-form-label>
<nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8"> <nz-form-control *ngIf="paramDefine.type === 'radio'" nzSpan="8">
<nz-radio-group [(ngModel)]="params[i].value" nzButtonStyle="solid" <nz-radio-group [(ngModel)]="params[i].value" nzButtonStyle="solid" [name]="paramDefine.field" [id]="paramDefine.field">
[name]="paramDefine.field" [id]="paramDefine.field">
<label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options"> <label nz-radio-button [nzValue]="optionItem.value" *ngFor="let optionItem of paramDefine.options">
{{optionItem.label}} {{ optionItem.label }}
</label> </label>
</nz-radio-group> </nz-radio-group>
</nz-form-control> </nz-form-control>
</nz-form-item>
</nz-form-item >
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor= "intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> <nz-form-label nzSpan="7" nzFor="intervals" nzTooltipTitle="监控周期性采集数据间隔时间,单位秒"> 采集间隔 </nz-form-label>
采集间隔
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="10000" [nzStep]="10" <nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="10000" [nzStep]="10" name="intervals" id="intervals">
name="intervals" id="intervals">
</nz-input-number> </nz-input-number>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label nzSpan="7" nzFor= "detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> <nz-form-label nzSpan="7" nzFor="detect" nzTooltipTitle="新增监控前是否先探测检查监控可用性"> 是否探测 </nz-form-label>
是否探测
</nz-form-label>
<nz-form-control nzSpan="8"> <nz-form-control nzSpan="8">
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch> <nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<nz-form-item> <nz-form-item>
<nz-form-label [nzSpan]="7" nzFor= 'description' nzTooltipTitle="更多标识和描述此监控的备注信息"> <nz-form-label [nzSpan]="7" nzFor="description" nzTooltipTitle="更多标识和描述此监控的备注信息"> 描述备注 </nz-form-label>
描述备注
</nz-form-label>
<nz-form-control [nzSpan]="8"> <nz-form-control [nzSpan]="8">
<nz-textarea-count [nzMaxCharacterCount]="100"> <nz-textarea-count [nzMaxCharacterCount]="100">
<textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea> <textarea [(ngModel)]="monitor.description" rows="3" nz-input name="description" id="description"></textarea>
</nz-textarea-count> </nz-textarea-count>
</nz-form-control> </nz-form-control>
</nz-form-item > </nz-form-item>
<div nz-row> <div nz-row>
<div nz-col nzSpan="8" nzOffset="9"> <div nz-col nzSpan="8" nzOffset="9">
<button nz-button nzType="primary" type="submit" (click)="onDetect()"> <button nz-button nzType="primary" type="submit" (click)="onDetect()"> 探测 </button>
探测 <button nz-button nzType="primary" type="submit" (click)="onSubmit()"> 确定 </button>
</button> <button nz-button nzType="primary" type="reset" (click)="onCancel()"> 取消 </button>
<button nz-button nzType="primary" type="submit" (click)="onSubmit()">
确定
</button>
<button nz-button nzType="primary" type="reset" (click)="onCancel()">
取消
</button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</nz-spin> </nz-spin>

View File

@@ -8,9 +8,8 @@ describe('MonitorAddComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ MonitorNewComponent ] declarations: [MonitorNewComponent]
}) }).compileComponents();
.compileComponents();
}); });
beforeEach(() => { beforeEach(() => {

View File

@@ -1,24 +1,23 @@
import {ChangeDetectorRef, Component, OnInit} from '@angular/core'; import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import {ParamDefine} from "../../../pojo/ParamDefine"; import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import {AppDefineService} from "../../../service/app-define.service"; import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import {ActivatedRoute, ParamMap, Router} from "@angular/router"; import { I18NService } from '@core';
import {switchMap} from "rxjs/operators"; import { TitleService } from '@delon/theme';
import {FormBuilder, FormControl, FormGroup} from "@angular/forms"; import { NzNotificationService } from 'ng-zorro-antd/notification';
import {I18NService} from "@core"; import { switchMap } from 'rxjs/operators';
import {Param} from "../../../pojo/Param";
import {Monitor} from "../../../pojo/Monitor"; import { Monitor } from '../../../pojo/Monitor';
import {MonitorService} from "../../../service/monitor.service"; import { Param } from '../../../pojo/Param';
import {NzNotificationService} from "ng-zorro-antd/notification"; import { ParamDefine } from '../../../pojo/ParamDefine';
import {TitleService} from "@delon/theme"; import { AppDefineService } from '../../../service/app-define.service';
import { MonitorService } from '../../../service/monitor.service';
@Component({ @Component({
selector: 'app-monitor-add', selector: 'app-monitor-add',
templateUrl: './monitor-new.component.html', templateUrl: './monitor-new.component.html',
styles: [ styles: []
]
}) })
export class MonitorNewComponent implements OnInit { export class MonitorNewComponent implements OnInit {
paramDefines!: ParamDefine[]; paramDefines!: ParamDefine[];
params!: Param[]; params!: Param[];
monitor!: Monitor; monitor!: Monitor;
@@ -26,8 +25,9 @@ export class MonitorNewComponent implements OnInit {
detected: boolean = true; detected: boolean = true;
passwordVisible: boolean = false; passwordVisible: boolean = false;
// 是否显示加载中 // 是否显示加载中
isSpinning:boolean = false isSpinning: boolean = false;
constructor(private appDefineSvc: AppDefineService, constructor(
private appDefineSvc: AppDefineService,
private monitorSvc: MonitorService, private monitorSvc: MonitorService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
@@ -35,42 +35,45 @@ export class MonitorNewComponent implements OnInit {
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private i18n: I18NService, private i18n: I18NService,
private titleSvc: TitleService, private titleSvc: TitleService,
private formBuilder: FormBuilder) { private formBuilder: FormBuilder
) {
this.monitor = new Monitor(); this.monitor = new Monitor();
} }
ngOnInit(): void { ngOnInit(): void {
this.route.queryParamMap.pipe( this.route.queryParamMap
.pipe(
switchMap((paramMap: ParamMap) => { switchMap((paramMap: ParamMap) => {
this.monitor.app = paramMap.get("app") || ''; this.monitor.app = paramMap.get('app') || '';
this.titleSvc.setTitleByI18n('monitor.app.' + this.monitor.app) this.titleSvc.setTitleByI18n(`monitor.app.${this.monitor.app}`);
this.detected = true; this.detected = true;
this.passwordVisible = false; this.passwordVisible = false;
this.isSpinning = false; this.isSpinning = false;
return this.appDefineSvc.getAppParamsDefine(this.monitor.app); return this.appDefineSvc.getAppParamsDefine(this.monitor.app);
}) })
).subscribe(message => { )
.subscribe(message => {
if (message.code === 0) { if (message.code === 0) {
this.paramDefines = message.data; this.paramDefines = message.data;
this.params = []; this.params = [];
this.paramDefines.forEach(define => { this.paramDefines.forEach(define => {
let param = new Param(); let param = new Param();
param.field = define.field; param.field = define.field;
param.type = define.type === "number" ? 0 : 1; param.type = define.type === 'number' ? 0 : 1;
if (define.type === "boolean") { if (define.type === 'boolean') {
param.value = false; param.value = false;
} }
if (define.defaultValue != undefined) { if (define.defaultValue != undefined) {
if (define.type === "number") { if (define.type === 'number') {
param.value = Number(define.defaultValue); param.value = Number(define.defaultValue);
} else if (define.type === "boolean") { } else if (define.type === 'boolean') {
param.value = define.defaultValue.toLowerCase() == 'true' param.value = define.defaultValue.toLowerCase() == 'true';
} else { } else {
param.value = define.defaultValue; param.value = define.defaultValue;
} }
} }
this.params.push(param); this.params.push(param);
}) });
} else { } else {
console.warn(message.msg); console.warn(message.msg);
} }
@@ -78,69 +81,71 @@ export class MonitorNewComponent implements OnInit {
} }
onHostChange(hostValue: string) { onHostChange(hostValue: string) {
this.monitor.name = this.monitor.app.toUpperCase() + '_' + hostValue; this.monitor.name = `${this.monitor.app.toUpperCase()}_${hostValue}`;
} }
onSubmit() { onSubmit() {
// todo 暂时单独设置host属性值 // todo 暂时单独设置host属性值
this.params.forEach(param => { this.params.forEach(param => {
if (param.field === "host") { if (param.field === 'host') {
param.value = this.monitor.host; param.value = this.monitor.host;
} }
}); });
let addMonitor = { let addMonitor = {
"detected": this.detected, detected: this.detected,
"monitor": this.monitor, monitor: this.monitor,
"params": this.params params: this.params
}; };
this.isSpinning = true; this.isSpinning = true;
this.monitorSvc.newMonitor(addMonitor) this.monitorSvc.newMonitor(addMonitor).subscribe(
.subscribe(message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("新增监控成功", ""); this.notifySvc.success('新增监控成功', '');
this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`) this.router.navigateByUrl(`/monitors?app=${this.monitor.app}`);
} else { } else {
this.notifySvc.error("新增监控失败", message.msg); this.notifySvc.error('新增监控失败', message.msg);
}}, }
},
error => { error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error("新增监控失败", error.error.msg); this.notifySvc.error('新增监控失败', error.error.msg);
} }
) );
} }
onDetect() { onDetect() {
// todo 暂时单独设置host属性值 // todo 暂时单独设置host属性值
this.params.forEach(param => { this.params.forEach(param => {
if (param.field === "host") { if (param.field === 'host') {
param.value = this.monitor.host; param.value = this.monitor.host;
} }
}); });
let detectMonitor = { let detectMonitor = {
"detected": this.detected, detected: this.detected,
"monitor": this.monitor, monitor: this.monitor,
"params": this.params params: this.params
}; };
this.isSpinning = true; this.isSpinning = true;
this.monitorSvc.detectMonitor(detectMonitor) this.monitorSvc.detectMonitor(detectMonitor).subscribe(
.subscribe(message => { message => {
this.isSpinning = false; this.isSpinning = false;
if (message.code === 0) { if (message.code === 0) {
this.notifySvc.success("探测成功", ""); this.notifySvc.success('探测成功', '');
} else { } else {
this.notifySvc.error("探测失败", message.msg); this.notifySvc.error('探测失败', message.msg);
} }
}, error => { },
error => {
this.isSpinning = false; this.isSpinning = false;
this.notifySvc.error("探测异常", error.error.msg); this.notifySvc.error('探测异常', error.error.msg);
} }
) );
} }
onCancel() { onCancel() {
let app = this.monitor.app; let app = this.monitor.app;
app = app ? app : ''; app = app ? app : '';
this.router.navigateByUrl(`/monitors?app=${app}`) this.router.navigateByUrl(`/monitors?app=${app}`);
} }
} }

View File

@@ -1,9 +1,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import {MonitorListComponent} from "./monitor-list/monitor-list.component";
import {MonitorNewComponent} from "./monitor-new/monitor-new.component"; import { MonitorDetailComponent } from './monitor-detail/monitor-detail.component';
import {MonitorEditComponent} from "./monitor-edit/monitor-edit.component"; import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
import {MonitorDetailComponent} from "./monitor-detail/monitor-detail.component"; import { MonitorListComponent } from './monitor-list/monitor-list.component';
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: MonitorListComponent }, { path: '', component: MonitorListComponent },
@@ -17,4 +18,4 @@ const routes: Routes = [
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(routes)],
exports: [RouterModule] exports: [RouterModule]
}) })
export class MonitorRoutingModule { } export class MonitorRoutingModule {}

View File

@@ -1,21 +1,22 @@
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';
import { MonitorRoutingModule } from './monitor-routing.module'; import { NzBreadCrumbModule } from 'ng-zorro-antd/breadcrumb';
import {MonitorNewComponent} from "./monitor-new/monitor-new.component"; import { NzDividerModule } from 'ng-zorro-antd/divider';
import {MonitorEditComponent} from "./monitor-edit/monitor-edit.component"; import { NzLayoutModule } from 'ng-zorro-antd/layout';
import {MonitorListComponent} from "./monitor-list/monitor-list.component"; import { NzRadioModule } from 'ng-zorro-antd/radio';
import {MonitorDetailComponent} from "./monitor-detail/monitor-detail.component"; import { NzSpaceModule } from 'ng-zorro-antd/space';
import {NzBreadCrumbModule} from "ng-zorro-antd/breadcrumb"; import { NzSwitchModule } from 'ng-zorro-antd/switch';
import {NzDividerModule} from "ng-zorro-antd/divider"; import { NzTagModule } from 'ng-zorro-antd/tag';
import {NzSwitchModule} from "ng-zorro-antd/switch"; import { NgxEchartsModule } from 'ngx-echarts';
import {NzTagModule} from "ng-zorro-antd/tag";
import {NzRadioModule} from "ng-zorro-antd/radio";
import {NgxEchartsModule} from "ngx-echarts";
import {NzLayoutModule} from "ng-zorro-antd/layout";
import {NzSpaceModule} from "ng-zorro-antd/space";
import {MonitorDataChartComponent} from "./monitor-data-chart/monitor-data-chart.component";
const COMPONENTS: Type<void>[] = [ import { MonitorDataChartComponent } from './monitor-data-chart/monitor-data-chart.component';
import { MonitorDetailComponent } from './monitor-detail/monitor-detail.component';
import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
import { MonitorListComponent } from './monitor-list/monitor-list.component';
import { MonitorNewComponent } from './monitor-new/monitor-new.component';
import { MonitorRoutingModule } from './monitor-routing.module';
const COMPONENTS: Array<Type<void>> = [
MonitorNewComponent, MonitorNewComponent,
MonitorEditComponent, MonitorEditComponent,
MonitorListComponent, MonitorListComponent,
@@ -36,6 +37,6 @@ const COMPONENTS: Type<void>[] = [
NzLayoutModule, NzLayoutModule,
NzSpaceModule NzSpaceModule
], ],
declarations: COMPONENTS, declarations: COMPONENTS
}) })
export class MonitorModule { } export class MonitorModule {}

View File

@@ -1,35 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SocialService } from '@delon/auth';
import { SettingsService } from '@delon/theme';
@Component({
selector: 'app-callback',
template: ``,
providers: [SocialService]
})
export class CallbackComponent implements OnInit {
type = '';
constructor(private socialService: SocialService, private settingsSrv: SettingsService, private route: ActivatedRoute) {}
ngOnInit(): void {
this.type = this.route.snapshot.params.type;
this.mockModel();
}
private mockModel(): void {
const info = {
token: '123456789',
name: 'cipchk',
email: `${this.type}@${this.type}.com`,
id: 10000,
time: +new Date()
};
this.settingsSrv.setUser({
...this.settingsSrv.user,
...info
});
this.socialService.callback(info);
}
}

View File

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

View File

@@ -15,11 +15,7 @@ export class UserLockComponent {
return this.settings.user; return this.settings.user;
} }
constructor( constructor(fb: FormBuilder, private settings: SettingsService, private router: Router) {
fb: FormBuilder,
private settings: SettingsService,
private router: Router
) {
this.f = fb.group({ this.f = fb.group({
password: [null, Validators.required] password: [null, Validators.required]
}); });

View File

@@ -3,7 +3,7 @@
<nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n"> <nz-tab [nzTitle]="'app.login.tab-login-credentials' | i18n">
<nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert> <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
<nz-form-item> <nz-form-item>
<nz-form-control nzErrorTip="Please enter mobile number, muse be: admin or user"> <nz-form-control nzErrorTip="Please enter username: admin or user">
<nz-input-group nzSize="large" nzPrefixIcon="user"> <nz-input-group nzSize="large" nzPrefixIcon="user">
<input nz-input formControlName="userName" placeholder="username: admin or user" /> <input nz-input formControlName="userName" placeholder="username: admin or user" />
</nz-input-group> </nz-input-group>
@@ -17,47 +17,11 @@
</nz-form-control> </nz-form-control>
</nz-form-item> </nz-form-item>
</nz-tab> </nz-tab>
<nz-tab [nzTitle]="'app.login.tab-login-mobile' | i18n">
<nz-form-item>
<nz-form-control [nzErrorTip]="mobileErrorTip">
<nz-input-group nzSize="large" nzPrefixIcon="user">
<input nz-input formControlName="mobile" placeholder="mobile number" />
</nz-input-group>
<ng-template #mobileErrorTip let-i>
<ng-container *ngIf="i.errors.required">
{{ 'validation.phone-number.required' | i18n }}
</ng-container>
<ng-container *ngIf="i.errors.pattern">
{{ 'validation.phone-number.wrong-format' | i18n }}
</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzErrorTip]="'validation.verification-code.required' | i18n">
<nz-row [nzGutter]="8">
<nz-col [nzSpan]="16">
<nz-input-group nzSize="large" nzPrefixIcon="mail">
<input nz-input formControlName="captcha" placeholder="captcha" />
</nz-input-group>
</nz-col>
<nz-col [nzSpan]="8">
<button type="button" nz-button nzSize="large" (click)="getCaptcha()" [disabled]="count >= 0" nzBlock [nzLoading]="loading">
{{ count ? count + 's' : ('app.register.get-verification-code' | i18n) }}
</button>
</nz-col>
</nz-row>
</nz-form-control>
</nz-form-item>
</nz-tab>
</nz-tabset> </nz-tabset>
<nz-form-item> <nz-form-item>
<nz-col [nzSpan]="12"> <nz-col [nzSpan]="12">
<label nz-checkbox formControlName="remember">{{ 'app.login.remember-me' | i18n }}</label> <label nz-checkbox formControlName="remember">{{ 'app.login.remember-me' | i18n }}</label>
</nz-col> </nz-col>
<nz-col [nzSpan]="12" class="text-right">
<a class="forgot" routerLink="/passport/register">{{ 'app.login.forgot-password' | i18n }}</a>
</nz-col>
</nz-form-item> </nz-form-item>
<nz-form-item> <nz-form-item>
<button nz-button type="submit" nzType="primary" nzSize="large" [nzLoading]="loading" nzBlock> <button nz-button type="submit" nzType="primary" nzSize="large" [nzLoading]="loading" nzBlock>
@@ -65,10 +29,3 @@
</button> </button>
</nz-form-item> </nz-form-item>
</form> </form>
<div class="other">
{{ 'app.login.sign-in-with' | i18n }}
<i nz-tooltip nzTooltipTitle="in fact Auth0 via window" (click)="open('auth0', 'window')" nz-icon nzType="alipay-circle" class="icon"></i>
<i nz-tooltip nzTooltipTitle="in fact Github via redirect" (click)="open('github')" nz-icon nzType="taobao-circle" class="icon"></i>
<i (click)="open('weibo', 'window')" nz-icon nzType="weibo-circle" class="icon"></i>
<a class="register" routerLink="/passport/register">{{ 'app.login.signup' | i18n }}</a>
</div>

View File

@@ -5,12 +5,12 @@ import { StartupService } from '@core';
import { ReuseTabService } from '@delon/abc/reuse-tab'; import { ReuseTabService } from '@delon/abc/reuse-tab';
import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth'; import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth';
import { SettingsService, _HttpClient } from '@delon/theme'; import { SettingsService, _HttpClient } from '@delon/theme';
import { environment } from '@env/environment'; import { User } from '@delon/theme/src/services/settings/types';
import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; import { NzTabChangeEvent } from 'ng-zorro-antd/tabs';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import {Message} from "../../../pojo/Message";
import {LocalStorageService} from "../../../service/local-storage.service"; import { Message } from '../../../pojo/Message';
import {User} from "@delon/theme/src/services/settings/types"; import { LocalStorageService } from '../../../service/local-storage.service';
@Component({ @Component({
selector: 'passport-login', selector: 'passport-login',
@@ -73,21 +73,6 @@ export class UserLoginComponent implements OnDestroy {
this.type = index!; this.type = index!;
} }
getCaptcha(): void {
if (this.mobile.invalid) {
this.mobile.markAsDirty({ onlySelf: true });
this.mobile.updateValueAndValidity({ onlySelf: true });
return;
}
this.count = 59;
this.interval$ = setInterval(() => {
this.count -= 1;
if (this.count <= 0) {
clearInterval(this.interval$);
}
}, 1000);
}
// #endregion // #endregion
submit(): void { submit(): void {
@@ -137,11 +122,11 @@ export class UserLoginComponent implements OnDestroy {
// 设置用户Token信息 // 设置用户Token信息
this.storageSvc.storageAuthorizationToken(message.data.token); this.storageSvc.storageAuthorizationToken(message.data.token);
this.storageSvc.storageRefreshToken(message.data.refreshToken); this.storageSvc.storageRefreshToken(message.data.refreshToken);
let user:User = { let user: User = {
name: this.userName.value, name: this.userName.value,
avatar: "./assets/tmp/img/avatar.svg", avatar: './assets/img/avatar.svg',
email: "" email: '管理员'
} };
this.settingsService.setUser(user); this.settingsService.setUser(user);
// 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响
this.startupSrv.load().subscribe(() => { this.startupSrv.load().subscribe(() => {
@@ -153,48 +138,6 @@ export class UserLoginComponent implements OnDestroy {
}); });
}); });
} }
// #region social
open(type: string, openType: SocialOpenType = 'href'): void {
let url = ``;
let callback = ``;
if (environment.production) {
callback = `https://ng-alain.github.io/ng-alain/#/passport/callback/${type}`;
} else {
callback = `http://localhost:4200/#/passport/callback/${type}`;
}
switch (type) {
case 'auth0':
url = `//cipchk.auth0.com/login?client=8gcNydIDzGBYxzqV0Vm1CX_RXH-wsWo5&redirect_uri=${decodeURIComponent(callback)}`;
break;
case 'github':
url = `//github.com/login/oauth/authorize?client_id=9d6baae4b04a23fcafa2&response_type=code&redirect_uri=${decodeURIComponent(
callback
)}`;
break;
case 'weibo':
url = `https://api.weibo.com/oauth2/authorize?client_id=1239507802&response_type=code&redirect_uri=${decodeURIComponent(callback)}`;
break;
}
if (openType === 'window') {
this.socialService
.login(url, '/', {
type: 'window'
})
.subscribe(res => {
if (res) {
this.settingsService.setUser(res);
this.router.navigateByUrl('/');
}
});
} else {
this.socialService.login(url, '/', {
type: 'href'
});
}
}
// #endregion // #endregion
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@@ -1,13 +0,0 @@
<result type="success" [title]="title" description="{{ 'app.register-result.activation-email' | i18n }}">
<ng-template #title>
<div class="title" style="font-size: 20px">
{{ 'app.register-result.msg' | i18n: params }}
</div>
</ng-template>
<button (click)="msg.success('email')" nz-button nzSize="large" [nzType]="'primary'">
{{ 'app.register-result.view-mailbox' | i18n }}
</button>
<button routerLink="/" nz-button nzSize="large">
{{ 'app.register-result.back-home' | i18n }}
</button>
</result>

View File

@@ -1,15 +0,0 @@
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'passport-register-result',
templateUrl: './register-result.component.html'
})
export class UserRegisterResultComponent {
params = { email: '' };
email = '';
constructor(route: ActivatedRoute, public msg: NzMessageService) {
this.params.email = this.email = route.snapshot.queryParams.email || 'ng-alain@example.com';
}
}

View File

@@ -1,100 +0,0 @@
<h3>{{ 'app.register.register' | i18n }}</h3>
<form nz-form [formGroup]="form" (ngSubmit)="submit()" role="form">
<nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
<nz-form-item>
<nz-form-control [nzErrorTip]="mailErrorTip">
<nz-input-group nzSize="large" nzAddonBeforeIcon="user">
<input nz-input formControlName="mail" placeholder="Email" />
</nz-input-group>
<ng-template #mailErrorTip let-i>
<ng-container *ngIf="i.errors?.required">{{ 'validation.email.required' | i18n }}</ng-container>
<ng-container *ngIf="i.errors?.email">{{ 'validation.email.wrong-format' | i18n }}</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzErrorTip]="'validation.password.required' | i18n">
<nz-input-group
nzSize="large"
nzAddonBeforeIcon="lock"
nz-popover
nzPopoverPlacement="right"
nzPopoverTrigger="focus"
[(nzPopoverVisible)]="visible"
nzPopoverOverlayClassName="register-password-cdk"
[nzPopoverOverlayStyle]="{ 'width.px': 240 }"
[nzPopoverContent]="pwdCdkTpl"
>
<input nz-input type="password" formControlName="password" placeholder="Password" />
</nz-input-group>
<ng-template #pwdCdkTpl>
<div style="padding: 4px 0">
<ng-container [ngSwitch]="status">
<div *ngSwitchCase="'ok'" class="success">{{ 'validation.password.strength.strong' | i18n }}</div>
<div *ngSwitchCase="'pass'" class="warning">{{ 'validation.password.strength.medium' | i18n }}</div>
<div *ngSwitchDefault class="error">{{ 'validation.password.strength.short' | i18n }}</div>
</ng-container>
<div class="progress-{{ status }}">
<nz-progress
[nzPercent]="progress"
[nzStatus]="passwordProgressMap[status]"
[nzStrokeWidth]="6"
[nzShowInfo]="false"
></nz-progress>
</div>
<p class="mt-sm">{{ 'validation.password.strength.msg' | i18n }}</p>
</div>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzErrorTip]="confirmErrorTip">
<nz-input-group nzSize="large" nzAddonBeforeIcon="lock">
<input nz-input type="password" formControlName="confirm" placeholder="Confirm Password" />
</nz-input-group>
<ng-template #confirmErrorTip let-i>
<ng-container *ngIf="i.errors?.required">{{ 'validation.confirm-password.required' | i18n }}</ng-container>
<ng-container *ngIf="i.errors?.matchControl">{{ 'validation.password.twice' | i18n }}</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzErrorTip]="mobileErrorTip">
<nz-input-group nzSize="large" [nzAddOnBefore]="addOnBeforeTemplate">
<ng-template #addOnBeforeTemplate>
<nz-select formControlName="mobilePrefix" style="width: 100px">
<nz-option [nzLabel]="'+86'" [nzValue]="'+86'"></nz-option>
<nz-option [nzLabel]="'+87'" [nzValue]="'+87'"></nz-option>
</nz-select>
</ng-template>
<input formControlName="mobile" nz-input placeholder="Phone number" />
</nz-input-group>
<ng-template #mobileErrorTip let-i>
<ng-container *ngIf="i.errors?.required">{{ 'validation.phone-number.required' | i18n }}</ng-container>
<ng-container *ngIf="i.errors?.pattern">{{ 'validation.phone-number.wrong-format' | i18n }}</ng-container>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzErrorTip]="'validation.verification-code.required' | i18n">
<nz-row [nzGutter]="8">
<nz-col [nzSpan]="16">
<nz-input-group nzSize="large" nzAddonBeforeIcon="mail">
<input nz-input formControlName="captcha" placeholder="Captcha" />
</nz-input-group>
</nz-col>
<nz-col [nzSpan]="8">
<button type="button" nz-button nzSize="large" (click)="getCaptcha()" [disabled]="count > 0" nzBlock [nzLoading]="loading">
{{ count ? count + 's' : ('app.register.get-verification-code' | i18n) }}
</button>
</nz-col>
</nz-row>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<button nz-button nzType="primary" nzSize="large" type="submit" [nzLoading]="loading" class="submit">
{{ 'app.register.register' | i18n }}
</button>
<a class="login" routerLink="/passport/login">{{ 'app.register.sign-in' | i18n }}</a>
</nz-form-item>
</form>

View File

@@ -1,42 +0,0 @@
@import '~@delon/theme/index';
:host {
display: block;
width: 368px;
margin: 0 auto;
::ng-deep {
h3 {
margin-bottom: 20px;
font-size: 16px;
}
.submit {
width: 50%;
}
.login {
float: right;
line-height: @btn-height-lg;
}
}
}
::ng-deep {
.register-password-cdk {
.success,
.warning,
.error {
transition: color 0.3s;
}
.success {
color: @success-color;
}
.warning {
color: @warning-color;
}
.error {
color: @error-color;
}
.progress-pass > .progress {
.ant-progress-bg {
background-color: @warning-color;
}
}
}
}

View File

@@ -1,139 +0,0 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { _HttpClient } from '@delon/theme';
import { MatchControl } from '@delon/util/form';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { finalize } from 'rxjs/operators';
@Component({
selector: 'passport-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserRegisterComponent implements OnDestroy {
constructor(fb: FormBuilder, private router: Router, private http: _HttpClient, private cdr: ChangeDetectorRef) {
this.form = fb.group(
{
mail: [null, [Validators.required, Validators.email]],
password: [null, [Validators.required, Validators.minLength(6), UserRegisterComponent.checkPassword.bind(this)]],
confirm: [null, [Validators.required, Validators.minLength(6)]],
mobilePrefix: ['+86'],
mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]],
captcha: [null, [Validators.required]]
},
{
validators: MatchControl('password', 'confirm')
}
);
}
// #region fields
get mail(): AbstractControl {
return this.form.controls.mail;
}
get password(): AbstractControl {
return this.form.controls.password;
}
get confirm(): AbstractControl {
return this.form.controls.confirm;
}
get mobile(): AbstractControl {
return this.form.controls.mobile;
}
get captcha(): AbstractControl {
return this.form.controls.captcha;
}
form: FormGroup;
error = '';
type = 0;
loading = false;
visible = false;
status = 'pool';
progress = 0;
passwordProgressMap: { [key: string]: 'success' | 'normal' | 'exception' } = {
ok: 'success',
pass: 'normal',
pool: 'exception'
};
// #endregion
// #region get captcha
count = 0;
interval$: any;
static checkPassword(control: FormControl): NzSafeAny {
if (!control) {
return null;
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self: any = this;
self.visible = !!control.value;
if (control.value && control.value.length > 9) {
self.status = 'ok';
} else if (control.value && control.value.length > 5) {
self.status = 'pass';
} else {
self.status = 'pool';
}
if (self.visible) {
self.progress = control.value.length * 10 > 100 ? 100 : control.value.length * 10;
}
}
getCaptcha(): void {
if (this.mobile.invalid) {
this.mobile.markAsDirty({ onlySelf: true });
this.mobile.updateValueAndValidity({ onlySelf: true });
return;
}
this.count = 59;
this.cdr.detectChanges();
this.interval$ = setInterval(() => {
this.count -= 1;
this.cdr.detectChanges();
if (this.count <= 0) {
clearInterval(this.interval$);
}
}, 1000);
}
// #endregion
submit(): void {
this.error = '';
Object.keys(this.form.controls).forEach(key => {
this.form.controls[key].markAsDirty();
this.form.controls[key].updateValueAndValidity();
});
if (this.form.invalid) {
return;
}
const data = this.form.value;
this.loading = true;
this.cdr.detectChanges();
this.http
.post('/register?_allow_anonymous=true', data)
.pipe(
finalize(() => {
this.loading = false;
this.cdr.detectChanges();
})
)
.subscribe(() => {
this.router.navigate(['passport', 'register-result'], { queryParams: { email: data.mail } });
});
}
ngOnDestroy(): void {
if (this.interval$) {
clearInterval(this.interval$);
}
}
}

View File

@@ -1,19 +1,17 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { environment } from '@env/environment'; import { environment } from '@env/environment';
// layout // layout
import { DetectAuthGuard } from '../core/guard/detect-auth-guard';
import { LayoutBasicComponent } from '../layout/basic/basic.component'; import { LayoutBasicComponent } from '../layout/basic/basic.component';
import { LayoutPassportComponent } from '../layout/passport/passport.component'; import { LayoutPassportComponent } from '../layout/passport/passport.component';
// dashboard pages // dashboard pages
import { DashboardComponent } from './dashboard/dashboard.component'; import { DashboardComponent } from './dashboard/dashboard.component';
// single pages // single pages
import { CallbackComponent } from './passport/callback.component';
import { UserLockComponent } from './passport/lock/lock.component'; import { UserLockComponent } from './passport/lock/lock.component';
// passport pages // passport pages
import { UserLoginComponent } from './passport/login/login.component'; import { UserLoginComponent } from './passport/login/login.component';
import { UserRegisterResultComponent } from './passport/register-result/register-result.component';
import { UserRegisterComponent } from './passport/register/register.component';
import {DetectAuthGuard} from "../core/guard/detect-auth-guard";
const routes: Routes = [ const routes: Routes = [
{ {
@@ -23,11 +21,12 @@ const routes: Routes = [
canActivate: [DetectAuthGuard], canActivate: [DetectAuthGuard],
children: [ children: [
// todo 根据路由自动生成面包屑 // todo 根据路由自动生成面包屑
{ path: '', redirectTo: 'dashboard', pathMatch: 'full'}, { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent, data: { title: '仪表盘' } }, { path: 'dashboard', component: DashboardComponent, data: { title: '仪表盘' } },
{ path: 'exception', loadChildren: () => import('./exception/exception.module').then(m => m.ExceptionModule) }, { path: 'exception', loadChildren: () => import('./exception/exception.module').then(m => m.ExceptionModule) },
{ path: 'monitors', loadChildren: () => import('./monitor/monitor.module').then((m) => m.MonitorModule) }, { path: 'monitors', loadChildren: () => import('./monitor/monitor.module').then(m => m.MonitorModule) },
{ path: 'alert', loadChildren: () => import('./alert/alert.module').then((m) => m.AlertModule) },] { path: 'alert', loadChildren: () => import('./alert/alert.module').then(m => m.AlertModule) }
]
}, },
// 空白布局 // 空白布局
// { // {
@@ -42,26 +41,21 @@ const routes: Routes = [
component: LayoutPassportComponent, component: LayoutPassportComponent,
children: [ children: [
{ path: 'login', component: UserLoginComponent, data: { title: '登录' } }, { path: 'login', component: UserLoginComponent, data: { title: '登录' } },
{ path: 'register', component: UserRegisterComponent, data: { title: '注册' } }, { path: 'lock', component: UserLockComponent, data: { title: '锁屏' } }
{ path: 'register-result', component: UserRegisterResultComponent, data: { title: '注册结果' } },
{ path: 'lock', component: UserLockComponent, data: { title: '锁屏' } },
] ]
}, },
// 单页不包裹Layout { path: '**', redirectTo: 'exception/404' }
{ path: 'passport/callback/:type', component: CallbackComponent },
{ path: '**', redirectTo: 'exception/404' },
]; ];
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forRoot( RouterModule.forRoot(routes, {
routes, {
useHash: environment.useHash, useHash: environment.useHash,
// NOTICE: If you use `reuse-tab` component and turn on keepingScroll you can set to `disabled` // NOTICE: If you use `reuse-tab` component and turn on keepingScroll you can set to `disabled`
// Pls refer to https://ng-alain.com/components/reuse-tab // Pls refer to https://ng-alain.com/components/reuse-tab
scrollPositionRestoration: 'top', scrollPositionRestoration: 'top'
} })
)], ],
exports: [RouterModule], exports: [RouterModule]
}) })
export class RouteRoutingModule { } export class RouteRoutingModule {}

View File

@@ -1,30 +1,26 @@
import { NgModule, Type } from '@angular/core'; import { NgModule, Type } from '@angular/core';
import { SharedModule } from '@shared'; import { SharedModule } from '@shared';
// dashboard pages // dashboard pages
import { NgxEchartsModule } from 'ngx-echarts';
import { DashboardComponent } from './dashboard/dashboard.component'; import { DashboardComponent } from './dashboard/dashboard.component';
import { RouteRoutingModule } from './routes-routing.module';
import {NgxEchartsModule} from "ngx-echarts";
// single pages // single pages
import { CallbackComponent } from './passport/callback.component';
import { UserLockComponent } from './passport/lock/lock.component'; import { UserLockComponent } from './passport/lock/lock.component';
// passport pages // passport pages
import { UserLoginComponent } from './passport/login/login.component'; import { UserLoginComponent } from './passport/login/login.component';
import { UserRegisterResultComponent } from './passport/register-result/register-result.component'; import { RouteRoutingModule } from './routes-routing.module';
import { UserRegisterComponent } from './passport/register/register.component';
const COMPONENTS: Array<Type<void>> = [ const COMPONENTS: Array<Type<void>> = [
DashboardComponent, DashboardComponent,
// passport pages // passport pages
UserLoginComponent, UserLoginComponent,
UserRegisterComponent,
UserRegisterResultComponent,
// single pages // single pages
CallbackComponent, UserLockComponent
UserLockComponent,
]; ];
@NgModule({ @NgModule({
imports: [SharedModule, RouteRoutingModule, NgxEchartsModule], imports: [SharedModule, RouteRoutingModule, NgxEchartsModule],
declarations: COMPONENTS, declarations: COMPONENTS
}) })
export class RoutesModule {} export class RoutesModule {}

View File

@@ -1,66 +1,64 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from "@angular/common/http"; import { Observable } from 'rxjs';
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"; import { AlertDefine } from '../pojo/AlertDefine';
const alert_defines_uri = "/alert/defines"; import { AlertDefineBind } from '../pojo/AlertDefineBind';
import { Message } from '../pojo/Message';
import { Page } from '../pojo/Page';
const alert_define_uri = '/alert/define';
const alert_defines_uri = '/alert/defines';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AlertDefineService { export class AlertDefineService {
constructor(private http: HttpClient) {}
constructor(private http : HttpClient) { } public newAlertDefine(body: AlertDefine): Observable<Message<any>> {
public newAlertDefine(body: AlertDefine) : Observable<Message<any>> {
return this.http.post<Message<any>>(alert_define_uri, body); return this.http.post<Message<any>>(alert_define_uri, body);
} }
public editAlertDefine(body: AlertDefine) : Observable<Message<any>> { public editAlertDefine(body: AlertDefine): Observable<Message<any>> {
return this.http.put<Message<any>>(alert_define_uri, body); return this.http.put<Message<any>>(alert_define_uri, body);
} }
public getAlertDefine(alertDefineId: number) : Observable<Message<AlertDefine>> { public getAlertDefine(alertDefineId: number): Observable<Message<AlertDefine>> {
return this.http.get<Message<AlertDefine>>(`${alert_define_uri}/${alertDefineId}`); return this.http.get<Message<AlertDefine>>(`${alert_define_uri}/${alertDefineId}`);
} }
public applyAlertDefineMonitorsBind(alertDefineId: number, public applyAlertDefineMonitorsBind(alertDefineId: number, binds: AlertDefineBind[]): Observable<Message<any>> {
binds: AlertDefineBind[]): Observable<Message<any>> {
return this.http.post<Message<any>>(`${alert_define_uri}/${alertDefineId}/monitors`, binds); return this.http.post<Message<any>>(`${alert_define_uri}/${alertDefineId}/monitors`, binds);
} }
public getAlertDefineMonitorsBind(alertDefineId: number) : Observable<Message<AlertDefineBind[]>> { public getAlertDefineMonitorsBind(alertDefineId: number): Observable<Message<AlertDefineBind[]>> {
return this.http.get<Message<AlertDefineBind[]>>(`${alert_define_uri}/${alertDefineId}/monitors`); return this.http.get<Message<AlertDefineBind[]>>(`${alert_define_uri}/${alertDefineId}/monitors`);
} }
public deleteAlertDefines(alertDefineIds: Set<number>) : Observable<Message<any>> { public deleteAlertDefines(alertDefineIds: Set<number>): Observable<Message<any>> {
let httpParams = new HttpParams(); let httpParams = new HttpParams();
alertDefineIds.forEach(alertDefineId => { alertDefineIds.forEach(alertDefineId => {
// 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象 // 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象
// append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value // append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value
httpParams = httpParams.append('ids', alertDefineId); httpParams = httpParams.append('ids', alertDefineId);
}) });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.delete<Message<any>>(alert_defines_uri, options); return this.http.delete<Message<any>>(alert_defines_uri, options);
} }
public getAlertDefines(pageIndex: number, pageSize: number) : Observable<Message<Page<AlertDefine>>> { public getAlertDefines(pageIndex: number, pageSize: number): Observable<Message<Page<AlertDefine>>> {
pageIndex = pageIndex ? pageIndex : 0; pageIndex = pageIndex ? pageIndex : 0;
pageSize = pageSize ? pageSize : 8; pageSize = pageSize ? pageSize : 8;
// 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象 // 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象
let httpParams = new HttpParams(); let httpParams = new HttpParams();
httpParams = httpParams.appendAll({ httpParams = httpParams.appendAll({
'sort': 'id', sort: 'id',
'order': 'desc', order: 'desc',
'pageIndex': pageIndex, pageIndex: pageIndex,
'pageSize': pageSize pageSize: pageSize
}); });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.get<Message<Page<AlertDefine>>>(alert_defines_uri, options); return this.http.get<Message<Page<AlertDefine>>>(alert_defines_uri, options);
} }
} }

View File

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

View File

@@ -1,8 +1,9 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http'; import { Observable } from 'rxjs';
import {Message} from "../pojo/Message";
import {Observable} from "rxjs"; import { Message } from '../pojo/Message';
import {ParamDefine} from "../pojo/ParamDefine"; import { ParamDefine } from '../pojo/ParamDefine';
const app_hierarchy = '/apps/hierarchy'; const app_hierarchy = '/apps/hierarchy';
@@ -10,21 +11,19 @@ const app_hierarchy = '/apps/hierarchy';
providedIn: 'root' providedIn: 'root'
}) })
export class AppDefineService { export class AppDefineService {
constructor(private http: HttpClient) {}
constructor(private http : HttpClient) { } public getAppParamsDefine(app: string | undefined | null): Observable<Message<ParamDefine[]>> {
public getAppParamsDefine(app: string | undefined | null) : Observable<Message<ParamDefine[]>> {
if (app === null || app === undefined) { if (app === null || app === undefined) {
console.log("getAppParamsDefine app can not null"); console.log('getAppParamsDefine app can not null');
} }
const paramDefineUri = `/apps/${app}/params`; const paramDefineUri = `/apps/${app}/params`;
return this.http.get<Message<ParamDefine[]>>(paramDefineUri); return this.http.get<Message<ParamDefine[]>>(paramDefineUri);
} }
public getAppHierarchy() : Observable<Message<any>> { public getAppHierarchy(): Observable<Message<any>> {
let httpParams = new HttpParams().append("lang",'zh-CN'); let httpParams = new HttpParams().append('lang', 'zh-CN');
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.get<Message<any>>(app_hierarchy,options); return this.http.get<Message<any>>(app_hierarchy, options);
} }
} }

View File

@@ -7,8 +7,7 @@ const refreshToken = 'refresh-token';
providedIn: 'root' providedIn: 'root'
}) })
export class LocalStorageService { export class LocalStorageService {
constructor() {}
constructor() { }
public putData(key: string, value: string) { public putData(key: string, value: string) {
localStorage.setItem(key, value); localStorage.setItem(key, value);
@@ -36,11 +35,10 @@ export class LocalStorageService {
} }
public hasAuthorizationToken() { public hasAuthorizationToken() {
return localStorage.getItem(Authorization) === null; return localStorage.getItem(Authorization) != null;
} }
public clear() { public clear() {
localStorage.clear(); localStorage.clear();
} }
} }

View File

@@ -1,115 +1,113 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from "@angular/common/http"; import { Observable } from 'rxjs';
import {Observable} from "rxjs";
import {Message} from "../pojo/Message";
import {Page} from "../pojo/Page";
import {Monitor} from "../pojo/Monitor";
const monitor_uri = "/monitor"; import { Message } from '../pojo/Message';
const monitors_uri = "/monitors"; import { Monitor } from '../pojo/Monitor';
const detect_monitor_uri = "/monitor/detect" import { Page } from '../pojo/Page';
const manage_monitors_uri = "/monitors/manage";
const summary_uri = "/summary"; const monitor_uri = '/monitor';
const monitors_uri = '/monitors';
const detect_monitor_uri = '/monitor/detect';
const manage_monitors_uri = '/monitors/manage';
const summary_uri = '/summary';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class MonitorService { export class MonitorService {
constructor(private http: HttpClient) {}
constructor(private http : HttpClient) { } public newMonitor(body: any): Observable<Message<any>> {
public newMonitor(body: any) : Observable<Message<any>> {
return this.http.post<Message<any>>(monitor_uri, body); return this.http.post<Message<any>>(monitor_uri, body);
} }
public editMonitor(body: any) : Observable<Message<any>> { public editMonitor(body: any): Observable<Message<any>> {
return this.http.put<Message<any>>(monitor_uri, body); return this.http.put<Message<any>>(monitor_uri, body);
} }
public deleteMonitor(monitorId: number) : Observable<Message<any>> { public deleteMonitor(monitorId: number): Observable<Message<any>> {
return this.http.delete<Message<any>>(`${monitor_uri}/${monitorId}`); return this.http.delete<Message<any>>(`${monitor_uri}/${monitorId}`);
} }
public deleteMonitors(monitorIds: Set<number>) : Observable<Message<any>> { public deleteMonitors(monitorIds: Set<number>): Observable<Message<any>> {
let httpParams = new HttpParams(); let httpParams = new HttpParams();
monitorIds.forEach(monitorId => { monitorIds.forEach(monitorId => {
// 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象 // 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象
// append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value // append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value
httpParams = httpParams.append('ids', monitorId); httpParams = httpParams.append('ids', monitorId);
}) });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.delete<Message<any>>(monitors_uri, options); return this.http.delete<Message<any>>(monitors_uri, options);
} }
public cancelManageMonitors(monitorIds: Set<number>) : Observable<Message<any>> { public cancelManageMonitors(monitorIds: Set<number>): Observable<Message<any>> {
let httpParams = new HttpParams(); let httpParams = new HttpParams();
monitorIds.forEach(monitorId => { monitorIds.forEach(monitorId => {
// 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象 // 注意HttpParams是不可变对象 需要保存append后返回的对象为最新对象
// append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value // append方法可以叠加同一key, set方法会把key之前的值覆盖只留一个key-value
httpParams = httpParams.append('ids', monitorId); httpParams = httpParams.append('ids', monitorId);
}) });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.delete<Message<any>>(manage_monitors_uri, options); return this.http.delete<Message<any>>(manage_monitors_uri, options);
} }
public enableManageMonitors(monitorIds: Set<number>) : Observable<Message<any>> { public enableManageMonitors(monitorIds: Set<number>): Observable<Message<any>> {
let httpParams = new HttpParams(); let httpParams = new HttpParams();
monitorIds.forEach(monitorId => { monitorIds.forEach(monitorId => {
httpParams = httpParams.append('ids', monitorId); httpParams = httpParams.append('ids', monitorId);
}) });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.get<Message<any>>(manage_monitors_uri, options); return this.http.get<Message<any>>(manage_monitors_uri, options);
} }
public detectMonitor(body: any) : Observable<Message<any>> { public detectMonitor(body: any): Observable<Message<any>> {
return this.http.post<Message<any>>(detect_monitor_uri, body); return this.http.post<Message<any>>(detect_monitor_uri, body);
} }
public getMonitor(monitorId: number) : Observable<Message<any>> { public getMonitor(monitorId: number): Observable<Message<any>> {
return this.http.get<Message<any>>(`${monitor_uri}/${monitorId}`); return this.http.get<Message<any>>(`${monitor_uri}/${monitorId}`);
} }
public getMonitorsByApp(app: string) : Observable<Message<Monitor[]>> { public getMonitorsByApp(app: string): Observable<Message<Monitor[]>> {
return this.http.get<Message<Monitor[]>>(`${monitors_uri}/${app}`); return this.http.get<Message<Monitor[]>>(`${monitors_uri}/${app}`);
} }
public getMonitors(app: string, pageIndex: number, pageSize: number) : Observable<Message<Page<Monitor>>> { public getMonitors(app: string, pageIndex: number, pageSize: number): Observable<Message<Page<Monitor>>> {
app = app.trim(); app = app.trim();
pageIndex = pageIndex ? pageIndex : 0; pageIndex = pageIndex ? pageIndex : 0;
pageSize = pageSize ? pageSize : 8; pageSize = pageSize ? pageSize : 8;
// 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象 // 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象
let httpParams = new HttpParams(); let httpParams = new HttpParams();
httpParams = httpParams.appendAll({ httpParams = httpParams.appendAll({
'app': app, app: app,
'pageIndex': pageIndex, pageIndex: pageIndex,
'pageSize': pageSize pageSize: pageSize
}); });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.get<Message<Page<Monitor>>>(monitors_uri, options); return this.http.get<Message<Page<Monitor>>>(monitors_uri, options);
} }
public searchMonitors(monitorName: string, monitorHost: string, public searchMonitors(monitorName: string, monitorHost: string, pageIndex: number, pageSize: number): Observable<Message<Page<Monitor>>> {
pageIndex: number, pageSize: number): Observable<Message<Page<Monitor>>> {
pageIndex = pageIndex ? pageIndex : 0; pageIndex = pageIndex ? pageIndex : 0;
pageSize = pageSize ? pageSize : 8; pageSize = pageSize ? pageSize : 8;
// 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象 // 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象
let httpParams = new HttpParams(); let httpParams = new HttpParams();
httpParams = httpParams.appendAll({ httpParams = httpParams.appendAll({
'name': monitorName, name: monitorName,
'host': monitorHost, host: monitorHost,
'pageIndex': pageIndex, pageIndex: pageIndex,
'pageSize': pageSize pageSize: pageSize
}); });
const options = { params: httpParams }; const options = { params: httpParams };
return this.http.get<Message<Page<Monitor>>>(monitors_uri, options); return this.http.get<Message<Page<Monitor>>>(monitors_uri, options);
} }
public getMonitorMetricsData(monitorId: number, metrics: string) : Observable<Message<any>> { public getMonitorMetricsData(monitorId: number, metrics: string): Observable<Message<any>> {
return this.http.get<Message<any>>(`/monitor/${monitorId}/metrics/${metrics}`); return this.http.get<Message<any>>(`/monitor/${monitorId}/metrics/${metrics}`);
} }
public getAppsMonitorSummary() : Observable<Message<any>> { public getAppsMonitorSummary(): Observable<Message<any>> {
return this.http.get<Message<any>>(summary_uri); return this.http.get<Message<any>>(summary_uri);
} }
} }

View File

@@ -1,8 +1,9 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {HttpClient} from "@angular/common/http"; import { Observable } from 'rxjs';
import {Observable} from "rxjs";
import {Message} from "../pojo/Message"; import { Message } from '../pojo/Message';
import {NoticeReceiver} from "../pojo/NoticeReceiver"; import { NoticeReceiver } from '../pojo/NoticeReceiver';
const notice_receiver_uri = '/notice/receiver'; const notice_receiver_uri = '/notice/receiver';
const notice_receivers_uri = '/notice/receivers'; const notice_receivers_uri = '/notice/receivers';
@@ -11,22 +12,20 @@ const notice_receivers_uri = '/notice/receivers';
providedIn: 'root' providedIn: 'root'
}) })
export class NoticeReceiverService { export class NoticeReceiverService {
constructor(private http: HttpClient) {}
constructor(private http : HttpClient) { } public newReceiver(body: NoticeReceiver): Observable<Message<any>> {
public newReceiver(body: NoticeReceiver) : Observable<Message<any>> {
return this.http.post<Message<any>>(notice_receiver_uri, body); return this.http.post<Message<any>>(notice_receiver_uri, body);
} }
public editReceiver(body: NoticeReceiver) : Observable<Message<any>> { public editReceiver(body: NoticeReceiver): Observable<Message<any>> {
return this.http.put<Message<any>>(notice_receiver_uri, body); return this.http.put<Message<any>>(notice_receiver_uri, body);
} }
public deleteReceiver(receiverId: number) : Observable<Message<any>> { public deleteReceiver(receiverId: number): Observable<Message<any>> {
return this.http.delete<Message<any>>(`${notice_receiver_uri}/${receiverId}`); return this.http.delete<Message<any>>(`${notice_receiver_uri}/${receiverId}`);
} }
public getReceivers() : Observable<Message<NoticeReceiver[]>> { public getReceivers(): Observable<Message<NoticeReceiver[]>> {
return this.http.get<Message<NoticeReceiver[]>>(notice_receivers_uri); return this.http.get<Message<NoticeReceiver[]>>(notice_receivers_uri);
} }
} }

View File

@@ -1,8 +1,9 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {Observable} from "rxjs"; import { Observable } from 'rxjs';
import {Message} from "../pojo/Message";
import {HttpClient} from "@angular/common/http"; import { Message } from '../pojo/Message';
import {NoticeRule} from "../pojo/NoticeRule"; import { NoticeRule } from '../pojo/NoticeRule';
const notice_rule_uri = '/notice/rule'; const notice_rule_uri = '/notice/rule';
const notice_rules_uri = '/notice/rules'; const notice_rules_uri = '/notice/rules';
@@ -11,22 +12,21 @@ const notice_rules_uri = '/notice/rules';
providedIn: 'root' providedIn: 'root'
}) })
export class NoticeRuleService { export class NoticeRuleService {
constructor(private http: HttpClient) {}
constructor(private http : HttpClient) { } public newNoticeRule(body: NoticeRule): Observable<Message<any>> {
public newNoticeRule(body: NoticeRule) : Observable<Message<any>> {
return this.http.post<Message<any>>(notice_rule_uri, body); return this.http.post<Message<any>>(notice_rule_uri, body);
} }
public editNoticeRule(body: NoticeRule) : Observable<Message<any>> { public editNoticeRule(body: NoticeRule): Observable<Message<any>> {
return this.http.put<Message<any>>(notice_rule_uri, body); return this.http.put<Message<any>>(notice_rule_uri, body);
} }
public deleteNoticeRule(ruleId: number) : Observable<Message<any>> { public deleteNoticeRule(ruleId: number): Observable<Message<any>> {
return this.http.delete<Message<any>>(`${notice_rule_uri}/${ruleId}`); return this.http.delete<Message<any>>(`${notice_rule_uri}/${ruleId}`);
} }
public getNoticeRules() : Observable<Message<NoticeRule[]>> { public getNoticeRules(): Observable<Message<NoticeRule[]>> {
return this.http.get<Message<NoticeRule[]>>(notice_rules_uri); return this.http.get<Message<NoticeRule[]>>(notice_rules_uri);
} }
} }

View File

@@ -41,5 +41,5 @@ export const SHARED_ZORRO_MODULES = [
NzToolTipModule, NzToolTipModule,
NzIconModule, NzIconModule,
NzCheckboxModule, NzCheckboxModule,
NzSpinModule, NzSpinModule
]; ];

View File

@@ -1,10 +1,10 @@
import { NgModule, Type } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule, Type } from '@angular/core';
import { ReactiveFormsModule, FormsModule } from '@angular/forms'; import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { AlainThemeModule } from '@delon/theme';
import { DelonACLModule } from '@delon/acl'; import { DelonACLModule } from '@delon/acl';
import { DelonFormModule } from '@delon/form'; import { DelonFormModule } from '@delon/form';
import { AlainThemeModule } from '@delon/theme';
import { SHARED_DELON_MODULES } from './shared-delon.module'; import { SHARED_DELON_MODULES } from './shared-delon.module';
import { SHARED_ZORRO_MODULES } from './shared-zorro.module'; import { SHARED_ZORRO_MODULES } from './shared-zorro.module';
@@ -58,4 +58,4 @@ const DIRECTIVES: Array<Type<void>> = [];
...DIRECTIVES ...DIRECTIVES
] ]
}) })
export class SharedModule { } export class SharedModule {}

View File

@@ -5,7 +5,7 @@
}, },
"user": { "user": {
"name": "Admin", "name": "Admin",
"avatar": "./assets/tmp/img/avatar.svg", "avatar": "./assets/img/avatar.svg",
"email": "管理员" "email": "管理员"
}, },
"menu": [ "menu": [
@@ -105,26 +105,6 @@
"link": "/alert/notice" "link": "/alert/notice"
} }
] ]
},
{
"text": "More",
"i18n": "menu.extras",
"group": true,
"hideInBreadcrumb": true,
"children": [
{
"text": "Help Center",
"link": "/extras/help",
"i18n": "menu.extras.help",
"icon": "anticon-link"
},
{
"text": "Settings",
"link": "/extras/setting",
"i18n": "menu.extras.setting",
"icon": "anticon-setting"
}
]
} }
] ]
} }

View File

Before

Width:  |  Height:  |  Size: 937 B

After

Width:  |  Height:  |  Size: 937 B