Procházet zdrojové kódy

整合在线参数配置

chendeben před 1 rokem
rodič
revize
076025c1f9

+ 186 - 0
entry/src/main/ets/common/util/ConfigManager.ets

@@ -0,0 +1,186 @@
+/**
+ * 配置管理器
+ * 负责从远程API获取配置参数并保存到AppStorage中
+ */
+import { http } from '@kit.NetworkKit';
+import Logger from './Logger';
+
+/**
+ * 配置项接口定义
+ */
+export interface ConfigItem {
+  name: string;
+  description: string;
+  value: string | number | boolean;
+  type: 'json' | 'boolean' | 'number' | 'string';
+}
+
+/**
+ * JSON配置值类型 - 使用ESObject作为通用对象类型
+ */
+export type JsonConfigValue = ESObject;
+
+/**
+ * 配置值联合类型
+ */
+export type ConfigValue = string | number | boolean | ESObject;
+
+/**
+ * API响应接口定义
+ */
+export interface ConfigResponse {
+  code: number;
+  msg: string;
+  data: ConfigItem[];
+}
+
+/**
+ * 配置管理器类
+ */
+export class ConfigManager {
+  private static readonly TAG = 'ConfigManager';
+  private static readonly CONFIG_API_URL = 'https://pay.ss5.xyz/switches/lists';
+  private static readonly REQUEST_TIMEOUT = 5000; // 5秒超时
+
+  /**
+   * 初始化配置 - 从API获取配置并保存到AppStorage
+   * @returns Promise<boolean> 是否初始化成功
+   */
+  public static async initConfig(): Promise<boolean> {
+    try {
+      Logger.info(ConfigManager.TAG, '开始初始化配置...');
+      
+      const configData = await ConfigManager.fetchConfigFromAPI();
+      if (!configData) {
+        Logger.error(ConfigManager.TAG, '获取配置数据失败');
+        return false;
+      }
+
+      ConfigManager.saveConfigToAppStorage(configData);
+      Logger.info(ConfigManager.TAG, '配置初始化完成');
+      return true;
+    } catch (error) {
+      Logger.error(ConfigManager.TAG, '配置初始化失败:' + error);
+      return false;
+    }
+  }
+
+  /**
+   * 从API获取配置数据
+   * @returns Promise<ConfigItem[] | null> 配置数据数组或null
+   */
+  private static async fetchConfigFromAPI(): Promise<ConfigItem[] | null> {
+    try {
+      const httpRequest = http.createHttp();
+      const options: http.HttpRequestOptions = {
+        method: http.RequestMethod.GET,
+        readTimeout: ConfigManager.REQUEST_TIMEOUT,
+        connectTimeout: ConfigManager.REQUEST_TIMEOUT,
+        header: {
+          'Content-Type': 'application/json'
+        }
+      };
+
+      Logger.info(ConfigManager.TAG, '请求配置API: ' + ConfigManager.CONFIG_API_URL);
+      const response: http.HttpResponse = await httpRequest.request(ConfigManager.CONFIG_API_URL, options);
+
+      if (response.responseCode === 200) {
+        const responseData = response.result as string;
+        const configResponse: ConfigResponse = JSON.parse(responseData);
+        
+        if (configResponse.code === 0) {
+          Logger.info(ConfigManager.TAG, `成功获取${configResponse.data.length}个配置项`);
+          return configResponse.data;
+        } else {
+          Logger.error(ConfigManager.TAG, 'API返回错误:' + configResponse.msg);
+          return null;
+        }
+      } else {
+        Logger.error(ConfigManager.TAG, '请求失败,状态码:' + response.responseCode);
+        return null;
+      }
+    } catch (error) {
+      Logger.error(ConfigManager.TAG, '请求配置API异常:' + error);
+      return null;
+    }
+  }
+
+  /**
+   * 将配置数据保存到AppStorage
+   * @param configData 配置数据数组
+   */
+  private static saveConfigToAppStorage(configData: ConfigItem[]): void {
+    try {
+      configData.forEach(config => {
+        let processedValue: ConfigValue = config.value;
+        
+        // 根据类型处理值
+        switch (config.type) {
+          case 'json':
+            try {
+              processedValue = JSON.parse(config.value as string) as ESObject;
+            } catch (e) {
+              Logger.error(ConfigManager.TAG, `解析JSON配置失败 ${config.name}: ${e}`);
+              processedValue = config.value;
+            }
+            break;
+          case 'boolean':
+            processedValue = Boolean(config.value);
+            break;
+          case 'number':
+            processedValue = Number(config.value);
+            break;
+          case 'string':
+          default:
+            processedValue = String(config.value);
+            break;
+        }
+
+        // 保存到AppStorage
+        AppStorage.setOrCreate(config.name, processedValue);
+        Logger.info(ConfigManager.TAG, `保存配置 ${config.name}: ${processedValue} (${config.type})`);
+      });
+    } catch (error) {
+      Logger.error(ConfigManager.TAG, '保存配置到AppStorage失败:' + error);
+    }
+  }
+
+  /**
+   * 获取配置值
+   * @param key 配置键名
+   * @param defaultValue 默认值
+   * @returns 配置值
+   */
+  public static getConfig<T extends ConfigValue>(key: string, defaultValue: T): T {
+    try {
+      const value: ConfigValue | undefined = AppStorage.get(key) as ConfigValue | undefined;
+      return value !== undefined ? value as T : defaultValue;
+    } catch (error) {
+      Logger.error(ConfigManager.TAG, `获取配置失败 ${key}: ${error}`);
+      return defaultValue;
+    }
+  }
+
+  /**
+   * 设置配置值
+   * @param key 配置键名
+   * @param value 配置值
+   */
+  public static setConfig(key: string, value: ConfigValue): void {
+    try {
+      AppStorage.setOrCreate(key, value);
+      Logger.info(ConfigManager.TAG, `更新配置 ${key}: ${value}`);
+    } catch (error) {
+      Logger.error(ConfigManager.TAG, `设置配置失败 ${key}: ${error}`);
+    }
+  }
+
+  /**
+   * 刷新配置 - 重新从API获取配置
+   * @returns Promise<boolean> 是否刷新成功
+   */
+  public static async refreshConfig(): Promise<boolean> {
+    Logger.info(ConfigManager.TAG, '刷新配置...');
+    return await ConfigManager.initConfig();
+  }
+}

