/** * 在线更新日志弹窗组件 * 参考WebIndex.ets的成功实现,确保WebView正常工作 */ import { webview } from '@kit.ArkWeb'; import { UpdateConstants } from '../common/constants/UpdateConstants'; import { UpdateLogManager } from '../common/util/UpdateLogManager'; import { ConfigurationConstant } from '@kit.AbilityKit'; import { AppUtil, PreferencesUtil } from '@pura/harmony-utils'; import { CommonConstants } from '../common/constants/CommonConstants'; @Component export default struct OnlineUpdateLog { /** 弹窗控制器 */ controller?: CustomDialogController; /** 关闭回调 */ onClose?: () => void; /** 更新日志URL */ @State updateLogUrl: string = ''; /** 当前应用版本 */ @State currentVersion: string = ''; /** WebView控制器 */ private webViewController: webview.WebviewController = new webview.WebviewController(); /** 是否加载完成 */ @State isLoading: boolean = true; /** 加载错误信息 */ @State errorMessage: string = ''; /** 加载进度 */ @State progressValue: number = 0; /** 进度条是否可见 */ @State progressVisible: boolean = true; /** 深色模式 */ @State isDarkMode: boolean = false; @StorageProp('currentColorMode') currentMode: number = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT; @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR; aboutToAppear() { try { // 获取当前应用版本 this.getCurrentVersion(); // 设置更新日志URL - 直接使用在线URL this.updateLogUrl = UpdateConstants.UPDATE_LOG_URL; // 检查深色模式 this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK; let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR); AppStorage.setOrCreate('themeColor', themeColor); this.themeColor = themeColor console.info('OnlineUpdateLogDialog URL:', this.updateLogUrl); console.info('OnlineUpdateLogDialog 开始加载在线更新日志'); // 确保WebView控制器已初始化 if (!this.webViewController) { this.webViewController = new webview.WebviewController(); } } catch (error) { console.error('OnlineUpdateLogDialog aboutToAppear error:', error); this.errorMessage = '初始化失败'; this.isLoading = false; } } /** * 获取当前应用版本号 */ private getCurrentVersion() { try { this.currentVersion = AppUtil.getVersionName()//UpdateConstants.APP_VERSION; } catch (error) { this.currentVersion = '1.0.0'; } } /** * 记录已显示的版本,避免重复显示 */ private markVersionShown() { try { UpdateLogManager.markCurrentVersionShown(); } catch (error) { console.error('OnlineUpdateLogDialog markVersionShown error:', error); } } /** * 颜色变亮工具方法 */ private lightenColor(color: string, amount: number): string { try { // 移除 # 号 const hex = color.replace('#', ''); // 转换为 RGB const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); // 增加亮度 const newR = Math.min(255, Math.floor(r + (255 - r) * amount)); const newG = Math.min(255, Math.floor(g + (255 - g) * amount)); const newB = Math.min(255, Math.floor(b + (255 - b) * amount)); // 转换回十六进制 const newHex = '#' + newR.toString(16).padStart(2, '0') + newG.toString(16).padStart(2, '0') + newB.toString(16).padStart(2, '0'); return newHex; } catch (error) { console.error('lightenColor error:', error); return color; // 出错时返回原色 } } /** * 组件销毁时清理资源 */ aboutToDisappear() { try { console.info('OnlineUpdateLogDialog aboutToDisappear'); // 清理WebView控制器 if (this.webViewController) { // 这里可以添加WebView的清理逻辑,如果需要的话 } } catch (error) { console.error('OnlineUpdateLogDialog aboutToDisappear error:', error); } } build() { Column() { // 版本信息和进度条 Column() { Row() { Text('当前版本:') .fontSize(15) .fontColor(this.isDarkMode ? '#E0E0E0' : Color.Gray) Text(`v${this.currentVersion}`) .fontSize(15) .fontColor(this.themeColor) .fontWeight(FontWeight.Medium) } .alignSelf(ItemAlign.Start) .margin({ bottom: 8 }) // 进度条 - 使用主题色 if (this.progressVisible && this.progressValue < 100) { Column() { Progress({ value: this.progressValue, total: 100, type: ProgressType.Linear }) .width('100%') .height(4) .color(this.themeColor) .backgroundColor(this.isDarkMode ? '#4A4A4A' : '#E0E0E0') .borderRadius(2) Text(`加载中... ${this.progressValue}%`) .fontSize(10) .fontColor(this.isDarkMode ? '#E0E0E0' : Color.Gray) .margin({ top: 4 }) .alignSelf(ItemAlign.End) } .width('100%') } } .width('100%') .padding({ left: 20, right: 20, top: 12, bottom: 8 }) .backgroundColor(this.isDarkMode ? '#3A3A3A' : '#F8F9FA') .borderRadius({ topLeft: 0, topRight: 0, bottomLeft: 8, bottomRight: 8 }) // WebView内容区域 - 完全参考WebIndex.ets的实现 if (this.errorMessage) { // 错误状态 Column() { // 错误图标背景 Column() { Text('❌') .fontSize(32) } .width(64) .height(64) .backgroundColor(this.isDarkMode ? '#4A4A4A' : '#FFF5F5') .borderRadius(32) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .border({ width: 1, color: this.isDarkMode ? '#666666' : '#FED7D7' }) Text('加载失败') .fontSize(16) .fontColor(this.isDarkMode ? Color.White : Color.Black) .fontWeight(FontWeight.Medium) .margin({ top: 16 }) Text(this.errorMessage) .fontSize(12) .fontColor(this.isDarkMode ? '#E0E0E0' : Color.Gray) .margin({ top: 8, left: 20, right: 20 }) .textAlign(TextAlign.Center) .maxLines(3) Button('重试') .fontSize(14) .backgroundColor(this.themeColor) .fontColor(Color.White) .borderRadius(8) .width(120) .height(40) .margin({ top: 20 }) .onClick(() => { try { this.errorMessage = ''; this.isLoading = true; this.progressValue = 0; this.progressVisible = true; // 重新加载 if (this.webViewController) { this.webViewController.refresh(); } } catch (error) { console.error('OnlineUpdateLogDialog 重试失败:', error); this.errorMessage = '重试失败,请稍后再试'; } }) } .width('100%') .height(350) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .padding(20) .backgroundColor(this.isDarkMode ? '#2C2C2C' : Color.White) } else { // WebView内容 - 完全按照WebIndex.ets的方式实现 Web({ src: this.updateLogUrl, controller: this.webViewController }) .width('100%') .height(350) .borderRadius(8) .backgroundColor(this.isDarkMode ? '#2C2C2C' : Color.White) // .border({ // width: 1, // color: this.isDarkMode ? '#333333' : '#E0E0E0' // }) .margin({ left: 12, right: 12, bottom: 8 }) .darkMode(this.isDarkMode ? WebDarkMode.On : WebDarkMode.Off) .forceDarkAccess(this.isDarkMode) .onProgressChange((event) => { if (event) { console.info('OnlineUpdateLogDialog WebView进度:', event.newProgress); this.progressValue = event.newProgress; // 进度完成时隐藏进度条 if (event.newProgress >= 100) { setTimeout(() => { this.progressVisible = false; this.isLoading = false; }, 500); } } }) .onPageBegin(() => { console.info('OnlineUpdateLogDialog WebView开始加载:', this.updateLogUrl); this.isLoading = true; this.errorMessage = ''; this.progressValue = 0; this.progressVisible = true; }) .onPageEnd(() => { console.info('OnlineUpdateLogDialog WebView加载完成'); this.isLoading = false; setTimeout(() => { this.progressVisible = false; }, 1000); }) .onErrorReceive((event) => { const errorInfo = event?.error?.getErrorInfo() || '网络错误'; console.error('OnlineUpdateLogDialog WebView加载错误:', errorInfo); this.isLoading = false; this.progressVisible = false; this.errorMessage = `加载失败:${errorInfo}`; }) } // 底部按钮 Row() { Button('稍后查看') .fontSize(14) .backgroundColor(this.isDarkMode ? '#666666' : '#9E9E9E') .fontColor(Color.White) .borderRadius(8) .layoutWeight(1) .height(44) .onClick(() => { try { if (this.onClose) { this.onClose(); } else { this.controller?.close(); } } catch (error) { console.error('OnlineUpdateLogDialog 稍后查看按钮失败:', error); } }) Blank().width(12) Button('知道了') .fontSize(14) .backgroundColor(this.themeColor) .fontColor(Color.White) .borderRadius(8) .layoutWeight(1) .height(44) .onClick(() => { try { this.markVersionShown(); if (this.onClose) { this.onClose(); } else { this.controller?.close(); } } catch (error) { console.error('OnlineUpdateLogDialog 知道了按钮失败:', error); } }) } .visibility(Visibility.Hidden) .width('100%') .padding({ left: 20, right: 20, top: 16, bottom: 16 }) .backgroundColor(this.isDarkMode ? '#3A3A3A' : '#F8F9FA') .borderRadius({ topLeft: 0, topRight: 0, bottomLeft: 12, bottomRight: 12 }) } .backgroundColor(this.isDarkMode ? '#2C2C2C' : Color.White) .borderRadius(12) .width('92%') .constraintSize({ maxHeight: '85%' }) .shadow({ radius: 16, color: this.isDarkMode ? 'rgba(0,0,0,0.8)' : 'rgba(0,0,0,0.15)', offsetX: 0, offsetY: 4 }) } }