3 files added
4 files modified
| | |
| | | ], |
| | | providers: [ |
| | | { provide: LOCALE_ID, useValue: 'zh-Hans' }, |
| | | // TODO 暂时关闭登陆验证 |
| | | //{ provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true}, |
| | | { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true}, |
| | | { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true}, |
| | | { provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false }, |
| | | StartupService, |
| | |
| | | <span class="title">ng-alain</span> |
| | | </a> |
| | | </div> |
| | | <p class="desc">武林中最有影响力的《葵花宝典》;欲练神功,挥刀自宫</p> |
| | | <p class="desc"></p> |
| | | </div> |
| | | <router-outlet></router-outlet> |
| | | <global-footer [links]="links"> |
New file |
| | |
| | | <form nz-form [formGroup]="form" (ngSubmit)="submit()" role="form"> |
| | | <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert> |
| | | <div nz-form-item> |
| | | <div nz-form-control [nzValidateStatus]="userName"> |
| | | <nz-input formControlName="userName" [nzPlaceHolder]="'admin'" [nzSize]="'large'"> |
| | | <ng-template #prefix> |
| | | <i class="anticon anticon-user"></i> |
| | | </ng-template> |
| | | </nz-input> |
| | | <ng-container *ngIf="userName.dirty || userName.touched"> |
| | | <p nz-form-explain *ngIf="userName.errors?.required">请输入账户名!</p> |
| | | <p nz-form-explain *ngIf="userName.errors?.minlength">至少五个字符</p> |
| | | </ng-container> |
| | | </div> |
| | | </div> |
| | | <div nz-form-item> |
| | | <div nz-form-control [nzValidateStatus]="password"> |
| | | <nz-input formControlName="password" [nzPlaceHolder]="'888888'" [nzType]="'password'" [nzSize]="'large'"> |
| | | <ng-template #prefix> |
| | | <i class="anticon anticon-lock"></i> |
| | | </ng-template> |
| | | </nz-input> |
| | | <div nz-form-explain *ngIf="(password.dirty || password.touched) && password.errors?.required">请输入密码!</div> |
| | | </div> |
| | | </div> |
| | | <div nz-form-item nz-row> |
| | | <div nz-col [nzSpan]="12"> |
| | | <label nz-checkbox formControlName="remember"> |
| | | <span>自动登录</span> |
| | | </label> |
| | | </div> |
| | | <div nz-col [nzSpan]="12" class="text-right"> |
| | | <a class="forgot" (click)="msg.error('请找欧阳锋')">忘记密码?</a> |
| | | </div> |
| | | </div> |
| | | <div nz-form-item> |
| | | <button nz-button [nzType]="'primary'" [nzLoading]="loading" [nzSize]="'large'" class="ant-btn__block"> |
| | | <span>登录</span> |
| | | </button> |
| | | </div> |
| | | </form> |
| | | <div class="other"> |
| | | 其他登录方式 |
| | | <nz-tooltip [nzTitle]="'in fact Auth0 via window'"> |
| | | <span nz-tooltip class="icon-alipay" (click)="open('auth0', 'window')"></span> |
| | | </nz-tooltip> |
| | | <nz-tooltip [nzTitle]="'in fact Github via redirect'"> |
| | | <span nz-tooltip class="icon-taobao" (click)="open('github')"></span> |
| | | </nz-tooltip> |
| | | <nz-tooltip [nzTitle]="'真的是微博'"> |
| | | <span nz-tooltip class="icon-weibo" (click)="open('weibo', 'window')"></span> |
| | | </nz-tooltip> |
| | | <a class="register" routerLink="/passport/register">注册账户</a> |
| | | </div> |
New file |
| | |
| | | @import '~@delon/theme/styles/antd/themes/default.less'; |
| | | |
| | | :host { |
| | | display: block; |
| | | width: 368px; |
| | | margin: 0 auto; |
| | | |
| | | ::ng-deep { |
| | | .tabs { |
| | | padding: 0 2px; |
| | | margin: 0 -2px; |
| | | .ant-tabs-tab { |
| | | font-size: 16px; |
| | | line-height: 24px; |
| | | } |
| | | .ant-input-affix-wrapper .ant-input:not(:first-child) { |
| | | padding-left: 34px; |
| | | } |
| | | } |
| | | |
| | | .ant-tabs .ant-tabs-bar { |
| | | border-bottom: 0; |
| | | margin-bottom: 24px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .ant-form-item { |
| | | margin-bottom: 24px; |
| | | } |
| | | |
| | | .icon-alipay, .icon-taobao, .icon-weibo { |
| | | display: inline-block; |
| | | width: 24px; |
| | | height: 24px; |
| | | background: url('https://gw.alipayobjects.com/zos/rmsportal/itDzjUnkelhQNsycranf.svg'); |
| | | margin-left: 16px; |
| | | vertical-align: middle; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .icon-alipay { |
| | | background-position: -24px 0; |
| | | |
| | | &:hover { |
| | | background-position: 0 0; |
| | | } |
| | | } |
| | | |
| | | .icon-taobao { |
| | | background-position: -24px -24px; |
| | | |
| | | &:hover { |
| | | background-position: 0 -24px; |
| | | } |
| | | } |
| | | |
| | | .icon-weibo { |
| | | background-position: -24px -48px; |
| | | |
| | | &:hover { |
| | | background-position: 0 -48px; |
| | | } |
| | | } |
| | | |
| | | .other { |
| | | text-align: left; |
| | | margin-top: 24px; |
| | | line-height: 22px; |
| | | |
| | | .register { |
| | | float: right; |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import { SettingsService } from '@delon/theme'; |
| | | import { Component, OnDestroy, Inject } from '@angular/core'; |
| | | import { Router } from '@angular/router'; |
| | | import { FormGroup, FormBuilder, Validators } from '@angular/forms'; |
| | | import { NzMessageService } from 'ng-zorro-antd'; |
| | | import { SocialService, SocialOpenType, ITokenService, DA_SERVICE_TOKEN } from '@delon/auth'; |
| | | import { environment } from '@env/environment'; |
| | | |
| | | @Component({ |
| | | selector: 'passport-login', |
| | | templateUrl: './login.component.html', |
| | | styleUrls: [ './login.component.less' ], |
| | | providers: [ SocialService ] |
| | | }) |
| | | export class UserLoginComponent implements OnDestroy { |
| | | |
| | | form: FormGroup; |
| | | error = ''; |
| | | type = 0; |
| | | loading = false; |
| | | |
| | | constructor( |
| | | fb: FormBuilder, |
| | | private router: Router, |
| | | public msg: NzMessageService, |
| | | private settingsService: SettingsService, |
| | | private socialService: SocialService, |
| | | @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) { |
| | | this.form = fb.group({ |
| | | userName: [null, [Validators.required, Validators.minLength(5)]], |
| | | password: [null, Validators.required], |
| | | mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], |
| | | captcha: [null, [Validators.required]], |
| | | remember: [true] |
| | | }); |
| | | } |
| | | |
| | | // region: fields |
| | | |
| | | get userName() { return this.form.controls.userName; } |
| | | get password() { return this.form.controls.password; } |
| | | get mobile() { return this.form.controls.mobile; } |
| | | get captcha() { return this.form.controls.captcha; } |
| | | |
| | | // endregion |
| | | |
| | | switch(ret: any) { |
| | | this.type = ret.index; |
| | | } |
| | | |
| | | // region: get captcha |
| | | |
| | | count = 0; |
| | | interval$: any; |
| | | |
| | | getCaptcha() { |
| | | this.count = 59; |
| | | this.interval$ = setInterval(() => { |
| | | this.count -= 1; |
| | | if (this.count <= 0) |
| | | clearInterval(this.interval$); |
| | | }, 1000); |
| | | } |
| | | |
| | | // endregion |
| | | |
| | | submit() { |
| | | this.error = ''; |
| | | if (this.type === 0) { |
| | | this.userName.markAsDirty(); |
| | | this.password.markAsDirty(); |
| | | if (this.userName.invalid || this.password.invalid) return; |
| | | } else { |
| | | this.mobile.markAsDirty(); |
| | | this.captcha.markAsDirty(); |
| | | if (this.mobile.invalid || this.captcha.invalid) return; |
| | | } |
| | | // mock http |
| | | this.loading = true; |
| | | setTimeout(() => { |
| | | this.loading = false; |
| | | if (this.type === 0) { |
| | | if (this.userName.value !== 'admin' || this.password.value !== '123456') { |
| | | this.error = `账户或密码错误`; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | this.tokenService.set({ |
| | | token: '123456789', |
| | | name: this.userName.value, |
| | | email: `cipchk@qq.com`, |
| | | id: 10000, |
| | | time: +new Date |
| | | }); |
| | | this.router.navigate(['/']); |
| | | }, 1000); |
| | | } |
| | | |
| | | // region: social |
| | | |
| | | open(type: string, openType: SocialOpenType = 'href') { |
| | | let url = ``; |
| | | let callback = ``; |
| | | if (environment.production) |
| | | callback = 'https://cipchk.github.io/ng-alain/callback/' + type; |
| | | else |
| | | callback = 'http://localhost:4200/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 |
| | | |
| | | ngOnDestroy(): void { |
| | | if (this.interval$) clearInterval(this.interval$); |
| | | } |
| | | } |
| | |
| | | import { DashboardAnalysisComponent } from './dashboard/analysis/analysis.component'; |
| | | import { DashboardMonitorComponent } from './dashboard/monitor/monitor.component'; |
| | | import { DashboardWorkplaceComponent } from './dashboard/workplace/workplace.component'; |
| | | import { UserLoginComponent } from 'app/routes/passport/login/login.component'; |
| | | |
| | | |
| | | const routes: Routes = [ |
| | |
| | | { path: 'sensors', loadChildren: './sensors/sensors.module#SensorsModule' }, |
| | | { path: 'systems', loadChildren: './systems/systems.module#SystemsModule' }, |
| | | ] |
| | | }, // passport |
| | | { |
| | | path: 'passport', |
| | | component: LayoutPassportComponent, |
| | | children: [ |
| | | { path: 'login', component: UserLoginComponent } |
| | | ] |
| | | }, |
| | | { path: '**', redirectTo: 'dashboard' } |
| | | ]; |
| | |
| | | import { UserLoginComponent } from './passport/login/login.component'; |
| | | import { DateService } from '@business/services/util/date.service'; |
| | | import { _HttpClient } from '@delon/theme'; |
| | | import { NgModule } from '@angular/core'; |
| | |
| | | DashboardV1Component, |
| | | DashboardAnalysisComponent, |
| | | DashboardMonitorComponent, |
| | | DashboardWorkplaceComponent |
| | | DashboardWorkplaceComponent, |
| | | UserLoginComponent |
| | | ], |
| | | providers: [ |
| | | _HttpClient, |