gio-miniprogram-sdk 4.0.0 → 4.1.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.
- 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 -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/package.json +39 -42
- package/rollup.config.js +11 -6
- package/rollup.plugins.config.js +13 -10
- package/src/{pluginsOut/frameworks → adapters}/gioTaobaoAdapter.ts +47 -44
- package/src/adapters/gioTaroAdapter.ts +459 -0
- package/src/{pluginsOut/frameworks → adapters}/gioUniAppAdapter.ts +35 -6
- package/src/constants/config.ts +49 -20
- package/src/constants/emitMsg.ts +23 -0
- package/src/constants/regex.ts +14 -0
- package/src/core/dataStore/eventContextBuilder.ts +28 -17
- package/src/core/dataStore/eventHooks/appEffects.ts +50 -31
- package/src/core/dataStore/eventHooks/index.ts +7 -5
- package/src/core/dataStore/eventHooks/minipPage.ts +2 -11
- package/src/core/dataStore/eventHooks/pageEffects.ts +61 -27
- package/src/core/dataStore/index.ts +266 -181
- package/src/core/growingIO.ts +312 -179
- package/src/core/pluginsInstance/base.ts +157 -0
- package/src/core/pluginsInstance/taro.ts +15 -0
- package/src/core/pluginsInstance/tb.ts +15 -0
- package/src/core/pluginsInstance/uniapp.ts +15 -0
- package/src/core/uploader.ts +131 -87
- package/src/core/userStore.ts +160 -121
- package/src/index.ts +37 -28
- package/src/minipInstance/base.ts +2 -1
- package/src/minipInstance/quickapp.ts +5 -19
- package/src/platformConfig/base.ts +0 -4
- package/src/{pluginsOut/ordinary → plugins}/gioABTest.ts +74 -37
- package/src/{pluginsOut/ordinary → plugins}/gioEventAutoTracking.ts +25 -18
- package/src/{pluginsOut/ordinary → plugins}/gioImpressionTracking.ts +109 -41
- package/src/plugins/gioMultipleInstances.ts +176 -0
- package/src/types/base.ts +12 -3
- package/src/types/dataStore.ts +31 -16
- package/src/types/eventHooks.ts +8 -9
- package/src/types/growingIO.ts +30 -14
- package/src/types/platforms.ts +0 -4
- package/src/types/plugins.ts +1 -1
- package/src/types/uploader.ts +16 -12
- package/src/types/userStore.ts +21 -17
- package/src/utils/glodash.ts +10 -3
- package/src/utils/tools.ts +27 -6
- package/src/utils/verifiers.ts +25 -50
- package/typings/global.d.ts +5 -0
- package/.babelrc +0 -4
- package/bin/build/full.sh +0 -32
- package/bin/build/jd.sh +0 -14
- package/bin/build/ks.sh +0 -14
- package/bin/build/my.sh +0 -14
- package/bin/build/plugins.sh +0 -5
- package/bin/build/qq.sh +0 -14
- package/bin/build/quickapp.sh +0 -14
- package/bin/build/swan.sh +0 -14
- package/bin/build/taro.sh +0 -18
- package/bin/build/tb.sh +0 -18
- package/bin/build/tt.sh +0 -14
- package/bin/build/uniapp.sh +0 -18
- package/bin/build/wx.sh +0 -14
- package/src/core/plugins.ts +0 -152
- package/src/pluginsOut/README.md +0 -50
- package/src/pluginsOut/frameworks/gioTaroAdapter.ts +0 -358
- package/src/pluginsOut/ordinary/gioCustomTracking.ts +0 -71
- package/bin/{build/all.sh → build.sh} +3 -3
- /package/src/{pluginsOut/ordinary → plugins}/gioCompress.ts +0 -0
|
@@ -7,10 +7,15 @@ import {
|
|
|
7
7
|
isEmpty,
|
|
8
8
|
isNaN,
|
|
9
9
|
isNumber,
|
|
10
|
+
isObject,
|
|
11
|
+
isString,
|
|
12
|
+
keys,
|
|
10
13
|
startsWith,
|
|
11
14
|
toString
|
|
12
15
|
} from '@@/utils/glodash';
|
|
13
16
|
import { consoleText, hashCode, niceCallback } from '@@/utils/tools';
|
|
17
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
18
|
+
import { ABTEST_DATA_REG, ABTEST_SIGN_REG } from '@@/constants/regex';
|
|
14
19
|
|
|
15
20
|
class GioABTest {
|
|
16
21
|
// 请求间隔时长
|
|
@@ -18,18 +23,29 @@ class GioABTest {
|
|
|
18
23
|
// 请求超时时长
|
|
19
24
|
public requestTimeout: number;
|
|
20
25
|
// 分流服务请求地址
|
|
21
|
-
public url:
|
|
26
|
+
public url: any;
|
|
22
27
|
// 接口重试计数
|
|
23
28
|
public retryCount: number;
|
|
24
29
|
constructor(public growingIO: GrowingIOType, options: any) {
|
|
25
|
-
const {
|
|
30
|
+
const {
|
|
31
|
+
abServerUrl = 'https://ab.growingio.com',
|
|
32
|
+
requestInterval,
|
|
33
|
+
requestTimeout
|
|
34
|
+
} = options ?? {};
|
|
26
35
|
this.timeoutCheck(requestInterval, requestTimeout);
|
|
27
36
|
const { emitter } = this.growingIO;
|
|
28
37
|
this.growingIO.getABTest = this.getABTest;
|
|
29
|
-
emitter.on(
|
|
30
|
-
if (abServerUrl) {
|
|
38
|
+
emitter.on(EMIT_MSG.OPTION_INITIALIZED, () => {
|
|
39
|
+
if (!isEmpty(abServerUrl)) {
|
|
31
40
|
this.abtStorageCheck();
|
|
32
|
-
this.
|
|
41
|
+
this.url = {};
|
|
42
|
+
if (isString(abServerUrl)) {
|
|
43
|
+
this.generateUrl(this.growingIO.trackingId, abServerUrl);
|
|
44
|
+
} else if (isObject(abServerUrl)) {
|
|
45
|
+
keys(abServerUrl).forEach((trackingId: string) => {
|
|
46
|
+
this.generateUrl(trackingId, abServerUrl[trackingId]);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
33
49
|
} else {
|
|
34
50
|
consoleText(
|
|
35
51
|
'如果您需要使用ABTest功能,请配置服务地址 abServerUrl!',
|
|
@@ -47,16 +63,16 @@ class GioABTest {
|
|
|
47
63
|
) => {
|
|
48
64
|
this.requestInterval =
|
|
49
65
|
isNumber(Number(requestInterval)) &&
|
|
50
|
-
!isNaN(Number
|
|
51
|
-
? Number
|
|
66
|
+
!isNaN(Number(requestInterval as string))
|
|
67
|
+
? Number(requestInterval as string)
|
|
52
68
|
: 5;
|
|
53
69
|
if (this.requestInterval > 60 * 24 || this.requestInterval < 0) {
|
|
54
70
|
this.requestInterval = 5;
|
|
55
71
|
}
|
|
56
72
|
this.requestTimeout =
|
|
57
73
|
isNumber(Number(requestTimeout)) &&
|
|
58
|
-
!isNaN(Number
|
|
59
|
-
? Number
|
|
74
|
+
!isNaN(Number(requestTimeout as string))
|
|
75
|
+
? Number(requestTimeout as string)
|
|
60
76
|
: 1000;
|
|
61
77
|
if (this.requestTimeout > 5000 || this.requestTimeout < 100) {
|
|
62
78
|
this.requestTimeout = 1000;
|
|
@@ -68,7 +84,7 @@ class GioABTest {
|
|
|
68
84
|
const { minipInstance }: any = this.growingIO;
|
|
69
85
|
const storageKeys = minipInstance.minip?.getStorageInfoSync().keys || [];
|
|
70
86
|
// 请求标记
|
|
71
|
-
const abtsKeys = storageKeys.filter((k) =>
|
|
87
|
+
const abtsKeys = storageKeys.filter((k) => ABTEST_SIGN_REG.test(k));
|
|
72
88
|
abtsKeys.forEach((k) => {
|
|
73
89
|
// 移除过期的数据,防止存储超限
|
|
74
90
|
const sign = minipInstance.getStorageSync(k);
|
|
@@ -77,7 +93,7 @@ class GioABTest {
|
|
|
77
93
|
}
|
|
78
94
|
});
|
|
79
95
|
// abtest数据
|
|
80
|
-
const abtdKeys = storageKeys.filter((k) =>
|
|
96
|
+
const abtdKeys = storageKeys.filter((k) => ABTEST_DATA_REG.test(k));
|
|
81
97
|
abtdKeys.forEach((k) => {
|
|
82
98
|
// 移除过期的数据,防止存储超限
|
|
83
99
|
if (isEmpty(minipInstance.getStorageSync(k))) {
|
|
@@ -87,28 +103,31 @@ class GioABTest {
|
|
|
87
103
|
};
|
|
88
104
|
|
|
89
105
|
// 生成存储的hash key
|
|
90
|
-
getHashKey = (layerId: string | number) => {
|
|
106
|
+
getHashKey = (trackingId: string, layerId: string | number) => {
|
|
91
107
|
const {
|
|
92
|
-
userStore: {
|
|
108
|
+
userStore: { getUid },
|
|
93
109
|
vdsConfig: { projectId }
|
|
94
110
|
} = this.growingIO;
|
|
95
|
-
return
|
|
111
|
+
return hashCode(`${trackingId}#${projectId}#${getUid()}#${layerId}`, true);
|
|
96
112
|
};
|
|
97
113
|
|
|
98
114
|
// 生成数据接口地址
|
|
99
|
-
generateUrl = (abServerUrl: string) => {
|
|
115
|
+
generateUrl = (trackingId: string, abServerUrl: string) => {
|
|
100
116
|
if (!startsWith(abServerUrl, 'http')) {
|
|
101
|
-
this.url
|
|
117
|
+
this.url[
|
|
118
|
+
trackingId
|
|
119
|
+
] = `https://${abServerUrl}/diversion/specified-layer-variables`;
|
|
102
120
|
} else {
|
|
103
|
-
this.url
|
|
121
|
+
this.url[
|
|
122
|
+
trackingId
|
|
123
|
+
] = `${abServerUrl}/diversion/specified-layer-variables`;
|
|
104
124
|
}
|
|
105
125
|
};
|
|
106
126
|
|
|
107
127
|
// 获取实验调用
|
|
108
|
-
getABTest = (layerId: string | number, callback: any) => {
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
return;
|
|
128
|
+
getABTest = (trackingId: string, layerId: string | number, callback: any) => {
|
|
129
|
+
if (isEmpty(this.url[trackingId])) {
|
|
130
|
+
this.generateUrl(trackingId, 'https://ab.growingio.com');
|
|
112
131
|
}
|
|
113
132
|
if (!layerId) {
|
|
114
133
|
consoleText('获取ABTest数据失败! 实验层Id不合法!', 'error');
|
|
@@ -119,15 +138,16 @@ class GioABTest {
|
|
|
119
138
|
// 接口调用的超时时间
|
|
120
139
|
const abtSign =
|
|
121
140
|
minipInstance.getStorageSync(
|
|
122
|
-
`${this.getHashKey(layerId)}_gdp_abt_sign`
|
|
141
|
+
`${this.getHashKey(trackingId, layerId)}_gdp_abt_sign`
|
|
123
142
|
) || 0;
|
|
124
143
|
// 没有超时尝试取数据
|
|
125
144
|
const abtData =
|
|
126
|
-
minipInstance.getStorageSync(
|
|
127
|
-
|
|
145
|
+
minipInstance.getStorageSync(
|
|
146
|
+
`${this.getHashKey(trackingId, layerId)}_gdp_abtd`
|
|
147
|
+
) || {};
|
|
128
148
|
// 没有有效数据或者接口请求标记超时则从调用分流服务获取数据
|
|
129
149
|
if (!abtSign || abtSign < Date.now()) {
|
|
130
|
-
this.initiateRequest(layerId, abtData, callback);
|
|
150
|
+
this.initiateRequest(trackingId, layerId, abtData, callback);
|
|
131
151
|
} else {
|
|
132
152
|
niceCallback(callback, abtData);
|
|
133
153
|
}
|
|
@@ -135,30 +155,36 @@ class GioABTest {
|
|
|
135
155
|
|
|
136
156
|
// 发起请求
|
|
137
157
|
initiateRequest = (
|
|
158
|
+
trackingId: string,
|
|
138
159
|
layerId: string | number,
|
|
139
160
|
originData: any,
|
|
140
161
|
callback: any
|
|
141
162
|
) => {
|
|
142
163
|
const {
|
|
143
|
-
userStore: {
|
|
144
|
-
|
|
164
|
+
userStore: { getUid },
|
|
165
|
+
dataStore,
|
|
145
166
|
minipInstance
|
|
146
167
|
} = this.growingIO;
|
|
147
|
-
|
|
168
|
+
const { projectId, dataSourceId } = dataStore.getTrackerVds(trackingId);
|
|
148
169
|
minipInstance.request({
|
|
149
|
-
url: this.url,
|
|
170
|
+
url: this.url[trackingId],
|
|
150
171
|
header: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
151
172
|
method: 'POST',
|
|
152
173
|
data: {
|
|
153
174
|
accountId: projectId,
|
|
154
175
|
datasourceId: dataSourceId,
|
|
155
|
-
distinctId:
|
|
176
|
+
distinctId: getUid(),
|
|
156
177
|
layerId
|
|
157
178
|
},
|
|
158
179
|
timeout: this.requestTimeout,
|
|
159
180
|
success: ({ data }: any) => {
|
|
160
181
|
if (data.code === 0) {
|
|
161
|
-
this.experimentVerify(
|
|
182
|
+
this.experimentVerify(
|
|
183
|
+
trackingId,
|
|
184
|
+
{ ...data, layerId },
|
|
185
|
+
originData,
|
|
186
|
+
callback
|
|
187
|
+
);
|
|
162
188
|
} else {
|
|
163
189
|
consoleText(`获取ABTest数据失败! ${data.errorMsg}!`, 'error');
|
|
164
190
|
// 接口业务失败返回false信息
|
|
@@ -166,7 +192,7 @@ class GioABTest {
|
|
|
166
192
|
}
|
|
167
193
|
// 接口调用返回后刷新接口调用标记
|
|
168
194
|
minipInstance.setStorageSync(
|
|
169
|
-
`${this.getHashKey(layerId)}_gdp_abt_sign`,
|
|
195
|
+
`${this.getHashKey(trackingId, layerId)}_gdp_abt_sign`,
|
|
170
196
|
Date.now() + 1000 * 60 * this.requestInterval
|
|
171
197
|
);
|
|
172
198
|
},
|
|
@@ -179,7 +205,7 @@ class GioABTest {
|
|
|
179
205
|
} else {
|
|
180
206
|
// 其他失败情况重试
|
|
181
207
|
if (this.retryCount < 2) {
|
|
182
|
-
this.initiateRequest(layerId, originData, callback);
|
|
208
|
+
this.initiateRequest(trackingId, layerId, originData, callback);
|
|
183
209
|
this.retryCount += 1;
|
|
184
210
|
} else {
|
|
185
211
|
consoleText(
|
|
@@ -195,9 +221,14 @@ class GioABTest {
|
|
|
195
221
|
};
|
|
196
222
|
|
|
197
223
|
// 实验校验(决定是否上报命中事件)
|
|
198
|
-
experimentVerify = (
|
|
224
|
+
experimentVerify = (
|
|
225
|
+
trackingId: string,
|
|
226
|
+
responseData: any,
|
|
227
|
+
originData: any,
|
|
228
|
+
callback: any
|
|
229
|
+
) => {
|
|
199
230
|
const { layerId, strategyId, experimentId, variables } = responseData;
|
|
200
|
-
const abtDataKey = `${this.getHashKey(layerId)}_gdp_abtd`;
|
|
231
|
+
const abtDataKey = `${this.getHashKey(trackingId, layerId)}_gdp_abtd`;
|
|
201
232
|
const abtData = {
|
|
202
233
|
layerId: toString(layerId),
|
|
203
234
|
strategyId: toString(strategyId),
|
|
@@ -221,6 +252,7 @@ class GioABTest {
|
|
|
221
252
|
// 数据不一致重新发命中埋点
|
|
222
253
|
if (strategyId && experimentId) {
|
|
223
254
|
this.buildExperimentHitEvent(
|
|
255
|
+
trackingId,
|
|
224
256
|
toString(layerId),
|
|
225
257
|
toString(experimentId),
|
|
226
258
|
toString(strategyId)
|
|
@@ -232,7 +264,12 @@ class GioABTest {
|
|
|
232
264
|
};
|
|
233
265
|
|
|
234
266
|
// 构建实验命中事件
|
|
235
|
-
buildExperimentHitEvent = (
|
|
267
|
+
buildExperimentHitEvent = (
|
|
268
|
+
trackingId: string,
|
|
269
|
+
layerId: string,
|
|
270
|
+
experimentId: string,
|
|
271
|
+
strategyId: string
|
|
272
|
+
) => {
|
|
236
273
|
const {
|
|
237
274
|
dataStore: { eventContextBuilder, eventConverter }
|
|
238
275
|
} = this.growingIO;
|
|
@@ -244,7 +281,7 @@ class GioABTest {
|
|
|
244
281
|
$exp_id: experimentId,
|
|
245
282
|
$exp_strategy_id: strategyId
|
|
246
283
|
},
|
|
247
|
-
...eventContextBuilder(),
|
|
284
|
+
...eventContextBuilder(trackingId),
|
|
248
285
|
customEventType: 0
|
|
249
286
|
};
|
|
250
287
|
eventConverter(event);
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* 名称:无埋点插件
|
|
3
3
|
* 用途:用于提供无埋点的事件构建方法。
|
|
4
4
|
*/
|
|
5
|
+
import { ID_REG, SWAN_XID_REG, TARO_XID_REG } from '@@/constants/regex';
|
|
5
6
|
import { EventTarget } from '@@/types/eventHooks';
|
|
6
7
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
7
8
|
import { consoleText, isTaro3 } from '@@/utils/tools';
|
|
9
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
8
10
|
|
|
9
11
|
let ut;
|
|
10
12
|
class GioEventAutoTracking {
|
|
@@ -15,8 +17,13 @@ class GioEventAutoTracking {
|
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
main = (e: EventTarget, eventName: string) => {
|
|
18
|
-
const {
|
|
19
|
-
|
|
20
|
+
const {
|
|
21
|
+
vdsConfig,
|
|
22
|
+
platformConfig,
|
|
23
|
+
plugins,
|
|
24
|
+
emitter,
|
|
25
|
+
trackingId
|
|
26
|
+
}: GrowingIOType = this.growingIO;
|
|
20
27
|
if (
|
|
21
28
|
// 无埋点事件拦截
|
|
22
29
|
!vdsConfig.autotrack ||
|
|
@@ -49,15 +56,15 @@ class GioEventAutoTracking {
|
|
|
49
56
|
console.log('Action:', e.type, Date.now());
|
|
50
57
|
}
|
|
51
58
|
// 向其他插件广播事件
|
|
52
|
-
emitter.emit(
|
|
59
|
+
emitter.emit(EMIT_MSG.ON_COMPOSE_BEFORE, {
|
|
53
60
|
event: eventName,
|
|
54
61
|
params: e ?? {}
|
|
55
62
|
});
|
|
56
63
|
const actionListeners = platformConfig.listeners.actions;
|
|
57
64
|
if (actionListeners.click.includes(e.type)) {
|
|
58
|
-
this.buildClickEvent(e, eventName);
|
|
65
|
+
this.buildClickEvent(trackingId, e, eventName);
|
|
59
66
|
} else if (actionListeners.change.includes(e.type)) {
|
|
60
|
-
this.buildChangeEvent(e, eventName);
|
|
67
|
+
this.buildChangeEvent(trackingId, e, eventName);
|
|
61
68
|
}
|
|
62
69
|
};
|
|
63
70
|
|
|
@@ -68,8 +75,8 @@ class GioEventAutoTracking {
|
|
|
68
75
|
let id = target.id;
|
|
69
76
|
if (
|
|
70
77
|
!id ||
|
|
71
|
-
(gioPlatform === 'swan' &&
|
|
72
|
-
(isTaro3(vdsConfig.taro) &&
|
|
78
|
+
(gioPlatform === 'swan' && SWAN_XID_REG.test(id)) ||
|
|
79
|
+
(isTaro3(vdsConfig.taro) && TARO_XID_REG.test(id))
|
|
73
80
|
) {
|
|
74
81
|
id = '';
|
|
75
82
|
}
|
|
@@ -77,7 +84,7 @@ class GioEventAutoTracking {
|
|
|
77
84
|
};
|
|
78
85
|
|
|
79
86
|
// 构建点击事件
|
|
80
|
-
buildClickEvent = (e: EventTarget, eventName: string) => {
|
|
87
|
+
buildClickEvent = (trackingId: string, e: EventTarget, eventName: string) => {
|
|
81
88
|
const xpath = this.getNodeXpath(e, eventName);
|
|
82
89
|
if (xpath) {
|
|
83
90
|
const {
|
|
@@ -87,11 +94,7 @@ class GioEventAutoTracking {
|
|
|
87
94
|
let idx;
|
|
88
95
|
if (ut.has(target?.dataset, 'index') && target?.dataset?.index !== '') {
|
|
89
96
|
const index: any = ut.toString(target.dataset.index);
|
|
90
|
-
if (
|
|
91
|
-
/^\d{1,10}$/.test(index) &&
|
|
92
|
-
index - 0 > 0 &&
|
|
93
|
-
index - 0 < 2147483647
|
|
94
|
-
) {
|
|
97
|
+
if (ID_REG.test(index) && index - 0 > 0 && index - 0 < 2147483647) {
|
|
95
98
|
idx = +index;
|
|
96
99
|
} else {
|
|
97
100
|
consoleText(
|
|
@@ -110,14 +113,14 @@ class GioEventAutoTracking {
|
|
|
110
113
|
hyperlink: target?.dataset?.src
|
|
111
114
|
}
|
|
112
115
|
],
|
|
113
|
-
...eventContextBuilder()
|
|
116
|
+
...eventContextBuilder(trackingId)
|
|
114
117
|
};
|
|
115
118
|
eventInterceptor(event);
|
|
116
119
|
}
|
|
117
120
|
};
|
|
118
121
|
|
|
119
122
|
// 构建tab菜单点击事件
|
|
120
|
-
buildTabClickEvent = (tabItem: any) => {
|
|
123
|
+
buildTabClickEvent = (trackingId: string, tabItem: any) => {
|
|
121
124
|
const {
|
|
122
125
|
dataStore: { eventContextBuilder, eventInterceptor }
|
|
123
126
|
} = this.growingIO;
|
|
@@ -131,13 +134,17 @@ class GioEventAutoTracking {
|
|
|
131
134
|
hyperlink: ut.toString(tabItem.pagePath)
|
|
132
135
|
}
|
|
133
136
|
],
|
|
134
|
-
...eventContextBuilder()
|
|
137
|
+
...eventContextBuilder(trackingId)
|
|
135
138
|
};
|
|
136
139
|
eventInterceptor(event);
|
|
137
140
|
};
|
|
138
141
|
|
|
139
142
|
// 构建表单变化事件
|
|
140
|
-
buildChangeEvent = (
|
|
143
|
+
buildChangeEvent = (
|
|
144
|
+
trackingId: string,
|
|
145
|
+
e: EventTarget,
|
|
146
|
+
eventName: string
|
|
147
|
+
) => {
|
|
141
148
|
const xpath = this.getNodeXpath(e, eventName);
|
|
142
149
|
if (xpath) {
|
|
143
150
|
const {
|
|
@@ -147,7 +154,7 @@ class GioEventAutoTracking {
|
|
|
147
154
|
const event = {
|
|
148
155
|
eventType: 'VIEW_CHANGE',
|
|
149
156
|
element: { xpath },
|
|
150
|
-
...eventContextBuilder()
|
|
157
|
+
...eventContextBuilder(trackingId)
|
|
151
158
|
};
|
|
152
159
|
const ev = ut.get(e, 'detail.value') || ut.get(e, 'target.attr.value');
|
|
153
160
|
if (target?.dataset?.growingTrack || target?.dataset?.growingtrack) {
|
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
* 名称:半自动浏览埋点插件
|
|
3
3
|
* 用途:用于提供半自动浏览埋点事件的自动注册、参数检验构建和创建事件方法。
|
|
4
4
|
*/
|
|
5
|
+
import { IMP_DATA_REG } from '@@/constants/regex';
|
|
5
6
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
6
|
-
import {
|
|
7
|
-
|
|
7
|
+
import {
|
|
8
|
+
compact,
|
|
9
|
+
isArray,
|
|
10
|
+
isEmpty,
|
|
11
|
+
isEqualArray,
|
|
12
|
+
isString,
|
|
13
|
+
toString
|
|
14
|
+
} from '@@/utils/glodash';
|
|
15
|
+
import { eventNameValidate, hashCode, niceTry } from '@@/utils/tools';
|
|
16
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
8
17
|
|
|
9
18
|
let ut;
|
|
10
19
|
class GioImpressionTracking {
|
|
@@ -27,7 +36,7 @@ class GioImpressionTracking {
|
|
|
27
36
|
}
|
|
28
37
|
minipInstance.initImpression(collect);
|
|
29
38
|
};
|
|
30
|
-
emitter.on(
|
|
39
|
+
emitter.on(EMIT_MSG.MINIP_LIFECYCLE, ({ event, params }) => {
|
|
31
40
|
const { minipInstance } = this.growingIO;
|
|
32
41
|
if (event === 'Page onShowEnd') {
|
|
33
42
|
const page = minipInstance.getCurrentPage();
|
|
@@ -68,13 +77,48 @@ class GioImpressionTracking {
|
|
|
68
77
|
return isEqualArray(controlGroup, comparisonGroup);
|
|
69
78
|
};
|
|
70
79
|
|
|
80
|
+
// 获取nodeId
|
|
81
|
+
getNodeId = (collectTarget: any) => {
|
|
82
|
+
const { gioPlatform } = this.growingIO;
|
|
83
|
+
switch (gioPlatform) {
|
|
84
|
+
case 'wx':
|
|
85
|
+
case 'qq':
|
|
86
|
+
case 'ks':
|
|
87
|
+
case 'jd':
|
|
88
|
+
return collectTarget.__wxExparserNodeId__; // wx page/component
|
|
89
|
+
case 'my':
|
|
90
|
+
case 'tb':
|
|
91
|
+
return collectTarget.$page
|
|
92
|
+
? `${collectTarget.$page.$id}-${collectTarget.$id}` //my component
|
|
93
|
+
: collectTarget.$id; // my page
|
|
94
|
+
case 'swan':
|
|
95
|
+
return collectTarget.route
|
|
96
|
+
? toString(hashCode(collectTarget.route)) // swan page
|
|
97
|
+
: collectTarget.nodeId; // swan component
|
|
98
|
+
case 'tt':
|
|
99
|
+
return collectTarget.route
|
|
100
|
+
? toString(hashCode(collectTarget.route)) // swan page
|
|
101
|
+
: collectTarget.__nodeId__; // swan component
|
|
102
|
+
default:
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
71
107
|
// 获取到可监听节点后校验节点信息
|
|
72
108
|
rectobserve = (rect, collectTarget, optionKey) => {
|
|
73
|
-
const
|
|
109
|
+
const { gioPlatform } = this.growingIO;
|
|
110
|
+
if (
|
|
111
|
+
(gioPlatform === 'tt' && collectTarget.__nodeId__) ||
|
|
112
|
+
(gioPlatform === 'ks' && collectTarget.is)
|
|
113
|
+
) {
|
|
114
|
+
// 字节和快手小程序页面监听时可以拿到自定义组件一次性完成监听,所以组件的节点实例不再处理
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
const nodeId = this.getNodeId(collectTarget);
|
|
74
118
|
const page = collectTarget.route
|
|
75
119
|
? collectTarget
|
|
76
120
|
: this.growingIO.minipInstance.getCurrentPage();
|
|
77
|
-
//
|
|
121
|
+
// 监听的目标页面和上一次的不一致,或者监听的组件或页面的监听已经被注销时,可以继续生成新的监听
|
|
78
122
|
let observerNeedNew = false;
|
|
79
123
|
if (page.route) {
|
|
80
124
|
const isEqualRects = this.isEqualRects(rect, page.route, nodeId);
|
|
@@ -109,15 +153,21 @@ class GioImpressionTracking {
|
|
|
109
153
|
?.createSelectorQuery()
|
|
110
154
|
.in(collectTarget);
|
|
111
155
|
if (['ks', 'qq'].includes(gioPlatform)) {
|
|
112
|
-
query
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
156
|
+
query
|
|
157
|
+
.selectAll('.growing_collect_imp')
|
|
158
|
+
.boundingClientRect(([rect = []]) => {
|
|
159
|
+
rect = ut.isArray(rect) ? rect : [rect];
|
|
160
|
+
if (!isEmpty(rect)) {
|
|
161
|
+
this.rectobserve(rect, collectTarget, optionKey);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
116
164
|
query.exec();
|
|
117
165
|
} else {
|
|
118
166
|
query.selectAll('.growing_collect_imp').boundingClientRect();
|
|
119
167
|
query.exec(([rect]) => {
|
|
120
|
-
|
|
168
|
+
if (!isEmpty(rect)) {
|
|
169
|
+
this.rectobserve(rect, collectTarget, optionKey);
|
|
170
|
+
}
|
|
121
171
|
});
|
|
122
172
|
}
|
|
123
173
|
};
|
|
@@ -136,8 +186,7 @@ class GioImpressionTracking {
|
|
|
136
186
|
) {
|
|
137
187
|
observerOption.dataset = true;
|
|
138
188
|
}
|
|
139
|
-
|
|
140
|
-
const nodeId = collectTarget.__wxExparserNodeId__;
|
|
189
|
+
const nodeId = this.getNodeId(collectTarget);
|
|
141
190
|
let page = collectTarget;
|
|
142
191
|
// uniapp是组件和页面一体,所以要分两次尝试监听;原生是组件和页面互相独立,按类型监听
|
|
143
192
|
// 自定义组件是不能直接在页面上被拿到,所以直接监听页面不会监听到自定义组件
|
|
@@ -148,7 +197,6 @@ class GioImpressionTracking {
|
|
|
148
197
|
) {
|
|
149
198
|
page = minipInstance.getCurrentPage();
|
|
150
199
|
}
|
|
151
|
-
|
|
152
200
|
if (!this.observerIds[page.route]) {
|
|
153
201
|
this.observerIds[page.route] = {};
|
|
154
202
|
}
|
|
@@ -158,13 +206,12 @@ class GioImpressionTracking {
|
|
|
158
206
|
originObserver.disconnect();
|
|
159
207
|
}
|
|
160
208
|
// 创建一个新的监听
|
|
161
|
-
let observer =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
: collectTarget.createIntersectionObserver(observerOption);
|
|
209
|
+
let observer = ['swan', 'jd'].includes(gioPlatform)
|
|
210
|
+
? minipInstance.minip?.createIntersectionObserver(
|
|
211
|
+
collectTarget,
|
|
212
|
+
observerOption
|
|
213
|
+
)
|
|
214
|
+
: collectTarget.createIntersectionObserver(observerOption);
|
|
168
215
|
observer = observer.relativeToViewport();
|
|
169
216
|
// 不管原先是否创建过,直接覆盖(obeserverId会更新)
|
|
170
217
|
this.observerIds[page.route][nodeId] = observer;
|
|
@@ -192,9 +239,28 @@ class GioImpressionTracking {
|
|
|
192
239
|
this.sentImps[sentId] = dataProperties;
|
|
193
240
|
}
|
|
194
241
|
}
|
|
195
|
-
if (dataProperties.
|
|
196
|
-
|
|
197
|
-
|
|
242
|
+
if (dataProperties.eventName) {
|
|
243
|
+
let sendTargets = [];
|
|
244
|
+
if (dataset.gioImpSendto) {
|
|
245
|
+
// 先尝试处理成数组
|
|
246
|
+
sendTargets = compact(
|
|
247
|
+
isArray(dataset.gioImpSendto)
|
|
248
|
+
? dataset.gioImpSendto
|
|
249
|
+
: niceTry(() => JSON.parse(dataset.gioImpSendto)) || []
|
|
250
|
+
);
|
|
251
|
+
// 在尝试处理字符串
|
|
252
|
+
if (isEmpty(sendTargets)) {
|
|
253
|
+
niceTry(() =>
|
|
254
|
+
dataset.gioImpSendto.split(',').forEach((s: string) => {
|
|
255
|
+
s = isString(s) && s.trim().replace('[', '').replace(']', '');
|
|
256
|
+
if (s) {
|
|
257
|
+
sendTargets.push(s);
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
this.buildImpEvent(dataProperties, sendTargets);
|
|
198
264
|
} else {
|
|
199
265
|
ut.consoleText(
|
|
200
266
|
'曝光事件格式不正确,事件名只能包含数字、字母和下划线,且不以数字开头!',
|
|
@@ -208,13 +274,13 @@ class GioImpressionTracking {
|
|
|
208
274
|
// 曝光参数获取
|
|
209
275
|
getImpressionProperties = (dataSet: any) => {
|
|
210
276
|
let data: any = {
|
|
211
|
-
|
|
277
|
+
eventName: undefined,
|
|
212
278
|
properties: {}
|
|
213
279
|
};
|
|
214
280
|
if (!dataSet?.gioImpTrack) {
|
|
215
281
|
return data;
|
|
216
282
|
} else {
|
|
217
|
-
data.
|
|
283
|
+
data.eventName = dataSet.gioImpTrack;
|
|
218
284
|
}
|
|
219
285
|
if (ut.has(dataSet, 'gioImpAttrs')) {
|
|
220
286
|
// imp写法二
|
|
@@ -225,10 +291,9 @@ class GioImpressionTracking {
|
|
|
225
291
|
);
|
|
226
292
|
} else {
|
|
227
293
|
// imp写法一
|
|
228
|
-
const propReg = /^gioTrack(.+)/;
|
|
229
294
|
for (const key in dataSet) {
|
|
230
295
|
let normKey;
|
|
231
|
-
const matchArr = key.match(
|
|
296
|
+
const matchArr = key.match(IMP_DATA_REG);
|
|
232
297
|
if (matchArr) {
|
|
233
298
|
normKey = ut.lowerFirst(matchArr[1]);
|
|
234
299
|
if (normKey !== 'track') {
|
|
@@ -239,13 +304,12 @@ class GioImpressionTracking {
|
|
|
239
304
|
}
|
|
240
305
|
// 对参数对象进行限制
|
|
241
306
|
data.properties = ut.limitObject(data.properties);
|
|
242
|
-
// 校验
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
data.eventId = null;
|
|
307
|
+
// 校验eventName
|
|
308
|
+
const validate = eventNameValidate(data.eventName, () => {
|
|
309
|
+
return data;
|
|
310
|
+
});
|
|
311
|
+
if (!validate) {
|
|
312
|
+
data.eventName = null;
|
|
249
313
|
data = {};
|
|
250
314
|
}
|
|
251
315
|
return data;
|
|
@@ -279,19 +343,23 @@ class GioImpressionTracking {
|
|
|
279
343
|
};
|
|
280
344
|
|
|
281
345
|
// 创建半自动曝光事件
|
|
282
|
-
buildImpEvent = (dataProperties: any) => {
|
|
283
|
-
const {
|
|
346
|
+
buildImpEvent = (dataProperties: any, sendTargets: string[]) => {
|
|
347
|
+
const { eventName, properties } = dataProperties;
|
|
284
348
|
const {
|
|
285
|
-
|
|
349
|
+
trackingId,
|
|
350
|
+
dataStore: { eventContextBuilder, eventConverter },
|
|
351
|
+
plugins
|
|
286
352
|
} = this.growingIO;
|
|
287
353
|
const event = {
|
|
288
354
|
eventType: 'CUSTOM',
|
|
289
|
-
eventName
|
|
355
|
+
eventName,
|
|
290
356
|
attributes: properties,
|
|
291
|
-
...eventContextBuilder()
|
|
292
|
-
customEventType: 0
|
|
357
|
+
...eventContextBuilder(trackingId)
|
|
293
358
|
};
|
|
294
|
-
|
|
359
|
+
if (plugins.gioMultipleInstances && !isEmpty(sendTargets)) {
|
|
360
|
+
event['&&sendTo'] = sendTargets;
|
|
361
|
+
}
|
|
362
|
+
eventConverter(event);
|
|
295
363
|
};
|
|
296
364
|
}
|
|
297
365
|
|