+ 11 - 2
entry/src/main/ets/common/util/UpdateLogManager.ets

@@ -5,6 +5,7 @@
 import { AppUtil, PreferencesUtil } from '@pura/harmony-utils';
 import { UpdateConstants } from '../constants/UpdateConstants';
 import Logger from './Logger';
+import { ConfigManager } from './ConfigManager';
 
 export class UpdateLogManager {
   private static readonly TAG = 'UpdateLogManager';
@@ -15,10 +16,18 @@ export class UpdateLogManager {
    */
   public static async checkAndShowUpdateLog(): Promise<boolean> {
     try {
-      if (!UpdateConstants.ENABLE_UPDATE_LOG) {
-        Logger.info(UpdateLogManager.TAG, '更新日志功能已禁用');
+      // 从API配置中获取是否显示更新日志的设置
+      const showUpdateLog = ConfigManager.getConfig('show_update_log', false);
+      if (!showUpdateLog) {
+        Logger.info(UpdateLogManager.TAG, '更新日志功能已通过API配置禁用');
         return false;
       }
+      Logger.info(UpdateLogManager.TAG, '更新日志功能已通过API配置启用');
+
+      // if (!UpdateConstants.ENABLE_UPDATE_LOG) {
+      //   Logger.info(UpdateLogManager.TAG, '更新日志功能已禁用');
+      //   return false;
+      // }
 
       const shouldShow = UpdateLogManager.shouldShowUpdateLog();
       if (!shouldShow) {

+ 0 - 97
entry/src/main/ets/dialog/OnlineUpdateLog.ets

@@ -81,36 +81,6 @@ export default struct OnlineUpdateLog {
     }
   }
 
-  /**
-   * 颜色变亮工具方法
-   */
-  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; // 出错时返回原色
-    }
-  }
 
   /**
    * 组件销毁时清理资源
@@ -133,19 +103,6 @@ export default struct OnlineUpdateLog {
 
       // 版本信息和进度条
       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() {
@@ -292,60 +249,6 @@ export default struct OnlineUpdateLog {
             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: 15,
-        topRight:15,
-        bottomLeft: 15,
-        bottomRight: 15
-      })
     }
     .backgroundColor(this.isDarkMode ? '#2C2C2C' : Color.White)
     .borderRadius(12)

+ 21 - 2
entry/src/main/ets/pages/SplashIndex.ets

@@ -5,6 +5,7 @@ import Logger from '../common/util/Logger'
 import { router, window } from '@kit.ArkUI'
 import { CommonConstants } from '../common/constants/CommonConstants'
 import { CSJUtil } from '../common/util/CSJUtil'
+import { ConfigManager } from '../common/util/ConfigManager'
 // import { AdSlotBuilder, CSJAdCreator, CSJAdSdk, CSJSplashAd,
 //   CSJSplashAdCloseType,
 //   CSJSplashAdInteractionListener,
@@ -203,15 +204,33 @@ struct  SplashIndex{
     })
 
     // this.junpToMainNow();
+
+    // 初始化配置
     this.initCSJSDK()
 
   }
 
   //初始化SDK
-  initCSJSDK(){
+  async initCSJSDK(){
+    await this.initAppConfig();
     this.mkDownLoadDir()
+  }
 
-
+  /**
+   * 初始化应用配置
+   */
+  private async initAppConfig(): Promise<void> {
+    try {
+      Logger.info('SplashIndex', '开始初始化应用配置...');
+      const success = await ConfigManager.initConfig();
+      if (success) {
+        Logger.info('SplashIndex', '应用配置初始化成功');
+      } else {
+        Logger.error('SplashIndex', '应用配置初始化失败,使用默认配置');
+      }
+    } catch (error) {
+      Logger.error('SplashIndex', '初始化应用配置异常:' + error);
+    }
   }
   //退出App
   exitApp(){

+ 159 - 0
配置系统使用说明.md

@@ -0,0 +1,159 @@
+# 应用配置系统使用说明
+
+## 概述
+
+本应用实现了一个基于远程API的配置管理系统,可以在应用启动时从 `https://pay.ss5.xyz/switches/lists` 获取配置参数,并将这些参数保存到AppStorage中供全应用使用。
+
+## 功能特性
+
+1. **自动初始化**:应用启动时自动从API获取配置
+2. **类型支持**:支持 `json`、`boolean`、`number`、`string` 四种数据类型
+3. **全局访问**:配置保存在AppStorage中,可在任意页面访问
+4. **实时更新**:支持手动刷新配置
+5. **错误处理**:网络异常时使用默认值,不影响应用正常运行
+
+## API接口格式
+
+```json
+{
+  "code": 0,
+  "msg": "请求成功",
+  "data": [
+    {
+      "name": "test_json",
+      "description": "test_json",
+      "value": "{\n \"test_json\": \"test_json\"\n}",
+      "type": "json"
+    },
+    {
+      "name": "show_update_log",
+      "description": "是否显示日志更新弹窗",
+      "value": false,
+      "type": "boolean"
+    },
+    {
+      "name": "test_number",
+      "description": "test_number",
+      "value": 123456,
+      "type": "number"
+    },
+    {
+      "name": "test_string",
+      "description": "test_string",
+      "value": "test_string",
+      "type": "string"
+    }
+  ]
+}
+```
+
+## 核心文件
+
+### 1. ConfigManager.ets
+配置管理器,负责:
+- 从API获取配置数据
+- 解析不同类型的配置值
+- 保存配置到AppStorage
+- 提供配置读取和更新接口
+
+### 2. ConfigDisplayView.ets
+配置展示组件,用于:
+- 在设置页面展示当前配置
+- 提供配置刷新功能
+- 实时监听配置变化
+
+## 使用方法
+
+### 1. 初始化配置(已在SplashIndex中实现)
+
+```typescript
+import { ConfigManager } from '../common/util/ConfigManager';
+
+// 在应用启动时初始化配置
+const success = await ConfigManager.initConfig();
+```
+
+### 2. 读取配置
+
+```typescript
+import { ConfigManager, ConfigValue } from '../common/util/ConfigManager';
+
+// 方法1:使用ConfigManager(推荐,类型安全)
+const showUpdateLog: boolean = ConfigManager.getConfig('show_update_log', false);
+const testNumber: number = ConfigManager.getConfig('test_number', 0);
+const testString: string = ConfigManager.getConfig('test_string', '');
+const testJson: ESObject = ConfigManager.getConfig('test_json', {});
+
+// 方法2:直接从AppStorage读取
+const showUpdateLog = AppStorage.get('show_update_log') as boolean ?? false;
+```
+
+### 3. 在组件中监听配置变化
+
+```typescript
+@Component
+export struct MyComponent {
+  // 使用@StorageLink监听配置变化,确保类型安全
+  @StorageLink('show_update_log') showUpdateLog: boolean = false;
+  @StorageLink('test_number') testNumber: number = 0;
+  @StorageLink('test_string') testString: string = '';
+  @StorageLink('test_json') testJson: ESObject = {};
+
+  build() {
+    Column() {
+      Text(`显示更新日志: ${this.showUpdateLog}`)
+      Text(`测试数字: ${this.testNumber}`)
+      Text(`测试字符串: ${this.testString}`)
+      Text(`JSON配置: ${JSON.stringify(this.testJson)}`)
+    }
+  }
+}
+```
+
+### 4. 更新配置
+
+```typescript
+import { ConfigValue } from '../common/util/ConfigManager';
+
+// 设置单个配置(类型安全)
+ConfigManager.setConfig('show_update_log', true as ConfigValue);
+ConfigManager.setConfig('test_number', 123 as ConfigValue);
+ConfigManager.setConfig('test_string', 'new value' as ConfigValue);
+
+// 刷新所有配置
+const success: boolean = await ConfigManager.refreshConfig();
+```
+
+## 实际应用示例
+
+### UpdateLogManager中的使用
+
+```typescript
+// 从API配置中获取是否显示更新日志的设置
+const showUpdateLog = ConfigManager.getConfig('show_update_log', false);
+if (!showUpdateLog) {
+  Logger.info(UpdateLogManager.TAG, '更新日志功能已通过API配置禁用');
+  return false;
+}
+```
+
+
+## 错误处理
+
+1. **网络异常**:使用默认值,记录错误日志
+2. **JSON解析失败**:保持原始字符串值
+3. **类型转换失败**:使用默认值
+
+## 注意事项
+
+1. 配置初始化是异步操作,确保在使用配置前完成初始化
+2. 配置键名要与API返回的name字段保持一致
+3. 为每个配置提供合理的默认值
+4. 配置变化会自动触发使用@StorageLink的组件重新渲染
+
+## 扩展建议
+
+1. 可以添加配置缓存机制,减少网络请求
+2. 可以添加配置版本控制,支持增量更新
+3. 可以添加配置验证机制,确保配置值的有效性
+4. 可以添加配置分组功能,支持不同模块的配置管理