From d81f98a820eefd6489263e41d422a1f39b8d6a6f Mon Sep 17 00:00:00 2001 From: panqihua <1029559041@qq.com> Date: Thu, 5 Mar 2020 05:17:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=B4=A6=E5=8F=B7=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/account/account/account.module.ts | 7 +- src/app/account/login/login.component.html | 17 ++- src/app/account/login/login.component.ts | 12 +- src/app/account/login/login.service.ts | 61 ++++++-- .../account/register/register.component.html | 42 +++--- .../account/register/register.component.ts | 102 ++++---------- .../account/register/register.service.spec.ts | 4 +- src/app/account/register/register.service.ts | 42 ++---- .../account/resetpwd/resetpwd.component.html | 113 +++++++++++++-- .../account/resetpwd/resetpwd.component.ts | 133 ++++++++++++++++-- .../account/resetpwd/resetpwd.service.spec.ts | 16 +++ src/app/account/resetpwd/resetpwd.service.ts | 66 +++++++++ src/app/app.component.html | 6 +- src/app/app.component.scss | 3 + src/app/app.component.ts | 30 +++- src/app/app.module.ts | 4 +- src/app/app.service.spec.ts | 16 +++ src/app/app.service.ts | 29 ++++ src/app/commons.ts | 42 +++++- src/app/forum/forum.component.ts | 6 +- src/app/forum/forum/forum.module.ts | 7 +- src/app/html.pipe.spec.ts | 8 ++ src/app/html.pipe.ts | 20 +++ src/app/interface/HttpInterface.ts | 14 +- src/app/interface/JSONRequest.ts | 5 +- src/app/interface/JSONResponse.ts | 38 +---- src/app/interface/vo/Token.ts | 9 ++ src/app/message/message.service.ts | 1 + src/assets/i18n/en-US.json | 12 +- src/assets/i18n/zh-CN.json | 14 +- src/environments/environment.prod.ts | 4 +- src/environments/environment.rap2.ts | 5 +- src/environments/environment.ts | 4 +- 33 files changed, 653 insertions(+), 239 deletions(-) create mode 100644 src/app/account/resetpwd/resetpwd.service.spec.ts create mode 100644 src/app/account/resetpwd/resetpwd.service.ts create mode 100644 src/app/app.service.spec.ts create mode 100644 src/app/app.service.ts create mode 100644 src/app/html.pipe.spec.ts create mode 100644 src/app/html.pipe.ts create mode 100644 src/app/interface/vo/Token.ts diff --git a/src/app/account/account/account.module.ts b/src/app/account/account/account.module.ts index e59873c..a04c49c 100644 --- a/src/app/account/account/account.module.ts +++ b/src/app/account/account/account.module.ts @@ -1,5 +1,5 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; // 登陆组件 import {LoginComponent} from '../login/login.component'; // 注册组件 @@ -26,4 +26,5 @@ import {InputComponent} from '../../input/input.component'; ReactiveFormsModule, ] }) -export class AccountModule { } +export class AccountModule { +} diff --git a/src/app/account/login/login.component.html b/src/app/account/login/login.component.html index 0cb64d3..599c425 100644 --- a/src/app/account/login/login.component.html +++ b/src/app/account/login/login.component.html @@ -8,7 +8,13 @@ {{ 'login.manager_name' | translate }} + [class.is-invalid]="getValue('managerName').invalid" + [placeholder]="'tip.input' | translate:{value:'login.manager_name'|translate}" + formControlName="managerName"> + +
+ {{'tip.notnull' | translate:{value: 'login.manager_name'|translate} }} +
@@ -17,17 +23,24 @@ {{ 'login.password' | translate }}
+ +
+ {{'tip.notnull' | translate:{value: 'login.password'|translate} }} +
+
- + diff --git a/src/app/account/login/login.component.ts b/src/app/account/login/login.component.ts index 9c7b6de..fe948f6 100644 --- a/src/app/account/login/login.component.ts +++ b/src/app/account/login/login.component.ts @@ -1,5 +1,5 @@ import {Component, OnInit} from '@angular/core'; -import {FormBuilder} from '@angular/forms'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {Commons} from '../../commons'; import {Router} from '@angular/router'; import {LoginService} from './login.service'; @@ -13,8 +13,10 @@ import {LoginService} from './login.service'; export class LoginComponent extends Commons implements OnInit { // 登陆表单 loginForm = this.fb.group({ - managerName: [''], - password: [''] + // 管理员名 + managerName: this.fb.control('', Validators.required), + // 密码 + password: this.fb.control('', Validators.required) }); @@ -39,4 +41,8 @@ export class LoginComponent extends Commons implements OnInit { } + form(): FormGroup { + return this.loginForm; + } + } diff --git a/src/app/account/login/login.service.ts b/src/app/account/login/login.service.ts index 5d7850d..c047bd8 100644 --- a/src/app/account/login/login.service.ts +++ b/src/app/account/login/login.service.ts @@ -3,6 +3,13 @@ import {CookieService} from 'ngx-cookie-service'; import {Router} from '@angular/router'; import {MessageService} from '../../message/message.service'; import {JSONRequest} from '../../interface/JSONRequest'; +import {environment} from '../../../environments/environment'; +import {HttpClient} from '@angular/common/http'; +import {HttpInterface} from '../../interface/HttpInterface'; +import {JSONResponse} from '../../interface/JSONResponse'; +import {catchError} from 'rxjs/operators'; +import {Result} from '../../interface/Result'; +import {Token} from '../../interface/vo/Token'; @Injectable({ providedIn: 'root' @@ -12,7 +19,8 @@ export class LoginService extends JSONRequest { constructor( private cookieService: CookieService, private router: Router, - private messageService: MessageService + private messageService: MessageService, + private http: HttpClient, ) { super(); } @@ -21,7 +29,7 @@ export class LoginService extends JSONRequest { * 检查登陆令牌是否有效 */ checkToken(): boolean { - return false; + return this.cookieService.check(environment.tokenKey); } /** @@ -35,22 +43,45 @@ export class LoginService extends JSONRequest { } } + /** + * 注销登录 + */ + logout() { + this.http.post>(HttpInterface.logout, {}, this.httpOptions) + .pipe( + catchError(this.handleError('注销')) + ) + .subscribe(r => { + if (r.result === Result.OK) { + this.cookieService.deleteAll(); + this.messageService.info('注销成功'); + this.router.navigateByUrl('/login'); + } else { + alert('注销失败'); + } + }); + } + /** * * @param body 请求表单 */ - request(body: string) { - // res => { - // this.message = res.message; - // if (res.result === 'OK') { - // this.messageStyle = 'info'; - // this.cookieService.set(environment.tokenKey, res.body.token, 3600); - // this.router.navigateByUrl('/forum'); - // } else { - // this.messageStyle = 'warning'; - // } - // } - this.messageService.danger('登陆失败'); - return false; + request(body) { + this.http.post>(HttpInterface.login, body, this.httpOptions) + .pipe( + catchError(this.handleError('登陆')) + ) + .subscribe(r => { + if (r.result === Result.OK) { + this.messageService.info('登陆成功'); + const time = new Date(); + time.setTime(r.body.useTime); + this.cookieService.set(environment.managerKey, r.body.managerName, time); + this.cookieService.set(environment.tokenKey, r.body.token, time); + this.router.navigateByUrl('/forum'); + } else { + this.messageService.danger('登陆失败'); + } + }); } } diff --git a/src/app/account/register/register.component.html b/src/app/account/register/register.component.html index 390051d..29a021a 100644 --- a/src/app/account/register/register.component.html +++ b/src/app/account/register/register.component.html @@ -7,11 +7,11 @@
{{ 'login.manager_name' | translate }}
-
- {{'tip.notnull' | translate:{value:'login.manager_name'|translate} }} + {{'tip.notnull' | translate:{value: 'login.manager_name'|translate} }}
@@ -21,11 +21,11 @@ {{ 'login.password' | translate }}
- {{'tip.notnull' | translate:{value:'login.password'|translate} }} + {{'tip.notnull' | translate:{value: 'login.password'|translate} }}
@@ -36,13 +36,17 @@ {{ 'register.confirm_pwd' | translate }} -
- {{ checkPwd()|async }} - +
+
+ {{'tip.notnull' | translate:{value: 'register.confirm_pwd'|translate} }} +
+
+ {{'tip.password_diff'|translate}} +
@@ -51,11 +55,16 @@
{{ 'register.mobile' | translate }}
- -
- {{ checkMobile()|async }} +
+
+ {{'tip.notnull' | translate:{value: 'register.mobile'|translate} }} +
+
+ {{'tip.mobile_error'|translate}} +
@@ -65,22 +74,23 @@ {{ 'register.email' | translate }} + [placeholder]="'tip.input' | translate:{value:'register.email'|translate}" formControlName="email" + [class.is-invalid]="getValue('email').invalid"/>
- {{'tip.notnull' | translate:{value:'register.email'|translate} }} + {{'tip.notnull' | translate:{value: 'register.email'|translate} }}
- + diff --git a/src/app/account/register/register.component.ts b/src/app/account/register/register.component.ts index 093f66c..a3273c1 100644 --- a/src/app/account/register/register.component.ts +++ b/src/app/account/register/register.component.ts @@ -1,9 +1,8 @@ import {Component, OnInit} from '@angular/core'; -import {FormBuilder} from '@angular/forms'; +import {AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators} from '@angular/forms'; import {Commons} from '../../commons'; import {RegisterService} from './register.service'; -import {TranslateService} from '@ngx-translate/core'; -import {Observable, of} from 'rxjs'; +import {AppService} from '../../app.service'; @Component({ selector: 'app-register', @@ -19,105 +18,58 @@ export class RegisterComponent extends Commons implements OnInit { // 注册表单 registerForm = this.fb.group({ // 管理员名 - managerName: [], + managerName: this.fb.control('', [Validators.required]), // 密码 - password: [], + password: this.fb.control('', [Validators.required]), // 确认密码 - confirmPassword: [], + confirmPassword: this.fb.control('', [this.checkPwd()]), // 手机号 - mobile: [], + mobile: this.fb.control('', [this.checkMobile()]), // 邮箱 - email: [], + email: this.fb.control('', [Validators.required]), // 邮箱类型 - emailType: this.fb.control('-1') + emailType: this.fb.control('', [Validators.required]) }); + /** * 邮箱类型 */ - emailType$ = this.registerService.getEmailType(); + emailType$ = this.appService.getEmailType(); - // 表单验证 - validForm = { - confirmPassword: { - flag: false - }, - mobile: { - flag: false - } - }; constructor( private fb: FormBuilder, private registerService: RegisterService, - private translateService: TranslateService + private appService: AppService ) { super(); } - /** - * 检查单个表单值 - * @param name formControlName - */ - checkValue(name): boolean { - if (!this.validForm.hasOwnProperty(name)) { - this.validForm[name] = {}; - } - this.validForm[name].flag = this.registerForm.value[name]; - return !this.validForm[name].flag; - } - - /** - * 检查表单所有值 - */ - checkForm(): boolean { - for (const key in this.validForm) { - if (!this.validForm[key].flag) { - return true; - } - } - return this.registerForm.value.emailType === '-1'; - } - - /** - * 检查确认密码 - */ - checkPwd(): Observable { - - if (!this.registerForm.value.confirmPassword) { - this.validForm.confirmPassword.flag = false; - return this.translateService.get('tip.password_null'); - } else if (this.registerForm.value.password !== this.registerForm.value.confirmPassword) { - this.validForm.confirmPassword.flag = false; - return this.translateService.get('tip.password_diff'); - } else { - this.validForm.confirmPassword.flag = true; - return of(''); - } - } - /** * 检查手机 */ - checkMobile(): Observable { - if (!this.registerForm.value.mobile) { - this.validForm.mobile.flag = false; - return this.translateService.get('tip.mobile_null'); - } else if (!/^1[3456789]\d{9}$/.test(this.registerForm.value.mobile)) { - this.validForm.mobile.flag = false; - return this.translateService.get('tip.mobile_error'); - } else { - this.validForm.mobile.flag = true; - return of(''); - } + checkMobile(): ValidatorFn { + return (control: AbstractControl): {} => { + if (/^1[3456789]\d{9}$/.test(control.value)) { + return null; + } else { + return {required: control.value === null || control.value.length === 0, mobile: true}; + } + }; } ngOnInit(): void { - + this.validForm = {}; + for (const key of Object.keys(this.registerForm.value)) { + this.validForm[key] = { + flag: false + }; + } } - register() { - this.registerService.register(this.registerForm.value); + form(): FormGroup { + return this.registerForm; } } diff --git a/src/app/account/register/register.service.spec.ts b/src/app/account/register/register.service.spec.ts index 2ba3960..fff1ac9 100644 --- a/src/app/account/register/register.service.spec.ts +++ b/src/app/account/register/register.service.spec.ts @@ -1,6 +1,6 @@ -import { TestBed } from '@angular/core/testing'; +import {TestBed} from '@angular/core/testing'; -import { RegisterService } from './register.service'; +import {RegisterService} from './register.service'; describe('RegisterService', () => { let service: RegisterService; diff --git a/src/app/account/register/register.service.ts b/src/app/account/register/register.service.ts index cacafda..d1969b5 100644 --- a/src/app/account/register/register.service.ts +++ b/src/app/account/register/register.service.ts @@ -1,14 +1,14 @@ import {Injectable} from '@angular/core'; import {JSONRequest} from '../../interface/JSONRequest'; import {HttpClient} from '@angular/common/http'; -import {catchError, tap} from 'rxjs/operators'; +import {catchError} from 'rxjs/operators'; import {JSONResponse} from '../../interface/JSONResponse'; import {HttpInterface} from '../../interface/HttpInterface'; -import {Observable} from 'rxjs'; import {Result} from '../../interface/Result'; import {Router} from '@angular/router'; import {MessageService} from '../../message/message.service'; + @Injectable({ providedIn: 'root' }) @@ -20,9 +20,6 @@ export class RegisterService extends JSONRequest { private messageService: MessageService ) { super(); - - this.httpError.result = Result.FAIL; - this.httpError.message = '注册失败'; } /** @@ -32,35 +29,14 @@ export class RegisterService extends JSONRequest { register(body) { this.http.post>(HttpInterface.register, body, this.httpOptions) .pipe( - catchError(this.handleError('注册', this.httpError)) + catchError(this.handleError('注册')) ).subscribe(r => { - if (r.result === Result.OK) { - this.messageService.info('注册成功'); - this.router.navigateByUrl('/login'); - } else { - this.messageService.danger('注册失败'); - } + if (r.result === Result.OK) { + this.messageService.info('注册成功'); + this.router.navigateByUrl('/login'); + } else { + this.messageService.danger('注册失败'); + } }); } - - - /** - * 获取邮箱类型 - */ - getEmailType(): Observable { - return this.http.get>(HttpInterface.getEmailType) - .pipe( - catchError(this.handleError('获取邮箱类型')) - ); - } - - /** - * 发送验证码 - */ - sendEmail(sender): Observable { - return this.http.post>(HttpInterface.sendCode, {email: 'sender'}) - .pipe( - catchError(this.handleError('发送邮件验证码')) - ); - } } diff --git a/src/app/account/resetpwd/resetpwd.component.html b/src/app/account/resetpwd/resetpwd.component.html index bc67666..e4d6e2b 100644 --- a/src/app/account/resetpwd/resetpwd.component.html +++ b/src/app/account/resetpwd/resetpwd.component.html @@ -2,44 +2,127 @@
-
+
{{ 'login.manager_name' | translate }}
- + +
+ {{'tip.notnull' | translate:{value: 'login.manager_name'|translate} }} +
-
+
{{ 'register.email' | translate }}
-
+ [placeholder]="'tip.input' | translate:{value:'register.email'|translate}" formControlName="email" + [class.is-invalid]="getValue('email').invalid"/> + + +
+ +
+ {{'tip.notnull' | translate:{value: 'register.email'|translate} }} +
+
+ + +
+
+ {{ 'reset_pwd.new_pwd' | translate }} +
+ +
+ {{'tip.notnull' | translate:{value: 'reset_pwd.new_pwd'|translate} }} +
+
+ + +
+
+ {{ 'reset_pwd.confirm_pwd' | translate }} +
+ + +
+
+ {{'tip.notnull' | translate:{value: 'reset_pwd.confirm_pwd'|translate} }} +
+
+ {{'tip.password_diff'|translate}} +
+
-
+
{{ 'reset_pwd.code' | translate }}
+ +
+ {{'tip.notnull' | translate:{value: 'reset_pwd.code'|translate} }} +
-
- - - - + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ +
diff --git a/src/app/account/resetpwd/resetpwd.component.ts b/src/app/account/resetpwd/resetpwd.component.ts index 9b70aec..2eaf343 100644 --- a/src/app/account/resetpwd/resetpwd.component.ts +++ b/src/app/account/resetpwd/resetpwd.component.ts @@ -1,6 +1,11 @@ import {Component, OnInit} from '@angular/core'; -import {FormBuilder} from '@angular/forms'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {Commons} from '../../commons'; +import {AppService} from '../../app.service'; +import {ResetpwdService} from './resetpwd.service'; +import {Result} from '../../interface/Result'; +import {MessageService} from '../../message/message.service'; +import {Router} from '@angular/router'; @Component({ selector: 'app-resetpwd', @@ -12,27 +17,139 @@ export class ResetpwdComponent extends Commons implements OnInit { // 重置密码表单 resetForm = this.fb.group({ - managerName: [], - email: [], - verificationCode: [] + // 管理员名 + managerName: this.fb.control('', [Validators.required]), + // 邮箱 + email: this.fb.control('', [Validators.required]), + // 验证码 + verificationCode: this.fb.control('', [Validators.required]), + // 邮箱类型 + emailType: this.fb.control('', [Validators.required]), + // 新密码 + password: this.fb.control('', [Validators.required]), + // 确认新密码 + confirmPassword: this.fb.control('', [this.checkPwd()]), }); - constructor(private fb: FormBuilder) { + /** + * 邮箱类型 + */ + emailType$ = this.appService.getEmailType(); + + // 当前步骤 + step = 1; + + constructor( + private fb: FormBuilder, + private appService: AppService, + private resetpwdService: ResetpwdService, + private messageService: MessageService, + private router: Router + ) { super(); } // ngOnInit(): void { + + } + + + // 检查邮箱 + checkEmail() { + this.resetpwdService.checkEmail(this.resetForm.value).subscribe(r => { + if (r.result === Result.OK) { + // this.messageService.info('邮箱正确'); + // 进入第二步 + this.step = 2; + // 清空提示 + this.messageService.message = null; + // 第二步不允许编辑账户和邮箱 + this.disabled(); + } else { + this.messageService.danger('账号或邮箱错误'); + } + }); + } + + // 第二步不允许编辑账户和邮箱 + disabled() { + this.getValue('managerName').disable(); + this.getValue('email').disable(); + this.getValue('emailType').disable(); + } + + enabled() { + this.getValue('managerName').enable(); + this.getValue('email').enable(); + this.getValue('emailType').enable(); } // 发送验证码 sendCode() { - alert('发送验证码'); + this.resetpwdService.sendCode({ + managerName: this.getValue('managerName').value + }).subscribe(res => { + this.disabled(); + if (res.result === Result.OK) { + this.messageService.info('验证码发送成功,请查收验证码'); + } else { + this.messageService.danger('验证码发送失败,请重试或联系管理员'); + } + }); + } + + // 返回第一步 + backFirst() { + this.step = 1; + this.enabled(); + this.getValue('verificationCode').reset(); + } + + /** + * 检查验证码 + */ + checkCode() { + this.resetpwdService.checkCode({ + managerName: this.getValue('managerName').value + }).subscribe(res => { + if (res.result === Result.OK) { + // 进入第三步 + this.step = 3; + // 清空提示 + this.messageService.message = null; + } else { + this.messageService.danger('验证码不正确,请重新输入'); + } + }); } - // 重置密码 + /** + * 重置密码 + */ resetPwd() { - alert('重置密码'); + this.resetpwdService.resetPwd({ + managerName: this.getValue('managerName').value, + password: this.getValue('password').value + }).subscribe(res => { + if (res.result === Result.OK) { + this.messageService.info('重制密码成功'); + this.router.navigateByUrl('/login'); + } else { + this.messageService.danger('重置密码失败'); + } + }); + } + + form(): FormGroup { + return this.resetForm; + } + + /** + * 检查是否允许进入第二步 + */ + allowCheckEmail() { + return this.getValue('managerName').invalid || this.getValue('email').invalid || this.getValue('emailType').invalid; } } diff --git a/src/app/account/resetpwd/resetpwd.service.spec.ts b/src/app/account/resetpwd/resetpwd.service.spec.ts new file mode 100644 index 0000000..38bf005 --- /dev/null +++ b/src/app/account/resetpwd/resetpwd.service.spec.ts @@ -0,0 +1,16 @@ +import {TestBed} from '@angular/core/testing'; + +import {ResetpwdService} from './resetpwd.service'; + +describe('ResetpwdService', () => { + let service: ResetpwdService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ResetpwdService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/account/resetpwd/resetpwd.service.ts b/src/app/account/resetpwd/resetpwd.service.ts new file mode 100644 index 0000000..e35260c --- /dev/null +++ b/src/app/account/resetpwd/resetpwd.service.ts @@ -0,0 +1,66 @@ +import {Injectable} from '@angular/core'; +import {JSONRequest} from '../../interface/JSONRequest'; +import {Router} from '@angular/router'; +import {HttpClient} from '@angular/common/http'; +import {HttpInterface} from '../../interface/HttpInterface'; +import {catchError} from 'rxjs/operators'; +import {JSONResponse} from '../../interface/JSONResponse'; +import {Observable} from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +/** + * 重置密码服务 + */ +export class ResetpwdService extends JSONRequest { + + constructor( + private http: HttpClient, + private router: Router + ) { + super(); + } + + /** + * 检查邮箱 + */ + checkEmail(body): Observable> { + return this.http.post>(HttpInterface.checkEmail, body, this.httpOptions) + .pipe( + catchError(this.handleError('检查邮箱')) + ); + } + + /** + * 发送验证码 + */ + sendCode(body): Observable> { + return this.http.post>(HttpInterface.sendCode, body, this.httpOptions) + .pipe( + catchError(this.handleError('发送验证码')) + ); + } + + /** + * 检查验证码 + * @param body 表单值 + */ + checkCode(body): Observable> { + return this.http.post>(HttpInterface.checkCode, body, this.httpOptions) + .pipe( + catchError(this.handleError('检查验证码')) + ); + } + + /** + * 重置密码 + */ + resetPwd(body): Observable> { + return this.http.post>(HttpInterface.resetPwd, body, this.httpOptions) + .pipe( + catchError(this.handleError('重置密码')) + ); + } + +} diff --git a/src/app/app.component.html b/src/app/app.component.html index 1da7f88..bdc5699 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -16,12 +16,14 @@ {{ 'english' | translate }}
+ diff --git a/src/app/app.component.scss b/src/app/app.component.scss index e69de29..966ac47 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -0,0 +1,3 @@ +.manager { + color: red; +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index d4be9f5..2bcd2a6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, OnInit} from '@angular/core'; // 路由 import {NavigationStart, Router} from '@angular/router'; // 国际化服务 @@ -9,17 +9,20 @@ import {filter} from 'rxjs/operators'; // cookie操作 import {CookieService} from 'ngx-cookie-service'; // 环境变量 -import {environment} from './../environments/environment'; +import {environment} from '../environments/environment'; +import {LoginService} from './account/login/login.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) -export class AppComponent { +export class AppComponent implements OnInit{ // 登陆状态 - isLogin = this.cookieService.check(environment.tokenKey); + isLogin = false; + // 当前登陆账户 + managerName = null; navStart: Observable; @@ -28,16 +31,31 @@ export class AppComponent { * @param translate 国际化 * @param router 路由器 * @param cookieService cookie管理服务 + * @param loginService 登陆服务 */ - constructor(public translate: TranslateService, private router: Router, private cookieService: CookieService) { + constructor( + public translate: TranslateService, + private router: Router, + private cookieService: CookieService, + private loginService: LoginService + ) { this.navStart = router.events.pipe( filter(evt => evt instanceof NavigationStart) ) as Observable; } - public async ngOnInit() { + /** + * 注销登录 + */ + logout() { + this.loginService.logout(); + } + + async ngOnInit() { this.navStart.subscribe(evt => { + this.isLogin = this.cookieService.check(environment.tokenKey); + this.managerName = this.cookieService.get(environment.managerKey); if (evt.url === '/' && this.isLogin) { this.router.navigateByUrl('/forum'); } else if (evt.url === '/') { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4cff0c0..4ed4df4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -19,6 +19,7 @@ import {AccountModule} from './account/account/account.module'; import {ForumModule} from './forum/forum/forum.module'; // Http请求模块 import {HttpClient, HttpClientModule} from '@angular/common/http'; +import {HtmlPipe} from './html.pipe'; export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http); @@ -30,7 +31,8 @@ export function HttpLoaderFactory(http: HttpClient) { @NgModule({ declarations: [ AppComponent, - ErrorComponent + ErrorComponent, + HtmlPipe ], imports: [ BrowserModule, diff --git a/src/app/app.service.spec.ts b/src/app/app.service.spec.ts new file mode 100644 index 0000000..6960af3 --- /dev/null +++ b/src/app/app.service.spec.ts @@ -0,0 +1,16 @@ +import {TestBed} from '@angular/core/testing'; + +import {AppService} from './app.service'; + +describe('AppService', () => { + let service: AppService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AppService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/app.service.ts b/src/app/app.service.ts new file mode 100644 index 0000000..0ee889b --- /dev/null +++ b/src/app/app.service.ts @@ -0,0 +1,29 @@ +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; +import {JSONResponse} from './interface/JSONResponse'; +import {HttpInterface} from './interface/HttpInterface'; +import {catchError} from 'rxjs/operators'; +import {JSONRequest} from './interface/JSONRequest'; +import {HttpClient} from '@angular/common/http'; + +@Injectable({ + providedIn: 'root' +}) +export class AppService extends JSONRequest { + + constructor( + private http: HttpClient, + ) { + super(); + } + + /** + * 获取邮箱类型 + */ + getEmailType(): Observable> { + return this.http.get>(HttpInterface.getEmailType) + .pipe( + catchError(this.handleError('获取邮箱类型')) + ); + } +} diff --git a/src/app/commons.ts b/src/app/commons.ts index f663454..c0bb735 100644 --- a/src/app/commons.ts +++ b/src/app/commons.ts @@ -1,5 +1,45 @@ // 组件通用配置 -export class Commons { +import {AbstractControl, FormGroup, ValidatorFn} from '@angular/forms'; + +export abstract class Commons { // 页面高度=屏幕的高度/2 height = 'height:' + screen.height / 2 + 'px'; + + validForm; + + /** + * 表单组 + */ + abstract form(): FormGroup; + + /** + * 获取单个表单控件 + * @param key formControlName + */ + getValue(key) { + return this.form().get(key); + } + + /** + * 检查确认密码 + */ + checkPwd(): ValidatorFn { + return (control: AbstractControl): {} => { + + const check = { + required: true, + pwd: true + }; + if (this.form()) { + check.required = control.value.length === 0; + check.pwd = !check.required && control.value !== this.getValue('password').value; + } + + if (check.required || check.pwd) { + return check; + } else { + return null; + } + }; + } } diff --git a/src/app/forum/forum.component.ts b/src/app/forum/forum.component.ts index 2437727..1b8b051 100644 --- a/src/app/forum/forum.component.ts +++ b/src/app/forum/forum.component.ts @@ -1,4 +1,5 @@ import {Component, OnInit} from '@angular/core'; +import {Router} from '@angular/router'; @Component({ selector: 'app-forum', @@ -7,10 +8,13 @@ import {Component, OnInit} from '@angular/core'; }) export class ForumComponent implements OnInit { - constructor() { + constructor( + private router: Router, + ) { } ngOnInit(): void { + console.debug(this.router); } } diff --git a/src/app/forum/forum/forum.module.ts b/src/app/forum/forum/forum.module.ts index bf94313..2cbde4a 100644 --- a/src/app/forum/forum/forum.module.ts +++ b/src/app/forum/forum/forum.module.ts @@ -1,5 +1,5 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; // 论坛组件 import {ForumComponent} from '../forum.component'; import {TranslateModule} from '@ngx-translate/core'; @@ -18,4 +18,5 @@ import {TranslateModule} from '@ngx-translate/core'; TranslateModule ] }) -export class ForumModule { } +export class ForumModule { +} diff --git a/src/app/html.pipe.spec.ts b/src/app/html.pipe.spec.ts new file mode 100644 index 0000000..6c30263 --- /dev/null +++ b/src/app/html.pipe.spec.ts @@ -0,0 +1,8 @@ +import {HtmlPipe} from './html.pipe'; + +describe('HtmlPipe', () => { + it('create an instance', () => { + const pipe = new HtmlPipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/html.pipe.ts b/src/app/html.pipe.ts new file mode 100644 index 0000000..8034e51 --- /dev/null +++ b/src/app/html.pipe.ts @@ -0,0 +1,20 @@ +import {Pipe, PipeTransform} from '@angular/core'; +import {DomSanitizer} from '@angular/platform-browser'; + +@Pipe({ + name: 'html' +}) +/** + * 解析html管道 + */ +export class HtmlPipe implements PipeTransform { + + constructor(private sanitizer?: DomSanitizer) { + + } + + transform(value: string): unknown { + return this.sanitizer.bypassSecurityTrustHtml(value); + } + +} diff --git a/src/app/interface/HttpInterface.ts b/src/app/interface/HttpInterface.ts index cedfdb4..4b5f8cc 100644 --- a/src/app/interface/HttpInterface.ts +++ b/src/app/interface/HttpInterface.ts @@ -8,13 +8,19 @@ const HttpInterface = { getEmailType: '/api/manager/emailType', // 登陆接口 login: '/api/manager/login', + // 注销接口 + logout: '/api/manager/logout', // 发送验证码接口 - sendCode: '/api/manager/sendcode' + sendCode: '/api/manager/reset/code', + // 检查验证码接口 + checkCode: '/api/manager/reset/checkCode', + // 检查邮箱接口 + checkEmail: '/api/manager/reset/checkEmail', + // 重置密码 + resetPwd: '/api/manager/reset/resetPwd' }; -// tslint:disable-next-line:forin -for (const key in HttpInterface) { +for (const key of Object.keys(HttpInterface)) { HttpInterface[key] = environment.apiServer + HttpInterface[key]; } -console.debug(HttpInterface); export {HttpInterface}; diff --git a/src/app/interface/JSONRequest.ts b/src/app/interface/JSONRequest.ts index da80746..cc3d6d0 100644 --- a/src/app/interface/JSONRequest.ts +++ b/src/app/interface/JSONRequest.ts @@ -1,15 +1,12 @@ -import {HttpInterface} from './HttpInterface'; import {Observable, of} from 'rxjs'; import {HttpHeaders} from '@angular/common/http'; -import {JSONResponse} from './JSONResponse'; export abstract class JSONRequest { protected httpOptions = { - headers: new HttpHeaders({ 'Content-Type': 'application/json' }) + headers: new HttpHeaders({'Content-Type': 'application/json'}) }; - protected httpError = new JSONResponse(); /** * Handle Http operation that failed. diff --git a/src/app/interface/JSONResponse.ts b/src/app/interface/JSONResponse.ts index f8a3534..3f6ac66 100644 --- a/src/app/interface/JSONResponse.ts +++ b/src/app/interface/JSONResponse.ts @@ -1,38 +1,12 @@ import {Result} from './Result'; -export class JSONResponse { +export interface JSONResponse { // 响应结果 - // tslint:disable-next-line:variable-name - private _result: Result; -// 响应详细结果 - // tslint:disable-next-line:variable-name - private _message: string; -// 自定义其他响应信息 - // tslint:disable-next-line:variable-name - private _body: T; + result: Result; + // 响应详细结果 + message: string; + // 自定义其他响应信息 + body: T; - get result(): Result { - return this._result; - } - - set result(value: Result) { - this._result = value; - } - - get message(): string { - return this._message; - } - - set message(value: string) { - this._message = value; - } - - get body(): T { - return this._body; - } - - set body(value: T) { - this._body = value; - } } diff --git a/src/app/interface/vo/Token.ts b/src/app/interface/vo/Token.ts new file mode 100644 index 0000000..510d26a --- /dev/null +++ b/src/app/interface/vo/Token.ts @@ -0,0 +1,9 @@ +// 登陆成功记录的令牌信息 +export interface Token { + // 令牌 + token: string; + // 创建时间 + createTime: number; + // 有效时间 + useTime: number; +} diff --git a/src/app/message/message.service.ts b/src/app/message/message.service.ts index 3227f41..ef7a311 100644 --- a/src/app/message/message.service.ts +++ b/src/app/message/message.service.ts @@ -41,6 +41,7 @@ export class MessageService { this.message = message; } + constructor() { } diff --git a/src/assets/i18n/en-US.json b/src/assets/i18n/en-US.json index bdab3eb..0adaa67 100644 --- a/src/assets/i18n/en-US.json +++ b/src/assets/i18n/en-US.json @@ -14,7 +14,9 @@ "emailType": "email type" }, "reset_pwd": { - "code": "verification code" + "code": "verification code", + "new_pwd": "password", + "confirm_pwd": "confirm password" }, "forum": { "name": "forum", @@ -32,9 +34,7 @@ "input": "please input {{value}}", "HELLO": "Hello {{value}} welcome to you", "notnull": "The {{value}} cannot be empty", - "password_null": "the password cannot be empty", "password_diff": "The passwords do not match", - "mobile_null": "The phone number cannot be empty", "mobile_error": "The phone number is illegal", "select": "please choose an {{value}}" }, @@ -44,6 +44,10 @@ "forget_pwd": "forget password?", "backLogin": "back", "send_code": "send verification code", - "reset_pwd": "reset password" + "reset_pwd": "reset password", + "logout": "logout", + "next": "next", + "prev": "prev", + "check_code": "check_code" } } diff --git a/src/assets/i18n/zh-CN.json b/src/assets/i18n/zh-CN.json index 192d479..1bc294c 100644 --- a/src/assets/i18n/zh-CN.json +++ b/src/assets/i18n/zh-CN.json @@ -14,7 +14,9 @@ "email_type": "邮箱类型" }, "reset_pwd": { - "code": "验证码" + "code": "验证码", + "new_pwd": "新密码", + "confirm_pwd": "确认新密码" }, "forum": { "name": "论坛管理", @@ -30,11 +32,9 @@ }, "tip":{ "input": "请输入{{value}}", - "HELLO": "欢迎管理员{{value}}登陆", + "HELLO": "欢迎管理员{{value}}登陆", "notnull": "{{value}}不能为空", - "password_null": "确认密码不能为空", "password_diff": "密码和确认密码不一致", - "mobile_null": "手机号不能为空", "mobile_error": "手机号不合法", "select": "请选择{{value}}" }, @@ -44,6 +44,10 @@ "forget_pwd": "忘记密码?", "backLogin": "返回登陆", "send_code": "发送验证码", - "reset_pwd": "重置密码" + "reset_pwd": "重置密码", + "logout": "注销登录", + "next": "下一步", + "prev": "上一步", + "check_code": "检查验证码" } } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index e68f231..0fef1e8 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -3,5 +3,7 @@ export const environment = { // 服务端地址 apiServer: 'http://localhost', // token key - tokenKey: 'token' + tokenKey: 'token', + // 账户 key + managerKey: 'manager_name' }; diff --git a/src/environments/environment.rap2.ts b/src/environments/environment.rap2.ts index 71ef8d1..3a0235f 100644 --- a/src/environments/environment.rap2.ts +++ b/src/environments/environment.rap2.ts @@ -7,8 +7,9 @@ export const environment = { // 服务端地址 apiServer: 'http://rap2.taobao.org:38080/app/mock/245830', // token key - tokenKey: 'token' - + tokenKey: 'token', +// 账户 key + managerKey: 'manager_name' }; /* diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 7c61dd8..b165bf6 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -7,7 +7,9 @@ export const environment = { // 服务端地址 apiServer: 'http://localhost:8080', // token key - tokenKey: 'token' + tokenKey: 'token', + // 账户 key + managerKey: 'manager_name' };