gio-miniprogram-sdk 4.1.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.github/workflows/publish.yml +2 -0
  2. package/dist/alipay.js +1 -1
  3. package/dist/baidu.js +1 -1
  4. package/dist/bytedance.js +1 -1
  5. package/dist/jingdong.js +1 -1
  6. package/dist/kuaishou.js +1 -1
  7. package/dist/plugins/gioABTest.js +1 -1
  8. package/dist/plugins/gioCompress.js +1 -1
  9. package/dist/plugins/gioEventAutoTracking.js +1 -1
  10. package/dist/plugins/gioImpressionTracking.js +1 -1
  11. package/dist/plugins/gioMultipleInstances.js +1 -1
  12. package/dist/qq.js +1 -1
  13. package/dist/quickapp.js +1 -1
  14. package/dist/taobao.js +1 -1
  15. package/dist/taro.js +1 -1
  16. package/dist/uniapp.js +1 -1
  17. package/dist/wechat.js +1 -1
  18. package/package.json +1 -1
  19. package/rollup.config.js +1 -1
  20. package/rollup.plugins.config.js +6 -1
  21. package/src/adapters/gioTaobaoAdapter.ts +7 -3
  22. package/src/adapters/gioTaroAdapter.ts +18 -10
  23. package/src/adapters/gioUniAppAdapter.ts +3 -32
  24. package/src/constants/config.ts +1 -0
  25. package/src/core/dataStore/eventContextBuilder.ts +27 -13
  26. package/src/core/dataStore/eventHooks/appEffects.ts +62 -76
  27. package/src/core/dataStore/eventHooks/index.ts +45 -24
  28. package/src/core/dataStore/eventHooks/minipPage.ts +129 -30
  29. package/src/core/dataStore/eventHooks/pageEffects.ts +25 -53
  30. package/src/core/dataStore/index.ts +67 -74
  31. package/src/core/growingIO.ts +93 -45
  32. package/src/index.ts +12 -12
  33. package/src/minipInstance/base.ts +53 -26
  34. package/src/minipInstance/my.ts +5 -0
  35. package/src/minipInstance/tb.ts +5 -0
  36. package/src/platformConfig/base.ts +0 -1
  37. package/src/plugins/gioABTest.ts +15 -8
  38. package/src/plugins/gioCompress.ts +2 -0
  39. package/src/plugins/gioEventAutoTracking.ts +20 -3
  40. package/src/plugins/gioImpressionTracking.ts +13 -2
  41. package/src/plugins/gioMultipleInstances.ts +14 -3
  42. package/src/types/dataStore.ts +5 -1
  43. package/src/types/eventHooks.ts +13 -8
  44. package/src/types/growingIO.ts +52 -33
  45. package/src/utils/tools.ts +26 -3
@@ -1,18 +1,11 @@
1
1
  import { AppHookLifeCircle } from '@@/types/eventHooks';
2
2
  import { GrowingIOType } from '@@/types/growingIO';
3
- import {
4
- isEmpty,
5
- isObject,
6
- typeOf,
7
- keys,
8
- forEach,
9
- has,
10
- isNil
11
- } from '@@/utils/glodash';
12
- import { qsStringify } from '@@/utils/tools';
3
+ import { isEmpty, typeOf } from '@@/utils/glodash';
4
+ import { getLaunchQuery, qsStringify } from '@@/utils/tools';
13
5
  import EMIT_MSG from '@@/constants/emitMsg';
14
6
 
