Răsfoiți Sursa

添加更新日志弹窗

chendeben 1 an în urmă
părinte
comite
718d0c6093

+ 49 - 0
entry/src/main/ets/common/constants/UpdateConstants.ets

@@ -0,0 +1,49 @@
+/**
+ * 更新相关常量配置
+ */
+export class UpdateConstants {
+  /**
+   * 更新日志URL
+   * 可以根据需要修改为你的更新日志地址
+   */
+  static readonly UPDATE_LOG_URL: string = 'https://static.ss5.xyz/files/update_log.html';
+  /**
+   * 备用更新日志URL(当主URL无法访问时使用)
+   */
+  static readonly BACKUP_UPDATE_LOG_URL: string = 'https://gitee.com/your-repo/raw/master/CHANGELOG.md';
+  /**
+   * 本地更新日志文件路径(可选,用于离线显示)
+   */
+  static readonly LOCAL_CHANGELOG_PATH: string = 'rawfile/changelog.html';
+  /**
+   * 更新日志缓存时间(毫秒)
+   */
+  static readonly CACHE_DURATION: number = 24 * 60 * 60 * 1000; // 24小时
+
+  /**
+   * 网络请求超时时间(毫秒)
+   */
+  static readonly REQUEST_TIMEOUT: number = 10000; // 10秒
+
+  /**
+   * 是否启用更新日志功能
+   */
+  static readonly ENABLE_UPDATE_LOG: boolean = true;
+  /**
+   * 是否在每次启动时都检查更新日志
+   */
+  static readonly CHECK_ON_EVERY_LAUNCH: boolean = true;
+  /**
+   * 更新日志弹窗显示延迟时间(毫秒)
+   */
+  static readonly DIALOG_SHOW_DELAY: number = 1500;
+  /**
+   * 应用版本号(手动维护,每次更新时修改此值)
+   * 这是一个简单可靠的版本管理方案
+   */
+  static readonly APP_VERSION: string = '2.1.0';
+  /**
+   * 构建时间戳(用于区分不同的构建版本)
+   */
+  static readonly BUILD_TIMESTAMP: string = Date.now().toString();
+}

+ 143 - 0
entry/src/main/ets/common/util/UpdateLogManager.ets

