gio-miniprogram-sdk 4.3.2 → 4.4.1
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.
- package/.github/workflows/publish.yml +3 -3
- package/dist/alipay.js +1 -1
- package/dist/baidu.js +1 -1
- package/dist/bytedance.js +1 -1
- package/dist/jingdong.js +1 -1
- package/dist/kuaishou.js +1 -1
- package/dist/plugins/gioABTest.js +1 -1
- package/dist/plugins/gioCompress.js +1 -1
- package/dist/plugins/gioEventAutoTracking.js +1 -1
- package/dist/plugins/gioImpressionTracking.js +1 -1
- package/dist/plugins/gioMultipleInstances.js +1 -1
- package/dist/plugins/gioPerformance.js +1 -0
- package/dist/qq.js +1 -1
- package/dist/quickapp.js +1 -1
- package/dist/taobao.js +1 -1
- package/dist/taro.js +1 -1
- package/dist/uniapp.js +1 -1
- package/dist/wechat.js +1 -1
- package/dist/xiaohongshu.js +1 -0
- package/package.json +12 -6
- package/rollup.config.js +9 -6
- package/rollup.plugins.config.js +1 -1
- package/src/adapters/gioUniAppAdapter.ts +324 -113
- package/src/constants/emitMsg.ts +1 -0
- package/src/core/dataStore/eventHooks/appEffects.ts +6 -1
- package/src/core/dataStore/eventHooks/index.ts +122 -80
- package/src/core/dataStore/eventHooks/minipPage.ts +78 -68
- package/src/core/dataStore/eventHooks/pageEffects.ts +9 -2
- package/src/core/dataStore/index.ts +1 -1
- package/src/core/growingIO.ts +27 -3
- package/src/core/uploader.ts +12 -3
- package/src/core/userStore.ts +1 -2
- package/src/minipInstance/base.ts +62 -23
- package/src/minipInstance/framework.ts +3 -1
- package/src/minipInstance/my.ts +34 -1
- package/src/minipInstance/quickapp.ts +11 -0
- package/src/minipInstance/wx.ts +15 -0
- package/src/minipInstance/xhs.ts +20 -0
- package/src/platformConfig/base.ts +1 -0
- package/src/platformConfig/framework.ts +2 -0
- package/src/platformConfig/my.ts +1 -0
- package/src/platformConfig/xhs.ts +27 -0
- package/src/plugins/gioABTest.ts +32 -3
- package/src/plugins/gioEventAutoTracking.ts +101 -1
- package/src/plugins/gioImpressionTracking.ts +8 -3
- package/src/plugins/gioPerformance/exception.ts +152 -0
- package/src/plugins/gioPerformance/monitor.ts +284 -0
- package/src/plugins/gioPerformance/network.ts +197 -0
- package/src/plugins/gioPerformance.ts +131 -0
- package/src/types/base.ts +5 -1
- package/src/types/eventHooks.ts +5 -4
- package/src/types/minipInstance.ts +8 -1
- package/src/types/platforms.ts +3 -0
- package/src/utils/tools.ts +47 -3
- package/src/utils/verifiers.ts +4 -3
- package/tsconfig.json +1 -1
- package/typings/global.d.ts +8 -0
- package/bin/build.sh +0 -38
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
isString,
|
|
14
14
|
last,
|
|
15
15
|
typeOf,
|
|
16
|
-
isEmpty
|
|
16
|
+
isEmpty,
|
|
17
|
+
isArray
|
|
17
18
|
} from '@@/utils/glodash';
|
|
18
19
|
import EMIT_MSG from '@@/constants/emitMsg';
|
|
19
20
|
import {
|
|
@@ -21,7 +22,8 @@ import {
|
|
|
21
22
|
niceTry,
|
|
22
23
|
getPlainMinip,
|
|
23
24
|
getPlainPlatform,
|
|
24
|
-
getPlainConfig
|
|
25
|
+
getPlainConfig,
|
|
26
|
+
getPlainAppCode
|
|
25
27
|
} from '@@/utils/tools';
|
|
26
28
|
|
|
27
29
|
// 此基础实现类仅包含所有小程序,快应用所有方法全部单独实现
|
|
@@ -139,39 +141,67 @@ class BaseInstance implements MinipInstanceType {
|
|
|
139
141
|
if (typeOf(instConfig) === 'string') {
|
|
140
142
|
instConfig = niceTry(() => JSON.parse(instConfig)) ?? {};
|
|
141
143
|
}
|
|
142
|
-
// 第一优先级在base中的hook setNavigationBarTitle设置的值(在dataStore page
|
|
143
|
-
// 第二优先级支持客户自己在页面中设置页面title
|
|
144
|
+
// 第一优先级在base中的hook setNavigationBarTitle设置的值(在dataStore page实例中实现,准确率最高)
|
|
145
|
+
// 第二优先级支持客户自己在页面中设置页面title(保持3.8的向下兼容,不准确但优先级高)
|
|
144
146
|
const data = page?.data || page.$data || {};
|
|
145
147
|
title = isString(data?.gioPageTitle) ? data?.gioPageTitle : '';
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
|
|
149
|
+
let instPage;
|
|
150
|
+
// 第三优先级取页面的配置json的navigationBarTitleText(仅部分支持)
|
|
151
|
+
if (!title) {
|
|
152
|
+
// 存在__[wx]AppCode__时尝试从__[wx]AppCode__中匹配
|
|
153
|
+
niceTry(() => {
|
|
154
|
+
const instAppCode = getPlainAppCode(platform);
|
|
155
|
+
if (instAppCode) {
|
|
156
|
+
instPage = instAppCode[`${page.route}.json`] || {};
|
|
157
|
+
title =
|
|
158
|
+
instPage?.navigationBarTitleText || // wx/qq/jd
|
|
159
|
+
instPage?.mod?.exports?.navigationBarTitleText; // ks
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (!title && instConfig) {
|
|
164
|
+
// 第四优先级在app生命周期中拿不到page对象,拿生命周期的参数来匹配
|
|
148
165
|
const { enterParams } = this.growingIO.dataStore.eventHooks.appEffects;
|
|
149
166
|
if (!page.route && !isEmpty(enterParams)) {
|
|
150
167
|
page.route = enterParams.path || '';
|
|
151
|
-
title =
|
|
168
|
+
title = page.route
|
|
169
|
+
? this._getTitleFromTabBar(instConfig, page.route)
|
|
170
|
+
: '';
|
|
152
171
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
172
|
+
|
|
173
|
+
// 第五优先级存在pages数组或page对象时尝试从page中匹配(大概率匹配不到,跟框架有关)
|
|
174
|
+
if (!title) {
|
|
175
|
+
if (isArray(instConfig.pages)) {
|
|
176
|
+
instPage = instConfig.pages.find((o) => o.path === page.route) ?? {};
|
|
177
|
+
} else {
|
|
178
|
+
instPage = instConfig.page || {};
|
|
179
|
+
}
|
|
180
|
+
if (instPage) {
|
|
157
181
|
const pageInfo =
|
|
158
|
-
instPage[page.route] || instPage[`${page.route}.html`];
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
title = (instConfig || global || $global)?.global?.window
|
|
163
|
-
?.navigationBarTitleText;
|
|
164
|
-
} else {
|
|
165
|
-
title = (instConfig || global || $global)?.window
|
|
166
|
-
?.navigationBarTitleText;
|
|
167
|
-
}
|
|
182
|
+
instPage[page.route] || instPage[`${page.route}.html`] || instPage;
|
|
183
|
+
title =
|
|
184
|
+
pageInfo?.navigationBarTitleText ||
|
|
185
|
+
pageInfo?.window?.navigationBarTitleText;
|
|
168
186
|
}
|
|
169
|
-
}
|
|
170
|
-
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 第六优先级取tabBar配置匹配(只有tabbar的4个页面有机会)
|
|
171
190
|
if (!title) {
|
|
172
191
|
title = this._getTitleFromTabBar(instConfig, page.route);
|
|
173
192
|
}
|
|
174
193
|
}
|
|
194
|
+
|
|
195
|
+
// 第七优先级兜底取全局window的navigationBarTitleText
|
|
196
|
+
if (!title) {
|
|
197
|
+
if (['wx', 'tt'].includes(platform)) {
|
|
198
|
+
title = (instConfig || global || $global)?.global?.window
|
|
199
|
+
?.navigationBarTitleText;
|
|
200
|
+
} else {
|
|
201
|
+
title = (instConfig || global || $global)?.window
|
|
202
|
+
?.navigationBarTitleText;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
175
205
|
return limitString(title);
|
|
176
206
|
};
|
|
177
207
|
|
|
@@ -308,6 +338,15 @@ class BaseInstance implements MinipInstanceType {
|
|
|
308
338
|
this.minip?.getSetting({ success: resolve, fail: resolve });
|
|
309
339
|
});
|
|
310
340
|
};
|
|
341
|
+
|
|
342
|
+
// 监听网络变更
|
|
343
|
+
setNetworkStatusListener = () => {
|
|
344
|
+
this.minip?.onNetworkStatusChange(({ networkType }) => {
|
|
345
|
+
if (networkType) {
|
|
346
|
+
this.network.networkType = networkType;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
};
|
|
311
350
|
}
|
|
312
351
|
|
|
313
352
|
export default BaseInstance;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getPlainPlatform } from '@@/utils/tools';
|
|
2
2
|
|
|
3
|
+
import XiaoHongShu from './xhs';
|
|
3
4
|
import JingDong from './jd';
|
|
4
5
|
import KuaiShou from './ks';
|
|
5
6
|
import Alipay from './my';
|
|
@@ -16,7 +17,8 @@ const INST = {
|
|
|
16
17
|
qq: QQ,
|
|
17
18
|
tt: Bytedance,
|
|
18
19
|
ks: KuaiShou,
|
|
19
|
-
jd: JingDong
|
|
20
|
+
jd: JingDong,
|
|
21
|
+
xhs: XiaoHongShu
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
export default INST[plainPlatform];
|
package/src/minipInstance/my.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { compareVersion } from '@@/utils/tools';
|
|
1
|
+
import { compareVersion, consoleText } from '@@/utils/tools';
|
|
2
2
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
3
3
|
import { isFunction } from '@@/utils/glodash';
|
|
4
4
|
import BaseImplements from './base';
|
|
@@ -93,6 +93,39 @@ class Alipay extends BaseImplements {
|
|
|
93
93
|
}
|
|
94
94
|
return requestTask;
|
|
95
95
|
};
|
|
96
|
+
|
|
97
|
+
// 执行支付宝特有的promise分享
|
|
98
|
+
handleSharePromise = (originResult, handlePromiseResult) => {
|
|
99
|
+
// 创建监听_result变化的Promise
|
|
100
|
+
const alipayPromise = new Promise((resolve) => {
|
|
101
|
+
// 如果已有_result直接返回
|
|
102
|
+
if (originResult._result) {
|
|
103
|
+
resolve(originResult._result);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// 监听_result属性变化
|
|
107
|
+
Object.defineProperty(originResult, '_result', {
|
|
108
|
+
set(value) {
|
|
109
|
+
this.__result = value;
|
|
110
|
+
resolve(value);
|
|
111
|
+
},
|
|
112
|
+
get() {
|
|
113
|
+
return this.__result;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
// 如果三秒内不resolve结果,分享会使用原默认参数
|
|
118
|
+
Promise.race([
|
|
119
|
+
alipayPromise,
|
|
120
|
+
new Promise((resolve) => {
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
resolve(originResult._result || {});
|
|
123
|
+
}, 3000);
|
|
124
|
+
})
|
|
125
|
+
])
|
|
126
|
+
.then(handlePromiseResult)
|
|
127
|
+
.catch((error) => consoleText(error, 'error'));
|
|
128
|
+
};
|
|
96
129
|
}
|
|
97
130
|
|
|
98
131
|
export default Alipay;
|
|
@@ -217,6 +217,17 @@ class QuickApp extends BaseImplements {
|
|
|
217
217
|
});
|
|
218
218
|
});
|
|
219
219
|
};
|
|
220
|
+
|
|
221
|
+
// 监听网络变更
|
|
222
|
+
setNetworkStatusListener = () => {
|
|
223
|
+
network.subscribe({
|
|
224
|
+
callback: (data) => {
|
|
225
|
+
if (data.type) {
|
|
226
|
+
this.network.networkType = data.type;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
};
|
|
220
231
|
}
|
|
221
232
|
|
|
222
233
|
export default QuickApp;
|
package/src/minipInstance/wx.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
2
|
+
import { SystemInfo } from '@@/types/minipInstance';
|
|
2
3
|
|
|
3
4
|
import BaseImplements from './base';
|
|
4
5
|
|
|
@@ -7,6 +8,20 @@ class Weixin extends BaseImplements {
|
|
|
7
8
|
super(growingIO);
|
|
8
9
|
this.hookSetTitle();
|
|
9
10
|
}
|
|
11
|
+
|
|
12
|
+
// 获取小程序系统信息
|
|
13
|
+
getSystemInfo = (): Promise<SystemInfo> => {
|
|
14
|
+
const self = this;
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
const systemInfo = {
|
|
17
|
+
...this.minip?.getDeviceInfo(),
|
|
18
|
+
...this.minip?.getWindowInfo(),
|
|
19
|
+
...this.minip?.getAppBaseInfo()
|
|
20
|
+
};
|
|
21
|
+
self.systemInfo = systemInfo;
|
|
22
|
+
resolve(systemInfo);
|
|
23
|
+
});
|
|
24
|
+
};
|
|
10
25
|
}
|
|
11
26
|
|
|
12
27
|
export default Weixin;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { GrowingIOType } from '@@/types/growingIO';
|
|
2
|
+
|
|
3
|
+
import BaseImplements from './base';
|
|
4
|
+
|
|
5
|
+
class XiaoHongShu extends BaseImplements {
|
|
6
|
+
constructor(public growingIO: GrowingIOType) {
|
|
7
|
+
super(growingIO);
|
|
8
|
+
this.hookSetTitle();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 采集曝光事件
|
|
12
|
+
initImpression = (collectPage: any) => {
|
|
13
|
+
this.growingIO.plugins?.gioImpressionTracking?.main(
|
|
14
|
+
collectPage,
|
|
15
|
+
'selectAll'
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default XiaoHongShu;
|
|
@@ -23,6 +23,7 @@ const Config: PlatformConfigType = {
|
|
|
23
23
|
'onReachBottom', // 实际sdk不会执行,但需要写在hook里,防止被归为自定义事件
|
|
24
24
|
'onResize' // 实际sdk不会执行,但需要写在hook里,防止被归为自定义事件
|
|
25
25
|
],
|
|
26
|
+
shareEventTypes: ['onShareAppMessage', 'onShareTimeline', 'onAddToFavorites'],
|
|
26
27
|
actionEventTypes: [
|
|
27
28
|
'onclick',
|
|
28
29
|
'tap',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { niceTry, getPlainPlatform } from '@@/utils/tools';
|
|
2
2
|
|
|
3
|
+
import XHSConfig from './xhs';
|
|
3
4
|
import JDConfig from './jd';
|
|
4
5
|
import KSConfig from './ks';
|
|
5
6
|
import MyConfig from './my';
|
|
@@ -12,6 +13,7 @@ import WXConfig from './wx';
|
|
|
12
13
|
const plainPlatform = getPlainPlatform();
|
|
13
14
|
const FrameworkConfig = niceTry(() => {
|
|
14
15
|
const INST = {
|
|
16
|
+
xhs: XHSConfig,
|
|
15
17
|
jd: JDConfig,
|
|
16
18
|
ks: KSConfig,
|
|
17
19
|
my: MyConfig,
|
package/src/platformConfig/my.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import BaseConfig from './base';
|
|
2
|
+
|
|
3
|
+
const XHSConfig = {
|
|
4
|
+
...BaseConfig,
|
|
5
|
+
pageHandlers: [
|
|
6
|
+
...BaseConfig.pageHandlers,
|
|
7
|
+
'onShareChat',
|
|
8
|
+
'onCopyUrl',
|
|
9
|
+
'onShareAppMessage',
|
|
10
|
+
'onShareTimeline'
|
|
11
|
+
],
|
|
12
|
+
shareEventTypes: [...BaseConfig.shareEventTypes, 'onShareChat', 'onCopyUrl'],
|
|
13
|
+
listeners: {
|
|
14
|
+
...BaseConfig.listeners,
|
|
15
|
+
page: {
|
|
16
|
+
...BaseConfig.listeners.page,
|
|
17
|
+
shareTime: 'onShareTimeline',
|
|
18
|
+
shareChat: 'onShareChat',
|
|
19
|
+
copyUrl: 'onCopyUrl'
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
name: 'XiaoHongShu',
|
|
23
|
+
platform: 'xhsp',
|
|
24
|
+
scnPrefix: 'xhs_'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default XHSConfig;
|
package/src/plugins/gioABTest.ts
CHANGED
|
@@ -33,6 +33,10 @@ class GioABTest {
|
|
|
33
33
|
public url: any;
|
|
34
34
|
// 接口重试计数
|
|
35
35
|
public retryCount: number;
|
|
36
|
+
// 标记当前是否为新访问设备
|
|
37
|
+
public newDevice: boolean;
|
|
38
|
+
// 各个实例新设备进入时的sessionId;小程序没有刷新页面保持session的问题,所以存在内存里就可以
|
|
39
|
+
public visitSids: any;
|
|
36
40
|
constructor(public growingIO: GrowingIOType, options: any) {
|
|
37
41
|
this.pluginVersion = '__PLUGIN_VERSION__';
|
|
38
42
|
const {
|
|
@@ -41,8 +45,9 @@ class GioABTest {
|
|
|
41
45
|
requestTimeout
|
|
42
46
|
} = options ?? {};
|
|
43
47
|
this.timeoutCheck(requestInterval, requestTimeout);
|
|
44
|
-
const { emitter } = this.growingIO;
|
|
48
|
+
const { emitter, userStore } = this.growingIO;
|
|
45
49
|
this.growingIO.getABTest = this.getABTest;
|
|
50
|
+
this.visitSids = {};
|
|
46
51
|
emitter.on(EMIT_MSG.OPTION_INITIALIZED, () => {
|
|
47
52
|
if (!isEmpty(abServerUrl)) {
|
|
48
53
|
this.abtStorageCheck();
|
|
@@ -61,6 +66,21 @@ class GioABTest {
|
|
|
61
66
|
);
|
|
62
67
|
}
|
|
63
68
|
});
|
|
69
|
+
emitter.on(EMIT_MSG.UID_UPDATE, ({ newUId, oldUId }) => {
|
|
70
|
+
// 没有旧deviceId说明是第一次进入的新设备
|
|
71
|
+
if (!oldUId && newUId) {
|
|
72
|
+
if (isString(abServerUrl)) {
|
|
73
|
+
const trackingId = this.growingIO.trackingId;
|
|
74
|
+
const sId = userStore.getSessionId(trackingId);
|
|
75
|
+
this.visitSids[trackingId] = sId;
|
|
76
|
+
} else if (isObject(abServerUrl)) {
|
|
77
|
+
keys(abServerUrl).forEach((trackingId: string) => {
|
|
78
|
+
const sId = userStore.getSessionId(trackingId);
|
|
79
|
+
this.visitSids[trackingId] = sId;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
64
84
|
this.retryCount = 0;
|
|
65
85
|
}
|
|
66
86
|
|
|
@@ -121,6 +141,14 @@ class GioABTest {
|
|
|
121
141
|
|
|
122
142
|
// 生成数据接口地址
|
|
123
143
|
generateUrl = (trackingId: string, abServerUrl: string) => {
|
|
144
|
+
// 如果是延迟初始化的实例,当前又是首次进入设备,要补充把session存起来
|
|
145
|
+
if (this.newDevice && !this.visitSids[trackingId]) {
|
|
146
|
+
// 这里要用userStore中的getSessionId,调用这个方法的时候实例肯定已经初始化了
|
|
147
|
+
// 如果是新初始化可以通过getSessionId准确获取sessionExpires来生成准确的session值;
|
|
148
|
+
// 如果是旧实例则直接用存储中的sessionId
|
|
149
|
+
this.visitSids[trackingId] =
|
|
150
|
+
this.growingIO.userStore.getSessionId(trackingId);
|
|
151
|
+
}
|
|
124
152
|
if (!startsWith(abServerUrl, 'http')) {
|
|
125
153
|
this.url[
|
|
126
154
|
trackingId
|
|
@@ -169,7 +197,7 @@ class GioABTest {
|
|
|
169
197
|
callback: any
|
|
170
198
|
) => {
|
|
171
199
|
const {
|
|
172
|
-
userStore: { getUid },
|
|
200
|
+
userStore: { getUid, getSessionId },
|
|
173
201
|
dataStore,
|
|
174
202
|
minipInstance
|
|
175
203
|
} = this.growingIO;
|
|
@@ -182,7 +210,8 @@ class GioABTest {
|
|
|
182
210
|
accountId: projectId,
|
|
183
211
|
datasourceId: dataSourceId,
|
|
184
212
|
distinctId: getUid(),
|
|
185
|
-
layerId
|
|
213
|
+
layerId,
|
|
214
|
+
newDevice: this.visitSids[trackingId] === getSessionId(trackingId)
|
|
186
215
|
},
|
|
187
216
|
timeout: this.requestTimeout,
|
|
188
217
|
success: ({ data }: any) => {
|
|
@@ -5,17 +5,21 @@
|
|
|
5
5
|
import { ID_REG, SWAN_XID_REG, TARO_XID_REG } from '@@/constants/regex';
|
|
6
6
|
import { EventTarget } from '@@/types/eventHooks';
|
|
7
7
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
8
|
-
import { consoleText, isTaro3 } from '@@/utils/tools';
|
|
8
|
+
import { consoleText, getExtraData, isTaro3 } from '@@/utils/tools';
|
|
9
9
|
import EMIT_MSG from '@@/constants/emitMsg';
|
|
10
|
+
import { isEmpty } from '@@/utils/glodash';
|
|
10
11
|
|
|
11
12
|
let ut;
|
|
12
13
|
class GioEventAutoTracking {
|
|
13
14
|
public pluginVersion: string;
|
|
14
15
|
private prevEvent: any;
|
|
16
|
+
public circleServerUrl: string;
|
|
17
|
+
public circleOpen = false;
|
|
15
18
|
constructor(public growingIO: GrowingIOType) {
|
|
16
19
|
this.pluginVersion = '__PLUGIN_VERSION__';
|
|
17
20
|
ut = this.growingIO.utils;
|
|
18
21
|
this.prevEvent = {};
|
|
22
|
+
this.listenForLunchEvent();
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
main = (e: EventTarget, eventName: string) => {
|
|
@@ -183,6 +187,102 @@ class GioEventAutoTracking {
|
|
|
183
187
|
eventInterceptor(event);
|
|
184
188
|
}
|
|
185
189
|
};
|
|
190
|
+
|
|
191
|
+
// --------------------- 以下内容是对新版小程序圈选的支持 ---------------------
|
|
192
|
+
|
|
193
|
+
// 监听小程序的onLunch事件
|
|
194
|
+
listenForLunchEvent = () => {
|
|
195
|
+
const { emitter } = this.growingIO;
|
|
196
|
+
emitter.on(EMIT_MSG.MINIP_LIFECYCLE, ({ event, params }) => {
|
|
197
|
+
if (['App onLaunch', 'App onShow'].includes(event)) {
|
|
198
|
+
this.circleInit(params);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// 初始化圈选
|
|
204
|
+
circleInit = (params: any) => {
|
|
205
|
+
const { emitter } = this.growingIO;
|
|
206
|
+
const extraData = getExtraData(
|
|
207
|
+
params.referrerInfo?.extraData || params.query || {}
|
|
208
|
+
);
|
|
209
|
+
// 额外参数中存在gdpCircleRoomCollectUrl,则表示是圈选的跳转,进入圈选状态
|
|
210
|
+
if (extraData?.gdpCircleRoomCollectUrl) {
|
|
211
|
+
// 圈选初始化
|
|
212
|
+
if (this.circleServerUrl !== extraData?.gdpCircleRoomCollectUrl) {
|
|
213
|
+
this.circleServerUrl = extraData?.gdpCircleRoomCollectUrl;
|
|
214
|
+
// 提前移除一次事件发送监听,防止重复监听
|
|
215
|
+
emitter.off(EMIT_MSG.ON_SEND_AFTER, this.collectorSendFn);
|
|
216
|
+
// 添加事件发送监听,用于发送圈选事件
|
|
217
|
+
emitter.on(EMIT_MSG.ON_SEND_AFTER, this.collectorSendFn);
|
|
218
|
+
this.showPromptModal('enter');
|
|
219
|
+
}
|
|
220
|
+
this.circleOpen = true;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// 数据采集发送监听回调
|
|
225
|
+
collectorSendFn = ({ requestData, trackingId }) => {
|
|
226
|
+
const { uploader } = this.growingIO;
|
|
227
|
+
if (this.circleOpen) {
|
|
228
|
+
// 过滤仅主实例的非CUSTOM事件可以圈选
|
|
229
|
+
const filteredEvents = requestData.filter(
|
|
230
|
+
(e) =>
|
|
231
|
+
e.eventType !== 'CUSTOM' && trackingId === this.growingIO.trackingId
|
|
232
|
+
);
|
|
233
|
+
if (!isEmpty(filteredEvents)) {
|
|
234
|
+
// 同时请求数在3个以下直接发起请求
|
|
235
|
+
if (uploader.requestingNum < uploader.requestLimit) {
|
|
236
|
+
this.circleRequest(filteredEvents);
|
|
237
|
+
} else {
|
|
238
|
+
// 同时有3个请求在发送时,设轮询延时直到请求数在3个以下
|
|
239
|
+
let t = setInterval(() => {
|
|
240
|
+
if (uploader.requestingNum < uploader.requestLimit) {
|
|
241
|
+
this.circleRequest(filteredEvents);
|
|
242
|
+
clearInterval(t);
|
|
243
|
+
t = undefined;
|
|
244
|
+
}
|
|
245
|
+
}, 500);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// 圈选结束
|
|
252
|
+
circleClose = () => {
|
|
253
|
+
this.circleOpen = false;
|
|
254
|
+
this.circleServerUrl = '';
|
|
255
|
+
this.growingIO.emitter.off(EMIT_MSG.ON_SEND_AFTER, this.collectorSendFn);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// 展示圈选提示
|
|
259
|
+
showPromptModal = (type: 'enter' | 'error', msg?: string) => {
|
|
260
|
+
this.growingIO.minipInstance.minip.showModal({
|
|
261
|
+
title: 'GrowingIO提示',
|
|
262
|
+
content: type === 'error' ? msg : '您已进入圈选模式',
|
|
263
|
+
showCancel: false
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// 发起圈选请求
|
|
268
|
+
circleRequest = (requestData: any) => {
|
|
269
|
+
const { minipInstance } = this.growingIO;
|
|
270
|
+
minipInstance.request({
|
|
271
|
+
url: this.circleServerUrl,
|
|
272
|
+
header: { 'content-type': 'application/json;charset=UTF-8' },
|
|
273
|
+
method: 'POST',
|
|
274
|
+
data: requestData,
|
|
275
|
+
complete: ({ statusCode, data, errMsg }: any) => {
|
|
276
|
+
if (![200, 204].includes(statusCode) || !data?.success) {
|
|
277
|
+
this.showPromptModal(
|
|
278
|
+
'error',
|
|
279
|
+
data?.message || data || errMsg || '圈选请求失败,请重试!'
|
|
280
|
+
);
|
|
281
|
+
this.circleClose();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
};
|
|
186
286
|
}
|
|
187
287
|
|
|
188
288
|
export default { name: 'gioEventAutoTracking', method: GioEventAutoTracking };
|
|
@@ -107,6 +107,10 @@ class GioImpressionTracking {
|
|
|
107
107
|
return collectTarget.route
|
|
108
108
|
? toString(hashCode(collectTarget.route)) // swan page
|
|
109
109
|
: collectTarget.__nodeId__; // swan component
|
|
110
|
+
case 'xhs':
|
|
111
|
+
return collectTarget.route
|
|
112
|
+
? collectTarget.pageId // xhs page
|
|
113
|
+
: collectTarget.componentId; // xhs component
|
|
110
114
|
default:
|
|
111
115
|
break;
|
|
112
116
|
}
|
|
@@ -117,9 +121,10 @@ class GioImpressionTracking {
|
|
|
117
121
|
const { gioPlatform } = this.growingIO;
|
|
118
122
|
if (
|
|
119
123
|
(gioPlatform === 'tt' && collectTarget.__nodeId__) ||
|
|
120
|
-
(gioPlatform === 'ks' && collectTarget.is)
|
|
124
|
+
(gioPlatform === 'ks' && collectTarget.is) ||
|
|
125
|
+
(gioPlatform === 'xhs' && collectTarget.componentId)
|
|
121
126
|
) {
|
|
122
|
-
//
|
|
127
|
+
// 字节/快手/小红书小程序页面监听时可以拿到自定义组件一次性完成监听,所以组件的节点实例不再处理
|
|
123
128
|
return false;
|
|
124
129
|
}
|
|
125
130
|
const nodeId = this.getNodeId(collectTarget);
|
|
@@ -216,7 +221,7 @@ class GioImpressionTracking {
|
|
|
216
221
|
originObserver.disconnect();
|
|
217
222
|
}
|
|
218
223
|
// 创建一个新的监听
|
|
219
|
-
let observer = ['swan', 'jd'].includes(gioPlatform)
|
|
224
|
+
let observer = ['swan', 'jd', 'xhs'].includes(gioPlatform)
|
|
220
225
|
? minipInstance.minip?.createIntersectionObserver(
|
|
221
226
|
collectTarget,
|
|
222
227
|
observerOption
|