diff --git a/angular.json b/angular.json
index 8753b78..7fee45f 100644
--- a/angular.json
+++ b/angular.json
@@ -64,6 +64,14 @@
"maximumError": "10kb"
}
]
+ },
+ "rap2": {
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.rap2.ts"
+ }
+ ]
}
}
},
@@ -75,6 +83,9 @@
"configurations": {
"production": {
"browserTarget": "PocketCommunityWeb:build:production"
+ },
+ "rap2": {
+ "browserTarget": "PocketCommunityWeb:build:rap2"
}
}
},
diff --git a/src/app/account/account/account.module.ts b/src/app/account/account/account.module.ts
index 09f9c52..e59873c 100644
--- a/src/app/account/account/account.module.ts
+++ b/src/app/account/account/account.module.ts
@@ -6,15 +6,24 @@ import {LoginComponent} from '../login/login.component';
import {RegisterComponent} from '../register/register.component';
// 重置密码组件
import {ResetpwdComponent} from '../resetpwd/resetpwd.component';
+import {TranslateModule} from '@ngx-translate/core';
+import {RouterModule} from '@angular/router';
+import {ReactiveFormsModule} from '@angular/forms';
+// 提示框组件
+import {MessageComponent} from '../../message/message.component';
+import {InputComponent} from '../../input/input.component';
/**
* 账号管理模块
*/
@NgModule({
- declarations: [LoginComponent, RegisterComponent, ResetpwdComponent],
+ declarations: [LoginComponent, RegisterComponent, ResetpwdComponent, MessageComponent, InputComponent],
imports: [
- CommonModule
+ CommonModule,
+ TranslateModule,
+ RouterModule,
+ ReactiveFormsModule,
]
})
export class AccountModule { }
diff --git a/src/app/account/login/login.component.html b/src/app/account/login/login.component.html
index df5a7b5..0cb64d3 100644
--- a/src/app/account/login/login.component.html
+++ b/src/app/account/login/login.component.html
@@ -8,7 +8,7 @@
{{ 'login.manager_name' | translate }}
+ [placeholder]="'tip.input' | translate:{value:'login.manager_name'|translate}" formControlName="managerName">
@@ -17,7 +17,7 @@
{{ 'login.password' | translate }}
+ [placeholder]="'tip.input' | translate:{value:'login.manager_name'|translate}" formControlName="password">
@@ -17,7 +21,12 @@
{{ 'login.password' | translate }}
+ [class.is-invalid]="checkValue('password')"
+ [placeholder]="'tip.input' | translate:{value:'login.password'|translate}" formControlName="password"/>
+
+
+ {{'tip.notnull' | translate:{value:'login.password'|translate} }}
+
@@ -27,8 +36,14 @@
{{ 'register.confirm_pwd' | translate }}
+ [class.is-invalid]="(checkPwd()|async) !==''"
+ [placeholder]="'tip.input' | translate:{value:'register.confirm_pwd'|translate}"
+ formControlName="confirmPassword"/>
+
+
+ {{ checkPwd()|async }}
+
+
@@ -36,29 +51,41 @@
{{ 'register.mobile' | translate }}
-
+
+
+
+ {{ checkMobile()|async }}
+
-
diff --git a/src/app/account/register/register.component.ts b/src/app/account/register/register.component.ts
index 86c6285..093f66c 100644
--- a/src/app/account/register/register.component.ts
+++ b/src/app/account/register/register.component.ts
@@ -1,37 +1,123 @@
import {Component, OnInit} from '@angular/core';
import {FormBuilder} from '@angular/forms';
import {Commons} from '../../commons';
-import {Router} from '@angular/router';
import {RegisterService} from './register.service';
+import {TranslateService} from '@ngx-translate/core';
+import {Observable, of} from 'rxjs';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.scss']
})
+
+
// 注册模块
export class RegisterComponent extends Commons implements OnInit {
+
+
// 注册表单
registerForm = this.fb.group({
+ // 管理员名
managerName: [],
+ // 密码
password: [],
+ // 确认密码
confirmPassword: [],
+ // 手机号
mobile: [],
- email: []
+ // 邮箱
+ email: [],
+ // 邮箱类型
+ emailType: this.fb.control('-1')
});
+ /**
+ * 邮箱类型
+ */
+ emailType$ = this.registerService.getEmailType();
+
+ // 表单验证
+ validForm = {
+ confirmPassword: {
+ flag: false
+ },
+ mobile: {
+ flag: false
+ }
+ };
+
constructor(
private fb: FormBuilder,
- private router: Router,
- private registerService: RegisterService
+ private registerService: RegisterService,
+ private translateService: TranslateService
) {
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('');
+ }
+ }
+
ngOnInit(): void {
+
}
register() {
- this.registerService.register(JSON.stringify(this.registerForm.value));
+ this.registerService.register(this.registerForm.value);
}
}
+
diff --git a/src/app/account/register/register.service.ts b/src/app/account/register/register.service.ts
index bae472c..cacafda 100644
--- a/src/app/account/register/register.service.ts
+++ b/src/app/account/register/register.service.ts
@@ -1,22 +1,66 @@
-import { Injectable } from '@angular/core';
-import {HttpInterface} from '../../interface/Http';
+import {Injectable} from '@angular/core';
+import {JSONRequest} from '../../interface/JSONRequest';
+import {HttpClient} from '@angular/common/http';
+import {catchError, tap} 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'
})
-export class RegisterService implements HttpInterface {
+export class RegisterService extends JSONRequest {
- constructor() { }
+ constructor(
+ private http: HttpClient,
+ private router: Router,
+ private messageService: MessageService
+ ) {
+ super();
+
+ this.httpError.result = Result.FAIL;
+ this.httpError.message = '注册失败';
+ }
/**
*
* @param body 注册表单
*/
- register(body: string) {
+ register(body) {
+ this.http.post>(HttpInterface.register, body, this.httpOptions)
+ .pipe(
+ catchError(this.handleError('注册', this.httpError))
+ ).subscribe(r => {
+ 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('获取邮箱类型'))
+ );
}
- url(): string {
- return '/api/manager/register';
+ /**
+ * 发送验证码
+ */
+ sendEmail(sender): Observable {
+ return this.http.post>(HttpInterface.sendCode, {email: 'sender'})
+ .pipe(
+ catchError(this.handleError('发送邮件验证码'))
+ );
}
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 88e0fd9..4cff0c0 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -7,18 +7,18 @@ import {AppComponent} from './app.component';
// 响应式表单
import {ReactiveFormsModule} from '@angular/forms';
// 国际化支持
-import {HttpClient, HttpClientModule} from '@angular/common/http';
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
// cookie
import {CookieService} from 'ngx-cookie-service';
-// 提示框组件
-import {MessageComponent} from './message/message.component'
// 异常处理组件
import {ErrorComponent} from './error/error.component';
// 账号管理模块
import {AccountModule} from './account/account/account.module';
+// 论坛模块
import {ForumModule} from './forum/forum/forum.module';
+// Http请求模块
+import {HttpClient, HttpClientModule} from '@angular/common/http';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
@@ -30,7 +30,6 @@ export function HttpLoaderFactory(http: HttpClient) {
@NgModule({
declarations: [
AppComponent,
- MessageComponent,
ErrorComponent
],
imports: [
diff --git a/src/app/commons.ts b/src/app/commons.ts
index ef320b2..f663454 100644
--- a/src/app/commons.ts
+++ b/src/app/commons.ts
@@ -1,24 +1,5 @@
-import {environment} from './../environments/environment';
-
// 组件通用配置
export class Commons {
// 页面高度=屏幕的高度/2
height = 'height:' + screen.height / 2 + 'px';
-
- // post请求
- request(url, b, res) {
- const header = new Headers();
- header.append('Content-Type', 'application/json');
- const req = new Request(environment.apiServer + url,
- {method: 'POST', body: b, headers: header});
- fetch(req).then(r => {
- if (r.status === 200) {
- return r.json();
- } else {
- throw new Error('666');
- }
- }).then(res).catch(err => {
- console.error(err);
- });
- }
}
diff --git a/src/app/forum/forum/forum.module.ts b/src/app/forum/forum/forum.module.ts
index f19a7f4..bf94313 100644
--- a/src/app/forum/forum/forum.module.ts
+++ b/src/app/forum/forum/forum.module.ts
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
// 论坛组件
import {ForumComponent} from '../forum.component';
+import {TranslateModule} from '@ngx-translate/core';
/**
@@ -9,8 +10,12 @@ import {ForumComponent} from '../forum.component';
*/
@NgModule({
declarations: [ForumComponent],
+ exports: [
+ ForumComponent
+ ],
imports: [
- CommonModule
+ CommonModule,
+ TranslateModule
]
})
export class ForumModule { }
diff --git a/src/app/interface/Http.ts b/src/app/interface/Http.ts
deleted file mode 100644
index 0518c20..0000000
--- a/src/app/interface/Http.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// 请求接口
-export interface HttpInterface {
- // 接口地址
- url(): string;
-}
diff --git a/src/app/interface/HttpInterface.ts b/src/app/interface/HttpInterface.ts
new file mode 100644
index 0000000..cedfdb4
--- /dev/null
+++ b/src/app/interface/HttpInterface.ts
@@ -0,0 +1,20 @@
+// 环境变量
+import {environment} from '../../environments/environment';
+// 请求接口
+const HttpInterface = {
+ // 注册接口
+ register: '/api/manager/register',
+ // 获取邮箱类型接口
+ getEmailType: '/api/manager/emailType',
+ // 登陆接口
+ login: '/api/manager/login',
+ // 发送验证码接口
+ sendCode: '/api/manager/sendcode'
+};
+
+// tslint:disable-next-line:forin
+for (const key in 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
new file mode 100644
index 0000000..da80746
--- /dev/null
+++ b/src/app/interface/JSONRequest.ts
@@ -0,0 +1,30 @@
+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' })
+ };
+
+ protected httpError = new JSONResponse();
+
+ /**
+ * Handle Http operation that failed.
+ * Let the app continue.
+ * @param operation - name of the operation that failed
+ * @param result - optional value to return as the observable result
+ */
+ protected handleError(operation = 'operation', result?: T) {
+ return (error: any): Observable => {
+
+ // TODO: send the error to remote logging infrastructure
+ console.error(error); // log to console instead
+
+ // Let the app keep running by returning an empty result.
+ return of(result as T);
+ };
+ }
+}
diff --git a/src/app/interface/JSONResponse.ts b/src/app/interface/JSONResponse.ts
new file mode 100644
index 0000000..f8a3534
--- /dev/null
+++ b/src/app/interface/JSONResponse.ts
@@ -0,0 +1,38 @@
+import {Result} from './Result';
+
+
+export class 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;
+
+ 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/Result.ts b/src/app/interface/Result.ts
new file mode 100644
index 0000000..30f4e6c
--- /dev/null
+++ b/src/app/interface/Result.ts
@@ -0,0 +1,4 @@
+export enum Result {
+ OK = 'OK',
+ FAIL = 'FAIL'
+}
diff --git a/src/assets/i18n/en-US.json b/src/assets/i18n/en-US.json
index 406a7d3..bdab3eb 100644
--- a/src/assets/i18n/en-US.json
+++ b/src/assets/i18n/en-US.json
@@ -10,7 +10,8 @@
"register": {
"confirm_pwd": "confrim password",
"mobile": "mobile",
- "email": "email"
+ "email": "email",
+ "emailType": "email type"
},
"reset_pwd": {
"code": "verification code"
@@ -28,8 +29,14 @@
"complaint": "time:{{time}}"
},
"tip":{
- "input": "please input ",
- "HELLO": "Hello {{value}} welcome to you"
+ "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}}"
},
"button": {
"login": "login",
diff --git a/src/assets/i18n/zh-CN.json b/src/assets/i18n/zh-CN.json
index f4afc12..192d479 100644
--- a/src/assets/i18n/zh-CN.json
+++ b/src/assets/i18n/zh-CN.json
@@ -10,7 +10,8 @@
"register": {
"confirm_pwd": "确认密码",
"mobile": "手机",
- "email": "邮箱"
+ "email": "邮箱",
+ "email_type": "邮箱类型"
},
"reset_pwd": {
"code": "验证码"
@@ -28,8 +29,14 @@
"complaint_time": "投诉时间:{{time}}"
},
"tip":{
- "input": "请输入",
- "HELLO": "欢迎管理员{{value}}登陆"
+ "input": "请输入{{value}}",
+ "HELLO": "欢迎管理员{{value}}登陆",
+ "notnull": "{{value}}不能为空",
+ "password_null": "确认密码不能为空",
+ "password_diff": "密码和确认密码不一致",
+ "mobile_null": "手机号不能为空",
+ "mobile_error": "手机号不合法",
+ "select": "请选择{{value}}"
},
"button": {
"login": "登陆",
diff --git a/src/environments/environment.rap2.ts b/src/environments/environment.rap2.ts
new file mode 100644
index 0000000..71ef8d1
--- /dev/null
+++ b/src/environments/environment.rap2.ts
@@ -0,0 +1,21 @@
+// This file can be replaced during build by using the `fileReplacements` array.
+// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
+// The list of file replacements can be found in `angular.json`.
+
+export const environment = {
+ production: false,
+ // 服务端地址
+ apiServer: 'http://rap2.taobao.org:38080/app/mock/245830',
+ // token key
+ tokenKey: 'token'
+
+};
+
+/*
+ * For easier debugging in development mode, you can import the following file
+ * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
+ *
+ * This import should be commented out in production mode because it will have a negative impact
+ * on performance if an error is thrown.
+ */
+// import 'zone.js/dist/zone-error'; // Included with Angular CLI.