import { Component, AfterViewInit } from '@angular/core'; import { Router } from '@angular/router'; import { ModalController, NavController, ToastController } from '@ionic/angular'; import { Observable } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { throwError } from 'rxjs'; import { Subscription } from 'rxjs'; import { UserService } from '../services/user.service'; import {ElementRef, OnInit, Renderer2 } from '@angular/core'; interface User { username: string; password: string; } @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'] }) export class Tab1Page implements AfterViewInit { doctors = [ { avatar: '../../assets/images/doctor1.jpg', name: '张医生', specialty: '心血管科' }, { avatar: '../../assets/images/doctor2.jpg', name: '李医生', specialty: '神经科' }, { avatar: '../../assets/images/doctor3.jpg', name: '王医生', specialty: '儿科' }, { avatar: '../../assets/images/doctor4.jpg', name: '赵医生', specialty: '外科' }, { avatar: '../../assets/images/doctor5.jpg', name: '陈医生', specialty: '内科' } ]; images = [ '../../assets/images/brackground.jpg', '../../assets/images/brackground2.jpg', '../../assets/images/brackground3.jpeg' ]; // 功能按钮数据 functionItems1 = [ { label: '我的病历', icon: 'document-text', route: '/case' }, { label: '在线问诊', icon: 'chatbubbles', route: '/consultation' }, { label: '健康档案', icon: 'person', route: '/health-record' }, { label: '预约挂号', icon: 'calendar', route: '/appointment' }, ]; functionItems2 = [ { label: '健康资讯', icon: 'newspaper', route: '/health-news' }, { label: '药品购买', icon: 'medkit', route: '/medicine-purchase' }, { label: '专家讲座', icon: 'podium', route: '/expert-lectures' }, { label: '健康社区', icon: 'people', route: '/health-community' } ]; userAvatar: string = '../../assets/images/user.png'; // 默认头像 private userInfoSubscription!: Subscription; currentIndex = 0; startX: number = 0; endX: number = 0; isDragging: boolean = false; currentTranslate: number = 0; cardWidth = 216; // 每个卡片的宽度加上间距 (200 + 16) isCyclic: boolean = true; errorMessage: string = ''; // 错误消息 isLoginModalOpen = false; user: User = { username: '', password: '' }; fileToUpload: File | null = null; constructor( private router: Router, private modalController: ModalController, private navCtrl: NavController, private http: HttpClient, private toastController: ToastController,// 添加 ToastController 注入 private userService: UserService , private el: ElementRef, private renderer: Renderer2 ) {} ngOnInit() { this.subscribeToUserInfo(); this.startImageRotation(); // 初始化时设置第一张图片 this.updateBackgroundImage(); } ionViewWillEnter() { this.subscribeToUserInfo(); } ngOnDestroy() { if (this.userInfoSubscription) { this.userInfoSubscription.unsubscribe(); } } // 实现 AfterViewInit 接口的 ngAfterViewInit 方法 ngAfterViewInit(): void { this.ngAfterViewInitLogic(); } private subscribeToUserInfo() { // 取消之前的订阅(如果有) if (this.userInfoSubscription) { this.userInfoSubscription.unsubscribe(); } // 订阅最新的用户信息 this.userInfoSubscription = this.userService.getUserInfo().subscribe(userInfo => { if (userInfo) { this.userAvatar = userInfo.userAvatar || this.userAvatar; console.log('Updated user info in Tab1:', userInfo); // 添加日志输出 } }); } startImageRotation(): void { setInterval(() => { this.currentIndex = (this.currentIndex + 1) % this.images.length; this.updateBackgroundImage(); }, 5000); // Change image every 5 seconds } updateBackgroundImage(): void { const imageUrl = `url('${this.images[this.currentIndex]}')`; this.renderer.setStyle(this.el.nativeElement.querySelector('.health-banner'), 'background-image', imageUrl); } // 将初始化逻辑移到单独的方法中,以保持代码清晰 private ngAfterViewInitLogic() { this.updateCarousel(); this.calculateCardWidth(); } calculateCardWidth() { const container = document.getElementById('carousel'); if (container && container.children.length > 0) { const firstCard = container.children[0] as HTMLElement; this.cardWidth = firstCard.offsetWidth + 16; // 加上间距 } } updateCarousel() { this.currentTranslate = -this.currentIndex * this.cardWidth; this.updateCarouselPosition(); } updateCarouselPosition() { const container = document.getElementById('carousel'); if (container) { container.style.transform = `translateX(${this.currentTranslate}px)`; } } onTouchStart(event: TouchEvent) { this.startX = event.touches[0].clientX; this.isDragging = true; } onTouchMove(event: TouchEvent) { if (this.isDragging) { const touchX = event.touches[0].clientX; const deltaX = touchX - this.startX; this.currentTranslate = -this.currentIndex * this.cardWidth + deltaX; const maxTranslate = -(this.doctors.length - 1) * this.cardWidth; this.currentTranslate = Math.max(Math.min(this.currentTranslate, 0), maxTranslate); this.updateCarouselPosition(); } } onTouchEnd(event: TouchEvent) { this.endX = event.changedTouches[0].clientX; this.isDragging = false; const swipeThreshold = 50; const deltaX = this.startX - this.endX; if (deltaX > swipeThreshold) { this.nextSlide(); } else if (deltaX < -swipeThreshold) { this.prevSlide(); } else { this.snapToNearestCard(); } } prevSlide() { if (this.isCyclic) { this.currentIndex = (this.currentIndex - 1 + this.doctors.length) % this.doctors.length; } else if (this.currentIndex > 0) { this.currentIndex--; } this.updateCarousel(); } nextSlide() { if (this.isCyclic) { this.currentIndex = (this.currentIndex + 1) % this.doctors.length; } else if (this.currentIndex < this.doctors.length - 1) { this.currentIndex++; } this.updateCarousel(); } snapToNearestCard() { const cardIndex = Math.round(-this.currentTranslate / this.cardWidth); this.currentIndex = Math.max(0, Math.min(cardIndex, this.doctors.length - 1)); this.updateCarousel(); } onConsultNow() { console.log(`立即咨询`); this.router.navigate(['/consultation']); } onlineConsultNow(doctor: any) { console.log(`在线咨询: ${doctor.name}`); this.router.navigate(['/consultation'], { state: { doctor: doctor } }); } navigateTo(route: string) { this.router.navigate([route]); } // // 发布求医信息 // handleClick() { // const fileInput = document.getElementById('fileInput'); // if (fileInput) { // fileInput.click(); // } else { // console.error('File input element not found'); // } // } // publishHealthInfo(files: FileList) { // if (files && files.length > 0) { // const file = files[0]; // const allowedTypes = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // 'image/jpeg', 'image/png', 'image/gif']; // if (allowedTypes.includes(file.type)) { // console.log('Selected file:', file.name); // // 在这里可以添加上传文件的逻辑 // this.fileToUpload = file; // // 在这里添加上传文件的逻辑 // this.uploadFile().then(() => this.navCtrl.navigateForward('/tabs/tab2')); // } else { // this.presentToast('仅支持 .doc, .docx, .jpg, .jpeg, .png, .gif 文件类型'); // } // } else { // console.log('No file selected'); // } // } // private async uploadFile(): Promise { // if (this.fileToUpload) { // // 这里是模拟文件上传的过程,您可以替换为实际的上传逻辑。 // // 比如调用API进行文件上传,并处理响应。 // // 简单示例: // // await this.http.post('your-upload-endpoint', this.fileToUpload).toPromise(); // return new Promise((resolve) => setTimeout(resolve, 1000)); // 模拟异步操作 // } // } openLoginModal() { this.isLoginModalOpen = true; console.log('打开登录/注册模态框'); } closeLoginModal() { this.isLoginModalOpen = false; console.log('关闭登录/注册模态框'); } onLoginModalDismissed(event: any) { this.isLoginModalOpen = false; console.log('登录/注册模态框已关闭'); } async onLoginFormSubmit(formValue: any) { console.log('登录表单提交:', formValue); // 验证用户名和密码长度 if (formValue.username.length < 3) { await this.presentToast('用户名至少需要3位字符', 'danger'); return; } if (formValue.password.length < 6) { await this.presentToast('密码至少需要6位字符', 'danger'); return; } this.loginUser(formValue.username, formValue.password) .subscribe( async (response) => { console.log('登录成功:', response); await this.presentToast('登录成功', 'success'); this.closeLoginModal(); }, async (error) => { console.error('登录失败:', error); await this.presentToast('登录失败,请检查用户名和密码', 'danger'); } ); } registerUser() { if (!this.user.username || !this.user.password) { console.error('用户名或密码为空'); this.presentToast('用户名和密码不能为空,请输入完整信息', 'danger'); return; } // 验证用户名和密码长度 if (this.user.username.length < 3) { this.presentToast('用户名至少需要3位字符', 'danger'); return; } if (this.user.password.length < 6) { this.presentToast('密码至少需要6位字符', 'danger'); return; } console.log('注册用户:', JSON.stringify(this.user, null, 2)); this.registerNewUser(this.user) .subscribe( async (response) => { console.log('注册成功:', response); await this.presentToast('注册成功', 'success'); this.closeLoginModal(); }, async (error) => { console.error('注册失败:', error); if (error.error && error.error.message.includes('cannot be null')) { await this.presentToast('密码不能为空,请输入密码', 'danger'); } else { await this.presentToast('注册失败,请稍后再试', 'danger'); } } ); } private loginUser(username: string, password: string): Observable { const loginUrl = 'http://localhost:8080/api/login'; // 替换为你的登录 API 端点 return this.http.post(loginUrl, { username, password }, { withCredentials: true, headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }).pipe( map(response => response), catchError(error => { console.error('登录请求出错:', error); return throwError(() => new Error('登录失败')); }) ); } private registerNewUser(user: User): Observable { const registerUrl = 'http://localhost:8080/api/register'; // 替换为你的注册 API 端点 return this.http.post(registerUrl, user) .pipe( map(response => response), catchError(error => { throw error; }) ); } onLearnMore() { this.navCtrl.navigateForward('/details'); } async presentToast(message: string, color: string = 'primary') { const toast = await this.toastController.create({ message: message, duration: 2000, color: color, position: 'top', }); toast.present(); } doRefresh(event: any) { console.log('Begin async operation'); setTimeout(() => { console.log('Async operations have ended'); event.target.complete(); }, 1000); } }