import { router } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; import settingsService, { ThemeColor, Language, SettingsModel, TextResources, UserInfoModel } from '../common/SettingsService'; import { VersionLogItem } from '../common/logtext'; import { promptAction } from '@kit.ArkUI'; @Entry @Component struct SettingsPage { // 使用SettingsService中的用户信息 @State userInfo: UserInfoModel = settingsService.getUserInfo(); // 从设置服务获取设置 @State settings: SettingsModel = settingsService.getSettings(); // 获取文本资源 @State texts: TextResources = settingsService.getTextResources(); @State themeColor: ThemeColor = settingsService.getSettings().themeColor; // 更新用户邮箱的方法 private updateUserEmail(newEmail: string): void { if (newEmail && newEmail.trim() !== '') { // 使用SettingsService更新用户邮箱 settingsService.updateUserEmail(newEmail.trim()); // 显示更新成功的提示 const currentLanguage = settingsService.getSettings().language; promptAction.showToast({ message: currentLanguage === Language.CHINESE ? '邮箱已更新' : 'Email updated', duration: 2000 }); } } aboutToAppear() { // 注册语言变化的回调 - 确保更新所有相关状态 settingsService.registerLanguageChangeCallback(() => { this.texts = settingsService.getTextResources(); this.settings = settingsService.getSettings(); }); //页面颜色变化 settingsService.registerColorChangeCallback(() => { this.themeColor = settingsService.getSettings().themeColor; this.settings = settingsService.getSettings(); // 同时更新整个设置对象 }); // 注册用户信息变化的回调 settingsService.registerUserInfoChangeCallback(() => { this.userInfo = settingsService.getUserInfo(); }); // 页面加载时初始化设置 this.Log_Event('aboutToAppear'); } build() { Column() { // 顶部导航栏 - 美化版 Row() { Text(this.texts.settingsTitle) .fontSize(24) .fontColor(Color.White) .fontWeight(FontWeight.Bold) } .width('100%') .backgroundColor(this.themeColor) .height(70) .padding({ left: 24, right: 24 }) .justifyContent(FlexAlign.Center) // 添加阴影效果 .shadow({ radius: 8, color: 'rgba(0, 0, 0, 0.1)', offsetY: 2 }) // 为顶部导航栏添加动画效果 .animation({ duration: 300, curve: Curve.EaseOut }) // 页面内容区 Scroll() { Column() { // 用户信息卡片 UserCard({ user: this.userInfo, themeColor: this.themeColor, updateEmail: (newEmail: string) => this.updateUserEmail(newEmail) }) .margin({ top: 24, bottom: 24 }) .width('100%') // 为卡片添加转场动画 .transition({ type: TransitionType.Insert, translate: { x: 0, y: 50, z: 0 }, opacity: 0 }) .animation({ duration: 300, delay: 100, curve: Curve.EaseOut }) .transition({ type: TransitionType.Delete, translate: { x: 0, y: 50, z: 0 }, opacity: 0 }) // 系统设置选项 SystemSettings({ themeColor: this.settings.themeColor, language: this.settings.language, notificationEnabled: this.settings.notificationEnabled, texts: this.texts }) .width('100%') // 为设置卡片添加转场动画 .transition({ type: TransitionType.Insert, translate: { x: 0, y: 50, z: 0 }, opacity: 0 }) .animation({ duration: 300, delay: 100, curve: Curve.EaseOut }) .transition({ type: TransitionType.Delete, translate: { x: 0, y: 50, z: 0 }, opacity: 0 }) } .width('100%') .padding({ left: 20, right: 20 }) .alignItems(HorizontalAlign.Center) } .layoutWeight(1) .scrollBar(BarState.Off) .edgeEffect(EdgeEffect.Spring) // 添加弹性滚动效果 // 底部导航栏 BottomNavigation({ activePage: 'settings', themeColor: this.settings.themeColor, texts: this.texts }) // 为底部导航添加阴影和动画 .shadow({ radius: 16, color: 'rgba(0, 0, 0, 0.08)', offsetY: -2 }) .animation({ duration: 300, curve: Curve.EaseOut }) } .width('100%') .height('100%') .backgroundColor('#f5f7fa') // 设置页面背景色,提升层次感 } // 页面生命周期方法 onPageShow(): void { this.Log_Event('onPageShow'); } onPageHide(): void { this.Log_Event('onPageHide'); } onBackPress(): void { this.Log_Event('onBackPress'); } aboutToDisappear(): void { this.Log_Event('aboutToDisappear'); } // 日志记录方法 public Log_Event(eventName: string): void { hilog.info(0, 'ClassMG', `SettingsPage: ${eventName}`); } } // 用户信息卡片组件 - 美化版 @Component struct UserCard { @ObjectLink user: UserInfoModel; // 使用@ObjectLink而不是直接值传递,确保对象引用更新 @Prop themeColor: string = '#409eff'; // 头像的动画状态 @State avatarScale: number = 1; // 添加编辑邮箱的状态 @State isEditingEmail: boolean = false; // 临时存储编辑中的邮箱 @State tempEmail: string = ''; // 编辑按钮的动画状态 @State editScale: number = 1; // 添加邮箱验证错误状态 @State emailError: boolean = false; @State errorMessage: string = ''; // 邮箱更新回调 updateEmail: (newEmail: string) => void = () => {}; // 验证邮箱格式 private validateEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } // 保存邮箱 private saveEmail(): void { // 验证邮箱格式 if (!this.validateEmail(this.tempEmail)) { this.emailError = true; this.errorMessage = '请输入有效的邮箱地址'; return; } // 更新邮箱 this.updateEmail(this.tempEmail); // 退出编辑模式 this.isEditingEmail = false; this.emailError = false; this.errorMessage = ''; } build() { Column() { // 用户信息标题 Row() { Text("用户信息") .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#333') } .width('100%') .padding({ top: 8, bottom: 16 }) // 头像和用户信息 Row() { // 头像 - 圆形设计 Stack() { // 圆形背景 Circle() .width(88) .height(88) .fill('#f5f5f5') // 用户头像 Image(this.user.avatar || 'http://139.155.155.67:2342/images/default_avatar.png') .width(80) .height(80) .borderRadius(40) .objectFit(ImageFit.Cover) .scale({ x: this.avatarScale, y: this.avatarScale }) .onHover((isHover: boolean) => { animateTo({ duration: 300, curve: Curve.EaseOut }, () => { this.avatarScale = isHover ? 1.05 : 1; }) }) } .margin({ right: 24 }) // 用户基本信息 Column() { // 用户名和用户类型 Row() { Text(this.user.name || '未设置昵称') .fontSize(20) .fontWeight(FontWeight.Bold) .fontColor('#333') // 用户类型标签 if (this.user.category) { Text(this.user.category === 'student' ? '学生' : '教师') .fontSize(12) .backgroundColor(this.user.category === 'student' ? '#e6f7ff' : '#f6ffed') .fontColor(this.user.category === 'student' ? '#1890ff' : '#52c41a') .borderRadius(4) .padding({ left: 8, right: 8, top: 2, bottom: 2 }) .margin({ left: 8 }) } } .width('100%') .margin({ bottom: 10 }) // 账号信息 Row() { Text("账号: ") .fontSize(14) .fontColor('#666') Text(this.user.account || '暂未配置') .fontSize(14) .fontColor('#666') } .margin({ bottom: 6 }) // 手机号 Row() { Text("手机: ") .fontSize(14) .fontColor('#666') Text(this.user.phone || '暂未配置') .fontSize(14) .fontColor('#666') } .margin({ bottom: 6 }) } .alignItems(HorizontalAlign.Start) .layoutWeight(1) } .width('100%') .alignItems(VerticalAlign.Center) .padding({ bottom: 20 }) // 邮箱信息 - 可编辑 Column() { // 邮箱编辑区域 Row() { Text("邮箱: ") .fontSize(14) .fontColor('#666') .width(50) if (this.isEditingEmail) { // 编辑模式 - 显示输入框 TextInput({ placeholder: '请输入邮箱', text: this.tempEmail || this.user.email || '' }) .width('60%') .height(36) .fontSize(14) .fontColor('#333') .backgroundColor('#f5f5f5') .borderRadius(4) .onChange((value: string) => { this.tempEmail = value; this.emailError = false; }) // 保存按钮 Button("保存") .fontSize(14) .fontColor(Color.White) .backgroundColor(this.themeColor) .borderRadius(4) .margin({ left: 10 }) .width(60) .height(36) .onClick(() => { this.saveEmail(); }) // 取消按钮 Button("取消") .fontSize(14) .fontColor('#666') .backgroundColor('#f0f0f0') .borderRadius(4) .margin({ left: 10 }) .width(60) .height(36) .onClick(() => { this.isEditingEmail = false; this.emailError = false; this.errorMessage = ''; }) } else { // 显示模式 - 显示当前邮箱 Text(this.user.email || '暂未配置') .fontSize(14) .fontColor('#666') .layoutWeight(1) // 编辑按钮 Button({ type: ButtonType.Circle }) { Image($r('app.media.edit')) .width(16) .height(16) .fillColor('#666') } .width(32) .height(32) .backgroundColor('#f5f5f5') .scale({ x: this.editScale, y: this.editScale }) .onClick(() => { this.isEditingEmail = true; this.tempEmail = this.user.email || ''; }) .onHover((isHover: boolean) => { animateTo({ duration: 300, curve: Curve.EaseOut }, () => { this.editScale = isHover ? 1.1 : 1; }) }) } } .width('100%') .alignItems(VerticalAlign.Center) // 邮箱错误提示 if (this.emailError) { Text(this.errorMessage) .fontSize(12) .fontColor('#ff4d4f') .margin({ top: 4, left: 50 }) } } .width('100%') .margin({ bottom: 10 }) } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(20) .shadow({ radius: 6, color: '#eeeeee', offsetY: 2 }) } } // 系统设置组件 - 美化版 @Component struct SystemSettings { @Prop themeColor: string; @Prop language: string; @Prop notificationEnabled: boolean; @Prop texts: TextResources = {} as TextResources; // 强制UI刷新的控制变量 @State refreshTrigger: number = 0; // 显示加载动画的状态 @State isLoading: boolean = false; // 添加本地状态,在组件内部获取最新设置 @State currentTexts: TextResources = settingsService.getTextResources(); // 添加本地状态跟踪当前设置 @State currentLanguage: string = settingsService.getSettings().language; @State currentThemeColor: string = settingsService.getSettings().themeColor; @State currentNotificationEnabled: boolean = settingsService.getSettings().notificationEnabled; aboutToAppear() { // 注册语言变化的回调,确保组件内文本也会更新 settingsService.registerLanguageChangeCallback(() => { this.currentTexts = settingsService.getTextResources(); this.currentLanguage = settingsService.getSettings().language; this.forceRefresh(); }); // 注册颜色变化的回调 settingsService.registerColorChangeCallback(() => { this.currentThemeColor = settingsService.getSettings().themeColor; this.forceRefresh(); }); // 注册通知设置变化的回调 settingsService.registerNotificationChangeCallback(() => { this.currentNotificationEnabled = settingsService.getSettings().notificationEnabled; this.forceRefresh(); }); } // 强制刷新UI private forceRefresh() { this.refreshTrigger++; } // 获取主题颜色显示名称 private getThemeColorDisplayName(): string { const settings = settingsService.getSettings(); const texts = settingsService.getTextResources(); switch (settings.themeColor) { case ThemeColor.BLUE: return texts.blue; case ThemeColor.GREEN: return texts.green; case ThemeColor.RED: return texts.red; case ThemeColor.ORANGE: return texts.orange; case ThemeColor.PURPLE: return texts.purple; default: return texts.blue; } } // 获取通知状态显示名称 private getNotificationStatusDisplayName(): string { const settings = settingsService.getSettings(); const texts = settingsService.getTextResources(); return settings.notificationEnabled ? texts.enabled : texts.disabled; } // 显示过渡动画并在完成后更新UI private showTransitionAndUpdate(updateFunc: () => void) { // 显示全屏过渡动画 this.isLoading = true; // 立即执行更新函数 updateFunc(); // 1秒后隐藏过渡动画,此时所有页面更新已完成 setTimeout(() => { this.isLoading = false; this.forceRefresh(); }, 1000); } build() { Stack({ alignContent: Alignment.Center }) { // 主要内容区(仅在非加载状态显示) if (!this.isLoading) { Column() { // 标题区域 Row() { Text(this.currentTexts.systemSettings) .fontSize(20) .fontWeight(FontWeight.Bold) .fontColor('#333') Blank() // 小标志 Circle({ width: 8, height: 8 }) .fill(this.currentThemeColor) .margin({ right: 6 }) .opacity(0.8) } .width('100%') .padding({ top: 20, bottom: 20, left: 24, right: 24 }) // 分隔线 Divider() .height(1) .opacity(0.08) .color('#000') .width('100%') // 设置项列表 Column({ space: 'none' }) { SettingItem({ title: this.currentTexts.themeColor, value: this.getThemeColorDisplayName(), refreshTrigger: this.refreshTrigger, themeColor: this.currentThemeColor, icon: $r('app.media.theme'), onItemClick: () => this.showThemeColorDialog() }) SettingItem({ title: this.currentTexts.languageText, value: settingsService.getSettings().language, refreshTrigger: this.refreshTrigger, themeColor: this.currentThemeColor, icon: $r('app.media.language'), onItemClick: () => this.showLanguageDialog() }) SettingItem({ title: this.currentTexts.notificationSettings, value: this.getNotificationStatusDisplayName(), refreshTrigger: this.refreshTrigger, themeColor: this.currentThemeColor, icon: $r('app.media.notification'), onItemClick: () => this.toggleNotification() }) // 添加日志记录设置项 SettingItem({ title: "日志记录", value: "查看更新记录", refreshTrigger: this.refreshTrigger, themeColor: this.currentThemeColor, icon: $r('app.media.info'), onItemClick: () => this.showVersionLogDialog() }) SettingItem({ title: this.currentTexts.about, value: this.currentTexts.versionInfo, refreshTrigger: this.refreshTrigger, themeColor: this.currentThemeColor, icon: $r('app.media.info'), onItemClick: () => this.showAboutInfo() }) } .width('100%') } .width('100%') .backgroundColor(Color.White) .borderRadius(16) .shadow({ radius: 15, color: 'rgba(0, 0, 0, 0.08)', offsetY: 2 }) } // 加载动画层 - 美化版 if (this.isLoading) { Column() { LoadingProgress() .color(this.currentThemeColor) .width(100).height(100) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .backgroundColor(Color.White) // 添加淡入淡出效果 .opacity(1) .animation({ delay: 0, duration: 300, curve: Curve.EaseInOut }) } } .width('100%') .height('100%') } // 显示主题颜色选择对话框 private showThemeColorDialog(): void { // 确保获取最新的文本资源 const texts = settingsService.getTextResources(); const currentLanguage = settingsService.getSettings().language; AlertDialog.show({ title: texts.themeColor, message: currentLanguage === Language.CHINESE ? '请选择您喜欢的应用主题颜色' : 'Choose your preferred theme color', buttons: [ { value: texts.blue, action: () => { // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setThemeColor(ThemeColor.BLUE); }); } }, { value: texts.green, action: () => { // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setThemeColor(ThemeColor.GREEN); }); } }, { value: texts.red, action: () => { // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setThemeColor(ThemeColor.RED); }); } }, { value: texts.orange, action: () => { // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setThemeColor(ThemeColor.ORANGE); }); } }, { value: currentLanguage === Language.CHINESE ? '取消' : 'Cancel', action: () => {} } ] }) } // 显示语言选择对话框 private showLanguageDialog(): void { // 确保获取最新的文本资源 const texts = settingsService.getTextResources(); const currentLanguage = settingsService.getSettings().language; AlertDialog.show({ title: texts.languageText, message: currentLanguage === Language.CHINESE ? '请选择应用语言' : 'Please select a language', buttons: [ { value: '中文', action: () => { // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setLanguage(Language.CHINESE); // 语言变更需要更新文本资源 setTimeout(() => { this.currentTexts = settingsService.getTextResources(); }, 500); }); } }, { value: 'English', action: () => { // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setLanguage(Language.ENGLISH); // 语言变更需要更新文本资源 setTimeout(() => { this.currentTexts = settingsService.getTextResources(); }, 500); }); } }, { value: currentLanguage === Language.CHINESE ? '取消' : 'Cancel', action: () => {} } ] }) } // 切换通知设置 private toggleNotification(): void { // 获取当前通知状态并切换 const settings = settingsService.getSettings(); const newValue = !settings.notificationEnabled; const currentLanguage = settings.language; // 使用过渡动画更新设置 this.showTransitionAndUpdate(() => { settingsService.setNotificationEnabled(newValue); // 延迟显示提示信息,等待动画结束后 setTimeout(() => { const texts = settingsService.getTextResources(); promptAction.showToast({ message: newValue ? (currentLanguage === Language.CHINESE ? '通知已开启' : 'Notifications enabled') : (currentLanguage === Language.CHINESE ? '通知已关闭' : 'Notifications disabled'), duration: 2000 }); }, 1100); }); } // 显示版本日志对话框 private showVersionLogDialog(): void { const versionLogs = settingsService.getVersionLogs(); if (versionLogs.length === 0) { promptAction.showToast({ message: '暂无版本日志', duration: 2000 }); return; } // 构建版本日志内容 let message = ''; for (const log of versionLogs) { message += `版本 ${log.version}(${log.date})\n`; for (const change of log.changes) { message += `• ${change}\n`; } message += '\n'; } // 显示对话框 AlertDialog.show({ title: '更新日志', message: message, confirm: { value: this.currentLanguage === Language.CHINESE ? '确定' : 'OK', action: () => {} } }); } // 显示关于信息 private showAboutInfo(): void { // 确保使用最新的文本资源 const texts = settingsService.getTextResources(); const currentLanguage = settingsService.getSettings().language; const currentVersion = settingsService.getCurrentVersion(); AlertDialog.show({ title: texts.about, message: `v${currentVersion}\n© 922213102鸿蒙第一组 版权所有`, confirm: { value: currentLanguage === Language.CHINESE ? '确定' : 'OK', action: () => {} } }) } } // 设置项组件 - 美化版 @Component struct SettingItem { title: string = ''; value: string = ''; // 添加刷新触发器属性,用于强制组件刷新 refreshTrigger: number = 0; // 添加主题颜色属性 themeColor: string = '#409eff'; // 添加图标属性 icon: Resource = $r('app.media.settings'); onItemClick: () => void = () => {}; // 动画状态 @State pressed: boolean = false; build() { Row() { // 图标容器 Row() { Image(this.icon) .width(22) .height(22) .fillColor(this.themeColor) .opacity(0.9) } .width(40) .height(40) .borderRadius(20) .backgroundColor(`${this.themeColor}15`) // 使用主题色的淡色背景 .justifyContent(FlexAlign.Center) .margin({ right: 16 }) // 标题和值 Column() { Text(this.title) .fontSize(16) .fontColor('#333') .fontWeight(FontWeight.Medium) } .alignItems(HorizontalAlign.Start) .layoutWeight(1) // 值和箭头 Row() { Text(this.value) .fontSize(16) .fontColor('#999') .textAlign(TextAlign.End) Image($r('app.media.arrow_right')) .width(18) .height(18) .margin({ left: 8 }) .fillColor('#999') } .alignItems(VerticalAlign.Center) } .width('100%') .height(76) .padding({ left: 20, right: 20 }) .backgroundColor(this.pressed ? '#f5f5f5' : Color.White) .alignItems(VerticalAlign.Center) .borderRadius(12) .animation({ duration: 200, curve: Curve.EaseInOut }) .onTouch((event) => { if (event.type === TouchType.Down) { this.pressed = true; } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) { this.pressed = false; if (event.type === TouchType.Up) { this.onItemClick(); } } }) } } // 底部导航栏组件 @Component struct BottomNavigation { @Prop activePage: string = 'settings'; @Prop themeColor: string; @Prop texts: TextResources = {} as TextResources; build() { Row() { // 首页按钮 Column() { Image($r('app.media.home')) .width(24) .height(24) .fillColor(this.activePage === 'home' ? this.themeColor : '#999') Text(this.texts.home) .fontSize(12) .fontColor(this.activePage === 'home' ? this.themeColor : '#999') .margin({ top: 4 }) } .layoutWeight(1) .onClick(() => { if (this.activePage !== 'home') { router.replaceUrl({ url: 'pages/HomePage', params: { direction: 'left' // 从设置页向左切换到首页 } }); } }) // 上课按钮 Column() { Image($r('app.media.class')) .width(24) .height(24) .fillColor(this.activePage === 'class' ? this.themeColor : '#999') Text(this.texts.class) .fontSize(12) .fontColor(this.activePage === 'class' ? this.themeColor : '#999') .margin({ top: 4 }) } .layoutWeight(1) .onClick(() => { if (this.activePage !== 'class') { router.replaceUrl({ url: 'pages/ClassPage', params: { direction: 'left' // 从设置页向左切换到上课页 } }); } }) // 设置按钮 Column() { Image($r('app.media.settings')) .width(24) .height(24) .fillColor(this.activePage === 'settings' ? this.themeColor : '#999') Text(this.texts.settings) .fontSize(12) .fontColor(this.activePage === 'settings' ? this.themeColor : '#999') .margin({ top: 4 }) } .layoutWeight(1) .onClick(() => { if (this.activePage !== 'settings') { router.replaceUrl({ url: 'pages/SettingsPage' }); } }) } .width('100%') .height(60) .backgroundColor(Color.White) .border({ color: '#eeeeee', width: 1, style: BorderStyle.Solid }) } }