You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
5.7 KiB
TypeScript
224 lines
5.7 KiB
TypeScript
1 month ago
|
import {
|
||
|
Component,
|
||
|
OnInit,
|
||
|
OnDestroy,
|
||
|
ViewChild,
|
||
|
HostListener,
|
||
|
ChangeDetectorRef,
|
||
|
AfterViewInit,
|
||
|
Input
|
||
|
} from '@angular/core';
|
||
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||
|
import { Router } from '@angular/router';
|
||
![]()
4 weeks ago
|
import {ModalController, NavController, ToastController} from '@ionic/angular';
|
||
1 month ago
|
import { MineService } from '../mine.service';
|
||
|
import {
|
||
|
SlidePoint,
|
||
|
SlideRef
|
||
|
} from "go-captcha-angular";
|
||
|
import {CaptchaModalComponent} from "../component/captcha-modal/captcha-modal.component";
|
||
|
@Component({
|
||
|
selector: 'app-login',
|
||
|
templateUrl: './login.page.html',
|
||
|
styleUrls: ['./login.page.scss'],
|
||
|
standalone: false,
|
||
|
})
|
||
|
export class LoginPage implements OnInit, OnDestroy,AfterViewInit {
|
||
|
loginForm: FormGroup ;
|
||
|
loginType: 'sms' | 'password' = 'sms';
|
||
|
canSendSms = true;
|
||
|
smsButtonText = '发送验证码';
|
||
|
slideConfigValid:SlidePoint = {x:0,y:9}
|
||
|
private countdown = 60;
|
||
|
private timer: any;
|
||
|
private verifyToken: string | null = null;
|
||
|
|
||
|
constructor(
|
||
|
private fb: FormBuilder,
|
||
|
private mineService: MineService,
|
||
|
private router: Router,
|
||
![]()
4 weeks ago
|
private navCtrl: NavController,
|
||
1 month ago
|
private cdr:ChangeDetectorRef,
|
||
|
private toastCtrl: ToastController,
|
||
|
private modalCtrl: ModalController,
|
||
|
) {
|
||
|
this.loginForm = this.fb.group({
|
||
|
phone: ['', [Validators.required, Validators.pattern(/^1\d{10}$/)]],
|
||
|
password: [''],
|
||
|
smsCode: ['']
|
||
|
});
|
||
|
}
|
||
|
|
||
|
ngOnInit() {
|
||
|
this.createForm();
|
||
|
}
|
||
|
ngAfterViewInit() {
|
||
|
}
|
||
|
|
||
|
ngOnDestroy() {
|
||
|
this.stopCountdown() ;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
private createForm() {
|
||
|
// 根据登录类型动态设置验证器
|
||
|
this.loginForm.get('password')?.setValidators(
|
||
|
this.loginType === 'password' ? [Validators.required, Validators.minLength(6)] : []
|
||
|
);
|
||
|
this.loginForm.get('smsCode')?.setValidators(
|
||
|
this.loginType === 'sms' ? [Validators.required, Validators.pattern(/^\d{6}$/)] : []
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 显示滑动验证码
|
||
|
showSlideVerify(type: 'sms' | 'password') {
|
||
|
|
||
|
const phone = this.loginForm.get('phone')?.value;
|
||
|
|
||
|
if (!phone || !this.loginForm.get('phone')?.valid) {
|
||
|
this.showToast('请输入正确的手机号');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// 调用滑动验证服务
|
||
|
this.mineService.getSlideCaptcha(phone).subscribe( (res) => {
|
||
|
this.slideConfigValid.x = res.thumbX;
|
||
|
this.slideConfigValid.y = res.thumbY;
|
||
|
res.thumbX = 0
|
||
|
const modal = this.modalCtrl.create({
|
||
|
component: CaptchaModalComponent,
|
||
|
componentProps: {
|
||
|
captchaData: res,
|
||
|
x: this.slideConfigValid.x
|
||
|
},
|
||
|
})
|
||
|
modal.catch((res)=>{
|
||
|
})
|
||
|
modal.then((res)=>{
|
||
|
res.present()
|
||
|
res.onDidDismiss().then((res)=>{
|
||
|
if(res.data < this.slideConfigValid.x+5 && res.data >this.slideConfigValid.x-5 ) {
|
||
|
this.sendSmsCode()
|
||
|
}
|
||
|
})
|
||
|
})
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 发送短信验证码
|
||
|
sendSmsCode() {
|
||
|
if (!this.canSendSms) return;
|
||
|
|
||
|
const phone = this.loginForm.get('phone')?.value;
|
||
|
|
||
|
if (!phone || !this.loginForm.get('phone')?.valid) {
|
||
|
this.showToast('请输入正确的手机号');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// 直接发送短信验证码
|
||
|
this.mineService.sendSmsCaptcha(phone, '').subscribe({
|
||
|
next: (response) => {
|
||
|
this.startCountdown();
|
||
|
this.showToast('验证码已发送');
|
||
|
},
|
||
|
error: (error) => {
|
||
|
let errorMessage = '发送失败,请重试';
|
||
|
|
||
|
if (error && error.error) {
|
||
|
if (typeof error.error === 'string') {
|
||
|
errorMessage = error.error;
|
||
|
} else if (typeof error.error === 'object' && error.error.error) {
|
||
|
errorMessage = error.error.error;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.showToast(errorMessage);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 提交登录
|
||
|
onSubmit() {
|
||
|
if (this.loginForm.invalid) {
|
||
|
this.showToast('请填写完整的登录信息');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const formValue = this.loginForm.value;
|
||
|
const loginRequest = this.loginType === 'password'
|
||
|
? this.mineService.passwordLogin(formValue.phone, formValue.password, '')
|
||
|
: this.mineService.smsLogin(formValue.phone, formValue.smsCode);
|
||
|
|
||
|
loginRequest.subscribe({
|
||
|
next: (response) => {
|
||
|
this.showToast('登录成功');
|
||
![]()
3 weeks ago
|
localStorage.setItem("token",response)
|
||
![]()
4 weeks ago
|
this.navCtrl.back()
|
||
1 month ago
|
},
|
||
|
error: (error) => {
|
||
|
let errorMessage = '登录失败,请重试';
|
||
|
if (error && error.error) {
|
||
|
if (typeof error.error === 'string') {
|
||
|
errorMessage = error.error;
|
||
|
} else if (typeof error.error === 'object' && error.error.error) {
|
||
|
errorMessage = error.error.error;
|
||
|
}
|
||
|
}
|
||
|
this.showToast(errorMessage);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 开始倒计时
|
||
|
private startCountdown() {
|
||
|
this.canSendSms = false;
|
||
|
this.countdown = 60;
|
||
|
this.updateSmsButtonText();
|
||
|
|
||
|
this.timer = setInterval(() => {
|
||
|
this.countdown--;
|
||
|
this.updateSmsButtonText();
|
||
|
if (this.countdown <= 0) {
|
||
|
this.stopCountdown();
|
||
|
}
|
||
|
}, 1000);
|
||
|
}
|
||
|
|
||
|
// 停止倒计时
|
||
|
private stopCountdown() {
|
||
|
if (this.timer) {
|
||
|
clearInterval(this.timer);
|
||
|
this.timer = null;
|
||
|
}
|
||
|
this.canSendSms = true;
|
||
|
this.smsButtonText = '发送验证码';
|
||
|
}
|
||
|
|
||
|
// 更新按钮文本
|
||
|
private updateSmsButtonText() {
|
||
|
this.smsButtonText = this.canSendSms ? '发送验证码' : `${this.countdown}秒后重试`;
|
||
|
}
|
||
|
|
||
|
// 显示提示信息
|
||
|
private showToast(message: string) {
|
||
|
this.toastCtrl.create({
|
||
|
message,
|
||
|
duration: 2000,
|
||
|
position: 'top',
|
||
|
color: 'primary',
|
||
|
buttons: [
|
||
|
{
|
||
|
icon: 'close',
|
||
|
role: 'cancel'
|
||
|
}
|
||
|
],
|
||
|
cssClass: 'custom-toast',
|
||
|
animated: true,
|
||
|
mode: 'ios'
|
||
|
}).then(toast => toast.present());
|
||
|
}
|
||
|
}
|