顾海波

【需求】补充上报信息

@@ -19,6 +19,7 @@ class _MyAppState extends State<MyApp> { @@ -19,6 +19,7 @@ class _MyAppState extends State<MyApp> {
19 void initState() { 19 void initState() {
20 AutoTrack() 20 AutoTrack()
21 .config(AutoTrackConfig( 21 .config(AutoTrackConfig(
  22 + buildContext: context,
22 host: "https://sitigrs.boeart.cn", 23 host: "https://sitigrs.boeart.cn",
23 appKey: "KEY_oVfNOQLQ", 24 appKey: "KEY_oVfNOQLQ",
24 appSecret: "w21tRLJt7LBVYJtD", 25 appSecret: "w21tRLJt7LBVYJtD",
@@ -17,6 +17,14 @@ packages: @@ -17,6 +17,14 @@ packages:
17 url: "https://pub.flutter-io.cn" 17 url: "https://pub.flutter-io.cn"
18 source: hosted 18 source: hosted
19 version: "3.6.1" 19 version: "3.6.1"
  20 + args:
  21 + dependency: transitive
  22 + description:
  23 + name: args
  24 + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
  25 + url: "https://pub.flutter-io.cn"
  26 + source: hosted
  27 + version: "2.6.0"
20 async: 28 async:
21 dependency: transitive 29 dependency: transitive
22 description: 30 description:
@@ -64,6 +72,23 @@ packages: @@ -64,6 +72,23 @@ packages:
64 url: "https://pub.flutter-io.cn" 72 url: "https://pub.flutter-io.cn"
65 source: hosted 73 source: hosted
66 version: "1.18.0" 74 version: "1.18.0"
  75 + connectivity_plus:
  76 + dependency: transitive
  77 + description:
  78 + path: "packages/connectivity_plus/connectivity_plus"
  79 + ref: HEAD
  80 + resolved-ref: ff774d947bd15d9be08629e3ccfb29dda2e864bd
  81 + url: "https://gitee.com/openharmony-sig/flutter_plus_plugins"
  82 + source: git
  83 + version: "5.0.1"
  84 + connectivity_plus_platform_interface:
  85 + dependency: transitive
  86 + description:
  87 + name: connectivity_plus_platform_interface
  88 + sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
  89 + url: "https://pub.flutter-io.cn"
  90 + source: hosted
  91 + version: "1.2.4"
67 crypto: 92 crypto:
68 dependency: transitive 93 dependency: transitive
69 description: 94 description:
@@ -80,6 +105,14 @@ packages: @@ -80,6 +105,14 @@ packages:
80 url: "https://pub.flutter-io.cn" 105 url: "https://pub.flutter-io.cn"
81 source: hosted 106 source: hosted
82 version: "1.0.8" 107 version: "1.0.8"
  108 + dbus:
  109 + dependency: transitive
  110 + description:
  111 + name: dbus
  112 + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
  113 + url: "https://pub.flutter-io.cn"
  114 + source: hosted
  115 + version: "0.7.11"
83 device_info_plus: 116 device_info_plus:
84 dependency: transitive 117 dependency: transitive
85 description: 118 description:
@@ -183,6 +216,14 @@ packages: @@ -183,6 +216,14 @@ packages:
183 description: flutter 216 description: flutter
184 source: sdk 217 source: sdk
185 version: "0.0.0" 218 version: "0.0.0"
  219 + js:
  220 + dependency: transitive
  221 + description:
  222 + name: js
  223 + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
  224 + url: "https://pub.flutter-io.cn"
  225 + source: hosted
  226 + version: "0.6.7"
186 leak_tracker: 227 leak_tracker:
187 dependency: transitive 228 dependency: transitive
188 description: 229 description:
@@ -239,6 +280,14 @@ packages: @@ -239,6 +280,14 @@ packages:
239 url: "https://pub.flutter-io.cn" 280 url: "https://pub.flutter-io.cn"
240 source: hosted 281 source: hosted
241 version: "1.12.0" 282 version: "1.12.0"
  283 + nm:
  284 + dependency: transitive
  285 + description:
  286 + name: nm
  287 + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
  288 + url: "https://pub.flutter-io.cn"
  289 + source: hosted
  290 + version: "0.5.0"
242 package_info_plus: 291 package_info_plus:
243 dependency: transitive 292 dependency: transitive
244 description: 293 description:
@@ -264,6 +313,14 @@ packages: @@ -264,6 +313,14 @@ packages:
264 url: "https://pub.flutter-io.cn" 313 url: "https://pub.flutter-io.cn"
265 source: hosted 314 source: hosted
266 version: "1.9.0" 315 version: "1.9.0"
  316 + petitparser:
  317 + dependency: transitive
  318 + description:
  319 + name: petitparser
  320 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
  321 + url: "https://pub.flutter-io.cn"
  322 + source: hosted
  323 + version: "6.0.2"
267 platform: 324 platform:
268 dependency: transitive 325 dependency: transitive
269 description: 326 description:
@@ -445,6 +502,14 @@ packages: @@ -445,6 +502,14 @@ packages:
445 url: "https://pub.flutter-io.cn" 502 url: "https://pub.flutter-io.cn"
446 source: hosted 503 source: hosted
447 version: "1.1.5" 504 version: "1.1.5"
  505 + xml:
  506 + dependency: transitive
  507 + description:
  508 + name: xml
  509 + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
  510 + url: "https://pub.flutter-io.cn"
  511 + source: hosted
  512 + version: "6.5.0"
448 sdks: 513 sdks:
449 dart: ">=3.4.0 <4.0.0" 514 dart: ">=3.4.0 <4.0.0"
450 flutter: ">=3.18.0-18.0.pre.54" 515 flutter: ">=3.18.0-18.0.pre.54"
@@ -2,6 +2,7 @@ import 'dart:convert'; @@ -2,6 +2,7 @@ import 'dart:convert';
2 2
3 import 'package:auto_track/auto_track/utils/track_model.dart'; 3 import 'package:auto_track/auto_track/utils/track_model.dart';
4 import 'package:crypto/crypto.dart'; 4 import 'package:crypto/crypto.dart';
  5 +import 'package:flutter/cupertino.dart';
5 import 'package:flutter/widgets.dart'; 6 import 'package:flutter/widgets.dart';
6 import 'package:uuid/uuid.dart'; 7 import 'package:uuid/uuid.dart';
7 8
@@ -9,6 +10,7 @@ typedef EventHandlerFunc = void Function(TrackModel); @@ -9,6 +10,7 @@ typedef EventHandlerFunc = void Function(TrackModel);
9 10
10 class AutoTrackConfig { 11 class AutoTrackConfig {
11 AutoTrackConfig({ 12 AutoTrackConfig({
  13 + this.buildContext,
12 this.host, // 数据上报地址 14 this.host, // 数据上报地址
13 this.uploadInterval, // 数据上报间隔 15 this.uploadInterval, // 数据上报间隔
14 this.samplingRate = 1, // 采样率 16 this.samplingRate = 1, // 采样率
@@ -37,6 +39,8 @@ class AutoTrackConfig { @@ -37,6 +39,8 @@ class AutoTrackConfig {
37 httpRequestConfig ??= HttpRequestConfig(); 39 httpRequestConfig ??= HttpRequestConfig();
38 } 40 }
39 41
  42 + BuildContext? buildContext;
  43 +
40 String? host; 44 String? host;
41 String? appKey; 45 String? appKey;
42 String? appSecret; 46 String? appSecret;
@@ -24,6 +24,7 @@ class AutoTrackConfigManager { @@ -24,6 +24,7 @@ class AutoTrackConfigManager {
24 PackageInfo.fromPlatform().then( (value) { 24 PackageInfo.fromPlatform().then( (value) {
25 _appVersion = value.version; 25 _appVersion = value.version;
26 _appName = value.appName; 26 _appName = value.appName;
  27 + _pkgName = value.packageName;
27 }); 28 });
28 DeviceInfoPlugin().deviceInfo.then((value) { 29 DeviceInfoPlugin().deviceInfo.then((value) {
29 _deviceInfo = value.data; 30 _deviceInfo = value.data;
@@ -38,6 +39,8 @@ class AutoTrackConfigManager { @@ -38,6 +39,8 @@ class AutoTrackConfigManager {
38 String _appName = ''; 39 String _appName = '';
39 String get appName => _appName; 40 String get appName => _appName;
40 41
  42 + String _pkgName = '';
  43 + String get pkgName => _pkgName;
41 44
42 BaseDeviceInfo? _baseDeviceInfo; 45 BaseDeviceInfo? _baseDeviceInfo;
43 BaseDeviceInfo? get baseDeviceInfo => _baseDeviceInfo; 46 BaseDeviceInfo? get baseDeviceInfo => _baseDeviceInfo;
@@ -7,9 +7,10 @@ import 'package:archive/archive.dart'; @@ -7,9 +7,10 @@ import 'package:archive/archive.dart';
7 import 'package:auto_track/auto_track/config/manager.dart'; 7 import 'package:auto_track/auto_track/config/manager.dart';
8 import 'package:auto_track/auto_track/utils/track_model.dart'; 8 import 'package:auto_track/auto_track/utils/track_model.dart';
9 import 'package:device_info_plus/device_info_plus.dart'; 9 import 'package:device_info_plus/device_info_plus.dart';
  10 +import 'package:flutter/cupertino.dart';
10 import 'package:path/path.dart' as path; 11 import 'package:path/path.dart' as path;
11 import 'package:sqflite/sqflite.dart'; 12 import 'package:sqflite/sqflite.dart';
12 - 13 +import 'package:connectivity_plus/connectivity_plus.dart';
13 import '../log/logger.dart'; 14 import '../log/logger.dart';
14 15
15 class AutoTrackQueue { 16 class AutoTrackQueue {
@@ -79,169 +80,194 @@ class AutoTrackQueue { @@ -79,169 +80,194 @@ class AutoTrackQueue {
79 } 80 }
80 81
81 Future<void> flush() async { 82 Future<void> flush() async {
82 - AutoTrackLogger.getInstance().debug("@@@start flush"); 83 + try {
  84 + AutoTrackLogger.getInstance().debug("@@@start flush");
83 85
84 - if (database == null) {  
85 - AutoTrackLogger.getInstance().debug('数据库未初始化,跳过 flush');  
86 - return;  
87 - } 86 + if (database == null) {
  87 + AutoTrackLogger.getInstance().debug('数据库未初始化,跳过 flush');
  88 + return;
  89 + }
88 90
89 - final List<TrackModel> uploadList = []; 91 + final List<TrackModel> uploadList = [];
90 92
91 - List<Map<String, dynamic>> events = await database.query("track",  
92 - columns: ["id", "event", "date"], limit: 100); 93 + List<Map<String, dynamic>> events = await database.query("track",
  94 + columns: ["id", "event", "date"], limit: 100);
  95 + if (events.isEmpty) {
  96 + AutoTrackLogger.getInstance().debug("@@@events is empty");
  97 + return;
  98 + }
93 99
94 - for (var event in events) {  
95 - Track model = Track.fromMap(event);  
96 - uploadList.add(TrackModel.fromMap(jsonDecode(model.event)));  
97 - } 100 + for (var event in events) {
  101 + Track model = Track.fromMap(event);
  102 + uploadList.add(TrackModel.fromMap(jsonDecode(model.event)));
  103 + }
98 104
99 - final config = AutoTrackConfigManager.instance.config;  
100 - final baseDeviceInfo = AutoTrackConfigManager.instance.baseDeviceInfo;  
101 - final host = config.host;  
102 - if (config.samplingRate != 1) {  
103 - if (Random().nextDouble() > config.samplingRate) {  
104 - // 不在采样范围不上传 105 + final config = AutoTrackConfigManager.instance.config;
  106 + final baseDeviceInfo = AutoTrackConfigManager.instance.baseDeviceInfo;
  107 + final host = config.host;
  108 + if (config.samplingRate != 1) {
  109 + if (Random().nextDouble() > config.samplingRate) {
  110 + // 不在采样范围不上传
  111 + return;
  112 + }
  113 + }
  114 + String? token = config.token;
  115 + if (token == null) {
  116 + AutoTrackConfigManager.instance.getToken(true);
105 return; 117 return;
106 } 118 }
107 - }  
108 - String? token = config.token;  
109 - if (token == null) {  
110 - AutoTrackConfigManager.instance.getToken(true);  
111 - return;  
112 - }  
113 - if (host != null) {  
114 - List<Map> datas = [];  
115 - uploadList.forEach((event) {  
116 - Random random = Random.secure();  
117 - int id = random.nextInt(1 << 32); // 模拟 Java 的 nextInt()  
118 - final t = DateTime.now().millisecondsSinceEpoch;  
119 -  
120 - String os = "";  
121 - String os_version = "";  
122 - String model = "";  
123 - String manufacturer = "";  
124 -  
125 - if (baseDeviceInfo != null) {  
126 - if (baseDeviceInfo is AndroidDeviceInfo) {  
127 - os = 'android';  
128 - os_version = baseDeviceInfo.version.release;  
129 - model = baseDeviceInfo.model;  
130 - manufacturer = baseDeviceInfo.manufacturer;  
131 - } else if (baseDeviceInfo is IosDeviceInfo) {  
132 - os = 'ios';  
133 - os_version = baseDeviceInfo.systemVersion;  
134 - model = baseDeviceInfo.model;  
135 - manufacturer = 'apple';  
136 - } else if (baseDeviceInfo is OhosDeviceInfo) {  
137 - os = 'ohos';  
138 - os_version = baseDeviceInfo.versionId ?? "";  
139 - model = baseDeviceInfo.productModel ?? "";  
140 - manufacturer = 'huawei'; 119 + ConnectivityResult connectivityResult =
  120 + await Connectivity().checkConnectivity();
  121 +
  122 + Map<ConnectivityResult, String> map = {
  123 + ConnectivityResult.mobile: 'MOBILE',
  124 + ConnectivityResult.wifi: 'WIFI',
  125 + ConnectivityResult.ethernet: 'ETHERNET',
  126 + ConnectivityResult.vpn: 'VPN',
  127 + ConnectivityResult.other: 'OTHER',
  128 + ConnectivityResult.none: 'NONE',
  129 + };
  130 +
  131 + if (host != null) {
  132 + List<Map> datas = [];
  133 + uploadList.forEach((event) {
  134 + Random random = Random.secure();
  135 + int id = random.nextInt(1 << 32); // 模拟 Java 的 nextInt()
  136 + final t = DateTime.now().millisecondsSinceEpoch;
  137 +
  138 + String os = "";
  139 + String os_version = "";
  140 + String model = "";
  141 + String manufacturer = "";
  142 +
  143 + if (baseDeviceInfo != null) {
  144 + if (baseDeviceInfo is AndroidDeviceInfo) {
  145 + os = 'android';
  146 + os_version = baseDeviceInfo.version.release;
  147 + model = baseDeviceInfo.model;
  148 + manufacturer = baseDeviceInfo.manufacturer;
  149 + } else if (baseDeviceInfo is IosDeviceInfo) {
  150 + os = 'ios';
  151 + os_version = baseDeviceInfo.systemVersion;
  152 + model = baseDeviceInfo.model;
  153 + manufacturer = 'apple';
  154 + } else if (baseDeviceInfo is OhosDeviceInfo) {
  155 + os = 'ohos';
  156 + os_version = baseDeviceInfo.versionId ?? "";
  157 + model = baseDeviceInfo.productModel ?? "";
  158 + manufacturer = 'huawei';
  159 + }
  160 + }
  161 + Size size = const Size(0, 0);
  162 + if (config.buildContext != null) {
  163 + size = Size(
  164 + MediaQuery.of(config.buildContext!).size.width *
  165 + MediaQuery.of(config.buildContext!).devicePixelRatio,
  166 + MediaQuery.of(config.buildContext!).size.width *
  167 + MediaQuery.of(config.buildContext!).devicePixelRatio);
141 } 168 }
142 - }  
143 - final properties = {  
144 - '\$os': os,  
145 - '\$os_version': os_version,  
146 - '\$model': model,  
147 - '\$lib': "Flutter",  
148 - '\$app_name': AutoTrackConfigManager.instance.appName,  
149 - '\$app_version': AutoTrackConfigManager.instance.appVersion,  
150 - '\$device_id': AutoTrackConfigManager.instance.deviceId,  
151 - '\$timezone_offset': getZoneOffset(),  
152 - "\$manufacturer": manufacturer,  
153 - // "$carrier": "NONE",  
154 - // "$os_version": "13",  
155 - // "$model": "C310CS",  
156 - // "$os": "Android",  
157 - // "$screen_width": 1200,  
158 - // "$brand": "BOE",  
159 - // "$screen_height": 1920,  
160 - // "$device_id": "afa4c7a98b3f6467",  
161 - // "$app_name": "Ewin Reading",  
162 - // "$lib_version": "5.3.3",  
163 - // "$timezone_offset": -480,  
164 - // "$app_id": "com.ewin.tech.reading",  
165 - // "$mac": "020000000000",  
166 - // "$manufacturer": "BOE",  
167 - // "$sn": "C310CS014820000006",  
168 - // "$wifi": true,  
169 - // "$network_type": "WIFI",  
170 - // "$screen_orientation": "portrait",  
171 - // "$screen_brightness": 204,  
172 - // "$event_duration": 0,  
173 - // "$lib_method": "autoTrack",  
174 - // "$is_first_day": true  
175 - };  
176 -  
177 - event.params.forEach((k, v) {  
178 - properties[k] = v;  
179 - });  
180 169
181 - datas.add({  
182 - '_track_id': id,  
183 - 'time': t,  
184 - 'type': 'track',  
185 - 'distinct_id':  
186 - config.userId ?? AutoTrackConfigManager.instance.deviceId,  
187 - 'anonymous_id': AutoTrackConfigManager.instance.deviceId,  
188 - 'event': event.type,  
189 - 'properties': properties 170 + final properties = {
  171 + '\$os': os,
  172 + '\$os_version': os_version,
  173 + '\$model': model,
  174 + '\$lib': "Flutter",
  175 + '\$app_name': AutoTrackConfigManager.instance.appName,
  176 + '\$app_version': AutoTrackConfigManager.instance.appVersion,
  177 + '\$device_id': AutoTrackConfigManager.instance.deviceId,
  178 + '\$timezone_offset': getZoneOffset(),
  179 + "\$manufacturer": manufacturer,
  180 + "\$screen_width": size.width,
  181 + "\$screen_height": size.height,
  182 + "\$app_id": AutoTrackConfigManager.instance.pkgName,
  183 + "\$lib_version": "6.0.0",
  184 + "\$network_type": map[connectivityResult],
  185 + "\$wifi": connectivityResult == ConnectivityResult.wifi,
  186 +
  187 + // "$carrier": "NONE",
  188 + // "$os_version": "13",
  189 + // "$model": "C310CS",
  190 + // "$brand": "BOE",
  191 + // "$mac": "020000000000",
  192 + // "$sn": "C310CS014820000006",
  193 + // "$screen_orientation": "portrait",
  194 + // "$screen_brightness": 204,
  195 + // "$event_duration": 0,
  196 + // "$lib_method": "autoTrack",
  197 + // "$is_first_day": true
  198 + };
  199 +
  200 + event.params.forEach((k, v) {
  201 + properties[k] = v;
  202 + });
  203 +
  204 + datas.add({
  205 + '_track_id': id,
  206 + 'time': t,
  207 + 'type': 'track',
  208 + 'distinct_id':
  209 + config.userId ?? AutoTrackConfigManager.instance.deviceId,
  210 + 'anonymous_id': AutoTrackConfigManager.instance.deviceId,
  211 + 'event': event.type,
  212 + 'properties': properties
  213 + });
  214 +
  215 + AutoTrackLogger.getInstance().debug('upload => data => $datas');
190 }); 216 });
191 217
192 - AutoTrackLogger.getInstance().debug('upload => data => $datas');  
193 - });  
194 -  
195 - try {  
196 - final httpClient = HttpClient();  
197 - final request = await httpClient.postUrl(Uri.parse(host + UPLOAD)); 218 + try {
  219 + final httpClient = HttpClient();
  220 + final request = await httpClient.postUrl(Uri.parse(host + UPLOAD));
198 221
199 - request.headers.set(HttpHeaders.contentTypeHeader, "application/json");  
200 - request.headers.set("token", token); // 设置 header 222 + request.headers
  223 + .set(HttpHeaders.contentTypeHeader, "application/json");
  224 + request.headers.set("token", token); // 设置 header
201 225
202 - // 对数据进行压缩并进行 Base64 编码  
203 - final compressedData = encodeData(jsonEncode(datas));  
204 - final jsonPayload = jsonEncode({"base64Str": compressedData}); 226 + // 对数据进行压缩并进行 Base64 编码
  227 + final compressedData = encodeData(jsonEncode(datas));
  228 + final jsonPayload = jsonEncode({"base64Str": compressedData});
205 229
206 - AutoTrackLogger.getInstance().debug("压缩数据:$jsonPayload"); 230 + AutoTrackLogger.getInstance().debug("压缩数据:$jsonPayload");
207 231
208 - request.write(jsonPayload);  
209 - final response = await request.close(); 232 + request.write(jsonPayload);
  233 + final response = await request.close();
210 234
211 - final responseCode = response.statusCode;  
212 - AutoTrackLogger.getInstance().debug("responseCode: $responseCode"); 235 + final responseCode = response.statusCode;
  236 + AutoTrackLogger.getInstance().debug("responseCode: $responseCode");
213 237
214 - final responseBody = await response.transform(utf8.decoder).join(); 238 + final responseBody = await response.transform(utf8.decoder).join();
215 239
216 - if (responseCode >= HttpStatus.ok &&  
217 - responseCode < HttpStatus.multipleChoices) {  
218 - // 状态码 200 - 300 认为是成功 240 + if (responseCode >= HttpStatus.ok &&
  241 + responseCode < HttpStatus.multipleChoices) {
  242 + // 状态码 200 - 300 认为是成功
219 243
220 - AutoTrackLogger.getInstance().debug(  
221 - 'upload => success ret_code: $responseCode ret_content: $responseBody'); 244 + AutoTrackLogger.getInstance().debug(
  245 + 'upload => success ret_code: $responseCode ret_content: $responseBody');
222 246
223 - try {  
224 - final jsonResponse = jsonDecode(responseBody);  
225 - if (jsonResponse["code"] == 4005) {  
226 - AutoTrackConfigManager.instance.getToken(true);  
227 - } else {  
228 - //批量删除  
229 - for (var event in events) {  
230 - await database  
231 - .delete("track", where: "id = ?", whereArgs: [event['id']]); 247 + try {
  248 + final jsonResponse = jsonDecode(responseBody);
  249 + if (jsonResponse["code"] == 4005) {
  250 + AutoTrackConfigManager.instance.getToken(true);
  251 + } else {
  252 + //批量删除
  253 + for (var event in events) {
  254 + await database.delete("track",
  255 + where: "id = ?", whereArgs: [event['id']]);
  256 + }
232 } 257 }
  258 + } catch (e) {
  259 + AutoTrackLogger.getInstance().debug("JSON 解析错误: $e");
233 } 260 }
234 - } catch (e) {  
235 - AutoTrackLogger.getInstance().debug("JSON 解析错误: $e");  
236 - 261 + } else {
  262 + AutoTrackLogger.getInstance().debug(
  263 + 'upload => fail ret_code: $responseCode ret_content: $responseBody');
237 } 264 }
238 - } else {  
239 - AutoTrackLogger.getInstance().debug(  
240 - 'upload => fail ret_code: $responseCode ret_content: $responseBody'); 265 + } catch (e) {
  266 + AutoTrackLogger.getInstance().debug("网络请求错误: $e");
241 } 267 }
242 - } catch (e) {  
243 - AutoTrackLogger.getInstance().debug("网络请求错误: $e");  
244 } 268 }
  269 + } catch (e) {
  270 + AutoTrackLogger.getInstance().debug("上报出错");
245 } 271 }
246 } 272 }
247 273
@@ -26,7 +26,10 @@ dependencies: @@ -26,7 +26,10 @@ dependencies:
26 uuid: ^4.3.3 26 uuid: ^4.3.3
27 archive: ^3.3.7 # 确保使用最新版本 27 archive: ^3.3.7 # 确保使用最新版本
28 sqflite: ^2.3.0 28 sqflite: ^2.3.0
29 - 29 + connectivity_plus:
  30 + git:
  31 + url: https://gitee.com/openharmony-sig/flutter_plus_plugins
  32 + path: packages/connectivity_plus/connectivity_plus
30 33
31 34
32 35