gio-miniprogram-sdk 4.0.1 → 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 -43
- package/src/{pluginsOut/frameworks → adapters}/gioTaroAdapter.ts +4 -4
- package/src/{pluginsOut/frameworks → adapters}/gioUniAppAdapter.ts +35 -6
- package/src/constants/config.ts +47 -18
- package/src/constants/emitMsg.ts +23 -0
- package/src/constants/regex.ts +0 -1
- 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 +263 -185
- package/src/core/growingIO.ts +312 -178
- 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 -82
- 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 +55 -22
- package/src/plugins/gioMultipleInstances.ts +176 -0
- package/src/types/base.ts +10 -3
- package/src/types/dataStore.ts +31 -16
- package/src/types/eventHooks.ts +5 -6
- 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 -10
- 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/ordinary/gioCustomTracking.ts +0 -71
- package/bin/{build/all.sh → build.sh} +3 -3
- /package/src/{pluginsOut/ordinary → plugins}/gioCompress.ts +0 -0
package/src/core/growingIO.ts
CHANGED
|
@@ -12,12 +12,14 @@ import {
|
|
|
12
12
|
callError,
|
|
13
13
|
consoleText,
|
|
14
14
|
eventNameValidate,
|
|
15
|
-
|
|
15
|
+
getDynamicAttributes,
|
|
16
|
+
getGlobal,
|
|
16
17
|
getPlainPlatform,
|
|
17
18
|
guid,
|
|
18
|
-
limitObject
|
|
19
|
+
limitObject,
|
|
20
|
+
niceCallback
|
|
19
21
|
} from '@@/utils/tools';
|
|
20
|
-
import {
|
|
22
|
+
import { ALLOW_SET_OPTIONS, DEFAULT_SETTINGS } from '@@/constants/config';
|
|
21
23
|
import { DataStoreType, OriginOptions } from '@@/types/dataStore';
|
|
22
24
|
import { FRAMEWORKS, PLATFORMTYPES } from '@@/types/platforms';
|
|
23
25
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
@@ -32,10 +34,11 @@ import DataStore from './dataStore';
|
|
|
32
34
|
import mitt from 'mitt';
|
|
33
35
|
import platformConfig from '__GIO_PLATFORM_CONFIG__';
|
|
34
36
|
import PlatformInstance from '__GIO_PLATFORM_INSTANCE__';
|
|
35
|
-
import Plugins from '
|
|
37
|
+
import Plugins from '__GIO_PLUGIN_INSTANCE__';
|
|
36
38
|
import qs from 'querystringify';
|
|
37
39
|
import Uploader from './uploader';
|
|
38
40
|
import UserStore from '@@/core/userStore';
|
|
41
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
39
42
|
|
|
40
43
|
// SDK全局参数 版本号、小程序平台、框架名称、运行环境 均由打包工具替换写入
|
|
41
44
|
const sdkVersion: any = '__SDK_VERSION__';
|
|
@@ -58,7 +61,9 @@ class GrowingIO implements GrowingIOType {
|
|
|
58
61
|
public dataStore: DataStoreType;
|
|
59
62
|
public plugins: PluginsType;
|
|
60
63
|
public uploader: UploaderType;
|
|
61
|
-
|
|
64
|
+
// 当前主SDK的trackingId,用于区分事件归属。
|
|
65
|
+
public trackingId: string;
|
|
66
|
+
public subInstance: any;
|
|
62
67
|
constructor() {
|
|
63
68
|
this.utils = { ...glodash, ...tools, qs };
|
|
64
69
|
this.emitter = mitt();
|
|
@@ -94,84 +99,143 @@ class GrowingIO implements GrowingIOType {
|
|
|
94
99
|
this.dataStore = new DataStore(this);
|
|
95
100
|
// 用户实例
|
|
96
101
|
this.userStore = new UserStore(this);
|
|
102
|
+
// 初始化请求逻辑
|
|
103
|
+
this.uploader = new Uploader(this);
|
|
97
104
|
// 插件管理实例
|
|
98
105
|
this.plugins = new Plugins(this);
|
|
99
106
|
// 加载内置插件
|
|
100
107
|
this.plugins.innerPluginInit();
|
|
101
|
-
// 数据管理实例和上传实例均在各自环境中继承实现
|
|
102
108
|
}
|
|
103
109
|
|
|
110
|
+
// SDK初始化方法
|
|
111
|
+
init = (options: any) => {
|
|
112
|
+
// 初始化实例之前
|
|
113
|
+
this.emitter.emit(EMIT_MSG.ON_SDK_INITIALIZE_BEFORE, { options });
|
|
114
|
+
try {
|
|
115
|
+
consoleText('Gio小程序SDK 初始化中...', 'info');
|
|
116
|
+
if (
|
|
117
|
+
options.trackingId &&
|
|
118
|
+
this.dataStore.initializedTrackingIds.includes(options.trackingId)
|
|
119
|
+
) {
|
|
120
|
+
throw new Error(`已存在实例 ${options.trackingId},请勿重复初始化!`);
|
|
121
|
+
}
|
|
122
|
+
if (this.trackingId && !this.plugins.gioMultipleInstances) {
|
|
123
|
+
throw new Error('您正在尝试初始化另一个实例,请集成多实例插件后重试!');
|
|
124
|
+
}
|
|
125
|
+
// 初始化实例配置
|
|
126
|
+
const vdsConfig = this.dataStore.initTrackerOptions(options);
|
|
127
|
+
// 广播基础配置初始化完成
|
|
128
|
+
this.emitter?.emit(EMIT_MSG.OPTION_INITIALIZED, vdsConfig);
|
|
129
|
+
// 标记SDK已初始化完成
|
|
130
|
+
this.gioSDKInitialized = true;
|
|
131
|
+
// 初始化实例hooker
|
|
132
|
+
this.dataStore.initTrackerHooker(vdsConfig);
|
|
133
|
+
// 手动初始化用户信息
|
|
134
|
+
if (this.gioPlatform !== 'quickapp') {
|
|
135
|
+
this.userStore.initUserInfo(options.trackingId);
|
|
136
|
+
}
|
|
137
|
+
// 广播SDK初始化完成
|
|
138
|
+
this.emitter.emit(EMIT_MSG.SDK_INITIALIZED, vdsConfig);
|
|
139
|
+
// 初始化完成后把实例注入到小程序全局
|
|
140
|
+
if (!this.trackingId || this.trackingId === options.trackingId) {
|
|
141
|
+
// ?直接挂载对象,存在问题:Page.data 触发深拷贝 存在循环引用会导致死循环
|
|
142
|
+
getGlobal().__gio__ = () => this;
|
|
143
|
+
}
|
|
144
|
+
consoleText('Gio小程序SDK 初始化完成!', 'success');
|
|
145
|
+
// 在插件中手动触发visit
|
|
146
|
+
if (this.inPlugin && this.minipInstance.platform !== 'tbp') {
|
|
147
|
+
this.dataStore.sendVisit(vdsConfig.trackingId);
|
|
148
|
+
}
|
|
149
|
+
if (this.vdsConfig.forceLogin) {
|
|
150
|
+
consoleText(
|
|
151
|
+
'forceLogin已开启,请调用 identify 方法设置 openId 以继续上报!',
|
|
152
|
+
'info'
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
consoleText(error, 'error');
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// 需要校验实例的方法执行
|
|
163
|
+
handlerDistribute = (trackingId: string, handler: string, args: any) => {
|
|
164
|
+
const { initializedTrackingIds, getTrackerVds } = this.dataStore;
|
|
165
|
+
const trakerVds = getTrackerVds(trackingId);
|
|
166
|
+
if (trakerVds && initializedTrackingIds.includes(trackingId)) {
|
|
167
|
+
return this[handler](trackingId, ...args);
|
|
168
|
+
} else {
|
|
169
|
+
consoleText(`不存在实例:${trackingId},请检查!`, 'warn');
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
104
173
|
// 手动注册插件
|
|
105
174
|
registerPlugins = (plugins: any) => {
|
|
106
175
|
this.plugins.pluginItems = [...this.plugins.pluginItems, ...plugins];
|
|
107
176
|
this.plugins.installAll(plugins);
|
|
108
177
|
};
|
|
109
178
|
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// 广播基础配置初始化完成
|
|
116
|
-
this.emitter?.emit('OPTION_INITIALIZED', this);
|
|
117
|
-
// 标记SDK已初始化完成
|
|
118
|
-
this.gioSDKInitialized = true;
|
|
119
|
-
// 初始化完成后把实例注入到小程序全局
|
|
120
|
-
// ?注意不要轻易修改实例挂载的地方(这里指app),会影响分包插件和运营SDK的实例取值
|
|
121
|
-
if (!this.vdsConfig.subpackage) {
|
|
122
|
-
const app = getAppInst();
|
|
123
|
-
// 直接挂载对象,存在问题:Page.data 触发深拷贝 存在循环引用会导致死循环
|
|
124
|
-
app.__gio__ = () => {
|
|
125
|
-
return this;
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
// 初始化请求逻辑
|
|
129
|
-
this.uploader = new Uploader(this);
|
|
130
|
-
// 没有开启IDMapping的时候要把userKey清掉,防止之前有数被带到上报数据里
|
|
131
|
-
if (!this.vdsConfig.idMapping) {
|
|
132
|
-
this.userStore.userKey = '';
|
|
133
|
-
}
|
|
134
|
-
// 广播SDK初始化完成
|
|
135
|
-
this.emitter.emit('SDK_INITIALIZED', this);
|
|
136
|
-
consoleText('Gio小程序SDK 初始化完成!', 'success');
|
|
137
|
-
if (this.vdsConfig.forceLogin) {
|
|
138
|
-
consoleText(
|
|
139
|
-
'forceLogin已开启,请调用 identify 方法设置 openId 以继续上报!',
|
|
140
|
-
'info'
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
// 在插件中手动触发visit
|
|
144
|
-
if (this.inPlugin && this.minipInstance.platform !== 'tbp') {
|
|
145
|
-
this.dataStore.sendVisit();
|
|
146
|
-
}
|
|
147
|
-
return true;
|
|
148
|
-
};
|
|
179
|
+
// 获取所有已注册插件
|
|
180
|
+
getPlugins = () => this.plugins.pluginItems;
|
|
181
|
+
|
|
182
|
+
// 获取设备ID(匿名用户ID)
|
|
183
|
+
getDeviceId = () => this.userStore.getUid();
|
|
149
184
|
|
|
150
185
|
// 运行中获取配置
|
|
151
|
-
getOption = (k?: string) =>
|
|
186
|
+
getOption = (trackingId: string, k?: string) =>
|
|
187
|
+
this.dataStore.getOption(trackingId, k);
|
|
152
188
|
|
|
153
189
|
// 运行中修改配置
|
|
154
|
-
setOption = (k: string, v: any) => {
|
|
155
|
-
if (keys(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
consoleText(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
);
|
|
190
|
+
setOption = (trackingId: string, k: string, v: any) => {
|
|
191
|
+
if (keys(ALLOW_SET_OPTIONS).includes(k)) {
|
|
192
|
+
if (typeof v === DEFAULT_SETTINGS[k]?.type) {
|
|
193
|
+
this.dataStore.setOption(trackingId, k, v);
|
|
194
|
+
consoleText(`已修改${ALLOW_SET_OPTIONS[k]}: ${v}`, 'info');
|
|
195
|
+
return true;
|
|
196
|
+
} else {
|
|
197
|
+
consoleText(`参数格式不正确:${v},请检查后重试!`, 'error');
|
|
198
|
+
return false;
|
|
162
199
|
}
|
|
163
|
-
return r;
|
|
164
200
|
} else {
|
|
165
|
-
consoleText(`不存在可修改的配置项:${k},请检查后重试!`, '
|
|
201
|
+
consoleText(`不存在可修改的配置项:${k},请检查后重试!`, 'error');
|
|
166
202
|
return false;
|
|
167
203
|
}
|
|
168
204
|
};
|
|
169
205
|
|
|
170
|
-
//
|
|
171
|
-
|
|
206
|
+
// 设置页面属性
|
|
207
|
+
setPageAttributes = (trackingId: string, properties: any) => {
|
|
208
|
+
const { currentPage } = this.dataStore.eventHooks;
|
|
209
|
+
if (isEmpty(currentPage.pageProps[trackingId])) {
|
|
210
|
+
currentPage.pageProps[trackingId] = {};
|
|
211
|
+
}
|
|
212
|
+
if (!isEmpty(properties)) {
|
|
213
|
+
currentPage.pageProps[trackingId] = {
|
|
214
|
+
...currentPage.pageProps[trackingId],
|
|
215
|
+
...limitObject(properties)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// 手动发page
|
|
221
|
+
sendPage = (trackingId: string, props?: any) => {
|
|
222
|
+
const { trackPage } = this.dataStore.getTrackerVds(trackingId);
|
|
223
|
+
if (!trackPage) {
|
|
224
|
+
this.dataStore.sendPage(trackingId, props);
|
|
225
|
+
} else {
|
|
226
|
+
consoleText(
|
|
227
|
+
'仅在关闭trackPage时允许调用sendPage,请确认后修改初始化配置项!',
|
|
228
|
+
'error'
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
172
232
|
|
|
173
233
|
// 设置设备ID,一般为openId
|
|
174
|
-
identify = (assignmentId: string | number) => {
|
|
234
|
+
identify = (trackingId: string, assignmentId: string | number) => {
|
|
235
|
+
if (trackingId !== this.trackingId) {
|
|
236
|
+
callError('identify', !1, '子实例不允许调用identify');
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
175
239
|
if (this.vdsConfig.forceLogin) {
|
|
176
240
|
if (!verifyId(assignmentId)) {
|
|
177
241
|
callError('identify');
|
|
@@ -180,33 +244,63 @@ class GrowingIO implements GrowingIOType {
|
|
|
180
244
|
// 截取长度
|
|
181
245
|
const asId = toString(assignmentId).slice(0, 1000);
|
|
182
246
|
// 在之后的请求中使用assignmentId作为uid(deviceId)使用
|
|
183
|
-
this.userStore.
|
|
247
|
+
this.userStore.setUid(asId);
|
|
248
|
+
// 修改forceLogin配置项
|
|
249
|
+
this.dataStore.setOption(this.trackingId, 'forceLogin', false);
|
|
184
250
|
// 为已积压的请求使用assignmentId全部赋值deviceId
|
|
185
|
-
this.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
251
|
+
this.dataStore.trackersExecute((tid: string) => {
|
|
252
|
+
const hq = this.uploader.getHoardingQueue(tid);
|
|
253
|
+
hq.forEach((o, i) => (hq[i].deviceId = asId));
|
|
254
|
+
// 发送积压队列中的请求
|
|
255
|
+
this.uploader.initiateRequest(tid, true);
|
|
256
|
+
});
|
|
191
257
|
} else {
|
|
192
258
|
callError('identify', !1, 'forceLogin未开启');
|
|
193
259
|
}
|
|
194
260
|
};
|
|
195
261
|
|
|
262
|
+
// 发送用户属性
|
|
263
|
+
setUserAttributes = (trackingId: string, userAttributes: any) => {
|
|
264
|
+
if (!isEmpty(userAttributes) && isObject(userAttributes)) {
|
|
265
|
+
const { eventContextBuilder, eventInterceptor, lastVisitEvent } =
|
|
266
|
+
this.dataStore;
|
|
267
|
+
const event = {
|
|
268
|
+
eventType: 'LOGIN_USER_ATTRIBUTES',
|
|
269
|
+
attributes: limitObject(userAttributes),
|
|
270
|
+
...eventContextBuilder(trackingId)
|
|
271
|
+
};
|
|
272
|
+
// 该方法很可能被放在在app的onShow中的wx.login异步回调中,
|
|
273
|
+
// 此时页面的path和query可能还没取到,就拿visit事件的path和query补上
|
|
274
|
+
if (!event.path) {
|
|
275
|
+
event.path = lastVisitEvent.path;
|
|
276
|
+
event.query = lastVisitEvent.query;
|
|
277
|
+
event.title = lastVisitEvent.title;
|
|
278
|
+
}
|
|
279
|
+
eventInterceptor(event);
|
|
280
|
+
} else {
|
|
281
|
+
callError('setUserAttributes');
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
196
285
|
// 设置登录用户Id
|
|
197
|
-
setUserId = (
|
|
286
|
+
setUserId = (
|
|
287
|
+
trackingId: string,
|
|
288
|
+
userId: string | number,
|
|
289
|
+
userKey?: string
|
|
290
|
+
) => {
|
|
198
291
|
if (verifyId(userId)) {
|
|
199
292
|
// 切换userId要重设session补发visit
|
|
200
|
-
const prevId = this.userStore.
|
|
293
|
+
const prevId = this.userStore.getGioId(trackingId);
|
|
201
294
|
userId = toString(userId).slice(0, 1000);
|
|
202
295
|
userKey = toString(userKey).slice(0, 1000);
|
|
203
|
-
this.userStore.
|
|
204
|
-
|
|
205
|
-
|
|
296
|
+
this.userStore.setUserId(trackingId, userId);
|
|
297
|
+
const { idMapping } = this.dataStore.getTrackerVds(trackingId);
|
|
298
|
+
if (idMapping) {
|
|
299
|
+
this.userStore.setUserKey(trackingId, isNil(userKey) ? '' : userKey);
|
|
206
300
|
}
|
|
207
301
|
// 切换userId时重置session并补发visit
|
|
208
302
|
if (prevId && prevId !== userId) {
|
|
209
|
-
this.userStore.
|
|
303
|
+
this.userStore.setSessionId(trackingId);
|
|
210
304
|
const { path, query, settedTitle } =
|
|
211
305
|
this.dataStore.eventHooks.currentPage;
|
|
212
306
|
// 重新获取页面title,防止切换配置前修改了title没取到
|
|
@@ -214,7 +308,7 @@ class GrowingIO implements GrowingIOType {
|
|
|
214
308
|
settedTitle[path] ||
|
|
215
309
|
this.minipInstance.getPageTitle(this.minipInstance.getCurrentPage());
|
|
216
310
|
// visit取当前页面值
|
|
217
|
-
this.dataStore.sendVisit({ path, query });
|
|
311
|
+
this.dataStore.sendVisit(trackingId, { path, query });
|
|
218
312
|
}
|
|
219
313
|
} else {
|
|
220
314
|
callError('setUserId');
|
|
@@ -222,65 +316,121 @@ class GrowingIO implements GrowingIOType {
|
|
|
222
316
|
};
|
|
223
317
|
|
|
224
318
|
// 清除登录用户Id
|
|
225
|
-
clearUserId = () => {
|
|
226
|
-
this.userStore.
|
|
227
|
-
this.userStore.
|
|
319
|
+
clearUserId = (trackingId: string) => {
|
|
320
|
+
this.userStore.setUserId(trackingId, undefined);
|
|
321
|
+
this.userStore.setUserKey(trackingId, undefined);
|
|
228
322
|
};
|
|
229
323
|
|
|
230
|
-
//
|
|
231
|
-
|
|
232
|
-
if (!isEmpty(
|
|
233
|
-
this.
|
|
324
|
+
// 设置埋点事件的通用属性(即每个埋点事件都会带上的属性值)
|
|
325
|
+
setGeneralProps = (trackingId: string, properties: any) => {
|
|
326
|
+
if (!isEmpty(properties)) {
|
|
327
|
+
this.dataStore.generalProps[trackingId] = {
|
|
328
|
+
...(this.dataStore.generalProps[trackingId] ?? {}),
|
|
329
|
+
...properties
|
|
330
|
+
};
|
|
331
|
+
return true;
|
|
234
332
|
} else {
|
|
235
|
-
callError('
|
|
333
|
+
callError('setGeneralProps');
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// 清空已设置的埋点事件的通用属性
|
|
339
|
+
clearGeneralProps = (
|
|
340
|
+
trackingId: string,
|
|
341
|
+
properties: string[] | undefined
|
|
342
|
+
) => {
|
|
343
|
+
try {
|
|
344
|
+
if (!isEmpty(this.dataStore.generalProps[trackingId])) {
|
|
345
|
+
// 获取目标tracker的引用
|
|
346
|
+
if (isArray(properties) && !isEmpty(properties)) {
|
|
347
|
+
properties.forEach((propName: string) => {
|
|
348
|
+
unset(this.dataStore.generalProps[trackingId], propName);
|
|
349
|
+
});
|
|
350
|
+
} else {
|
|
351
|
+
this.dataStore.generalProps[trackingId] = {};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} catch (error) {
|
|
355
|
+
callError('setGeneralProps');
|
|
356
|
+
return false;
|
|
236
357
|
}
|
|
237
358
|
};
|
|
238
359
|
|
|
239
360
|
// 自定义埋点事件
|
|
240
|
-
track = (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
361
|
+
track = (
|
|
362
|
+
trackingId: string,
|
|
363
|
+
name: string,
|
|
364
|
+
properties: { [key: string]: string | string[] }
|
|
365
|
+
) => {
|
|
366
|
+
eventNameValidate(name, () => {
|
|
367
|
+
const { eventContextBuilder, eventInterceptor, generalProps } =
|
|
368
|
+
this.dataStore;
|
|
369
|
+
const mergedProperties = {
|
|
370
|
+
...(generalProps[trackingId] ?? {}),
|
|
371
|
+
...(isObject(properties) && !isEmpty(properties) ? properties : {})
|
|
372
|
+
};
|
|
373
|
+
const event = {
|
|
374
|
+
eventType: 'CUSTOM',
|
|
375
|
+
eventName: name,
|
|
376
|
+
attributes: limitObject(getDynamicAttributes(mergedProperties)),
|
|
377
|
+
...eventContextBuilder(trackingId)
|
|
378
|
+
};
|
|
379
|
+
// 埋点事件要保留'&&sendTo'字段用于多实例复制发送
|
|
380
|
+
if (
|
|
381
|
+
this.plugins.gioMultipleInstances &&
|
|
382
|
+
properties &&
|
|
383
|
+
properties['&&sendTo']
|
|
384
|
+
) {
|
|
385
|
+
event['&&sendTo'] = properties['&&sendTo'];
|
|
386
|
+
}
|
|
387
|
+
eventInterceptor(event);
|
|
246
388
|
});
|
|
247
389
|
};
|
|
248
390
|
|
|
249
391
|
// 初始化事件计时器
|
|
250
|
-
trackTimerStart = (eventName: string) => {
|
|
251
|
-
|
|
392
|
+
trackTimerStart = (trackingId: string, eventName: string) => {
|
|
393
|
+
const { dataCollect } = this.dataStore.getTrackerVds(trackingId);
|
|
394
|
+
if (dataCollect) {
|
|
252
395
|
return eventNameValidate(eventName, () => {
|
|
253
396
|
const timerId = guid();
|
|
254
|
-
this.dataStore.trackTimers[
|
|
397
|
+
if (!this.dataStore.trackTimers[trackingId]) {
|
|
398
|
+
this.dataStore.trackTimers[trackingId] = {};
|
|
399
|
+
}
|
|
400
|
+
this.dataStore.trackTimers[trackingId][timerId] = {
|
|
255
401
|
eventName,
|
|
256
402
|
leng: 0,
|
|
257
403
|
start: +Date.now()
|
|
258
404
|
};
|
|
259
405
|
return timerId;
|
|
260
406
|
});
|
|
407
|
+
} else {
|
|
408
|
+
consoleText('指定实例未开启数据采集,请检查!', 'error');
|
|
261
409
|
}
|
|
262
410
|
return false;
|
|
263
411
|
};
|
|
264
412
|
|
|
265
413
|
// 暂停事件计时器
|
|
266
|
-
trackTimerPause = (timerId: string) => {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
414
|
+
trackTimerPause = (trackingId: string, timerId: string) => {
|
|
415
|
+
const timers = this.dataStore.trackTimers[trackingId];
|
|
416
|
+
if (timerId && timers && timers[timerId]) {
|
|
417
|
+
const timer = timers[timerId];
|
|
418
|
+
if (timer.start) {
|
|
419
|
+
timer.leng = timer.leng + (+Date.now() - timer.start);
|
|
271
420
|
}
|
|
272
|
-
|
|
421
|
+
timer.start = 0;
|
|
273
422
|
return true;
|
|
274
423
|
}
|
|
275
424
|
return false;
|
|
276
425
|
};
|
|
277
426
|
|
|
278
427
|
// 恢复事件计时器
|
|
279
|
-
trackTimerResume = (timerId: string) => {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
428
|
+
trackTimerResume = (trackingId: string, timerId: string) => {
|
|
429
|
+
const timers = this.dataStore.trackTimers[trackingId];
|
|
430
|
+
if (timerId && timers && timers[timerId]) {
|
|
431
|
+
const timer = timers[timerId];
|
|
432
|
+
if (timer.start === 0) {
|
|
433
|
+
timer.start = +Date.now();
|
|
284
434
|
}
|
|
285
435
|
return true;
|
|
286
436
|
}
|
|
@@ -288,114 +438,98 @@ class GrowingIO implements GrowingIOType {
|
|
|
288
438
|
};
|
|
289
439
|
|
|
290
440
|
// 停止事件计时器并上报事件
|
|
291
|
-
trackTimerEnd = (timerId: string,
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
441
|
+
trackTimerEnd = (trackingId: string, timerId: string, properties: any) => {
|
|
442
|
+
const { dataCollect } = this.dataStore.getTrackerVds(trackingId);
|
|
443
|
+
const timers = this.dataStore.trackTimers[trackingId];
|
|
444
|
+
if (timerId && timers && timers[timerId]) {
|
|
445
|
+
if (dataCollect) {
|
|
446
|
+
const maxEnd = 60 * 60 * 24 * 1000;
|
|
447
|
+
const timer = timers[timerId];
|
|
448
|
+
if (timer.start !== 0) {
|
|
449
|
+
const shortCut = +Date.now() - timer.start;
|
|
450
|
+
timer.leng = shortCut > 0 ? timer.leng + shortCut : 0;
|
|
299
451
|
}
|
|
300
|
-
// 要直接构建custom事件,不要去调用埋点插件的方法,万一插件没有加载就发不出去了
|
|
301
452
|
const { eventContextBuilder, eventInterceptor } = this.dataStore;
|
|
302
453
|
const event = {
|
|
303
454
|
eventType: 'CUSTOM',
|
|
304
|
-
eventName:
|
|
455
|
+
eventName: timer.eventName,
|
|
305
456
|
attributes: limitObject({
|
|
306
|
-
...
|
|
307
|
-
event_duration:
|
|
457
|
+
...properties,
|
|
458
|
+
event_duration: timer.leng > maxEnd ? 0 : timer.leng / 1000
|
|
308
459
|
}),
|
|
309
|
-
...eventContextBuilder()
|
|
460
|
+
...eventContextBuilder(trackingId)
|
|
310
461
|
};
|
|
462
|
+
// 埋点事件要保留'&&sendTo'字段用于多实例复制发送
|
|
463
|
+
if (
|
|
464
|
+
this.plugins.gioMultipleInstances &&
|
|
465
|
+
properties &&
|
|
466
|
+
properties['&&sendTo']
|
|
467
|
+
) {
|
|
468
|
+
event['&&sendTo'] = properties['&&sendTo'];
|
|
469
|
+
}
|
|
311
470
|
eventInterceptor(event);
|
|
312
|
-
this.removeTimer(timerId);
|
|
313
471
|
return true;
|
|
314
472
|
} else {
|
|
315
|
-
consoleText('
|
|
473
|
+
consoleText('指定实例未开启数据采集,计时器已移除,请检查!', 'error');
|
|
316
474
|
return false;
|
|
317
475
|
}
|
|
476
|
+
this.removeTimer(trackingId, timerId);
|
|
477
|
+
} else {
|
|
478
|
+
consoleText('未查询到指定计时器,请检查!', 'error');
|
|
479
|
+
return false;
|
|
318
480
|
}
|
|
319
|
-
return false;
|
|
320
481
|
};
|
|
321
482
|
|
|
322
483
|
// 移除事件计时器
|
|
323
|
-
removeTimer = (timerId: string) => {
|
|
324
|
-
|
|
325
|
-
|
|
484
|
+
removeTimer = (trackingId: string, timerId: string) => {
|
|
485
|
+
const timers = this.dataStore.trackTimers[trackingId];
|
|
486
|
+
if (timerId && timers && timers[timerId]) {
|
|
487
|
+
delete timers[timerId];
|
|
326
488
|
return true;
|
|
489
|
+
} else {
|
|
490
|
+
consoleText('未查询到指定计时器,请检查!', 'error');
|
|
491
|
+
return false;
|
|
327
492
|
}
|
|
328
|
-
return false;
|
|
329
493
|
};
|
|
330
494
|
|
|
331
495
|
// 清除所有事件计时器
|
|
332
|
-
clearTrackTimer = () => {
|
|
333
|
-
this.dataStore.trackTimers = {};
|
|
496
|
+
clearTrackTimer = (trackingId: string) => {
|
|
497
|
+
this.dataStore.trackTimers[trackingId] = {};
|
|
334
498
|
};
|
|
335
499
|
|
|
336
|
-
//
|
|
337
|
-
|
|
338
|
-
if (
|
|
339
|
-
this.dataStore.
|
|
340
|
-
...this.dataStore.generalProps,
|
|
341
|
-
...properties
|
|
342
|
-
};
|
|
343
|
-
keys(this.dataStore.generalProps).forEach((k: string) => {
|
|
344
|
-
if ([undefined, null].includes(this.dataStore.generalProps[k])) {
|
|
345
|
-
this.dataStore.generalProps[k] = '';
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
} else {
|
|
349
|
-
callError('setGeneralProps');
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
// 清空已设置的埋点事件的通用属性
|
|
354
|
-
clearGeneralProps = (properties: string[] | undefined) => {
|
|
355
|
-
if (isArray(properties) && !isEmpty(properties)) {
|
|
356
|
-
properties.forEach((prop: string) => {
|
|
357
|
-
unset(this.dataStore.generalProps, prop);
|
|
358
|
-
});
|
|
359
|
-
} else {
|
|
360
|
-
this.dataStore.generalProps = {};
|
|
500
|
+
// 手动获取位置信息补发visit上报
|
|
501
|
+
setLocation = (trackingId: string, latitude: number, longitude: number) => {
|
|
502
|
+
if (isEmpty(this.dataStore.locationData[trackingId])) {
|
|
503
|
+
this.dataStore.locationData[trackingId] = {};
|
|
361
504
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
currentPage.pageProps[currentPath] = limitObject(properties);
|
|
505
|
+
const ld = this.dataStore.locationData[trackingId];
|
|
506
|
+
const verifyLT = (o: number) => o >= -180 && o <= 180;
|
|
507
|
+
if (
|
|
508
|
+
verifyLT(latitude) &&
|
|
509
|
+
verifyLT(longitude) &&
|
|
510
|
+
(ld.latitude !== latitude || ld.longitude !== longitude)
|
|
511
|
+
) {
|
|
512
|
+
this.dataStore.locationData[trackingId] = { latitude, longitude };
|
|
371
513
|
}
|
|
372
514
|
};
|
|
373
515
|
|
|
374
516
|
// 手动更新曝光监听(该方法会在曝光插件加载时被重写)
|
|
375
517
|
updateImpression = () => {
|
|
376
518
|
consoleText(
|
|
377
|
-
'
|
|
378
|
-
'
|
|
519
|
+
'updateImpression 错误! 请集成半自动埋点浏览插件后重试!',
|
|
520
|
+
'error'
|
|
379
521
|
);
|
|
380
522
|
};
|
|
381
523
|
|
|
382
|
-
//
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
const verifyLT = (o: number) => o >= -180 && o <= 180;
|
|
387
|
-
if (
|
|
388
|
-
verifyLT(latitude) &&
|
|
389
|
-
verifyLT(longitude) &&
|
|
390
|
-
(ld.latitude !== latitude || ld.longitude !== longitude)
|
|
391
|
-
) {
|
|
392
|
-
this.dataStore.locationData = nld;
|
|
393
|
-
}
|
|
524
|
+
// 获取A/B实验数据
|
|
525
|
+
getABTest = (trackingId: string, layerId: string | number, callback: any) => {
|
|
526
|
+
consoleText('获取ABTest数据错误! 请集成ABTest插件后重试!', 'error');
|
|
527
|
+
niceCallback(callback, {});
|
|
394
528
|
};
|
|
395
529
|
|
|
396
530
|
// 获取打通信息
|
|
397
|
-
getGioInfo = () => {
|
|
398
|
-
const {
|
|
531
|
+
getGioInfo = (trackingId: string) => {
|
|
532
|
+
const { getUid, getUserId, getUserKey, getSessionId } = this.userStore;
|
|
399
533
|
const {
|
|
400
534
|
projectId,
|
|
401
535
|
appId,
|
|
@@ -404,19 +538,19 @@ class GrowingIO implements GrowingIOType {
|
|
|
404
538
|
idMapping,
|
|
405
539
|
extraParams,
|
|
406
540
|
ignoreFields
|
|
407
|
-
} = this.
|
|
541
|
+
} = this.dataStore.getTrackerVds(trackingId);
|
|
408
542
|
const infos: any = {
|
|
409
543
|
gioappid: appId,
|
|
410
|
-
giocs1:
|
|
544
|
+
giocs1: getUserId(trackingId) || '',
|
|
411
545
|
gioplatform: this.platformConfig.platform,
|
|
412
546
|
gioprojectid: projectId,
|
|
413
|
-
gios:
|
|
414
|
-
giou:
|
|
547
|
+
gios: getSessionId(trackingId),
|
|
548
|
+
giou: getUid()
|
|
415
549
|
};
|
|
416
550
|
infos.giodatacollect = dataCollect;
|
|
417
551
|
infos.giodatasourceid = dataSourceId;
|
|
418
552
|
if (idMapping) {
|
|
419
|
-
infos.giouserkey =
|
|
553
|
+
infos.giouserkey = getUserKey(trackingId);
|
|
420
554
|
}
|
|
421
555
|
if (!isEmpty(extraParams)) {
|
|
422
556
|
extraParams.forEach((o) => {
|