刘向辉
2 years ago
19 changed files with 317 additions and 31 deletions
@ -0,0 +1,53 @@
|
||||
<div class="box"> |
||||
<div class="step1" *ngIf="currentStep == 1"> |
||||
<form nz-form [formGroup]="validateForm" (ngSubmit)="step1()"> |
||||
<nz-form-item> |
||||
<nz-form-label nzRequired nzFor="">请输入要修改密码的账号</nz-form-label> |
||||
<nz-form-control> |
||||
<input autocomplete="off" nz-input formControlName="account" id="account" /> |
||||
</nz-form-control> |
||||
</nz-form-item> |
||||
<div class="btn"> |
||||
<button type="submit" nz-button nzType="primary">下一步</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
<div class="step2" *ngIf="currentStep == 2"> |
||||
<div class="phonebox"> |
||||
该账号绑定的手机号为:{{phoneNum}} <button [nzLoading]="codeCountDown != 0" type="button" nz-button nzType="primary" |
||||
(click)="code()">{{ codeCountDown == 0 ? '点击获取验证码' : codeCountDown + '秒后可重新获取'}}</button> |
||||
</div> |
||||
<form nz-form [formGroup]="validateForm2" (ngSubmit)="step2()"> |
||||
<nz-form-item> |
||||
<nz-form-label nzRequired nzFor="">请输入验证码</nz-form-label> |
||||
<nz-form-control> |
||||
<input autocomplete="off" nz-input formControlName="code" id="code" /> |
||||
</nz-form-control> |
||||
</nz-form-item> |
||||
<div class="btn"> |
||||
<button type="submit" nz-button nzType="primary">下一步</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
<div class="step3" *ngIf="currentStep == 3"> |
||||
<form nz-form [formGroup]="validateForm3" (ngSubmit)="step3()"> |
||||
<nz-form-item> |
||||
<!-- <nz-form-label nzRequired nzFor="">请输入新密码</nz-form-label> --> |
||||
<nz-form-control> |
||||
<input name="newpassword" nz-input type="password" formControlName="newpassword" |
||||
placeholder="请输入新密码" autocomplete="off" /> |
||||
</nz-form-control> |
||||
</nz-form-item> |
||||
<nz-form-item> |
||||
<!-- <nz-form-label nzRequired nzFor="">确认新密码</nz-form-label> --> |
||||
<nz-form-control> |
||||
<input name="affirmpassword" nz-input type="password" formControlName="affirmpassword" |
||||
placeholder="确认新密码" autocomplete="new-password" /> |
||||
</nz-form-control> |
||||
</nz-form-item> |
||||
<div class="btn"> |
||||
<button type="submit" nz-button nzType="primary">确定</button> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
@ -0,0 +1,26 @@
|
||||
.step1, |
||||
.step2 { |
||||
nz-form-item { |
||||
display: flex; |
||||
flex-direction: column; |
||||
|
||||
nz-form-label { |
||||
text-align: left; |
||||
} |
||||
} |
||||
|
||||
.btn { |
||||
width: 100%; |
||||
text-align: center; |
||||
margin-top: 50px; |
||||
} |
||||
} |
||||
|
||||
|
||||
.step3 { |
||||
.btn { |
||||
width: 100%; |
||||
text-align: center; |
||||
margin-top: 10px; |
||||
} |
||||
} |
@ -0,0 +1,144 @@
|
||||
import { Component, OnInit } from '@angular/core'; |
||||
import { FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms'; |
||||
import { NzMessageService } from 'ng-zorro-antd/message'; |
||||
import { NzSafeAny } from 'ng-zorro-antd/core/types'; |
||||
import { HttpClient } from '@angular/common/http'; |
||||
import { NzModalRef } from 'ng-zorro-antd/modal'; |
||||
@Component({ |
||||
selector: 'app-forget', |
||||
templateUrl: './forget.component.html', |
||||
styleUrls: ['./forget.component.scss'] |
||||
}) |
||||
export class ForgetComponent implements OnInit { |
||||
validateForm!: FormGroup; |
||||
validateForm2!: FormGroup; |
||||
validateForm3!: FormGroup; |
||||
constructor(private fb: FormBuilder, private message: NzMessageService, private http: HttpClient, private modal: NzModalRef) { } |
||||
|
||||
ngOnInit(): void { |
||||
this.validateForm = this.fb.group({ |
||||
account: [null, [Validators.required]] |
||||
}); |
||||
this.validateForm2 = this.fb.group({ |
||||
code: [null, [Validators.required]] |
||||
}); |
||||
const { password } = MyValidators; |
||||
this.validateForm3 = this.fb.group({ |
||||
newpassword: [null, [Validators.required, password]], |
||||
affirmpassword: [null, [Validators.required, password]] |
||||
}); |
||||
} |
||||
currentStep = 1 |
||||
phoneNum: string |
||||
step1() { |
||||
console.log(this.validateForm) |
||||
if (this.validateForm.invalid) { |
||||
this.message.create('warning', '请填写完整'); |
||||
} else { |
||||
this.http.get('/api/services/app/User/GetPhoneNumber', { |
||||
params: { |
||||
userName: this.validateForm.value.account |
||||
} |
||||
}).subscribe({ |
||||
next: (data: any) => { |
||||
this.phoneNum = data.result |
||||
this.currentStep = 2 |
||||
} |
||||
}) |
||||
|
||||
} |
||||
} |
||||
|
||||
//发送验证码
|
||||
codeCountDown = 0 |
||||
code() { |
||||
let params = { |
||||
userName: this.validateForm.value.account, |
||||
} |
||||
this.http.post('/api/services/app/User/SendVerificationCode', null, { params: params }).subscribe({ |
||||
next: (data: any) => { |
||||
this.message.create('success', '已发送'); |
||||
//按钮倒计时
|
||||
this.codeCountDown = 30 |
||||
let codesetInterval = setInterval(() => { |
||||
this.codeCountDown = this.codeCountDown - 1 |
||||
if (this.codeCountDown == 0) { |
||||
clearInterval(codesetInterval) |
||||
} |
||||
}, 1000); |
||||
} |
||||
}) |
||||
} |
||||
|
||||
step2() { |
||||
if (this.validateForm2.invalid) { |
||||
this.message.create('warning', '请填写完整'); |
||||
} else { |
||||
console.log(this.validateForm.value.account) |
||||
let params = { |
||||
userName: this.validateForm.value.account, |
||||
code: this.validateForm2.value.code |
||||
} |
||||
this.http.get('/api/services/app/User/VerifyVerificationCode', { params: params }).subscribe({ |
||||
next: (data: any) => { |
||||
this.currentStep = 3 |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
step3() { |
||||
if (this.validateForm3.valid) { |
||||
let word = JSON.parse(JSON.stringify(this.validateForm3.value.newpassword)).toLowerCase() |
||||
if (this.validateForm3.value.newpassword != this.validateForm3.value.affirmpassword) { |
||||
this.message.create('warning', '两次密码输入不一致!'); |
||||
return false |
||||
} if (word.indexOf('sino') != -1 || word.indexOf('zhonghua') != -1) { |
||||
this.message.create('warning', '口令禁止包含 sinochem、sino、zhonghua (含大小写变体) 等中国中化相关字符'); |
||||
return false |
||||
} else { |
||||
|
||||
let body = { |
||||
userName: this.validateForm.value.account, |
||||
code: this.validateForm2.value.code, |
||||
newPassword: this.validateForm3.value.newpassword, |
||||
} |
||||
this.http.post('/api/services/app/User/ChangePasswordBySms', body).subscribe(data => { |
||||
this.message.create('success', '修改成功!'); |
||||
this.modal.close() |
||||
return true |
||||
}, err => { |
||||
return false |
||||
}) |
||||
|
||||
} |
||||
|
||||
} else { |
||||
this.message.create('warning', '请填写完整!'); |
||||
return false |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
export type MyErrorsOptions = { 'zh-cn': string; en: string } & Record<string, NzSafeAny>; |
||||
export type MyValidationErrors = Record<string, MyErrorsOptions>; |
||||
export class MyValidators extends Validators { |
||||
static password(control: AbstractControl): MyValidationErrors | null { |
||||
const value = control.value; |
||||
|
||||
if (isEmptyInputValue(value)) { |
||||
return null; |
||||
} |
||||
|
||||
return isPassword(value) ? null : { mobile: { 'zh-cn': `长度至少 8 位,必须包含大写字母、小写字母、数字、符号四种中的三种,且口令禁止包含 sinochem、sino、zhonghua (含大小写变体) 等中国中化相关字符`, en: `Password phone number is not valid` } }; |
||||
} |
||||
|
||||
} |
||||
function isEmptyInputValue(value: NzSafeAny): boolean { |
||||
return value == null || value.length === 0; |
||||
} |
||||
function isPassword(value: string): boolean { |
||||
return typeof value === 'string' && /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)(?!.*[sS][iI][nN][oO].*)(?!.*[zZ][hH][oO][nN][gG][hH][uU][aA].*)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]{8,99}$/.test(value); |
||||
} |
Loading…
Reference in new issue