[web-app] http拦截器修改,新增监控页面编码
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~12.2.0",
|
||||
"@angular/cdk": "~12.2.0",
|
||||
"@angular/common": "~12.2.0",
|
||||
"@angular/compiler": "~12.2.0",
|
||||
"@angular/core": "~12.2.0",
|
||||
@@ -29,43 +30,38 @@
|
||||
"@angular/platform-browser": "~12.2.0",
|
||||
"@angular/platform-browser-dynamic": "~12.2.0",
|
||||
"@angular/router": "~12.2.0",
|
||||
"@angular/cdk": "~12.2.0",
|
||||
"ng-alain": "^12.4.2",
|
||||
"ng-zorro-antd": "^12.0.2",
|
||||
"rxjs": "~6.6.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4",
|
||||
"@delon/abc": "^12.4.2",
|
||||
"@delon/acl": "^12.4.2",
|
||||
"@delon/auth": "^12.4.2",
|
||||
"@delon/cache": "^12.4.2",
|
||||
"@delon/chart": "^12.4.2",
|
||||
"@delon/form": "^12.4.2",
|
||||
"@delon/mock": "^12.4.2",
|
||||
"@delon/theme": "^12.4.2",
|
||||
"@delon/util": "^12.4.2",
|
||||
"@delon/chart": "^12.4.2",
|
||||
"ajv": "^8.6.2",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"screenfull": "^5.1.0"
|
||||
"ng-alain": "^12.4.2",
|
||||
"ng-zorro-antd": "^12.0.2",
|
||||
"rxjs": "~6.6.0",
|
||||
"screenfull": "^5.1.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~12.2.13",
|
||||
"@angular/cli": "~12.2.13",
|
||||
"@angular/compiler-cli": "~12.2.0",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.3.5",
|
||||
"@angular-eslint/builder": "~12.3.1",
|
||||
"@angular-eslint/eslint-plugin": "~12.3.1",
|
||||
"@angular-eslint/eslint-plugin-template": "~12.3.1",
|
||||
"@angular-eslint/schematics": "~12.3.1",
|
||||
"@angular-eslint/template-parser": "~12.3.1",
|
||||
"@angular/cli": "~12.2.13",
|
||||
"@angular/compiler-cli": "~12.2.0",
|
||||
"@angular/language-service": "~12.2.0",
|
||||
"@delon/testing": "^12.4.2",
|
||||
"@ngx-formly/schematics": "^5.10.23",
|
||||
"@types/jasmine": "~3.8.0",
|
||||
"@types/node": "^12.11.1",
|
||||
"@typescript-eslint/eslint-plugin": "~4.29.2",
|
||||
"@typescript-eslint/parser": "~4.29.2",
|
||||
"eslint": "^7.32.0",
|
||||
@@ -74,19 +70,24 @@
|
||||
"eslint-plugin-jsdoc": "~36.0.7",
|
||||
"eslint-plugin-prefer-arrow": "~1.2.3",
|
||||
"eslint-plugin-prettier": "^2.2.1",
|
||||
"prettier": "^2.2.1",
|
||||
"jasmine-core": "~3.8.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.0.3",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"lint-staged": "^11.1.2",
|
||||
"ng-alain": "^12.4.2",
|
||||
"ng-alain-plugin-theme": "^12.0.0",
|
||||
"prettier": "^2.2.1",
|
||||
"source-map-explorer": "^2.5.2",
|
||||
"@angular/language-service": "~12.2.0",
|
||||
"@delon/testing": "^12.4.2",
|
||||
"lint-staged": "^11.1.2",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-config-prettier": "^8.0.2",
|
||||
"stylelint-config-rational-order": "^0.1.2",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "^2.4.0",
|
||||
"stylelint-order": "^4.1.0"
|
||||
"stylelint-order": "^4.1.0",
|
||||
"typescript": "~4.3.5"
|
||||
},
|
||||
"lint-staged": {
|
||||
"(src)/**/*.{html,ts}": [
|
||||
|
||||
@@ -9,8 +9,8 @@ module.exports = {
|
||||
/**
|
||||
* The following means that all requests are directed to the backend `https://localhost:9000/`
|
||||
*/
|
||||
// '/': {
|
||||
// target: 'https://localhost:9000/',
|
||||
// '/apps/*': {
|
||||
// target: 'https://localhost:8080',
|
||||
// secure: false, // Ignore invalid SSL certificates
|
||||
// changeOrigin: true
|
||||
// }
|
||||
|
||||
@@ -51,7 +51,7 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { DefaultInterceptor } from '@core';
|
||||
import { SimpleInterceptor } from '@delon/auth';
|
||||
const INTERCEPTOR_PROVIDES = [
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true},
|
||||
// { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true},
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true}
|
||||
];
|
||||
// #endregion
|
||||
@@ -65,7 +65,7 @@ import { StartupService } from '@core';
|
||||
export function StartupServiceFactory(startupService: StartupService): () => Observable<void> {
|
||||
return () => startupService.load();
|
||||
}
|
||||
const APPINIT_PROVIDES = [
|
||||
const APP_INIT_PROVIDES = [
|
||||
StartupService,
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
@@ -83,6 +83,7 @@ import { LayoutModule } from './layout/layout.module';
|
||||
import { RoutesModule } from './routes/routes.module';
|
||||
import { SharedModule } from './shared/shared.module';
|
||||
import { STWidgetModule } from './shared/st-widget/st-widget.module';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -101,13 +102,14 @@ import { STWidgetModule } from './shared/st-widget/st-widget.module';
|
||||
NzMessageModule,
|
||||
NzNotificationModule,
|
||||
...FORM_MODULES,
|
||||
...GLOBAL_THIRD_MODULES
|
||||
...GLOBAL_THIRD_MODULES,
|
||||
ReactiveFormsModule
|
||||
],
|
||||
providers: [
|
||||
...LANG_PROVIDES,
|
||||
...INTERCEPTOR_PROVIDES,
|
||||
...I18NSERVICE_PROVIDES,
|
||||
...APPINIT_PROVIDES
|
||||
...APP_INIT_PROVIDES
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
||||
@@ -92,7 +92,7 @@ export class I18NService extends AlainI18nBaseService {
|
||||
}
|
||||
|
||||
loadLangData(lang: string): Observable<NzSafeAny> {
|
||||
return this.http.get(`assets/tmp/i18n/${lang}.json`);
|
||||
return this.http.get(`http://localhost:4200/assets/tmp/i18n/${lang}.json`);
|
||||
}
|
||||
|
||||
use(lang: string, data: Record<string, unknown>): void {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from './i18n/i18n.service';
|
||||
export * from './module-import-guard';
|
||||
export * from './net/default.interceptor';
|
||||
export * from './interceptor/default.interceptor';
|
||||
export * from './startup/startup.service';
|
||||
|
||||
@@ -15,8 +15,9 @@ import { environment } from '@env/environment';
|
||||
import { NzNotificationService } from 'ng-zorro-antd/notification';
|
||||
import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
|
||||
import { catchError, filter, mergeMap, switchMap, take } from 'rxjs/operators';
|
||||
import {LocalStorageService} from "../../service/local-storage.service";
|
||||
|
||||
const CODEMESSAGE: { [key: number]: string } = {
|
||||
const CODE_MESSAGE: { [key: number]: string } = {
|
||||
200: '服务器成功返回请求的数据。',
|
||||
201: '新建或修改数据成功。',
|
||||
202: '一个请求已经进入后台排队(异步任务)。',
|
||||
@@ -40,15 +41,10 @@ const CODEMESSAGE: { [key: number]: string } = {
|
||||
@Injectable()
|
||||
export class DefaultInterceptor implements HttpInterceptor {
|
||||
private refreshTokenEnabled = environment.api.refreshTokenEnabled;
|
||||
private refreshTokenType: 're-request' | 'auth-refresh' = environment.api.refreshTokenType;
|
||||
private refreshToking = false;
|
||||
private refreshToken$: BehaviorSubject<any> = new BehaviorSubject<any>(null);
|
||||
|
||||
constructor(private injector: Injector) {
|
||||
if (this.refreshTokenType === 'auth-refresh') {
|
||||
this.buildAuthRefresh();
|
||||
}
|
||||
}
|
||||
constructor(private injector: Injector, private storageSvc: LocalStorageService) { }
|
||||
|
||||
private get notification(): NzNotificationService {
|
||||
return this.injector.get(NzNotificationService);
|
||||
@@ -67,12 +63,11 @@ export class DefaultInterceptor implements HttpInterceptor {
|
||||
}
|
||||
|
||||
private checkStatus(ev: HttpResponseBase): void {
|
||||
if ((ev.status >= 200 && ev.status < 300) || ev.status === 401) {
|
||||
if (ev.status >= 200 && ev.status < 500) {
|
||||
return;
|
||||
}
|
||||
|
||||
const errortext = CODEMESSAGE[ev.status] || ev.statusText;
|
||||
this.notification.error(`请求错误 ${ev.status}: ${ev.url}`, errortext);
|
||||
const errorText = CODE_MESSAGE[ev.status] || ev.statusText;
|
||||
this.notification.error(`抱歉服务器繁忙 ${ev.status}: ${ev.url}`, errorText);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,6 +104,7 @@ export class DefaultInterceptor implements HttpInterceptor {
|
||||
this.refreshToking = false;
|
||||
this.refreshToken$.next(res);
|
||||
// 重新保存新 token
|
||||
this.storageSvc.storageAuthorizationToken(res);
|
||||
this.tokenSrv.set(res);
|
||||
// 重新发起请求
|
||||
return next.handle(this.reAttachToken(req));
|
||||
@@ -124,138 +120,69 @@ export class DefaultInterceptor implements HttpInterceptor {
|
||||
/**
|
||||
* 重新附加新 Token 信息
|
||||
*
|
||||
* > 由于已经发起的请求,不会再走一遍 `@delon/auth` 因此需要结合业务情况重新附加新的 Token
|
||||
*/
|
||||
private reAttachToken(req: HttpRequest<any>): HttpRequest<any> {
|
||||
// 以下示例是以 NG-ALAIN 默认使用 `SimpleInterceptor`
|
||||
const token = this.tokenSrv.get()?.token;
|
||||
let token = this.storageSvc.getAuthorizationToken();
|
||||
return req.clone({
|
||||
setHeaders: {
|
||||
token: `Bearer ${token}`
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region 刷新Token方式二:使用 `@delon/auth` 的 `refresh` 接口
|
||||
|
||||
private buildAuthRefresh(): void {
|
||||
if (!this.refreshTokenEnabled) {
|
||||
return;
|
||||
}
|
||||
this.tokenSrv.refresh
|
||||
.pipe(
|
||||
filter(() => !this.refreshToking),
|
||||
switchMap(res => {
|
||||
console.log(res);
|
||||
this.refreshToking = true;
|
||||
return this.refreshTokenRequest();
|
||||
})
|
||||
)
|
||||
.subscribe(
|
||||
res => {
|
||||
// TODO: Mock expired value
|
||||
res.expired = +new Date() + 1000 * 60 * 5;
|
||||
this.refreshToking = false;
|
||||
this.tokenSrv.set(res);
|
||||
},
|
||||
() => this.toLogin()
|
||||
);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
private toLogin(): void {
|
||||
this.notification.error(`未登录或登录已过期,请重新登录。`, ``);
|
||||
this.goTo(this.tokenSrv.login_url!);
|
||||
}
|
||||
|
||||
private handleData(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> {
|
||||
this.checkStatus(ev);
|
||||
// 业务处理:一些通用操作
|
||||
switch (ev.status) {
|
||||
case 200:
|
||||
// 业务层级错误处理,以下是假定restful有一套统一输出格式(指不管成功与否都有相应的数据格式)情况下进行处理
|
||||
// 例如响应内容:
|
||||
// 错误内容:{ status: 1, msg: '非法参数' }
|
||||
// 正确内容:{ status: 0, response: { } }
|
||||
// 则以下代码片断可直接适用
|
||||
// if (ev instanceof HttpResponse) {
|
||||
// const body = ev.body;
|
||||
// if (body && body.status !== 0) {
|
||||
// this.injector.get(NzMessageService).error(body.msg);
|
||||
// // 注意:这里如果继续抛出错误会被行254的 catchError 二次拦截,导致外部实现的 Pipe、subscribe 操作被中断,例如:this.http.get('/').subscribe() 不会触发
|
||||
// // 如果你希望外部实现,需要手动移除行254
|
||||
// return throwError({});
|
||||
// } else {
|
||||
// // 忽略 Blob 文件体
|
||||
// if (ev.body instanceof Blob) {
|
||||
// return of(ev);
|
||||
// }
|
||||
// // 重新修改 `body` 内容为 `response` 内容,对于绝大多数场景已经无须再关心业务状态码
|
||||
// return of(new HttpResponse(Object.assign(ev, { body: body.response })));
|
||||
// // 或者依然保持完整的格式
|
||||
// return of(ev);
|
||||
// }
|
||||
// }
|
||||
break;
|
||||
case 401:
|
||||
if (this.refreshTokenEnabled && this.refreshTokenType === 're-request') {
|
||||
return this.tryRefreshToken(ev, req, next);
|
||||
}
|
||||
this.toLogin();
|
||||
break;
|
||||
case 403:
|
||||
case 404:
|
||||
case 500:
|
||||
// this.goTo(`/exception/${ev.status}?url=${req.urlWithParams}`);
|
||||
break;
|
||||
default:
|
||||
if (ev instanceof HttpErrorResponse) {
|
||||
console.warn(
|
||||
'未可知错误,大部分是由于后端不支持跨域CORS或无效配置引起,请参考 https://ng-alain.com/docs/server 解决跨域问题',
|
||||
ev
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ev instanceof HttpErrorResponse) {
|
||||
return throwError(ev);
|
||||
} else {
|
||||
return of(ev);
|
||||
}
|
||||
}
|
||||
|
||||
private getAdditionalHeaders(headers?: HttpHeaders): { [name: string]: string } {
|
||||
private fillHeaders(headers?: HttpHeaders): { [name: string]: string } {
|
||||
const res: { [name: string]: string } = {};
|
||||
const lang = this.injector.get(ALAIN_I18N_TOKEN).currentLang;
|
||||
if (!headers?.has('Accept-Language') && lang) {
|
||||
res['Accept-Language'] = lang;
|
||||
}
|
||||
|
||||
let token = this.storageSvc.getAuthorizationToken();
|
||||
if (token !== null) {
|
||||
res['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
// 统一加上服务端前缀
|
||||
let url = req.url;
|
||||
if (!url.startsWith('https://') && !url.startsWith('http://')) {
|
||||
const { baseUrl } = environment.api;
|
||||
url = baseUrl + (baseUrl.endsWith('/') && url.startsWith('/') ? url.substring(1) : url);
|
||||
}
|
||||
|
||||
const newReq = req.clone({ url, setHeaders: this.getAdditionalHeaders(req.headers) });
|
||||
const newReq = req.clone({ url, setHeaders: this.fillHeaders(req.headers) });
|
||||
return next.handle(newReq).pipe(
|
||||
mergeMap(ev => {
|
||||
// 允许统一对请求错误处理
|
||||
if (ev instanceof HttpResponseBase) {
|
||||
return this.handleData(ev, newReq, next);
|
||||
mergeMap(httpEvent => {
|
||||
if (httpEvent instanceof HttpResponseBase) {
|
||||
// 处理token过期自动刷新
|
||||
switch (httpEvent.status) {
|
||||
case 401:
|
||||
if (this.refreshTokenEnabled) {
|
||||
return this.tryRefreshToken(httpEvent, req, next);
|
||||
}
|
||||
this.toLogin();
|
||||
break;
|
||||
case 403 | 404 | 500:
|
||||
this.goTo(`/exception/${httpEvent.status}?url=${req.urlWithParams}`);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return of(httpEvent);
|
||||
} else {
|
||||
return of(httpEvent);
|
||||
}
|
||||
// 若一切都正常,则后续操作
|
||||
return of(ev);
|
||||
}),
|
||||
catchError((err: HttpErrorResponse) => this.handleData(err, newReq, next))
|
||||
catchError((err: HttpErrorResponse) => {
|
||||
this.checkStatus(err);
|
||||
console.warn(`${err.status} == ${err.message}`)
|
||||
return throwError(err);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import { NzIconService } from 'ng-zorro-antd/icon';
|
||||
|
||||
import { ICONS } from '../../../style-icons';
|
||||
import { ICONS_AUTO } from '../../../style-icons-auto';
|
||||
|
||||
/**
|
||||
* Used for application startup
|
||||
* Generally used to get the basic data of the application, like: Menu Data, User Data, etc.
|
||||
@@ -36,7 +35,7 @@ export class StartupService {
|
||||
|
||||
private viaHttp(): Observable<void> {
|
||||
const defaultLang = this.i18n.defaultLang;
|
||||
return zip(this.i18n.loadLangData(defaultLang), this.httpClient.get('assets/tmp/app-data.json')).pipe(
|
||||
return zip(this.i18n.loadLangData(defaultLang), this.httpClient.get('http://localhost:4200/assets/tmp/app-data.json')).pipe(
|
||||
catchError((res: NzSafeAny) => {
|
||||
console.warn(`StartupService.load: Network request failed`, res);
|
||||
setTimeout(() => this.router.navigateByUrl(`/exception/500`));
|
||||
|
||||
5
web-app/src/app/pojo/Message.ts
Normal file
5
web-app/src/app/pojo/Message.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export class Message {
|
||||
data: any;
|
||||
msg!: string;
|
||||
code: number = 0;
|
||||
}
|
||||
13
web-app/src/app/pojo/Monitor.ts
Normal file
13
web-app/src/app/pojo/Monitor.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export class Monitor {
|
||||
id!: number;
|
||||
name!: string;
|
||||
app!: string;
|
||||
host!: string;
|
||||
intervals!: number;
|
||||
status!: number;
|
||||
description!: string;
|
||||
creator!: string;
|
||||
modifier!: string;
|
||||
gmtCreate!: number;
|
||||
gmtUpdate!: number;
|
||||
}
|
||||
6
web-app/src/app/pojo/Param.ts
Normal file
6
web-app/src/app/pojo/Param.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export class Param {
|
||||
id!: number;
|
||||
field: string | undefined;
|
||||
type: number | undefined;
|
||||
value: string | undefined;
|
||||
}
|
||||
9
web-app/src/app/pojo/ParamDefine.ts
Normal file
9
web-app/src/app/pojo/ParamDefine.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class ParamDefine {
|
||||
name!: string;
|
||||
field!: string;
|
||||
type!: string;
|
||||
required: boolean | undefined;
|
||||
range: string | undefined;
|
||||
limit: number | undefined;
|
||||
option: string | undefined;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>monitor-detail works!</p>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MonitorDetailComponent } from './monitor-detail.component';
|
||||
|
||||
describe('MonitorDetailComponent', () => {
|
||||
let component: MonitorDetailComponent;
|
||||
let fixture: ComponentFixture<MonitorDetailComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MonitorDetailComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MonitorDetailComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-monitor-detail',
|
||||
templateUrl: './monitor-detail.component.html',
|
||||
styles: [
|
||||
]
|
||||
})
|
||||
export class MonitorDetailComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>monitor-modify works!</p>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MonitorEditComponent } from './monitor-edit.component';
|
||||
|
||||
describe('MonitorModifyComponent', () => {
|
||||
let component: MonitorEditComponent;
|
||||
let fixture: ComponentFixture<MonitorEditComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MonitorEditComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MonitorEditComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-monitor-modify',
|
||||
templateUrl: './monitor-edit.component.html',
|
||||
styles: [
|
||||
]
|
||||
})
|
||||
export class MonitorEditComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<nz-breadcrumb [nzAutoGenerate]="true"></nz-breadcrumb>
|
||||
<p>monitor-list works!</p>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MonitorListComponent } from './monitor-list.component';
|
||||
|
||||
describe('MonitorListComponent', () => {
|
||||
let component: MonitorListComponent;
|
||||
let fixture: ComponentFixture<MonitorListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MonitorListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MonitorListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-monitor-list',
|
||||
templateUrl: './monitor-list.component.html',
|
||||
styles: [
|
||||
]
|
||||
})
|
||||
export class MonitorListComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<nz-divider></nz-divider>
|
||||
<nz-breadcrumb>
|
||||
<nz-breadcrumb-item>
|
||||
<a [routerLink]="['/']">
|
||||
<i nz-icon nzType="home"></i>
|
||||
</a>
|
||||
</nz-breadcrumb-item>
|
||||
<nz-breadcrumb-item>
|
||||
<a [routerLink]="['/monitors']">
|
||||
<i nz-icon nzType="monitor"></i>
|
||||
<span>监控列表</span>
|
||||
</a>
|
||||
</nz-breadcrumb-item>
|
||||
<nz-breadcrumb-item>
|
||||
<i nz-icon nzType="plus-circle"></i>
|
||||
<span>新增 {{monitor.app}} 监控</span>
|
||||
</nz-breadcrumb-item>
|
||||
</nz-breadcrumb>
|
||||
<nz-divider></nz-divider>
|
||||
|
||||
<div class = "-inner-content">
|
||||
<form nz-form (ngSubmit)="onSubmit()">
|
||||
<nz-form-item>
|
||||
<nz-form-label [nzSpan]="7" nzFor= 'host' nzRequired="true">监控Host</nz-form-label>
|
||||
<nz-form-control [nzSpan]="10">
|
||||
<input [(ngModel)]="monitor.host" nz-input name="host" type="text" id="host">
|
||||
</nz-form-control>
|
||||
</nz-form-item >
|
||||
<nz-form-item>
|
||||
<nz-form-label [nzSpan]="7" nzFor= 'name' nzRequired="true">监控名称</nz-form-label>
|
||||
<nz-form-control [nzSpan]="10">
|
||||
<input [(ngModel)]="monitor.name" nz-input name="name" type="text" id="name">
|
||||
</nz-form-control>
|
||||
</nz-form-item >
|
||||
|
||||
<nz-divider></nz-divider>
|
||||
|
||||
<nz-form-item *ngFor="let paramDefine of paramDefines; let i = index">
|
||||
<nz-form-label *ngIf="paramDefine.field !== 'host' && paramDefine.type ==='text'"
|
||||
nzSpan="7"
|
||||
[nzRequired]="paramDefine.required"
|
||||
[nzFor]= "paramDefine.field">{{paramDefine.name}}
|
||||
</nz-form-label>
|
||||
<nz-form-control *ngIf="paramDefine.field !== 'host' && paramDefine.type ==='text'" nzSpan="10">
|
||||
<input nz-input [(ngModel)]="params[i].value" [name]="paramDefine.field" [type]="paramDefine.type" [id]="paramDefine.field">
|
||||
</nz-form-control>
|
||||
|
||||
<nz-form-label *ngIf="paramDefine.type === 'password'"
|
||||
nzSpan="7"
|
||||
[nzRequired]="paramDefine.required"
|
||||
[nzFor]= "paramDefine.field">{{paramDefine.name}}
|
||||
</nz-form-label>
|
||||
<nz-form-control *ngIf="paramDefine.type === 'password'" nzSpan="10">
|
||||
<nz-input-group [nzSuffix]="suffixTemplate">
|
||||
<input
|
||||
[type]="passwordVisible ? 'text' : 'password'"
|
||||
nz-input
|
||||
placeholder="input password"
|
||||
[(ngModel)]="params[i].value"
|
||||
[id]="paramDefine.field"
|
||||
[name]="paramDefine.field"
|
||||
/>
|
||||
</nz-input-group>
|
||||
<ng-template #suffixTemplate>
|
||||
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
|
||||
</ng-template>
|
||||
</nz-form-control>
|
||||
|
||||
|
||||
<nz-form-label *ngIf="paramDefine.type === 'number'"
|
||||
nzSpan="7"
|
||||
[nzRequired]="paramDefine.required"
|
||||
[nzFor]= "paramDefine.field">{{paramDefine.name}}
|
||||
</nz-form-label>
|
||||
<nz-form-control *ngIf="paramDefine.type === 'number'" nzSpan="10">
|
||||
<nz-input-number
|
||||
[(ngModel)]="params[i].value"
|
||||
[nzMin]="-1000"
|
||||
[nzMax]="65535"
|
||||
[nzStep]="1"
|
||||
[nzPlaceHolder]="paramDefine.name"
|
||||
[name]="paramDefine.field" [id]="paramDefine.field"
|
||||
></nz-input-number>
|
||||
</nz-form-control>
|
||||
|
||||
<nz-form-label *ngIf="paramDefine.type === 'boolean'"
|
||||
nzSpan="7"
|
||||
[nzRequired]="paramDefine.required"
|
||||
[nzFor]= "paramDefine.field">{{paramDefine.name}}
|
||||
</nz-form-label>
|
||||
<nz-form-control *ngIf="paramDefine.type === 'boolean'" nzSpan="10">
|
||||
<nz-switch [(ngModel)]="params[i].value" [name]="paramDefine.field" [id]="paramDefine.field"></nz-switch>
|
||||
</nz-form-control>
|
||||
|
||||
</nz-form-item >
|
||||
|
||||
<nz-divider></nz-divider>
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="7" nzFor= "intervals">采集间隔</nz-form-label>
|
||||
<nz-form-control nzSpan="10">
|
||||
<nz-input-number [(ngModel)]="monitor.intervals" [nzMin]="10" [nzMax]="10000" [nzStep]="10" id="intervals"></nz-input-number>
|
||||
</nz-form-control>
|
||||
</nz-form-item >
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="7" nzFor= "detect">启动探测</nz-form-label>
|
||||
<nz-form-control nzSpan="10">
|
||||
<nz-switch [(ngModel)]="detected" name="detect" id="detect"></nz-switch>
|
||||
</nz-form-control>
|
||||
</nz-form-item >
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label [nzSpan]="7" nzFor= 'description'>描述备注</nz-form-label>
|
||||
<nz-form-control [nzSpan]="10">
|
||||
<nz-textarea-count [nzMaxCharacterCount]="100">
|
||||
<textarea rows="3" nz-input name="description" id="description"></textarea>
|
||||
</nz-textarea-count>
|
||||
</nz-form-control>
|
||||
</nz-form-item >
|
||||
|
||||
<div nz-row>
|
||||
<div nz-col nzSpan="8" nzOffset="9">
|
||||
<button nz-button nzType="primary" type="submit">
|
||||
探测
|
||||
</button>
|
||||
<button nz-button nzType="primary" type="submit">
|
||||
确定
|
||||
</button>
|
||||
<button nz-button nzType="primary" nzDanger="true" type="reset">
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MonitorNewComponent } from './monitor-new.component';
|
||||
|
||||
describe('MonitorAddComponent', () => {
|
||||
let component: MonitorNewComponent;
|
||||
let fixture: ComponentFixture<MonitorNewComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MonitorNewComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MonitorNewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {ParamDefine} from "../../../pojo/ParamDefine";
|
||||
import {AppDefineService} from "../../../service/app-define.service";
|
||||
import {ActivatedRoute, ParamMap, Router} from "@angular/router";
|
||||
import {switchMap} from "rxjs/operators";
|
||||
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
|
||||
import {I18NService} from "@core";
|
||||
import {Param} from "../../../pojo/Param";
|
||||
import {Monitor} from "../../../pojo/Monitor";
|
||||
import {MonitorService} from "../../../service/monitor.service";
|
||||
import {NzNotificationService} from "ng-zorro-antd/notification";
|
||||
|
||||
@Component({
|
||||
selector: 'app-monitor-add',
|
||||
templateUrl: './monitor-new.component.html',
|
||||
styles: [
|
||||
]
|
||||
})
|
||||
export class MonitorNewComponent implements OnInit {
|
||||
|
||||
paramDefines!: ParamDefine[];
|
||||
params!: Param[];
|
||||
monitor!: Monitor;
|
||||
profileForm: FormGroup = new FormGroup({});
|
||||
detected: boolean = true;
|
||||
passwordVisible!: boolean;
|
||||
constructor(private appDefineSvc: AppDefineService,
|
||||
private monitorSvc: MonitorService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private notifySvc: NzNotificationService,
|
||||
private i18n: I18NService,
|
||||
private formBuilder: FormBuilder) {
|
||||
this.monitor = new Monitor();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const paramDefine$ = this.route.queryParamMap.pipe(
|
||||
switchMap((paramMap: ParamMap) => {
|
||||
this.monitor.app = paramMap.get("app") || '';
|
||||
return this.appDefineSvc.getAppParamsDefine(this.monitor.app);
|
||||
})
|
||||
).subscribe(message => {
|
||||
if (message.code === 0) {
|
||||
this.paramDefines = message.data;
|
||||
this.params = [];
|
||||
this.paramDefines.forEach(define => {
|
||||
let param = new Param();
|
||||
param.field = define.field;
|
||||
param.type = define.type === "number" ? 0 : 1;
|
||||
this.params.push(param);
|
||||
})
|
||||
} else {
|
||||
console.warn(message.msg);
|
||||
}
|
||||
paramDefine$.unsubscribe();
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
let addMonitor = {
|
||||
"detected": this.detected,
|
||||
"monitor": this.monitor,
|
||||
"params": this.params
|
||||
};
|
||||
this.monitorSvc.newMonitor(addMonitor)
|
||||
.subscribe(message => {
|
||||
if (message.code === 0) {
|
||||
this.notifySvc.success("新增监控成功", "");
|
||||
this.router.navigateByUrl("/monitors")
|
||||
} else {
|
||||
this.notifySvc.error("新增监控失败", message.msg);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import {MonitorListComponent} from "./monitor-list/monitor-list.component";
|
||||
import {MonitorNewComponent} from "./monitor-new/monitor-new.component";
|
||||
import {MonitorEditComponent} from "./monitor-edit/monitor-edit.component";
|
||||
import {MonitorDetailComponent} from "./monitor-detail/monitor-detail.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: MonitorNewComponent },
|
||||
{ path: 'new', component: MonitorNewComponent },
|
||||
{ path: ':monitorId/edit', component: MonitorEditComponent },
|
||||
{ path: ':monitorId', component: MonitorDetailComponent },
|
||||
{ path: '**', component: MonitorListComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { SharedModule } from '@shared';
|
||||
import { MonitorRoutingModule } from './monitor-routing.module';
|
||||
import {MonitorNewComponent} from "./monitor-new/monitor-new.component";
|
||||
import {MonitorEditComponent} from "./monitor-edit/monitor-edit.component";
|
||||
import {MonitorListComponent} from "./monitor-list/monitor-list.component";
|
||||
import {MonitorDetailComponent} from "./monitor-detail/monitor-detail.component";
|
||||
import {NzBreadCrumbModule} from "ng-zorro-antd/breadcrumb";
|
||||
import {NzDividerModule} from "ng-zorro-antd/divider";
|
||||
import {NzSwitchModule} from "ng-zorro-antd/switch";
|
||||
|
||||
const COMPONENTS: Type<void>[] = [];
|
||||
const COMPONENTS: Type<void>[] = [
|
||||
MonitorNewComponent,
|
||||
MonitorEditComponent,
|
||||
MonitorListComponent,
|
||||
MonitorDetailComponent
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
MonitorRoutingModule
|
||||
MonitorRoutingModule,
|
||||
NzBreadCrumbModule,
|
||||
NzDividerModule,
|
||||
NzSwitchModule
|
||||
],
|
||||
declarations: COMPONENTS,
|
||||
})
|
||||
|
||||
@@ -21,12 +21,11 @@ const routes: Routes = [
|
||||
component: LayoutBasicComponent,
|
||||
canActivate: [SimpleGuard],
|
||||
children: [
|
||||
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
|
||||
// todo 根据路由自动生成面包屑
|
||||
{ path: '', redirectTo: 'dashboard', pathMatch: 'full'},
|
||||
{ path: 'dashboard', component: DashboardComponent, data: { title: '仪表盘' } },
|
||||
{ path: 'exception', loadChildren: () => import('./exception/exception.module').then(m => m.ExceptionModule) },
|
||||
// 业务子模块
|
||||
// { path: 'widgets', loadChildren: () => import('./widgets/widgets.module').then(m => m.WidgetsModule) },
|
||||
{ path: 'monitor', loadChildren: () => import('./monitor/monitor.module').then((m) => m.MonitorModule) },]
|
||||
{ path: 'monitors', loadChildren: () => import('./monitor/monitor.module').then((m) => m.MonitorModule) },]
|
||||
},
|
||||
// 空白布局
|
||||
// {
|
||||
|
||||
16
web-app/src/app/service/app-define.service.spec.ts
Normal file
16
web-app/src/app/service/app-define.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppDefineService } from './app-define.service';
|
||||
|
||||
describe('AppDefineService', () => {
|
||||
let service: AppDefineService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(AppDefineService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
22
web-app/src/app/service/app-define.service.ts
Normal file
22
web-app/src/app/service/app-define.service.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import {Message} from "../pojo/Message";
|
||||
import {Observable} from "rxjs";
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AppDefineService {
|
||||
|
||||
constructor(private http : HttpClient) { }
|
||||
|
||||
public getAppParamsDefine(app: string | undefined | null) : Observable<Message> {
|
||||
if (app === null || app === undefined) {
|
||||
console.log("getAppParamsDefine app can not null");
|
||||
}
|
||||
const paramDefineUri = `/apps/${app}/params`;
|
||||
return this.http.get<Message>(paramDefineUri);
|
||||
}
|
||||
|
||||
}
|
||||
16
web-app/src/app/service/local-storage.service.spec.ts
Normal file
16
web-app/src/app/service/local-storage.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LocalStorageService } from './local-storage.service';
|
||||
|
||||
describe('LocalStorageService', () => {
|
||||
let service: LocalStorageService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(LocalStorageService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
29
web-app/src/app/service/local-storage.service.ts
Normal file
29
web-app/src/app/service/local-storage.service.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
const Authorization = 'Authorization';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LocalStorageService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
public putData(key: string, value: string) {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
public getData(key: string): string | null {
|
||||
const data = localStorage.getItem(key);
|
||||
return data === null ? null : data;
|
||||
}
|
||||
|
||||
public getAuthorizationToken(): string | null {
|
||||
return this.getData(Authorization);
|
||||
}
|
||||
|
||||
public storageAuthorizationToken(token: string) {
|
||||
return this.putData(Authorization, token);
|
||||
}
|
||||
|
||||
}
|
||||
16
web-app/src/app/service/monitor.service.spec.ts
Normal file
16
web-app/src/app/service/monitor.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MonitorService } from './monitor.service';
|
||||
|
||||
describe('MonitorService', () => {
|
||||
let service: MonitorService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(MonitorService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
19
web-app/src/app/service/monitor.service.ts
Normal file
19
web-app/src/app/service/monitor.service.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {Observable} from "rxjs";
|
||||
import {Message} from "../pojo/Message";
|
||||
|
||||
const monitor_uri = "/monitor";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MonitorService {
|
||||
|
||||
constructor(private http : HttpClient) { }
|
||||
|
||||
public newMonitor(body: any) : Observable<Message> {
|
||||
return this.http.post<Message>(monitor_uri, body);
|
||||
}
|
||||
|
||||
}
|
||||
16
web-app/src/app/service/my-service.service.spec.ts
Normal file
16
web-app/src/app/service/my-service.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MyServiceService } from './my-service.service';
|
||||
|
||||
describe('MyServiceService', () => {
|
||||
let service: MyServiceService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(MyServiceService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
9
web-app/src/app/service/my-service.service.ts
Normal file
9
web-app/src/app/service/my-service.service.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class MyServiceService {
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"text": "仪表盘",
|
||||
"i18n": "menu.dashboard",
|
||||
"icon": "anticon-dashboard",
|
||||
"link": "/dashboard/v1"
|
||||
"link": "/dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -35,18 +35,18 @@
|
||||
"icon": "anticon-cloud",
|
||||
"children": [
|
||||
{
|
||||
"text": "仪表盘V1",
|
||||
"link": "/dashboard/v1",
|
||||
"text": "http",
|
||||
"link": "/monitors",
|
||||
"i18n": "monitor.app.http"
|
||||
},
|
||||
{
|
||||
"text": "分析页",
|
||||
"link": "/dashboard/analysis",
|
||||
"text": "ping",
|
||||
"link": "/monitors",
|
||||
"i18n": "monitor.app.ping"
|
||||
},
|
||||
{
|
||||
"text": "监控页",
|
||||
"link": "/dashboard/monitor",
|
||||
"text": "telnet",
|
||||
"link": "/monitors",
|
||||
"i18n": "monitor.app.telnet"
|
||||
}
|
||||
]
|
||||
@@ -58,17 +58,17 @@
|
||||
"children": [
|
||||
{
|
||||
"text": "Mysql",
|
||||
"link": "/dashboard/v1",
|
||||
"link": "/monitors",
|
||||
"i18n": "monitor.app.mysql"
|
||||
},
|
||||
{
|
||||
"text": "Oracle",
|
||||
"link": "/dashboard/analysis",
|
||||
"link": "/monitors",
|
||||
"i18n": "monitor.app.oracle"
|
||||
},
|
||||
{
|
||||
"text": "Redis",
|
||||
"link": "/dashboard/monitor",
|
||||
"link": "/monitors",
|
||||
"i18n": "monitor.app.redis"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -5,7 +5,6 @@ export const environment = {
|
||||
useHash: true,
|
||||
api: {
|
||||
baseUrl: './',
|
||||
refreshTokenEnabled: true,
|
||||
refreshTokenType: 'auth-refresh'
|
||||
refreshTokenEnabled: true
|
||||
}
|
||||
} as Environment;
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
import { DelonMockModule } from '@delon/mock';
|
||||
import { Environment } from '@delon/theme';
|
||||
|
||||
import * as MOCKDATA from '../../_mock';
|
||||
import * as MOCK_DATA from '../../_mock';
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
useHash: true,
|
||||
api: {
|
||||
baseUrl: './',
|
||||
refreshTokenEnabled: true,
|
||||
refreshTokenType: 'auth-refresh'
|
||||
baseUrl: 'http://localhost:8080/',
|
||||
refreshTokenEnabled: true
|
||||
},
|
||||
modules: [DelonMockModule.forRoot({ data: MOCKDATA })]
|
||||
modules: [DelonMockModule.forRoot({ data: MOCK_DATA })]
|
||||
} as Environment;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user