15
7
  class AppEffects {
8
+ public enterParams: any = {};
16
9
  constructor(public growingIO: GrowingIOType) {}
17
10
 
18
11
  main = (event: AppHookLifeCircle, args: any) => {
@@ -28,7 +21,6 @@ class AppEffects {
28
21
  trackersExecute,
29
22
  shareOut,
30
23
  lastCloseTime,
31
- eventHooks,
32
24
  saveStorageInfo,
33
25
  setOriginalSource
34
26
  }
@@ -48,25 +40,35 @@ class AppEffects {
48
40
  params: args[0] ?? {}
49
41
  });
50
42
  switch (event) {
43
+ case appListeners.appLaunch:
44
+ // 在launch先获取一次是防止在此生命周期中发埋点或调用其他api时获取不到path和query
45
+ this.enterParams = { ...args[0] };
46
+ break;
51
47
  // 快应用是执行onCreate
52
48
  case appListeners.appCreate:
53
49
  // 各小程序执行onShow
54
50
  case appListeners.appShow: {
55
51
  // 获取进入小程序的path、query和scene
56
- const { path, query } = this.enterParamsParse(args[0]);
52
+ const { path, query, referralPage } = this.enterParamsParse(args[0]);
57
53
  if (!shareOut && vdsConfig.originalSource) {
58
- // 保存初始来源信息
59
- trackersExecute((trackingId: string) => {
60
- setOriginalSource(trackingId, { path, query });
61
- });
54
+ // 个别(说的就是你:淘宝)小程序场景值不一样后台拉起时可能args中会没有path和query
55
+ if (path) {
56
+ // 保存初始来源信息
57
+ trackersExecute((trackingId: string) => {
58
+ setOriginalSource(trackingId, { path, query, referralPage });
59
+ });
60
+ }
62
61
  }
63
62
  // 以下条件均会被认为是一次新的访问
64
63
  // 没有关闭时间说明是新访问
65
64
  if (!lastCloseTime) {
66
- // 保存进入小程序的参数
67
- dataStore.lastVisitEvent = { path, query };
68
65
  trackersExecute((trackingId: string) => {
69
- this.buildVisitEvent(trackingId, { path, query });
66
+ dataStore.lastVisitEvent[trackingId] = {
67
+ path,
68
+ query,
69
+ referralPage
70
+ };
71
+ this.buildVisitEvent(trackingId, { path, query, referralPage });
70
72
  });
71
73
  } else if (
72
74
  // 两次打开间隔时间超过keepAlive设定(默认5分钟)
@@ -78,10 +80,17 @@ class AppEffects {
78
80
  trackersExecute((trackingId: string) => {
79
81
  userStore.setSessionId(trackingId);
80
82
  });
81
- // 需要按自然逻辑发visit时,清掉pagetime,防止取值错误(会在page中重新生成)
82
- eventHooks.currentPage.time = undefined;
83
83
  trackersExecute((trackingId: string) => {
84
- this.buildVisitEvent(trackingId, { path, query });
84
+ if (!path) {
85
+ // 个别(说的就是你:淘宝)小程序场景值不一样后台拉起时可能args中会没有path和query,直接取上一个最后发送的page中的值
86
+ const lastPage = dataStore.lastPageEvent[trackingId];
87
+ this.buildVisitEvent(trackingId, {
88
+ path: lastPage.path,
89
+ query: lastPage.query
90
+ });
91
+ } else {
92
+ this.buildVisitEvent(trackingId, { path, query });
93
+ }
85
94
  });
86
95
  }
87
96
  break;
@@ -108,16 +117,11 @@ class AppEffects {
108
117
  };
109
118
 
110
119
  // 进入小程序时的相关数据处理
111
- enterParamsParse = (args: any) => {
120
+ enterParamsParse = (args: any = {}) => {
112
121
  const { gioPlatform, minipInstance, dataStore } = this.growingIO;
113
- let vPath = ''; // 进入小程序时的path
114
- let vQuery = ''; // 进入小程序时的参数(启动参数)
115
- const assignment = (p: string, q = {}) => {
116
- vPath = p;
117
- vQuery = keys(q)
118
- .map((k) => `${k}=${q[k]}`)
119
- .join('&');
120
- };
122
+ let rPath = ''; // 进入小程序时的path
123
+ let rQuery = ''; // 进入小程序时的参数(启动参数)
124
+ let rAppId = ''; // scene=1037或1038时来源小程序、公众号或 App 的 appId
121
125
  // 支持getEnterOptionsSync
122
126
  if (
123
127
  gioPlatform !== 'quickapp' &&
@@ -125,35 +129,25 @@ class AppEffects {
125
129
  ) {
126
130
  const { path, query, scene, referrerInfo } =
127
131
  minipInstance.minip.getEnterOptionsSync() || {};
128
- const originQuery = args.query || query;
129
- assignment(args.path || path, originQuery);
130
- dataStore.scene = args.scene || scene;
131
- // extraData字段计入query
132
- if (!isEmpty(referrerInfo) && isObject(referrerInfo?.extraData)) {
133
- let extraQuery = [];
134
- forEach(referrerInfo.extraData, (v, k) => {
135
- if (
136
- // 与原始query中的key冲突时,以原始query为准
137
- !has(originQuery, k) &&
138
- // 只处理字符串、数字和布尔类型的值
139
- ['string', 'number', 'boolean'].includes(typeOf(v))
140
- ) {
141
- extraQuery.push(`${k}=${v}`);
142
- }
143
- });
144
- const extraQueryString = extraQuery.join('&');
145
- vQuery =
146
- vQuery && extraQueryString
147
- ? `${vQuery}&${extraQueryString}`
148
- : vQuery || extraQueryString;
132
+ rPath = path || args.path;
133
+ rQuery = query || args.query;
134
+ rAppId = referrerInfo?.appId || args?.referrerInfo?.appId || '';
135
+ dataStore.scene = scene || args.scene;
136
+ // 来源有额外参数时并入页面参数
137
+ if (!isEmpty(referrerInfo?.extraData)) {
138
+ rQuery = qsStringify(getLaunchQuery(rQuery, referrerInfo.extraData));
139
+ } else {
140
+ rQuery = qsStringify(rQuery);
149
141
  }
150
142
  } else {
151
143
  // 不支持的按老逻辑兜底
152
- const { path, query } = args;
153
- assignment(path, query);
144
+ const { path, query, referrerInfo } = args;
145
+ rPath = path;
146
+ rQuery = qsStringify(query);
147
+ rAppId = referrerInfo?.appId || '';
154
148
  this.parseScene(args);
155
149
  }
156
- return { path: vPath, query: vQuery };
150
+ return { path: rPath, query: rQuery, referralPage: rAppId };
157
151
  };
158
152
 
159
153
  // 获取来源场景值
@@ -188,13 +182,7 @@ class AppEffects {
188
182
  // 构建访问事件
189
183
  buildVisitEvent = (trackingId: string, props?: any) => {
190
184
  const {
191
- dataStore: {
192
- getOriginalSource,
193
- eventContextBuilder,
194
- eventInterceptor,
195
- eventHooks
196
- },
197
- minipInstance,
185
+ dataStore: { getOriginalSource, eventContextBuilder, eventInterceptor },
198
186
  vdsConfig
199
187
  } = this.growingIO;
200
188
  const originalSource = getOriginalSource(trackingId);
@@ -202,22 +190,20 @@ class AppEffects {
202
190
  const query = props?.query || '';
203
191
  let event = {
204
192
  eventType: 'VISIT',
205
- ...eventContextBuilder(trackingId, {
206
- // params.path是生命周期值或者是已有的值
207
- path: props?.path || '',
208
- // params.query是对象说明是生命周期调用,否则是补发调用
209
- query: typeOf(query) === 'string' ? query : qsStringify(query),
210
- // visit事件要单独设一次title以覆盖eventContextBuilder中的lastPage的可能的title错误值
211
- title:
212
- eventHooks.currentPage?.title ||
213
- minipInstance.getPageTitle(minipInstance.getCurrentPage()),
214
- timestamp: eventHooks.currentPage.time
215
- ? eventHooks.currentPage.time - 1
216
- : +Date.now()
217
- })
193
+ ...eventContextBuilder(trackingId, {})
218
194
  };
195
+ if (!isEmpty(props) && props.path) {
196
+ // params.path是生命周期值或者是已有的值
197
+ event.path = props.path || '';
198
+ // params.query是对象说明是生命周期调用,否则是补发调用
199
+ event.query = typeOf(query) === 'string' ? query : qsStringify(query);
200
+ // 如果有来源
201
+ if (props.referralPage) {
202
+ event.referralPage = props.referralPage;
203
+ }
204
+ }
219
205
  // 配置使用初始来源时,visit使用初始来源数据
220
- if (vdsConfig.originalSource && !isNil(originalSource)) {
206
+ if (vdsConfig.originalSource && !isEmpty(originalSource)) {
221
207
  event = { ...event, ...originalSource };
222
208
  }
223
209
  eventInterceptor(event);
@@ -118,7 +118,12 @@ class EventHooks implements EventHooksType {
118
118
  if (eventName === 'onShareAppMessage') {
119
119
  // 先执行分享的生命周期拿到分享数据
120
120
  // 与基础库保持一致,没有返回值时默认使用{}
121
- result = (await method.apply(this, args)) ?? {};
121
+ result = method.apply(this, args) ?? {};
122
+ // 如果分享事件是个promise函数,需要等待异步结果
123
+ if (typeOf(result) === 'promise') {
124
+ result = await result.then((r) => r);
125
+ }
126
+ // 如果返回的对象中包含promise,要等待异步结果
122
127
  if (typeOf(result.promise) === 'promise') {
123
128
  const f = async function () {
124
129
  let sRes = result;
@@ -299,15 +304,25 @@ class EventHooks implements EventHooksType {
299
304
  });
300
305
  };
301
306
 
302
- growingApp = (app: any) => this.originalApp(this.appOverriding(app));
307
+ growingApp = (app: any) =>
308
+ isFunction(this.originalApp)
309
+ ? this.originalApp(this.appOverriding(app))
310
+ : this.appOverriding(app);
303
311
 
304
- growingPage = (page: any) => this.originalPage(this.pageOverriding(page));
312
+ growingPage = (page: any) =>
313
+ isFunction(this.originalPage)
314
+ ? this.originalPage(this.pageOverriding(page))
315
+ : this.pageOverriding(page);
305
316
 
306
317
  growingComponent = (component: any) =>
307
- this.originalComponent(this.componentOverriding(component));
318
+ isFunction(this.originalComponent)
319
+ ? this.originalComponent(this.componentOverriding(component))
320
+ : this.componentOverriding(component);
308
321
 
309
322
  growingBehavior = (behavior: any) =>
310
- this.originalBehavior(this.componentOverriding(behavior));
323
+ isFunction(this.originalBehavior)
324
+ ? this.originalBehavior(this.componentOverriding(behavior))
325
+ : this.componentOverriding(behavior);
311
326
 
312
327
  nativeGrowing = (
313
328
  designated: string[] = ['App', 'Page', 'Component', 'Behavior']
@@ -315,15 +330,12 @@ class EventHooks implements EventHooksType {
315
330
  const self = this;
316
331
  const { platformConfig } = this.growingIO;
317
332
  const platformHooks = platformConfig.hooks;
318
- this.setAppEffectCbs();
319
- this.setPageEffectCbs();
320
333
  if (designated.includes('App')) {
321
334
  try {
322
335
  // 重写App
323
336
  if (platformHooks.App && !this.appHooked) {
324
- this.originalApp = App || global.App || function () {};
325
337
  App = function (...args) {
326
- return self.growingApp(args[0]);
338
+ return self.originalApp(self.appOverriding(args[0]));
327
339
  };
328
340
  this.appHooked = true;
329
341
  }
@@ -335,9 +347,8 @@ class EventHooks implements EventHooksType {
335
347
  try {
336
348
  // 重写Page
337
349
  if (platformHooks.Page && !this.pageHooked) {
338
- this.originalPage = Page || global.Page || function () {};
339
350
  Page = function (...args) {
340
- return self.growingPage(args[0]);
351
+ return self.originalPage(self.pageOverriding(args[0]));
341
352
  };
342
353
  this.pageHooked = true;
343
354
  }
@@ -349,10 +360,8 @@ class EventHooks implements EventHooksType {
349
360
  try {
350
361
  // 重写Component
351
362
  if (platformHooks.Component && !this.componentHooked) {
352
- this.originalComponent =
353
- Component || global.Component || function () {};
354
363
  Component = function (...args) {
355
- return self.growingComponent(args[0]);
364
+ return self.originalComponent(self.componentOverriding(args[0]));
356
365
  };
357
366
  this.componentHooked = true;
358
367
  }
@@ -364,9 +373,8 @@ class EventHooks implements EventHooksType {
364
373
  try {
365
374
  // 重写Behavior
366
375
  if (platformHooks.Behavior && !this.behaviorHooked) {
367
- this.originalBehavior = Behavior || global.Behavior || function () {};
368
376
  Behavior = function (...args) {
369
- return self.growingBehavior(args[0]);
377
+ return self.originalBehavior(self.componentOverriding(args[0]));
370
378
  };
371
379
  this.behaviorHooked = true;
372
380
  }
@@ -376,26 +384,39 @@ class EventHooks implements EventHooksType {
376
384
  }
377
385
  };
378
386
 
379
- // 初始化无埋点
387
+ // 初始化原始值
388
+ initOriginalValue = () => {
389
+ this.setAppEffectCbs();
390
+ this.setPageEffectCbs();
391
+ this.originalApp = niceTry(() => App || global.App);
392
+ this.originalPage = niceTry(() => Page || global.Page);
393
+ this.originalComponent = niceTry(() => Component || global.Component);
394
+ this.originalBehavior = niceTry(() => Behavior || global.Behavior);
395
+ };
396
+
397
+ // 初始化事件钩子
380
398
  initEventHooks = () => {
381
399
  const self = this;
382
400
  const { platformConfig, gioPlatform } = this.growingIO;
401
+ this.initOriginalValue();
383
402
  if (platformConfig.canHook) {
384
403
  this.nativeGrowing();
385
- getGlobal().GioApp = niceTry(() => App ?? window.GioApp);
386
- getGlobal().GioPage = niceTry(() => Page ?? window.GioPage);
404
+ getGlobal().GioApp = niceTry(() => App ?? this.originalApp);
405
+ getGlobal().GioPage = niceTry(() => Page ?? this.originalPage);
387
406
  getGlobal().GioComponent = niceTry(
388
- () => Component ?? window.GioComponent
407
+ () => Component ?? this.originalComponent
408
+ );
409
+ getGlobal().GioBehavior = niceTry(
410
+ () => Behavior ?? this.originalBehavior
389
411
  );
390
- getGlobal().GioBehavior = niceTry(() => Behavior);
391
412
  } else if (gioPlatform === 'quickapp') {
392
- window.GioApp = function (...args) {
413
+ getGlobal().GioApp = function (...args) {
393
414
  return self.appOverriding(args[0]);
394
415
  };
395
- window.GioPage = function (...args) {
416
+ getGlobal().GioPage = function (...args) {
396
417
  return self.pageOverriding(args[0]);
397
418
  };
398
- window.GioComponent = function (...args) {
419
+ getGlobal().GioComponent = function (...args) {
399
420
  return self.pageOverriding(args[0]);
400
421
  };
401
422
  }
@@ -1,14 +1,29 @@
1
- import { has, head, isEmpty, last, unset } from '@@/utils/glodash';
1
+ import {
2
+ compact,
3
+ has,
4
+ head,
5
+ isEmpty,
6
+ keys,
7
+ last,
8
+ unset
9
+ } from '@@/utils/glodash';
2
10
  import { GrowingIOType } from '@@/types/growingIO';
3
11
  import { MinipPageType, PageShareResult } from '@@/types/eventHooks';
4
- import { qsStringify, normalPath, splitPath, qsParse } from '@@/utils/tools';
12
+ import {
13
+ qsStringify,
14
+ normalPath,
15
+ splitPath,
16
+ qsParse,
17
+ niceTry,
18
+ getDynamicAttributes,
19
+ limitObject,
20
+ getLaunchQuery
21
+ } from '@@/utils/tools';
22
+ import { EVENT } from '@@/types/base';
5
23
 
6
24
  class MinipPage implements MinipPageType {
7
- public path: string;
8
- public time: number;
9
- public query: any;
10
- // 页面title (优先级:setNavigationBarTitle > data.gioPageTitle[不保证能取到] > config.js中设置的值 > tabBar配置)
11
- public title: string;
25
+ // 根据页面存储的页面参数
26
+ public queryOption: any;
12
27
  // 通过调用wx.setNavigationBarTitle设置的title
13
28
  public settedTitle: any;
14
29
  // 页面级属性
@@ -19,48 +34,108 @@ class MinipPage implements MinipPageType {
19
34
  public currentLifecycle: string;
20
35
 
21
36
  constructor(public growingIO: GrowingIOType) {
22
- this.query = undefined;
37
+ this.queryOption = {};
23
38
  this.settedTitle = {};
24
39
  this.pageProps = {};
25
40
  }
26
41
 
27
- // 存储页面参数
28
- parsePage = (page: any, query: any) => {
29
- // wx/my取route; swan取uri; tt取__route__; qq无值
30
- const path =
31
- page.route || page.uri || page.__route__ || page?.$page?.fullPath || '';
32
- if (!isEmpty(query)) {
33
- this.query = this.getQuery(query);
42
+ // 获取页面地址
43
+ getPagePath = () => {
44
+ const { minipInstance, inPlugin, dataStore, trackingId } = this.growingIO;
45
+ const path = minipInstance.getCurrentPath();
46
+ if (inPlugin) {
47
+ const vds = dataStore.getTrackerVds(trackingId);
48
+ // 插件中没有页面时直接将插件appId作为页面信息
49
+ return path || `/插件${vds.appId}`;
34
50
  } else {
35
- this.query = undefined;
51
+ return (
52
+ path ||
53
+ dataStore.eventHooks.appEffects.enterParams?.path ||
54
+ // 作为页面组件时component created生命周期中的埋点会取不到页面堆栈,所以拿最近的一个page事件中的页面信息做兜底
55
+ dataStore.lastPageEvent[trackingId]?.path ||
56
+ // 没有最近的一个page事件说明在app初始化的生命周期中,有些框架可能会有异步处理逻辑导致事件触发比visit晚,则使用visit事件中的页面信息兜底
57
+ dataStore.lastVisitEvent[trackingId]?.path
58
+ );
36
59
  }
37
- if (this.path !== path) {
38
- this.time = Date.now();
60
+ };
61
+
62
+ // 获取页面参数
63
+ getPageQeury = () => {
64
+ const { minipInstance, dataStore, trackingId } = this.growingIO;
65
+ const stackPage = minipInstance.getCurrentPage();
66
+ const stackPath = minipInstance.getCurrentPath();
67
+ const { enterParams = {} } = dataStore.eventHooks.appEffects;
68
+ if (stackPath) {
69
+ const pageParams = stackPage.options ?? stackPage.$taroParams;
70
+ // 堆栈中有页面信息,则使用堆栈中的页面参数
71
+ if (!isEmpty(pageParams)) {
72
+ // 删掉taro框架中自带的字段
73
+ unset(pageParams, '$taroTimestamp');
74
+ // 有页面解析的option直接取
75
+ return this.qsQuery(pageParams);
76
+ } else if (!isEmpty(this.queryOption[stackPath])) {
77
+ // 没有option从hook获取的生命周期参数中取
78
+ return this.qsQuery(this.queryOption[stackPath]);
79
+ } else if (stackPath === enterParams.path) {
80
+ // 某些小程序虽然有页面堆栈,但是页面还没加载完,兜底取启动参数
81
+ return this.qsQuery(
82
+ getLaunchQuery(
83
+ enterParams?.query,
84
+ enterParams?.referrerInfo?.extraData
85
+ )
86
+ );
87
+ }
88
+ } else if (enterParams.path) {
89
+ // 堆栈中没有页面信息,但启动参数中有,说明是小程序刚启动还没加载页面,直接取启动参数
90
+ return this.qsQuery(
91
+ getLaunchQuery(enterParams?.query, enterParams?.referrerInfo?.extraData)
92
+ );
93
+ } else {
94
+ // 作为页面组件时component created生命周期中的埋点会取不到页面堆栈,所以拿最近的一个page事件中的页面信息做兜底
95
+ return dataStore.lastPageEvent[trackingId]?.path
96
+ ? dataStore.lastPageEvent[trackingId]?.query
97
+ : // 没有最近的一个page事件说明在app初始化的生命周期中,有些框架可能会有异步处理逻辑导致事件触发比visit晚,则使用visit事件中的页面信息兜底
98
+ dataStore.lastVisitEvent[trackingId]?.query;
39
99
  }
40
- this.path = path;
41
- this.title =
42
- // 如果在parse前(onLoad)动态设置了title,则优先获取动态设置的值
43
- this.settedTitle[this.path] ||
44
- this.growingIO.minipInstance.getPageTitle(
45
- page || this.growingIO.minipInstance.getCurrentPage()
100
+ };
101
+
102
+ // 获取页面标题
103
+ // 页面title (优先级:setNavigationBarTitle > data.gioPageTitle[不保证能取到] > config.js中设置的值 > tabBar配置)
104
+ getPageTitle = (trackingId?: string) => {
105
+ const { minipInstance, inPlugin, dataStore } = this.growingIO;
106
+ const path = minipInstance.getCurrentPath();
107
+ const title =
108
+ this.settedTitle[path] ||
109
+ minipInstance.getPageTitle(minipInstance.getCurrentPage());
110
+ if (inPlugin) {
111
+ const vds = dataStore.getTrackerVds(
112
+ trackingId || this.growingIO.trackingId
46
113
  );
114
+ // 插件中没有页面时直接将插件appId作为页面信息
115
+ return (
116
+ title || `/插件${vds.appId}${path ? '_' + last(path.split('/')) : ''}`
117
+ );
118
+ } else {
119
+ return title;
120
+ }
47
121
  };
48
122
 
49
- // 获取页面参数
50
- getQuery = (query: any) => {
123
+ // 格式化页面参数
124
+ qsQuery = (query = {}) => {
51
125
  const filtQeury = { ...query };
52
126
  unset(filtQeury, 'wxShoppingListScene');
53
127
  return qsStringify(filtQeury);
54
128
  };
55
129
 
56
- // 获取上一个页面路径
130
+ // 获取页面来源
57
131
  getReferralPage = (trackingId: string) => {
58
132
  const {
59
133
  minipInstance,
60
- dataStore: { lastPageEvent, scene }
134
+ dataStore: { lastPageEvent, scene, eventHooks }
61
135
  } = this.growingIO;
62
136
  return (
63
137
  lastPageEvent[trackingId]?.path ||
138
+ eventHooks.appEffects.enterParams?.referrerInfo?.appId ||
64
139
  (scene ? `scn:${minipInstance.scnPrefix}${scene}` : null)
65
140
  );
66
141
  };
@@ -72,7 +147,7 @@ class MinipPage implements MinipPageType {
72
147
  // 自定义path的地址参数截取(onShareAppMessage中的页面参数是拼在地址中的)
73
148
  const customSplit = splitPath(result.path ?? '');
74
149
 
75
- let path = this.path;
150
+ let path = this.getPagePath();
76
151
  let parsedQeury: any = {};
77
152
  let resultHasPath = has(result, 'path');
78
153
  // 优先使用自定义的地址
@@ -84,6 +159,12 @@ class MinipPage implements MinipPageType {
84
159
  // 自定义path中没有截取到query说明是在onShareAppMessage中没有参数,或是在onShareTimeline中需要取自定义query
85
160
  if (isEmpty(parsedQeury)) {
86
161
  parsedQeury = qsParse(result.query ?? '') || {};
162
+ compact(keys(parsedQeury)).forEach((key) => {
163
+ // 删除从默认页面的query中原有的utm参数,防止带入到下一次分享导致渠道统计错误(如果客户质疑参数被删,让他们自己拼回去或者关followshare)
164
+ if (key.toLowerCase().startsWith('utm_')) {
165
+ unset(parsedQeury, key);
166
+ }
167
+ });
87
168
  }
88
169
 
89
170
  // 以上两种都是自定义的地址和参数,不做处理直接用,防止出现encode/decode的问题。
@@ -91,7 +172,9 @@ class MinipPage implements MinipPageType {
91
172
  // 自定义query没有值则使用当前页面默认参数
92
173
  // 如果path存在,但是不携带参数,此时不使用当前页面的默认参数
93
174
  if (!resultHasPath && isEmpty(parsedQeury)) {
94
- parsedQeury = qsParse(this.query ?? '') || {};
175
+ const stackPage = this.growingIO.minipInstance.getCurrentPage();
176
+ parsedQeury =
177
+ stackPage.options || this.queryOption[stackPage.route] || {};
95
178
  }
96
179
 
97
180
  return [path, qsStringify(parsedQeury)];
@@ -118,6 +201,22 @@ class MinipPage implements MinipPageType {
118
201
  result.query = queryString;
119
202
  return result;
120
203
  };
204
+
205
+ // 给事件合并页面属性
206
+ eventSetPageProps = (trackingId: string, event: EVENT) => {
207
+ const pageProps = niceTry(
208
+ () => this.pageProps[trackingId][this.getPagePath()]
209
+ );
210
+ if (!isEmpty(pageProps)) {
211
+ return limitObject(
212
+ getDynamicAttributes({
213
+ ...event.attributes,
214
+ ...pageProps
215
+ })
216
+ );
217
+ }
218
+ return event.attributes;
219
+ };
121
220
  }
122
221
 
123
222
  export default MinipPage;