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.
cls/ui/src/app/mine/login/login.page.ts

233 lines
6.1 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';
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";
1 month ago
@Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
standalone: false,
})
export class LoginPage implements OnInit, OnDestroy,AfterViewInit {
loginForm: FormGroup;
1 month ago
loginType: 'sms' | 'password' = 'sms';
canSendSms = true;
smsButtonText = '发送验证码';
slideConfigValid:SlidePoint = {x:0,y:9}
private countdown = 60;
private timer: any;
private verifyToken: string | null = null;
private returnUrl: string | null = null;
1 month ago
constructor(
private fb: FormBuilder,
private mineService: MineService,
private router: Router,
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: ['']
});
// 获取返回路径
const navigation = this.router.getCurrentNavigation();
if (navigation?.extras?.state?.['returnUrl']) {
this.returnUrl = navigation.extras.state['returnUrl'];
}
1 month ago
}
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('登录成功');
localStorage.setItem("token",response);
// 如果有返回路径,则导航到该路径
if (this.returnUrl) {
this.router.navigateByUrl(this.returnUrl);
} else {
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());
}
}