import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { StartupService } from '@core'; import { ReuseTabService } from '@delon/abc/reuse-tab'; import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth'; import { SettingsService, _HttpClient } from '@delon/theme'; import { User } from '@delon/theme/src/services/settings/types'; import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; import { finalize } from 'rxjs/operators'; import { Message } from '../../../pojo/Message'; import { LocalStorageService } from '../../../service/local-storage.service'; @Component({ selector: 'passport-login', templateUrl: './login.component.html', styleUrls: ['./login.component.less'], providers: [SocialService], changeDetection: ChangeDetectionStrategy.OnPush }) export class UserLoginComponent implements OnDestroy { constructor( fb: FormBuilder, private router: Router, private settingsService: SettingsService, private socialService: SocialService, @Optional() @Inject(ReuseTabService) private reuseTabService: ReuseTabService, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, private startupSrv: StartupService, private http: _HttpClient, private cdr: ChangeDetectorRef, private storageSvc: LocalStorageService ) { this.form = fb.group({ userName: [null, [Validators.required]], password: [null, [Validators.required]], mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], captcha: [null, [Validators.required]], remember: [true] }); } // #region fields get userName(): AbstractControl { return this.form.controls.userName; } get password(): AbstractControl { return this.form.controls.password; } get mobile(): AbstractControl { return this.form.controls.mobile; } get captcha(): AbstractControl { return this.form.controls.captcha; } form: FormGroup; error = ''; type = 0; loading = false; // #region get captcha count = 0; interval$: any; // #endregion switch({ index }: NzTabChangeEvent): void { this.type = index!; } // #endregion submit(): void { this.error = ''; if (this.type === 0) { this.userName.markAsDirty(); this.userName.updateValueAndValidity(); this.password.markAsDirty(); this.password.updateValueAndValidity(); if (this.userName.invalid || this.password.invalid) { return; } } else { this.mobile.markAsDirty(); this.mobile.updateValueAndValidity(); this.captcha.markAsDirty(); this.captcha.updateValueAndValidity(); if (this.mobile.invalid || this.captcha.invalid) { return; } } // 默认配置中对所有HTTP请求都会强制 [校验](https://ng-alain.com/auth/getting-started) 用户 Token // 然一般来说登录请求不需要校验,因此可以在请求URL加上:`/login?_allow_anonymous=true` 表示不触发用户 Token 校验 this.loading = true; this.cdr.detectChanges(); this.http .post>('/account/auth/form', { type: this.type, identifier: this.userName.value, credential: this.password.value }) .pipe( finalize(() => { this.loading = false; this.cdr.detectChanges(); }) ) .subscribe(message => { if (message.code !== 0) { this.error = message.msg; this.cdr.detectChanges(); return; } // 清空路由复用信息 this.reuseTabService.clear(); // 设置用户Token信息 this.storageSvc.storageAuthorizationToken(message.data.token); this.storageSvc.storageRefreshToken(message.data.refreshToken); let user: User = { name: this.userName.value, avatar: './assets/img/avatar.svg', email: '管理员' }; this.settingsService.setUser(user); // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 this.startupSrv.load().subscribe(() => { let url = this.tokenService.referrer!.url || '/'; if (url.includes('/passport')) { url = '/'; } this.router.navigateByUrl(url); }); }); } // #endregion ngOnDestroy(): void { if (this.interval$) { clearInterval(this.interval$); } } }