顾海波

【需求】针对大数据平台兼容,todo保存数据库恢复

@@ -173,3 +173,44 @@ class PageA extends StatelessWidget { @@ -173,3 +173,44 @@ class PageA extends StatelessWidget {
173 } 173 }
174 174
175 ``` 175 ```
  176 +
  177 +
  178 +```
  179 +{
  180 + "_track_id": 2102988140,
  181 + "time": 1738981685455,
  182 + "type": "track",
  183 + "distinct_id": "afa4c7a98b3f6467",
  184 + "anonymous_id": "afa4c7a98b3f6467",
  185 + "event": "$AppEnd",
  186 + "properties": {
  187 + "$carrier": "NONE",
  188 + "$os_version": "13",
  189 + "$model": "C310CS",
  190 + "$os": "Android",
  191 + "$screen_width": 1200,
  192 + "$brand": "BOE",
  193 + "$screen_height": 1920,
  194 + "$app_version": "2.0.2",
  195 + "$lib": "Android",
  196 + "$device_id": "afa4c7a98b3f6467",
  197 + "$app_name": "Ewin Reading",
  198 + "$lib_version": "5.3.3",
  199 + "$timezone_offset": -480,
  200 + "$app_id": "com.ewin.tech.reading",
  201 + "$mac": "020000000000",
  202 + "$manufacturer": "BOE",
  203 + "$sn": "C310CS014820000006",
  204 + "$wifi": true,
  205 + "$network_type": "WIFI",
  206 + "$screen_orientation": "portrait",
  207 + "$screen_brightness": 204,
  208 + "$screen_name": "com.boe.usercenterlibrary.LoginActivity",
  209 + "$title": "Ewin Reading",
  210 + "$event_duration": 0,
  211 + "$lib_method": "autoTrack",
  212 + "$is_first_day": true
  213 + }
  214 +}
  215 +
  216 +```