@@ -0,0 +1,143 @@
+/**
+ * 更新日志管理器
+ * 负责管理更新日志的显示逻辑、版本检查等功能
+ */
+import { PreferencesUtil } from '@pura/harmony-utils';
+import { UpdateConstants } from '../constants/UpdateConstants';
+import Logger from './Logger';
+
+export class UpdateLogManager {
+  private static readonly TAG = 'UpdateLogManager';
+  
+  /**
+   * 检查并显示更新日志
+   * @returns Promise<boolean> 是否显示了更新日志
+   */
+  public static async checkAndShowUpdateLog(): Promise<boolean> {
+    try {
+      if (!UpdateConstants.ENABLE_UPDATE_LOG) {
+        Logger.info(UpdateLogManager.TAG, '更新日志功能已禁用');
+        return false;
+      }
+
+      const shouldShow = UpdateLogManager.shouldShowUpdateLog();
+      if (!shouldShow) {
+        Logger.info(UpdateLogManager.TAG, '无需显示更新日志');
+        return false;
+      }
+
+      Logger.info(UpdateLogManager.TAG, '准备显示更新日志弹窗');
+      return true;
+    } catch (error) {
+      Logger.error(UpdateLogManager.TAG, '检查更新日志失败:' + error);
+      return false;
+    }
+  }
+
+
+  /**
+   * 检查是否需要显示更新日志
+   */
+  private static shouldShowUpdateLog(): boolean {
+    try {
+      const currentVersion = UpdateLogManager.getCurrentVersion();
+      const lastShownVersion = PreferencesUtil.getStringSync('last_shown_update_version', '');
+      
+      // 如果配置为每次启动都检查
+      if (UpdateConstants.CHECK_ON_EVERY_LAUNCH) {
+        Logger.info(UpdateLogManager.TAG, '配置为每次启动都显示更新日志');
+        return true;
+      }
+      
+      // 检查版本是否更新
+      const isVersionUpdated = lastShownVersion !== currentVersion;
+      
+      if (isVersionUpdated) {
+        Logger.info(UpdateLogManager.TAG, `检测到版本更新:${lastShownVersion} -> ${currentVersion}`);
+      }
+      
+      return isVersionUpdated;
+    } catch (error) {
+      Logger.error(UpdateLogManager.TAG, '检查更新日志显示条件失败:' + error);
+      return false;
+    }
+  }
+
+  /**
+   * 获取当前应用版本号
+   */
+  private static getCurrentVersion(): string {
+    try {
+      // 使用配置中的版本号,这是最可靠的方案
+      return UpdateConstants.APP_VERSION;
+    } catch (error) {
+      Logger.error(UpdateLogManager.TAG, '获取应用版本号失败:' + error);
+      return '1.0.0';
+    }
+  }
+
+  /**
+   * 标记当前版本的更新日志已显示
+   */
+  public static markCurrentVersionShown(): void {
+    try {
+      const currentVersion = UpdateLogManager.getCurrentVersion();
+      PreferencesUtil.putSync('last_shown_update_version', currentVersion);
+      Logger.info(UpdateLogManager.TAG, `已标记版本 ${currentVersion} 的更新日志为已显示`);
+    } catch (error) {
+      Logger.error(UpdateLogManager.TAG, '标记更新日志已显示失败:' + error);
+    }
+  }
+
+  /**
+   * 重置更新日志显示状态(用于测试)
+   */
+  public static resetUpdateLogStatus(): void {
+    try {
+      PreferencesUtil.deleteSync('last_shown_update_version');
+      Logger.info(UpdateLogManager.TAG, '已重置更新日志显示状态');
+    } catch (error) {
+      Logger.error(UpdateLogManager.TAG, '重置更新日志显示状态失败:' + error);
+    }
+  }
+
+  /**
+   * 获取更新日志URL
+   */
+  public static getUpdateLogUrl(): string {
+    const currentVersion = UpdateLogManager.getCurrentVersion();
+    
+    // 使用配置的URL
+    if (UpdateConstants.UPDATE_LOG_URL) {
+      Logger.info(UpdateLogManager.TAG, `使用配置的URL: ${UpdateConstants.UPDATE_LOG_URL}`);
+      return `${UpdateConstants.UPDATE_LOG_URL}?version=${currentVersion}&t=${Date.now()}`;
+    }
+
+    // 使用备用URL
+    if (UpdateConstants.BACKUP_UPDATE_LOG_URL) {
+      Logger.info(UpdateLogManager.TAG, `使用备用URL: ${UpdateConstants.BACKUP_UPDATE_LOG_URL}`);
+      return UpdateConstants.BACKUP_UPDATE_LOG_URL;
+    }
+
+    // 最后使用本地HTML文件
+    const localUrl = `resource://rawfile/simple-changelog.html`;
+    Logger.info(UpdateLogManager.TAG, `使用本地HTML文件: ${localUrl}`);
+    return localUrl;
+  }
+
+  /**
+   * 获取备用URL(网络失败时使用)
+   */
+  public static getBackupUrl(): string {
+    return `resource://rawfile/simple-changelog.html`;
+  }
+
+  /**
+   * 检查网络连接状态
+   */
+  private static async checkNetworkConnection(): Promise<boolean> {
+    // 这里可以添加网络连接检查逻辑
+    // 暂时返回true,实际项目中可以根据需要实现
+    return true;
+  }
+}

+ 225 - 0
entry/src/main/ets/dialog/OnlineUpdateLogDialog.ets

@@ -0,0 +1,225 @@
+/**
+ * 在线更新日志弹窗组件
+ * 参考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 } from '@pura/harmony-utils';
+
+@CustomDialog
+export default struct OnlineUpdateLogDialog {
+  /** 弹窗控制器 */
+  controller: CustomDialogController;
+  /** 更新日志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;
+
+  aboutToAppear() {
+    // 获取当前应用版本
+    this.getCurrentVersion();
+    // 设置更新日志URL - 直接使用在线URL
+    this.updateLogUrl = UpdateConstants.UPDATE_LOG_URL;
+    // 检查深色模式
+    this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
+    
+    console.info('OnlineUpdateLogDialog URL:', this.updateLogUrl);
+    console.info('OnlineUpdateLogDialog 开始加载在线更新日志');
+  }
+
+  /**
+   * 获取当前应用版本号
+   */
+  private getCurrentVersion() {
+    try {
+      this.currentVersion = AppUtil.getVersionName()//UpdateConstants.APP_VERSION;
+    } catch (error) {
+      this.currentVersion = '1.0.0';
+    }
+  }
+
+  /**
+   * 记录已显示的版本,避免重复显示
+   */
+  private markVersionShown() {
+    UpdateLogManager.markCurrentVersionShown();
+  }
+
+  build() {
+    Column() {
+      // 标题栏
+      Row() {
+        Text('更新日志')
+          .fontSize(18)
+          .fontWeight(FontWeight.Bold)
+          .fontColor(Color.White)
+          .layoutWeight(1)
+        
+        Text('关闭')
+          .fontSize(14)
+          .fontColor(Color.White)
+          .padding({ left: 12, right: 12, top: 6, bottom: 6 })
+          .borderRadius(4)
+          .backgroundColor('rgba(255,255,255,0.2)')
+          .onClick(() => {
+            this.markVersionShown();
+            this.controller.close();
+          })
+      }
+      .width('100%')
+      .height(48)
+      .padding({ left: 20, right: 20 })
+      .backgroundColor('#2196F3')
+      .justifyContent(FlexAlign.SpaceBetween)
+      .alignItems(VerticalAlign.Center)
+
+      // 版本信息和进度条
+      Column() {
+        Text(`当前版本:v${this.currentVersion}`)
+          .fontSize(12)
+          .fontColor(Color.Gray)
+          .alignSelf(ItemAlign.Start)
+          .margin({ bottom: 8 })
+
+        // 进度条 - 参考WebIndex.ets的实现
+        if (this.progressVisible && this.progressValue < 100) {
+          Progress({ value: this.progressValue, total: 100, type: ProgressType.Linear })
+            .width('100%')
+            .height(3)
+            .color('#2196F3')
+            .backgroundColor('#E0E0E0')
+        }
+      }
+      .width('100%')
+      .padding({ left: 20, right: 20, top: 12, bottom: 8 })
+
+      // WebView内容区域 - 完全参考WebIndex.ets的实现
+      if (this.errorMessage) {
+        // 错误状态
+        Column() {
+          Text('❌')
+            .fontSize(48)
+          
+          Text('加载失败')
+            .fontSize(16)
+            .fontColor(Color.Black)
+            .margin({ top: 12 })
+          
+          Text(this.errorMessage)
+            .fontSize(12)
+            .fontColor(Color.Gray)
+            .margin({ top: 4 })
+            .textAlign(TextAlign.Center)
+          
+          Button('重试')
+            .fontSize(14)
+            .backgroundColor('#2196F3')
+            .margin({ top: 16 })
+            .onClick(() => {
+              this.errorMessage = '';
+              this.isLoading = true;
+              this.progressValue = 0;
+              this.progressVisible = true;
+              // 重新加载
+              this.webViewController.refresh();
+            })
+        }
+        .width('100%')
+        .height(350)
+        .justifyContent(FlexAlign.Center)
+        .alignItems(HorizontalAlign.Center)
+        .padding(20)
+      } else {
+        // WebView内容 - 完全按照WebIndex.ets的方式实现
+        Web({
+          src: this.updateLogUrl,
+          controller: this.webViewController
+        })
+          .width('100%')
+          .height(350)
+          .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('#9E9E9E')
+          .fontColor(Color.White)
+          .layoutWeight(1)
+          .onClick(() => {
+            this.controller.close();
+          })
+        
+        Blank().width(12)
+        
+        Button('知道了')
+          .fontSize(14)
+          .backgroundColor('#2196F3')
+          .fontColor(Color.White)
+          .layoutWeight(1)
+          .onClick(() => {
+            this.markVersionShown();
+            this.controller.close();
+          })
+      }
+      .width('100%')
+      .padding({ left: 20, right: 20, top: 16, bottom: 16 })
+    }
+    .backgroundColor(Color.White)
+    .borderRadius(12)
+    .width('92%')
+    .constraintSize({ maxHeight: '85%' })
+  }
+}

+ 40 - 0
entry/src/main/ets/pages/NewIndex.ets

@@ -35,6 +35,8 @@ import { UserCenter } from './UserCenter';
 import { ScanFilePage } from './ScanFilePage';
 import { AboutPage } from './AboutPage';
 import { smartMobilityCommon } from '@kit.CarKit';
+import { UpdateLogManager } from '../common/util/UpdateLogManager';
+import OnlineUpdateLogDialog from '../dialog/OnlineUpdateLogDialog';
 
 const TAG = 'NewIndex'; // 日志标签
 
@@ -237,6 +239,44 @@ struct NewIndex {
       this.isShowTitleBar = false
     }
 
+    // 检查并显示更新日志
+    this.checkAndShowUpdateLog();
+  }
+
+  /**
+   * 检查并显示更新日志
+   */
+  private async checkAndShowUpdateLog() {
+    try {
+      const shouldShow = await UpdateLogManager.checkAndShowUpdateLog();
+      if (shouldShow) {
+        // 延迟显示,确保页面完全加载
+        setTimeout(() => {
+          this.showUpdateLogDialog();
+        }, 3000); // 3秒延迟,确保主页面完全加载
+      }
+    } catch (error) {
+      console.error('NewIndex checkAndShowUpdateLog error:', error);
+    }
+  }
+
+  /**
+   * 显示更新日志弹窗
+   */
+  private showUpdateLogDialog() {
+    try {
+      const dialogController = new CustomDialogController({
+        builder: OnlineUpdateLogDialog({}),
+        autoCancel: false,
+        alignment: DialogAlignment.Center,
+        customStyle: true
+      });
+
+      dialogController.open();
+      console.info('NewIndex 更新日志弹窗已显示');
+    } catch (error) {
+      console.error('NewIndex 显示更新日志弹窗失败:', error);
+    }
   }
 
   /**