1 buildscript { 1 buildscript {
2 ext.kotlin_version = '1.7.10' 2 ext.kotlin_version = '1.7.10'
3 repositories { 3 repositories {
  4 +
  5 + maven { url 'https://maven.aliyun.com/repository/google/' }
  6 + maven { url 'https://maven.aliyun.com/repository/public' }
  7 + maven { url 'https://maven.aliyun.com/repository/central' }
4 google() 8 google()
5 mavenCentral() 9 mavenCentral()
6 } 10 }
@@ -12,6 +16,9 @@ buildscript { @@ -12,6 +16,9 @@ buildscript {
12 16
13 allprojects { 17 allprojects {
14 repositories { 18 repositories {
  19 + maven { url 'https://maven.aliyun.com/repository/google/' }
  20 + maven { url 'https://maven.aliyun.com/repository/public' }
  21 + maven { url 'https://maven.aliyun.com/repository/central' }
15 google() 22 google()
16 mavenCentral() 23 mavenCentral()
17 } 24 }
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
2 distributionPath=wrapper/dists 2 distributionPath=wrapper/dists
3 zipStoreBase=GRADLE_USER_HOME 3 zipStoreBase=GRADLE_USER_HOME
4 zipStorePath=wrapper/dists 4 zipStorePath=wrapper/dists
5 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 5 +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-all.zip
@@ -19,20 +19,29 @@ class _MyAppState extends State<MyApp> { @@ -19,20 +19,29 @@ class _MyAppState extends State<MyApp> {
19 void initState() { 19 void initState() {
20 AutoTrack() 20 AutoTrack()
21 .config(AutoTrackConfig( 21 .config(AutoTrackConfig(
22 - samplingRate: 0.9, // 采样率 22 + host: "https://sitigrs.boeart.cn",
  23 + appKey: "KEY_oVfNOQLQ",
  24 + appSecret: "w21tRLJt7LBVYJtD",
  25 + samplingRate: 1, // 采样率
  26 + enableUpload : true,
  27 + uploadInterval:5,
23 eventHandler: (model) => {print('event handler ${model.type}')}, 28 eventHandler: (model) => {print('event handler ${model.type}')},
24 pageConfigs: [ 29 pageConfigs: [
  30 + AutoTrackPageConfig<Home>(
  31 + pageID: 'home',
  32 + ),
25 AutoTrackPageConfig<PageA>( 33 AutoTrackPageConfig<PageA>(
26 pageID: 'page_a', 34 pageID: 'page_a',
27 ), 35 ),
28 ])) 36 ]))
  37 + // .enablePageLeave()
  38 + // .enablePageView()
  39 + // .enableClick()
  40 + // .enableDrag()
  41 + // .enableIgnoreNullKey()
  42 + .enableLog()
29 .enable() 43 .enable()
30 - .enablePageLeave()  
31 - .enablePageView()  
32 - .enableClick()  
33 - .enableDrag()  
34 - .enableIgnoreNullKey()  
35 - .enableLog(); 44 + ;
36 super.initState(); 45 super.initState();
37 46
38 // AutoTrack().updateSampleRate(0.5); 更新采样率 47 // AutoTrack().updateSampleRate(0.5); 更新采样率
1 # Generated by pub 1 # Generated by pub
2 # See https://dart.dev/tools/pub/glossary#lockfile 2 # See https://dart.dev/tools/pub/glossary#lockfile
3 packages: 3 packages:
  4 + android_id:
  5 + dependency: transitive
  6 + description:
  7 + name: android_id
  8 + sha256: "748ba5f93dd5c497e675d8eaa1404346ce4d1794464ea654576ff192d153b92a"
  9 + url: "https://pub.flutter-io.cn"
  10 + source: hosted
  11 + version: "0.4.0"
  12 + archive:
  13 + dependency: transitive
  14 + description:
  15 + name: archive
  16 + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
  17 + url: "https://pub.flutter-io.cn"
  18 + source: hosted
  19 + version: "3.6.1"
4 async: 20 async:
5 dependency: transitive 21 dependency: transitive
6 description: 22 description:
7 name: async 23 name: async
8 sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 24 sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
9 - url: "https://pub.dev" 25 + url: "https://pub.flutter-io.cn"
10 source: hosted 26 source: hosted
11 version: "2.11.0" 27 version: "2.11.0"
12 auto_track: 28 auto_track:
@@ -15,13 +31,13 @@ packages: @@ -15,13 +31,13 @@ packages:
15 path: ".." 31 path: ".."
16 relative: true 32 relative: true
17 source: path 33 source: path
18 - version: "0.0.1" 34 + version: "0.1.0"
19 boolean_selector: 35 boolean_selector:
20 dependency: transitive 36 dependency: transitive
21 description: 37 description:
22 name: boolean_selector 38 name: boolean_selector
23 sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 39 sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
24 - url: "https://pub.dev" 40 + url: "https://pub.flutter-io.cn"
25 source: hosted 41 source: hosted
26 version: "2.1.1" 42 version: "2.1.1"
27 characters: 43 characters:
@@ -29,7 +45,7 @@ packages: @@ -29,7 +45,7 @@ packages:
29 description: 45 description:
30 name: characters 46 name: characters
31 sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 47 sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
32 - url: "https://pub.dev" 48 + url: "https://pub.flutter-io.cn"
33 source: hosted 49 source: hosted
34 version: "1.3.0" 50 version: "1.3.0"
35 clock: 51 clock:
@@ -37,7 +53,7 @@ packages: @@ -37,7 +53,7 @@ packages:
37 description: 53 description:
38 name: clock 54 name: clock
39 sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 55 sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
40 - url: "https://pub.dev" 56 + url: "https://pub.flutter-io.cn"
41 source: hosted 57 source: hosted
42 version: "1.1.1" 58 version: "1.1.1"
43 collection: 59 collection:
@@ -45,57 +61,74 @@ packages: @@ -45,57 +61,74 @@ packages:
45 description: 61 description:
46 name: collection 62 name: collection
47 sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 63 sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
48 - url: "https://pub.dev" 64 + url: "https://pub.flutter-io.cn"
49 source: hosted 65 source: hosted
50 version: "1.18.0" 66 version: "1.18.0"
51 crypto: 67 crypto:
52 dependency: transitive 68 dependency: transitive
53 description: 69 description:
54 name: crypto 70 name: crypto
55 - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab  
56 - url: "https://pub.dev" 71 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
  72 + url: "https://pub.flutter-io.cn"
57 source: hosted 73 source: hosted
58 - version: "3.0.3" 74 + version: "3.0.6"
59 cupertino_icons: 75 cupertino_icons:
60 dependency: "direct main" 76 dependency: "direct main"
61 description: 77 description:
62 name: cupertino_icons 78 name: cupertino_icons
63 - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d  
64 - url: "https://pub.dev" 79 + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
  80 + url: "https://pub.flutter-io.cn"
65 source: hosted 81 source: hosted
66 - version: "1.0.6"  
67 - dio: 82 + version: "1.0.8"
  83 + device_info_plus:
  84 + dependency: transitive
  85 + description:
  86 + path: "packages/device_info_plus/device_info_plus"
  87 + ref: HEAD
  88 + resolved-ref: ff774d947bd15d9be08629e3ccfb29dda2e864bd
  89 + url: "https://gitee.com/openharmony-sig/flutter_plus_plugins"
  90 + source: git
  91 + version: "9.1.0"
  92 + device_info_plus_platform_interface:
68 dependency: transitive 93 dependency: transitive
69 description: 94 description:
70 - name: dio  
71 - sha256: "49af28382aefc53562459104f64d16b9dfd1e8ef68c862d5af436cc8356ce5a8"  
72 - url: "https://pub.dev" 95 + name: device_info_plus_platform_interface
  96 + sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
  97 + url: "https://pub.flutter-io.cn"
73 source: hosted 98 source: hosted
74 - version: "5.4.1" 99 + version: "7.0.2"
75 fake_async: 100 fake_async:
76 dependency: transitive 101 dependency: transitive
77 description: 102 description:
78 name: fake_async 103 name: fake_async
79 sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 104 sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
80 - url: "https://pub.dev" 105 + url: "https://pub.flutter-io.cn"
81 source: hosted 106 source: hosted
82 version: "1.3.1" 107 version: "1.3.1"
  108 + ffi:
  109 + dependency: transitive
  110 + description:
  111 + name: ffi
  112 + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
  113 + url: "https://pub.flutter-io.cn"
  114 + source: hosted
  115 + version: "2.1.3"
83 file: 116 file:
84 dependency: transitive 117 dependency: transitive
85 description: 118 description:
86 name: file 119 name: file
87 - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"  
88 - url: "https://pub.dev" 120 + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
  121 + url: "https://pub.flutter-io.cn"
89 source: hosted 122 source: hosted
90 - version: "6.1.4" 123 + version: "7.0.0"
91 fixnum: 124 fixnum:
92 dependency: transitive 125 dependency: transitive
93 description: 126 description:
94 name: fixnum 127 name: fixnum
95 - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"  
96 - url: "https://pub.dev" 128 + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
  129 + url: "https://pub.flutter-io.cn"
97 source: hosted 130 source: hosted
98 - version: "1.1.0" 131 + version: "1.1.1"
99 flutter: 132 flutter:
100 dependency: "direct main" 133 dependency: "direct main"
101 description: flutter 134 description: flutter
@@ -111,7 +144,7 @@ packages: @@ -111,7 +144,7 @@ packages:
111 description: 144 description:
112 name: flutter_lints 145 name: flutter_lints
113 sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 146 sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
114 - url: "https://pub.dev" 147 + url: "https://pub.flutter-io.cn"
115 source: hosted 148 source: hosted
116 version: "2.0.3" 149 version: "2.0.3"
117 flutter_test: 150 flutter_test:
@@ -119,17 +152,30 @@ packages: @@ -119,17 +152,30 @@ packages:
119 description: flutter 152 description: flutter
120 source: sdk 153 source: sdk
121 version: "0.0.0" 154 version: "0.0.0"
  155 + flutter_web_plugins:
  156 + dependency: transitive
  157 + description: flutter
  158 + source: sdk
  159 + version: "0.0.0"
122 fuchsia_remote_debug_protocol: 160 fuchsia_remote_debug_protocol:
123 dependency: transitive 161 dependency: transitive
124 description: flutter 162 description: flutter
125 source: sdk 163 source: sdk
126 version: "0.0.0" 164 version: "0.0.0"
  165 + http:
  166 + dependency: transitive
  167 + description:
  168 + name: http
  169 + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
  170 + url: "https://pub.flutter-io.cn"
  171 + source: hosted
  172 + version: "1.3.0"
127 http_parser: 173 http_parser:
128 dependency: transitive 174 dependency: transitive
129 description: 175 description:
130 name: http_parser 176 name: http_parser
131 sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 177 sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
132 - url: "https://pub.dev" 178 + url: "https://pub.flutter-io.cn"
133 source: hosted 179 source: hosted
134 version: "4.0.2" 180 version: "4.0.2"
135 integration_test: 181 integration_test:
@@ -137,70 +183,111 @@ packages: @@ -137,70 +183,111 @@ packages:
137 description: flutter 183 description: flutter
138 source: sdk 184 source: sdk
139 version: "0.0.0" 185 version: "0.0.0"
  186 + leak_tracker:
  187 + dependency: transitive
  188 + description:
  189 + name: leak_tracker
  190 + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
  191 + url: "https://pub.flutter-io.cn"
  192 + source: hosted
  193 + version: "10.0.4"
  194 + leak_tracker_flutter_testing:
  195 + dependency: transitive
  196 + description:
  197 + name: leak_tracker_flutter_testing
  198 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
  199 + url: "https://pub.flutter-io.cn"
  200 + source: hosted
  201 + version: "3.0.3"
  202 + leak_tracker_testing:
  203 + dependency: transitive
  204 + description:
  205 + name: leak_tracker_testing
  206 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
  207 + url: "https://pub.flutter-io.cn"
  208 + source: hosted
  209 + version: "3.0.1"
140 lints: 210 lints:
141 dependency: transitive 211 dependency: transitive
142 description: 212 description:
143 name: lints 213 name: lints
144 sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 214 sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
145 - url: "https://pub.dev" 215 + url: "https://pub.flutter-io.cn"
146 source: hosted 216 source: hosted
147 version: "2.1.1" 217 version: "2.1.1"
148 matcher: 218 matcher:
149 dependency: transitive 219 dependency: transitive
150 description: 220 description:
151 name: matcher 221 name: matcher
152 - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"  
153 - url: "https://pub.dev" 222 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
  223 + url: "https://pub.flutter-io.cn"
154 source: hosted 224 source: hosted
155 - version: "0.12.16" 225 + version: "0.12.16+1"
156 material_color_utilities: 226 material_color_utilities:
157 dependency: transitive 227 dependency: transitive
158 description: 228 description:
159 name: material_color_utilities 229 name: material_color_utilities
160 - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"  
161 - url: "https://pub.dev" 230 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
  231 + url: "https://pub.flutter-io.cn"
162 source: hosted 232 source: hosted
163 - version: "0.5.0" 233 + version: "0.8.0"
164 meta: 234 meta:
165 dependency: transitive 235 dependency: transitive
166 description: 236 description:
167 name: meta 237 name: meta
168 - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e  
169 - url: "https://pub.dev" 238 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
  239 + url: "https://pub.flutter-io.cn"
170 source: hosted 240 source: hosted
171 - version: "1.10.0" 241 + version: "1.12.0"
  242 + package_info_plus:
  243 + dependency: transitive
  244 + description:
  245 + path: "packages/package_info_plus/package_info_plus"
  246 + ref: HEAD
  247 + resolved-ref: ff774d947bd15d9be08629e3ccfb29dda2e864bd
  248 + url: "https://gitee.com/openharmony-sig/flutter_plus_plugins"
  249 + source: git
  250 + version: "4.2.0"
  251 + package_info_plus_platform_interface:
  252 + dependency: transitive
  253 + description:
  254 + name: package_info_plus_platform_interface
  255 + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
  256 + url: "https://pub.flutter-io.cn"
  257 + source: hosted
  258 + version: "2.0.1"
172 path: 259 path:
173 dependency: transitive 260 dependency: transitive
174 description: 261 description:
175 name: path 262 name: path
176 - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"  
177 - url: "https://pub.dev" 263 + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
  264 + url: "https://pub.flutter-io.cn"
178 source: hosted 265 source: hosted
179 - version: "1.8.3" 266 + version: "1.9.0"
180 platform: 267 platform:
181 dependency: transitive 268 dependency: transitive
182 description: 269 description:
183 name: platform 270 name: platform
184 - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102  
185 - url: "https://pub.dev" 271 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
  272 + url: "https://pub.flutter-io.cn"
186 source: hosted 273 source: hosted
187 - version: "3.1.2" 274 + version: "3.1.4"
188 plugin_platform_interface: 275 plugin_platform_interface:
189 dependency: transitive 276 dependency: transitive
190 description: 277 description:
191 name: plugin_platform_interface 278 name: plugin_platform_interface
192 sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 279 sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
193 - url: "https://pub.dev" 280 + url: "https://pub.flutter-io.cn"
194 source: hosted 281 source: hosted
195 version: "2.1.8" 282 version: "2.1.8"
196 process: 283 process:
197 dependency: transitive 284 dependency: transitive
198 description: 285 description:
199 name: process 286 name: process
200 - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"  
201 - url: "https://pub.dev" 287 + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
  288 + url: "https://pub.flutter-io.cn"
202 source: hosted 289 source: hosted
203 - version: "4.2.4" 290 + version: "5.0.2"
204 sky_engine: 291 sky_engine:
205 dependency: transitive 292 dependency: transitive
206 description: flutter 293 description: flutter
@@ -211,7 +298,7 @@ packages: @@ -211,7 +298,7 @@ packages:
211 description: 298 description:
212 name: source_span 299 name: source_span
213 sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 300 sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
214 - url: "https://pub.dev" 301 + url: "https://pub.flutter-io.cn"
215 source: hosted 302 source: hosted
216 version: "1.10.0" 303 version: "1.10.0"
217 sprintf: 304 sprintf:
@@ -219,7 +306,7 @@ packages: @@ -219,7 +306,7 @@ packages:
219 description: 306 description:
220 name: sprintf 307 name: sprintf
221 sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" 308 sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
222 - url: "https://pub.dev" 309 + url: "https://pub.flutter-io.cn"
223 source: hosted 310 source: hosted
224 version: "7.0.0" 311 version: "7.0.0"
225 stack_trace: 312 stack_trace:
@@ -227,7 +314,7 @@ packages: @@ -227,7 +314,7 @@ packages:
227 description: 314 description:
228 name: stack_trace 315 name: stack_trace
229 sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 316 sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
230 - url: "https://pub.dev" 317 + url: "https://pub.flutter-io.cn"
231 source: hosted 318 source: hosted
232 version: "1.11.1" 319 version: "1.11.1"
233 stream_channel: 320 stream_channel:
@@ -235,7 +322,7 @@ packages: @@ -235,7 +322,7 @@ packages:
235 description: 322 description:
236 name: stream_channel 323 name: stream_channel
237 sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 324 sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
238 - url: "https://pub.dev" 325 + url: "https://pub.flutter-io.cn"
239 source: hosted 326 source: hosted
240 version: "2.1.2" 327 version: "2.1.2"
241 string_scanner: 328 string_scanner:
@@ -243,7 +330,7 @@ packages: @@ -243,7 +330,7 @@ packages:
243 description: 330 description:
244 name: string_scanner 331 name: string_scanner
245 sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 332 sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
246 - url: "https://pub.dev" 333 + url: "https://pub.flutter-io.cn"
247 source: hosted 334 source: hosted
248 version: "1.2.0" 335 version: "1.2.0"
249 sync_http: 336 sync_http:
@@ -251,7 +338,7 @@ packages: @@ -251,7 +338,7 @@ packages:
251 description: 338 description:
252 name: sync_http 339 name: sync_http
253 sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" 340 sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
254 - url: "https://pub.dev" 341 + url: "https://pub.flutter-io.cn"
255 source: hosted 342 source: hosted
256 version: "0.3.1" 343 version: "0.3.1"
257 term_glyph: 344 term_glyph:
@@ -259,65 +346,81 @@ packages: @@ -259,65 +346,81 @@ packages:
259 description: 346 description:
260 name: term_glyph 347 name: term_glyph
261 sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 348 sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
262 - url: "https://pub.dev" 349 + url: "https://pub.flutter-io.cn"
263 source: hosted 350 source: hosted
264 version: "1.2.1" 351 version: "1.2.1"
265 test_api: 352 test_api:
266 dependency: transitive 353 dependency: transitive
267 description: 354 description:
268 name: test_api 355 name: test_api
269 - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"  
270 - url: "https://pub.dev" 356 + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
  357 + url: "https://pub.flutter-io.cn"
271 source: hosted 358 source: hosted
272 - version: "0.6.1" 359 + version: "0.7.0"
273 typed_data: 360 typed_data:
274 dependency: transitive 361 dependency: transitive
275 description: 362 description:
276 name: typed_data 363 name: typed_data
277 sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 364 sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
278 - url: "https://pub.dev" 365 + url: "https://pub.flutter-io.cn"
279 source: hosted 366 source: hosted
280 version: "1.3.2" 367 version: "1.3.2"
281 uuid: 368 uuid:
282 dependency: transitive 369 dependency: transitive
283 description: 370 description:
284 name: uuid 371 name: uuid
285 - sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8  
286 - url: "https://pub.dev" 372 + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
  373 + url: "https://pub.flutter-io.cn"
287 source: hosted 374 source: hosted
288 - version: "4.3.3" 375 + version: "4.5.1"
289 vector_math: 376 vector_math:
290 dependency: transitive 377 dependency: transitive
291 description: 378 description:
292 name: vector_math 379 name: vector_math
293 sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 380 sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
294 - url: "https://pub.dev" 381 + url: "https://pub.flutter-io.cn"
295 source: hosted 382 source: hosted
296 version: "2.1.4" 383 version: "2.1.4"
297 vm_service: 384 vm_service:
298 dependency: transitive 385 dependency: transitive
299 description: 386 description:
300 name: vm_service 387 name: vm_service
301 - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583  
302 - url: "https://pub.dev" 388 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
  389 + url: "https://pub.flutter-io.cn"
303 source: hosted 390 source: hosted
304 - version: "11.10.0" 391 + version: "14.2.1"
305 web: 392 web:
306 dependency: transitive 393 dependency: transitive
307 description: 394 description:
308 name: web 395 name: web
309 - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152  
310 - url: "https://pub.dev" 396 + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
  397 + url: "https://pub.flutter-io.cn"
311 source: hosted 398 source: hosted
312 - version: "0.3.0" 399 + version: "1.1.0"
313 webdriver: 400 webdriver:
314 dependency: transitive 401 dependency: transitive
315 description: 402 description:
316 name: webdriver 403 name: webdriver
317 - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49"  
318 - url: "https://pub.dev" 404 + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
  405 + url: "https://pub.flutter-io.cn"
  406 + source: hosted
  407 + version: "3.0.3"
  408 + win32:
  409 + dependency: transitive
  410 + description:
  411 + name: win32
  412 + sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
  413 + url: "https://pub.flutter-io.cn"
  414 + source: hosted
  415 + version: "5.5.4"
  416 + win32_registry:
  417 + dependency: transitive
  418 + description:
  419 + name: win32_registry
  420 + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
  421 + url: "https://pub.flutter-io.cn"
319 source: hosted 422 source: hosted
320 - version: "3.0.2" 423 + version: "1.1.5"
321 sdks: 424 sdks:
322 - dart: ">=3.2.3 <4.0.0"  
323 - flutter: ">=3.3.0" 425 + dart: ">=3.4.0 <4.0.0"
  426 + flutter: ">=3.18.0-18.0.pre.54"
@@ -24,9 +24,9 @@ class AutoTrackConfig { @@ -24,9 +24,9 @@ class AutoTrackConfig {
24 this.useCustomRoute = false, // 使用自定义路由 24 this.useCustomRoute = false, // 使用自定义路由
25 this.ignoreElementKeys = const [], // 忽略key列表 25 this.ignoreElementKeys = const [], // 忽略key列表
26 this.ignoreElementStringKeys = const [], 26 this.ignoreElementStringKeys = const [],
27 - this.enablePageView = true, // 监听页面进入事件 27 + this.enablePageView = false, // 监听页面进入事件
28 this.enablePageLeave = false, // 监听页面离开事件 28 this.enablePageLeave = false, // 监听页面离开事件
29 - this.enableClick = true, // 监听点击事件 29 + this.enableClick = false, // 监听点击事件
30 this.enableDrag = false, // 监听拖拽事件 30 this.enableDrag = false, // 监听拖拽事件
31 this.enableIgnoreNullKey = false, // 忽略空key事件 31 this.enableIgnoreNullKey = false, // 忽略空key事件
32 this.httpRequestConfig, 32 this.httpRequestConfig,
@@ -43,6 +43,7 @@ class AutoTrackConfig { @@ -43,6 +43,7 @@ class AutoTrackConfig {
43 String? trackId; 43 String? trackId;
44 String? userId; 44 String? userId;
45 String? uniqueId; 45 String? uniqueId;
  46 + String? token;
46 47
47 /// 采样率,默认 1 (100%) 48 /// 采样率,默认 1 (100%)
48 double samplingRate; 49 double samplingRate;
@@ -6,16 +6,25 @@ import 'package:crypto/crypto.dart'; @@ -6,16 +6,25 @@ import 'package:crypto/crypto.dart';
6 import 'package:device_info_plus/device_info_plus.dart'; 6 import 'package:device_info_plus/device_info_plus.dart';
7 import 'package:flutter/widgets.dart'; 7 import 'package:flutter/widgets.dart';
8 import 'package:package_info_plus/package_info_plus.dart'; 8 import 'package:package_info_plus/package_info_plus.dart';
  9 +import 'package:http/http.dart' as http; // 使用 http 包
9 10
  11 +import '../log/logger.dart';
  12 +import '../utils/sign.dart';
10 import 'config.dart'; 13 import 'config.dart';
11 14
12 typedef UpdateConfigFunc = AutoTrackConfig Function(AutoTrackConfig); 15 typedef UpdateConfigFunc = AutoTrackConfig Function(AutoTrackConfig);
13 16
  17 +const String GET_TOKEN = "/equipment-auth/equipment/getToken/v1";
  18 +const String UPLOAD = "/bd-datapoint/equipment/dataPoint/zip";
  19 +
14 class AutoTrackConfigManager { 20 class AutoTrackConfigManager {
15 static final AutoTrackConfigManager instance = AutoTrackConfigManager._(); 21 static final AutoTrackConfigManager instance = AutoTrackConfigManager._();
16 22
17 AutoTrackConfigManager._() { 23 AutoTrackConfigManager._() {
18 - PackageInfo.fromPlatform().then((value) => _appVersion = value.version); 24 + PackageInfo.fromPlatform().then( (value) {
  25 + _appVersion = value.version;
  26 + _appName = value.appName;
  27 + });
19 DeviceInfoPlugin().deviceInfo.then((value) { 28 DeviceInfoPlugin().deviceInfo.then((value) {
20 _deviceInfo = value.data; 29 _deviceInfo = value.data;
21 _baseDeviceInfo = value; 30 _baseDeviceInfo = value;
@@ -26,7 +35,14 @@ class AutoTrackConfigManager { @@ -26,7 +35,14 @@ class AutoTrackConfigManager {
26 String _appVersion = ''; 35 String _appVersion = '';
27 String get appVersion => _appVersion; 36 String get appVersion => _appVersion;
28 37
  38 + String _appName = '';
  39 + String get appName => _appName;
  40 +
  41 +
29 BaseDeviceInfo? _baseDeviceInfo; 42 BaseDeviceInfo? _baseDeviceInfo;
  43 + BaseDeviceInfo? get baseDeviceInfo => _baseDeviceInfo;
  44 +
  45 +
30 String? _deviceId; 46 String? _deviceId;
31 String? get deviceId => _deviceId; 47 String? get deviceId => _deviceId;
32 48
@@ -67,6 +83,9 @@ class AutoTrackConfigManager { @@ -67,6 +83,9 @@ class AutoTrackConfigManager {
67 } else if (_baseDeviceInfo is MacOsDeviceInfo) { 83 } else if (_baseDeviceInfo is MacOsDeviceInfo) {
68 _deviceId = 84 _deviceId =
69 '${(_baseDeviceInfo as MacOsDeviceInfo).hostName}-${(_baseDeviceInfo as MacOsDeviceInfo).computerName}'; 85 '${(_baseDeviceInfo as MacOsDeviceInfo).hostName}-${(_baseDeviceInfo as MacOsDeviceInfo).computerName}';
  86 + } else if (_baseDeviceInfo is OhosDeviceInfo) {
  87 + _deviceId =
  88 + '${(_baseDeviceInfo as OhosDeviceInfo).odID}${config.appKey}';
70 } else { 89 } else {
71 _deviceId = null; 90 _deviceId = null;
72 } 91 }
@@ -74,8 +93,72 @@ class AutoTrackConfigManager { @@ -74,8 +93,72 @@ class AutoTrackConfigManager {
74 93
75 void enableAutoTrack(bool enable) { 94 void enableAutoTrack(bool enable) {
76 _autoTrackEnable = enable; 95 _autoTrackEnable = enable;
  96 + //获取token
  97 + getToken(false);
  98 + }
  99 +
  100 + bool _isGetting = false;
  101 +
  102 + void getToken(bool refreshToken) async {
  103 + if (_isGetting) {
  104 + return;
  105 + }
  106 + _isGetting = true;
  107 + AutoTrackLogger.getInstance().debug('track getToken => start');
  108 +
  109 + await Future.delayed(const Duration(milliseconds: 2000));
  110 + try {
  111 + int currentSeconds = DateTime.now().millisecondsSinceEpoch;
  112 +
  113 + Map<String, String> sParams = {
  114 + "productKey": _config.appKey ?? '',
  115 + "equipmentId": _deviceId ?? '',
  116 + "otherInfo": _appName,
  117 + "time": currentSeconds.toString(),
  118 + };
  119 +
  120 + AutoTrackLogger.getInstance().debug('track getToken => param $sParams');
  121 +
  122 + String sign = SignUtil.sign(sParams, _config.appSecret!);
  123 + sParams["sign"] = sign;
  124 +
  125 + // 发送 POST 请求(使用 http 包)
  126 + final response = await http
  127 + .post(
  128 + Uri.parse(_config.host! + GET_TOKEN),
  129 + body: sParams,
  130 + )
  131 + .timeout(const Duration(seconds: 10)); // 添加超时
  132 +
  133 + // 处理响应
  134 + if (response.statusCode == 200) {
  135 + final jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
  136 + final code = jsonResponse['code'] as int;
  137 + if (code == 200) {
  138 + final tokenValue = jsonResponse['data'] as String;
  139 + AutoTrackLogger.getInstance().debug('track getToken => success $tokenValue');
  140 + _config.token = tokenValue;
  141 + } else {
  142 + AutoTrackLogger.getInstance().debug('track getToken => fail $code');
  143 + _reGetToken(refreshToken); // 重试
  144 + }
  145 + } else {
  146 + AutoTrackLogger.getInstance().debug('track getToken => failCode: ${response.statusCode}');
  147 + _reGetToken(refreshToken); // 非 200 状态码重试
  148 + }
  149 + } catch (e) {
  150 + print('BoeDataAPI Error: $e');
  151 + _reGetToken(refreshToken); // 异常重试
  152 + } finally {
  153 + _isGetting = false; // 无论成功与否,重置标志
  154 + }
77 } 155 }
78 156
  157 + void _reGetToken(bool refreshToken) {
  158 + Future.delayed(const Duration(seconds: 2), () => getToken(refreshToken));
  159 + }
  160 +
  161 +
79 List<AutoTrackPageConfig> get pageConfigs => _config.pageConfigs; 162 List<AutoTrackPageConfig> get pageConfigs => _config.pageConfigs;
80 163
81 bool get useCustomRoute => _config.useCustomRoute; 164 bool get useCustomRoute => _config.useCustomRoute;
@@ -119,3 +202,4 @@ class AutoTrackConfigManager { @@ -119,3 +202,4 @@ class AutoTrackConfigManager {
119 202
120 bool get ignoreNullKeyEnable => _config.enableIgnoreNullKey; 203 bool get ignoreNullKeyEnable => _config.enableIgnoreNullKey;
121 } 204 }
  205 +
@@ -5,6 +5,8 @@ import 'dart:math'; @@ -5,6 +5,8 @@ import 'dart:math';
5 5
6 import 'package:auto_track/auto_track/config/manager.dart'; 6 import 'package:auto_track/auto_track/config/manager.dart';
7 import 'package:auto_track/auto_track/utils/track_model.dart'; 7 import 'package:auto_track/auto_track/utils/track_model.dart';
  8 +import 'package:archive/archive.dart';
  9 +import 'package:device_info_plus/device_info_plus.dart';
8 10
9 import '../log/logger.dart'; 11 import '../log/logger.dart';
10 12
@@ -39,11 +41,17 @@ class AutoTrackQueue { @@ -39,11 +41,17 @@ class AutoTrackQueue {
39 _timer = null; 41 _timer = null;
40 } 42 }
41 43
  44 + /**
  45 + * todo 存储数据库,目前会丢失数据
  46 + */
42 void flush() { 47 void flush() {
  48 + AutoTrackLogger.getInstance().debug('start flush ${_queue.length}');
  49 +
43 if (_queue.isEmpty) return; 50 if (_queue.isEmpty) return;
44 - final uploadList = List.from(_queue); 51 + final List<TrackModel> uploadList = List.from(_queue);
45 _queue.clear(); 52 _queue.clear();
46 final config = AutoTrackConfigManager.instance.config; 53 final config = AutoTrackConfigManager.instance.config;
  54 + final baseDeviceInfo = AutoTrackConfigManager.instance.baseDeviceInfo;
47 final host = config.host; 55 final host = config.host;
48 if (config.samplingRate != 1) { 56 if (config.samplingRate != 1) {
49 if (Random().nextDouble() > config.samplingRate) { 57 if (Random().nextDouble() > config.samplingRate) {
@@ -51,31 +59,156 @@ class AutoTrackQueue { @@ -51,31 +59,156 @@ class AutoTrackQueue {
51 return; 59 return;
52 } 60 }
53 } 61 }
  62 + String? token = config.token;
  63 + if (token == null) {
  64 + return;
  65 + }
54 if (host != null) { 66 if (host != null) {
55 - final t = DateTime.now().millisecondsSinceEpoch;  
56 -  
57 - httpClient.postUrl(Uri.parse(host)).then((request) {  
58 - request.headers.contentType = ContentType.json;  
59 - request.write(json.encode({  
60 - 'app_key': config.appKey ?? '',  
61 - 'signature': config.signature!(t),  
62 - 't': t,  
63 - 'user_id': config.userId ?? '',  
64 - 'track_id': config.trackId ?? '',  
65 - 'unique_id':  
66 - config.uniqueId ?? AutoTrackConfigManager.instance.deviceId,  
67 - 'device_id': AutoTrackConfigManager.instance.deviceId,  
68 - 'data_list': uploadList.map((e) => e.toMap()).toList(),  
69 - 'app_version': AutoTrackConfigManager.instance.appVersion,  
70 - 'device_info': AutoTrackConfigManager.instance.deviceInfo  
71 - })); 67 +
  68 + List<Map> datas = [];
  69 + uploadList.forEach((event) {
  70 + Random random = Random.secure();
  71 + int id = random.nextInt(1 << 32); // 模拟 Java 的 nextInt()
  72 + final t = DateTime.now().millisecondsSinceEpoch;
  73 +
  74 +
  75 + String os = "";
  76 + String os_version = "";
  77 + String model = "";
  78 + String manufacturer = "";
  79 +
  80 + if (baseDeviceInfo != null) {
  81 + if (baseDeviceInfo is AndroidDeviceInfo) {
  82 + os = 'android';
  83 + os_version = baseDeviceInfo.version.release;
  84 + model = baseDeviceInfo.model;
  85 + manufacturer = baseDeviceInfo.manufacturer;
  86 + } else if (baseDeviceInfo is IosDeviceInfo) {
  87 + os = 'ios';
  88 + os_version = baseDeviceInfo.systemVersion;
  89 + model = baseDeviceInfo.model;
  90 + manufacturer = 'apple';
  91 + } else if (baseDeviceInfo is OhosDeviceInfo) {
  92 + os = 'ohos';
  93 + os_version = baseDeviceInfo.versionId??"";
  94 + model = baseDeviceInfo.productModel??"";
  95 + manufacturer = 'huawei';
  96 + }
  97 + }
  98 + final properties = {
  99 + '\$os': os,
  100 + '\$os_version': os_version,
  101 + '\$model': model,
  102 + '\$lib': "Flutter",
  103 + '\$app_name': AutoTrackConfigManager.instance.appName,
  104 + '\$app_version': AutoTrackConfigManager.instance.appVersion,
  105 + '\$device_id': AutoTrackConfigManager.instance.deviceId,
  106 + '\$timezone_offset': getZoneOffset(),
  107 + "\$manufacturer": manufacturer,
  108 + // "$carrier": "NONE",
  109 + // "$os_version": "13",
  110 + // "$model": "C310CS",
  111 + // "$os": "Android",
  112 + // "$screen_width": 1200,
  113 + // "$brand": "BOE",
  114 + // "$screen_height": 1920,
  115 + // "$device_id": "afa4c7a98b3f6467",
  116 + // "$app_name": "Ewin Reading",
  117 + // "$lib_version": "5.3.3",
  118 + // "$timezone_offset": -480,
  119 + // "$app_id": "com.ewin.tech.reading",
  120 + // "$mac": "020000000000",
  121 + // "$manufacturer": "BOE",
  122 + // "$sn": "C310CS014820000006",
  123 + // "$wifi": true,
  124 + // "$network_type": "WIFI",
  125 + // "$screen_orientation": "portrait",
  126 + // "$screen_brightness": 204,
  127 + // "$event_duration": 0,
  128 + // "$lib_method": "autoTrack",
  129 + // "$is_first_day": true
  130 + };
  131 +
  132 + event.params.forEach((k,v){
  133 + properties[k] = v;
  134 + });
  135 +
  136 +
  137 + datas.add({
  138 + '_track_id': id,
  139 + 'time': t,
  140 + 'type': 'track',
  141 + 'distinct_id':
  142 + config.userId ?? AutoTrackConfigManager.instance.deviceId,
  143 + 'anonymous_id': AutoTrackConfigManager.instance.deviceId,
  144 + 'event':event.type,
  145 + 'properties':properties
  146 + });
  147 +
  148 + AutoTrackLogger.getInstance().debug('upload => data => $datas');
  149 +
  150 + });
  151 +
  152 +
  153 + httpClient
  154 + .postUrl(Uri.parse(host + UPLOAD))
  155 + .then((HttpClientRequest request) {
  156 + request.headers
  157 + .set(HttpHeaders.contentTypeHeader, "application/json");
  158 + request.headers.set("token", token); // 设置 header
  159 +
  160 + // 对数据进行压缩并进行 Base64 编码
  161 + final compressedData = encodeData(jsonEncode(datas));
  162 +
  163 + final jsonPayload = jsonEncode({"base64Str": compressedData});
  164 + print("压缩数据:$jsonPayload");
  165 +
  166 + request.write(jsonPayload);
72 return request.close(); 167 return request.close();
73 - }).then((response) {  
74 - AutoTrackLogger.getInstance()  
75 - .debug('upload status => ${response.statusCode}');  
76 - }).catchError((error) {  
77 - AutoTrackLogger.getInstance().error(error); 168 + }).then((HttpClientResponse response) {
  169 + final responseCode = response.statusCode;
  170 + print("responseCode: $responseCode");
  171 + response.transform(utf8.decoder).join().then((responseBody) {
  172 + if (responseCode >= HttpStatus.ok &&
  173 + responseCode < HttpStatus.multipleChoices) {
  174 + // 状态码 200 - 300 认为是成功
  175 + print("response: $responseBody");
  176 + AutoTrackLogger.getInstance().debug('upload => success ret_code: $responseCode ret_content: $responseBody');
  177 +
  178 + try {
  179 + final jsonResponse = jsonDecode(responseBody);
  180 + if (jsonResponse["code"] == 4005) {
  181 + AutoTrackConfigManager.instance.getToken(true);
  182 + }
  183 + } catch (e) {
  184 + print("JSON 解析错误: $e");
  185 + }
  186 + } else {
  187 + AutoTrackLogger.getInstance().debug('upload => fail ret_code: $responseCode ret_content: $responseBody');
  188 + }
  189 + if (responseCode < HttpStatus.ok ||
  190 + responseCode >= HttpStatus.multipleChoices) {
  191 + AutoTrackLogger.getInstance().debug('upload => fail ret_code: $responseCode ret_content: $responseBody');
  192 + }
  193 + });
78 }); 194 });
79 } 195 }
80 } 196 }
  197 +
  198 + int getZoneOffset() {
  199 + final now = DateTime.now();
  200 + final localOffset = now.timeZoneOffset.inMinutes; // 获取时区偏移量(分钟)
  201 + return -localOffset; // 取反,保持与 Java 代码一致
  202 + }
  203 +
  204 + String encodeData(String rawMessage) {
  205 + try {
  206 + // 使用 GZip 压缩
  207 + List<int> compressed = GZipEncoder().encode(utf8.encode(rawMessage))!;
  208 + // Base64 编码
  209 + return base64.encode(compressed);
  210 + } catch (e) {
  211 + throw FormatException('Invalid data: ${e.toString()}');
  212 + }
  213 + }
81 } 214 }
@@ -185,6 +185,7 @@ class _PageTask { @@ -185,6 +185,7 @@ class _PageTask {
185 if (leavePage != null && !leavePage.pageInfo.ignore) { 185 if (leavePage != null && !leavePage.pageInfo.ignore) {
186 leavePage.pageInfo.timer.end(); 186 leavePage.pageInfo.timer.end();
187 Track.instance.pageLeave(leavePage.pageInfo); 187 Track.instance.pageLeave(leavePage.pageInfo);
  188 + Track.instance.pageDuration(leavePage.pageInfo);
188 } 189 }
189 if (enterPage != null && !enterPage.pageInfo.ignore) { 190 if (enterPage != null && !enterPage.pageInfo.ignore) {
190 enterPage.pageInfo.timer.start(); 191 enterPage.pageInfo.timer.start();
@@ -15,9 +15,9 @@ class Track { @@ -15,9 +15,9 @@ class Track {
15 15
16 Map<String, dynamic> _appendPageInfo(Map<String, dynamic> params, PageInfo pageInfo) { 16 Map<String, dynamic> _appendPageInfo(Map<String, dynamic> params, PageInfo pageInfo) {
17 params['page_key'] = pageInfo.pageKey; 17 params['page_key'] = pageInfo.pageKey;
18 - params['page_title'] = pageInfo.pageTitle; 18 + params['\$title'] = pageInfo.pageTitle;
19 params['page_manual_key'] = pageInfo.pageManualKey; 19 params['page_manual_key'] = pageInfo.pageManualKey;
20 - params['page_path'] = pageInfo.pagePath; 20 + params['\$screen_name'] = pageInfo.pageKey;
21 params['is_back'] = pageInfo.isBack ? 1 : 0; 21 params['is_back'] = pageInfo.isBack ? 1 : 0;
22 return params; 22 return params;
23 } 23 }
@@ -37,6 +37,19 @@ class Track { @@ -37,6 +37,19 @@ class Track {
37 AutoTrackLogger.getInstance().debug('track page_view => $params'); 37 AutoTrackLogger.getInstance().debug('track page_view => $params');
38 } 38 }
39 39
  40 + void pageDuration(PageInfo pageInfo) {
  41 + if (!AutoTrackConfigManager.instance.autoTrackEnable) {
  42 + return;
  43 + }
  44 +
  45 + Map<String, dynamic> params = _appendPageInfo({}, pageInfo);
  46 + params['use_time'] = pageInfo.timer.duration.inMilliseconds;
  47 + params['use_name'] = pageInfo.pageKey;
  48 + _TrackPlugin.pageDuration(params);
  49 + AutoTrackLogger.getInstance().debug('track page_leave => $params');
  50 + }
  51 +
  52 +
40 void pageLeave(PageInfo pageInfo) { 53 void pageLeave(PageInfo pageInfo) {
41 if (!AutoTrackConfigManager.instance.autoTrackEnable) { 54 if (!AutoTrackConfigManager.instance.autoTrackEnable) {
42 return; 55 return;
@@ -130,8 +143,15 @@ class _TrackPlugin { @@ -130,8 +143,15 @@ class _TrackPlugin {
130 AutoTrackQueue.instance.appendQueue(model); 143 AutoTrackQueue.instance.appendQueue(model);
131 } 144 }
132 145
  146 + static void pageDuration(Map<String, dynamic> params) {
  147 + var model = TrackModel('page_duration_event', DateTime.now().millisecondsSinceEpoch, params, params['page_manual_key']);
  148 + AutoTrackConfigManager.instance.config.eventHandler?.call(model);
  149 + AutoTrackQueue.instance.appendQueue(model);
  150 + }
  151 +
  152 +
133 static void click(Map<String, dynamic> params) { 153 static void click(Map<String, dynamic> params) {
134 - var model = TrackModel('click', DateTime.now().millisecondsSinceEpoch, params, params['element_manual_key']); 154 + var model = TrackModel('\$AppClick', DateTime.now().millisecondsSinceEpoch, params, params['element_manual_key']);
135 AutoTrackConfigManager.instance.config.eventHandler?.call(model); 155 AutoTrackConfigManager.instance.config.eventHandler?.call(model);
136 AutoTrackQueue.instance.appendQueue(model); 156 AutoTrackQueue.instance.appendQueue(model);
137 } 157 }
  1 +import 'dart:convert';
  2 +import 'package:crypto/crypto.dart';
  3 +
  4 +class SignUtil {
  5 + /// 签名方法
  6 + static String sign(Map<String, String> sPara, String appecret) {
  7 + String prestr = createLinkString(paraFilter(sPara)); // 把数组所有元素,
  8 + String mysign = md5Sign(prestr, appecret, "utf-8");
  9 + return mysign;
  10 + }
  11 +
  12 + /// 除去数组中的空值和签名参数
  13 + static Map<String, String> paraFilter(Map<String, String> sArray) {
  14 + Map<String, String> result = {};
  15 + if (sArray == null || sArray.isEmpty) {
  16 + return result;
  17 + }
  18 + sArray.forEach((key, value) {
  19 + if (value == null || value.isEmpty || key.toLowerCase() == "sign" || key.toLowerCase() == "sign_type") {
  20 + return;
  21 + }
  22 + result[key] = value;
  23 + });
  24 + return result;
  25 + }
  26 +
  27 + /// 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
  28 + static String createLinkString(Map<String, String> params) {
  29 + List<String> keys = params.keys.toList();
  30 + keys.sort();
  31 + String prestr = "";
  32 + for (int i = 0; i < keys.length; i++) {
  33 + String key = keys[i];
  34 + String value = params[key]!;
  35 + if (i == keys.length - 1) {
  36 + // 拼接时,不包括最后一个&字符
  37 + prestr = "$prestr$key=$value";
  38 + } else {
  39 + prestr = "$prestr$key=$value&";
  40 + }
  41 + }
  42 + return prestr;
  43 + }
  44 +
  45 + /// MD5签名
  46 + static String md5Sign(String prestr, String secret, String encoding) {
  47 + String toSign = prestr + secret;
  48 + var bytes = utf8.encode(toSign);
  49 + var digest = md5.convert(bytes);
  50 + return digest.toString();
  51 + }
  52 +}
  53 +
@@ -10,12 +10,24 @@ environment: @@ -10,12 +10,24 @@ environment:
10 dependencies: 10 dependencies:
11 android_id: ^0.4.0 11 android_id: ^0.4.0
12 crypto: ^3.0.3 12 crypto: ^3.0.3
13 - device_info_plus: ^10.1.2 13 +# device_info_plus: ^10.1.2
  14 + device_info_plus:
  15 + git:
  16 + url: https://gitee.com/openharmony-sig/flutter_plus_plugins
  17 + path: packages/device_info_plus/device_info_plus
14 flutter: 18 flutter:
15 sdk: flutter 19 sdk: flutter
16 - package_info_plus: ^8.0.1 20 +# package_info_plus: ^8.0.1
  21 + package_info_plus:
  22 + git:
  23 + url: https://gitee.com/openharmony-sig/flutter_plus_plugins
  24 + path: packages/package_info_plus/package_info_plus
17 plugin_platform_interface: ^2.0.2 25 plugin_platform_interface: ^2.0.2
18 uuid: ^4.3.3 26 uuid: ^4.3.3
  27 + archive: ^3.3.7 # 确保使用最新版本
  28 +
  29 +
  30 +
19 31
20 dev_dependencies: 32 dev_dependencies:
21 flutter_test: 33 flutter_test: