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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* 名称:uniapp代理插件
|
|
3
3
|
* 用途:用于重写uniapp框架下的创建App/Page/Component方法实现代理Hook;并获取uniapp框架下的自定义方法真实方法名获取。
|
|
4
4
|
*/
|
|
5
|
+
import { UNIAPP_FUNC_REG } from '@@/constants/regex';
|
|
5
6
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
6
7
|
|
|
7
8
|
const ONCE = '~';
|
|
@@ -23,11 +24,7 @@ class GioUniAppAdapter {
|
|
|
23
24
|
this.uniVue = this.growingIO?.vdsConfig?.uniVue;
|
|
24
25
|
}
|
|
25
26
|
console.log('Vue version: ', this.uniVue.version);
|
|
26
|
-
|
|
27
|
-
const mainVersion = Number.parseInt(
|
|
28
|
-
ut.head(ut.split(this.uniVue.version, '.')),
|
|
29
|
-
10
|
|
30
|
-
);
|
|
27
|
+
const mainVersion = Number(ut.head(ut.split(this.uniVue.version, '.')));
|
|
31
28
|
switch (mainVersion) {
|
|
32
29
|
case 2:
|
|
33
30
|
this.uniVue2Proxy(this.uniVue);
|
|
@@ -112,6 +109,38 @@ class GioUniAppAdapter {
|
|
|
112
109
|
dataStore: { eventHooks },
|
|
113
110
|
minipInstance
|
|
114
111
|
} = this.growingIO;
|
|
112
|
+
// 重写对象遍历逻辑,优先hook methods最后才是原生
|
|
113
|
+
eventHooks.objectTraverse = (target: any, fn: any) => {
|
|
114
|
+
if (ut.has(target, 'methods')) {
|
|
115
|
+
Object.getOwnPropertyNames(target.methods).forEach((k: string) => {
|
|
116
|
+
fn(k, target.methods);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (ut.has(target, 'lifetimes')) {
|
|
120
|
+
Object.getOwnPropertyNames(target.lifetimes).forEach((k: string) => {
|
|
121
|
+
fn(k, target.lifetimes);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (ut.has(target, 'pageLifetimes')) {
|
|
125
|
+
Object.getOwnPropertyNames(target.pageLifetimes).forEach(
|
|
126
|
+
(k: string) => {
|
|
127
|
+
fn(k, target.pageLifetimes);
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
Object.getOwnPropertyNames(target).forEach((k: string) => {
|
|
132
|
+
if (
|
|
133
|
+
!ut.niceTry(
|
|
134
|
+
() =>
|
|
135
|
+
!target?.methods[k] &&
|
|
136
|
+
!target?.lifetimes[k] &&
|
|
137
|
+
!target?.pageLifetimes[k]
|
|
138
|
+
)
|
|
139
|
+
) {
|
|
140
|
+
fn(k, target);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
};
|
|
115
144
|
eventHooks.nativeGrowing();
|
|
116
145
|
// 需要单独处理getPageTitle,防止在vue中onShow里拿的是错误的
|
|
117
146
|
const originGetter = minipInstance.getPageTitle;
|
|
@@ -180,7 +209,7 @@ class GioUniAppAdapter {
|
|
|
180
209
|
const methodKeys = ut
|
|
181
210
|
.keys(this.$scope)
|
|
182
211
|
.filter(
|
|
183
|
-
(k) =>
|
|
212
|
+
(k) => UNIAPP_FUNC_REG.test(k) && ut.isFunction(this.$scope[k])
|
|
184
213
|
);
|
|
185
214
|
methodKeys.forEach((k, i) => {
|
|
186
215
|
const originFunc = this.$scope[k].value;
|
package/src/constants/config.ts
CHANGED
|
@@ -15,7 +15,7 @@ export const DEFAULT_SETTINGS = {
|
|
|
15
15
|
extraParams: { type: 'array', default: [] },
|
|
16
16
|
// 是否开启分享跟踪
|
|
17
17
|
followShare: { type: 'boolean', default: true },
|
|
18
|
-
//
|
|
18
|
+
// 是否开启强制登录;多实例时仅主实例生效(其他实例无条件服从主实例)
|
|
19
19
|
forceLogin: { type: 'boolean', default: false },
|
|
20
20
|
// 或略上报字段
|
|
21
21
|
ignoreFields: { type: 'array', default: [] },
|
|
@@ -29,8 +29,8 @@ export const DEFAULT_SETTINGS = {
|
|
|
29
29
|
performance: { type: 'object', default: { monitor: true, exception: true } },
|
|
30
30
|
// 数据上报域名
|
|
31
31
|
serverUrl: { type: 'string', default: 'https://napi.growingio.com' },
|
|
32
|
-
//
|
|
33
|
-
|
|
32
|
+
// 请求超时时长
|
|
33
|
+
requestTimeout: { type: 'number', default: 5000 },
|
|
34
34
|
// taro框架实例
|
|
35
35
|
taro: { type: ['object', 'module'], default: false },
|
|
36
36
|
// taro框架vue实例
|
|
@@ -47,6 +47,8 @@ export const DEFAULT_SETTINGS = {
|
|
|
47
47
|
path: undefined
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
+
// 是否自动采集页面访问事件
|
|
51
|
+
trackPage: { type: 'boolean', default: true },
|
|
50
52
|
// uniapp vue实例
|
|
51
53
|
uniVue: { type: ['object', 'function'], default: false },
|
|
52
54
|
// 上报间隔(1秒)
|
|
@@ -55,35 +57,48 @@ export const DEFAULT_SETTINGS = {
|
|
|
55
57
|
version: { type: 'string', default: '1.0.0' }
|
|
56
58
|
};
|
|
57
59
|
|
|
58
|
-
//
|
|
59
|
-
export const
|
|
60
|
-
'
|
|
60
|
+
// 不管实例直接调用的方法
|
|
61
|
+
export const DIRECT_HANDLERS = [
|
|
62
|
+
'getPlugins', // 获取所有已加载插件
|
|
63
|
+
'getDeviceId', // 获取设备id
|
|
64
|
+
'updateImpression' // 手动更新曝光
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
// 多实例的方法
|
|
68
|
+
export const INSTANCE_HANDLERS = [
|
|
69
|
+
'clearGeneralProps', // 清除埋点通用属性
|
|
61
70
|
'clearTrackTimer', // 清除所有事件计时器
|
|
62
|
-
'clearUserId', //
|
|
63
|
-
'
|
|
71
|
+
'clearUserId', // 清除用户id
|
|
72
|
+
'getABTest', // 获取AB实验数据
|
|
64
73
|
'getGioInfo', // 内嵌页打通信息
|
|
65
|
-
'getOption', //
|
|
66
|
-
'identify', //
|
|
67
|
-
'init', // 初始化SDK
|
|
68
|
-
'registerPlugins', // 手动注册插件
|
|
74
|
+
'getOption', // 获取当前SDK配置项状态
|
|
75
|
+
'identify', // 强制登录设置设备id
|
|
69
76
|
'removeTimer', // 移除事件计时器
|
|
77
|
+
'sendPage', // 手动发page事件
|
|
78
|
+
'sendVisit', // 手动发visit事件
|
|
70
79
|
'setGeneralProps', // 设置埋点通用属性
|
|
71
|
-
'setLocation', //
|
|
72
|
-
'setOption', //
|
|
80
|
+
'setLocation', // 手动设置位置信息
|
|
81
|
+
'setOption', // 设置配置项
|
|
73
82
|
'setPageAttributes', // 设置页面属性
|
|
74
83
|
'setUserAttributes', // 设置用户属性
|
|
75
|
-
'setUserId', //
|
|
76
|
-
'track', //
|
|
84
|
+
'setUserId', // 设置用户id
|
|
85
|
+
'track', // 上报埋点
|
|
77
86
|
'trackTimerEnd', // 停止事件计时器并上报事件
|
|
78
87
|
'trackTimerPause', // 暂停事件计时器
|
|
79
88
|
'trackTimerResume', // 恢复事件计时器
|
|
80
|
-
'trackTimerStart'
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
'trackTimerStart' // 初始化事件计时器
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
// 直接调用的通用方法
|
|
93
|
+
export const HANDLERS = [
|
|
94
|
+
'init', // 初始化SDK
|
|
95
|
+
'registerPlugins', // 手动注册插件
|
|
96
|
+
...DIRECT_HANDLERS,
|
|
97
|
+
...INSTANCE_HANDLERS
|
|
83
98
|
];
|
|
84
99
|
|
|
85
100
|
// 允许通过setOption修改的配置项
|
|
86
|
-
export const
|
|
101
|
+
export const ALLOW_SET_OPTIONS = {
|
|
87
102
|
autotrack: '无埋点',
|
|
88
103
|
dataCollect: '数据采集',
|
|
89
104
|
debug: '调试模式',
|
|
@@ -134,3 +149,17 @@ export const PLATFORMTYPES = [
|
|
|
134
149
|
'xhs',
|
|
135
150
|
'quickapp'
|
|
136
151
|
];
|
|
152
|
+
|
|
153
|
+
// 各个需要拼接的在存储中的key后缀
|
|
154
|
+
export const STORAGE_KEYS: any = {
|
|
155
|
+
gsid: '_growing_gsid_',
|
|
156
|
+
originalSource: '_gdp_original_source_',
|
|
157
|
+
userId: '_growing_userId_',
|
|
158
|
+
userKey: '_growing_userKey_',
|
|
159
|
+
gioId: '_growing_gioId_',
|
|
160
|
+
plugin_gsid: '_growing_plugin_gsid_',
|
|
161
|
+
plugin_originalSource: '_gdp_plugin_original_source_',
|
|
162
|
+
plugin_userId: '_growing_plugin_userId_',
|
|
163
|
+
plugin_userKey: '_growing_plugin_userKey_',
|
|
164
|
+
plugin_gioId: '_growing_plugin_gioId_'
|
|
165
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
GIOID_UPDATE: 'GIOID_UPDATE', // gioId变更事件
|
|
3
|
+
MINIP_LIFECYCLE: 'MINIP_LIFECYCLE', // 小程序生命周期
|
|
4
|
+
ON_COMMIT_REQUEST: 'ON_COMMIT_REQUEST', // 小程序事件提交队列
|
|
5
|
+
ON_COMPOSE_AFTER: 'ON_COMPOSE_AFTER', // 插件生命周期:构建事件后
|
|
6
|
+
ON_COMPOSE_BEFORE: 'ON_COMPOSE_BEFORE', // 插件生命周期:构建事件前
|
|
7
|
+
ON_ERROR: 'ON_ERROR', // 插件生命周期:插件执行错误
|
|
8
|
+
ON_INSTALL: 'ON_INSTALL', // 插件生命周期:插件被正确加载
|
|
9
|
+
ON_SDK_INITIALIZE_BEFORE: 'ON_SDK_INITIALIZE_BEFORE', // SDK开始初始化之前
|
|
10
|
+
ON_SEND_AFTER: 'ON_SEND_AFTER', // 插件生命周期:发送事件后
|
|
11
|
+
ON_SEND_BEFORE: 'ON_SEND_BEFORE', // 插件生命周期:发送事件前
|
|
12
|
+
OPTION_CHANGE: 'OPTION_CHANGE', // 设置变更事件
|
|
13
|
+
OPTION_INITIALIZED: 'OPTION_INITIALIZED', // 配置项初始化完成
|
|
14
|
+
SCENE_UPDATE: 'SCENE_UPDATE', // scene变更事件
|
|
15
|
+
SDK_INITIALIZED: 'SDK_INITIALIZED', // SDK初始化完成发送事件之前
|
|
16
|
+
SESSIONID_UPDATE: 'SESSIONID_UPDATE', // sessionId变更事件
|
|
17
|
+
SET_USERID: 'SET_USERID', // setUserId事件
|
|
18
|
+
SET_USERKEY: 'SET_USERKEY', // setUserKey事件
|
|
19
|
+
UID_UPDATE: 'UID_UPDATE', // uId(设备Id)变更事件
|
|
20
|
+
UN_EXECUTE_CALL: 'UN_EXECUTE_CALL', // SDK加载完成但没有初始化时的调用事件
|
|
21
|
+
USERID_UPDATE: 'USERID_UPDATE', // userId变更事件
|
|
22
|
+
USERKEY_UPDATE: 'USERKEY_UPDATE' // userKey变更事件
|
|
23
|
+
};
|
package/src/constants/regex.ts
CHANGED
|
@@ -2,3 +2,17 @@ export const IPReg =
|
|
|
2
2
|
/^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/i;
|
|
3
3
|
export const URLReg =
|
|
4
4
|
/^(https?:\/\/)|(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i;
|
|
5
|
+
export const UNIAPP_FUNC_REG = /^e[0-9]+$/;
|
|
6
|
+
export const ABTEST_SIGN_REG = /^\d+_gdp_abt_sign$/;
|
|
7
|
+
export const ABTEST_DATA_REG = /^\d+_gdp_abtd$/;
|
|
8
|
+
export const ID_REG = /^\d{1,10}$/;
|
|
9
|
+
export const IMP_DATA_REG = /^gioTrack(.+)/;
|
|
10
|
+
export const IMP_EVENTNAME_REG = /^[a-zA-Z_][0-9a-zA-Z_]{0,100}$/;
|
|
11
|
+
export const SWAN_XID_REG = /^_[0-9a-z]+/;
|
|
12
|
+
export const TARO_XID_REG = /^_n_[0-9]+$/;
|
|
13
|
+
export const TARO_EVENT_PROPS_REG = /^__reactProps\$[a-z0-9]+$/i;
|
|
14
|
+
export const TARO_EVENT_REACT_FUNC1_REG = /return [$\w]+.\w+\(/;
|
|
15
|
+
export const TARO_EVENT_REACT_FUNC2_REG = /return \w+\(/;
|
|
16
|
+
export const TARO_EVENT_VUE_FUNC1_REG = /return [$\w]+.\$emit\(['"]\w+/;
|
|
17
|
+
export const TARO_EVENT_VUE_FUNC2_REG = /return [$\w]+.\w+/;
|
|
18
|
+
export const TARO_EVENT_VUE_FUNC3_REG = /return [$\w]+/;
|
|
@@ -6,27 +6,34 @@ class EventContextBuilder {
|
|
|
6
6
|
constructor(public growingIO: GrowingIOType) {}
|
|
7
7
|
|
|
8
8
|
// 通用字段组装
|
|
9
|
-
main = (params?: any) => {
|
|
9
|
+
main = (trackingId: string, params?: any) => {
|
|
10
|
+
// 预置事件或者默认就是发给主实例的事件不需要传trackingId
|
|
11
|
+
if (!trackingId) {
|
|
12
|
+
trackingId = this.growingIO.trackingId;
|
|
13
|
+
}
|
|
10
14
|
const {
|
|
11
15
|
sdkVersion,
|
|
12
|
-
vdsConfig,
|
|
13
16
|
platformConfig,
|
|
14
17
|
minipInstance,
|
|
15
18
|
userStore,
|
|
16
|
-
dataStore
|
|
19
|
+
dataStore,
|
|
20
|
+
dataStore: { scene, eventHooks, lastVisitEvent, lastPageEvent }
|
|
17
21
|
} = this.growingIO;
|
|
22
|
+
const { version, dataSourceId, appId, idMapping, ignoreFields } =
|
|
23
|
+
dataStore.getTrackerVds(trackingId);
|
|
24
|
+
const locationData = dataStore.locationData[trackingId];
|
|
18
25
|
const { systemInfo = {}, network = {} } = minipInstance;
|
|
19
|
-
const { brand, model, platform, language
|
|
26
|
+
const { brand, model, platform, language } = systemInfo;
|
|
20
27
|
// 事件主要内容组装
|
|
21
28
|
const context: any = {
|
|
22
29
|
appChannel: `scn:${scene || 'NA'}`,
|
|
23
|
-
appVersion:
|
|
24
|
-
dataSourceId:
|
|
30
|
+
appVersion: version,
|
|
31
|
+
dataSourceId: dataSourceId,
|
|
25
32
|
deviceBrand: brand,
|
|
26
|
-
deviceId: userStore.
|
|
33
|
+
deviceId: userStore.getUid(),
|
|
27
34
|
deviceModel: model,
|
|
28
35
|
deviceType: getOS(platform, platformConfig.name),
|
|
29
|
-
domain:
|
|
36
|
+
domain: appId,
|
|
30
37
|
language: language,
|
|
31
38
|
latitude: locationData?.latitude,
|
|
32
39
|
longitude: locationData?.longitude,
|
|
@@ -36,34 +43,38 @@ class EventContextBuilder {
|
|
|
36
43
|
? eventHooks.currentPage?.path
|
|
37
44
|
: lastVisitEvent.path, // 如果页面中的path取不到,说明页面没初始化,还在app的生命周期中(appOnLoad/appOnShow),需要拿visit的path补上
|
|
38
45
|
platform: platformConfig.platform,
|
|
39
|
-
platformVersion:
|
|
46
|
+
platformVersion:
|
|
47
|
+
platformConfig.name +
|
|
48
|
+
(systemInfo.version ? ` ${systemInfo.version}` : ''),
|
|
40
49
|
query: eventHooks.currentPage?.path
|
|
41
50
|
? eventHooks.currentPage?.query
|
|
42
51
|
: lastVisitEvent.query, // 如果页面中的path取不到,说明页面没初始化,还在app的生命周期中(appOnLoad/appOnShow),需要拿visit的query补上
|
|
43
52
|
screenHeight: getScreenHeight(systemInfo),
|
|
44
53
|
screenWidth: getScreenWidth(systemInfo),
|
|
45
54
|
sdkVersion,
|
|
46
|
-
sessionId: userStore.
|
|
55
|
+
sessionId: userStore.getSessionId(trackingId),
|
|
47
56
|
title:
|
|
57
|
+
lastPageEvent[trackingId]?.title || // 除visit,page事件外,其他事件都用lastpage中的title以保持一致
|
|
48
58
|
eventHooks.currentPage?.title ||
|
|
49
59
|
minipInstance.getPageTitle(minipInstance.getCurrentPage()),
|
|
50
60
|
timestamp: Date.now(),
|
|
51
61
|
timezoneOffset: new Date().getTimezoneOffset(),
|
|
52
|
-
userId: userStore.
|
|
62
|
+
userId: userStore.getUserId(trackingId)
|
|
53
63
|
};
|
|
54
|
-
if (
|
|
55
|
-
context.userKey = userStore.
|
|
64
|
+
if (idMapping) {
|
|
65
|
+
context.userKey = userStore.getUserKey(trackingId);
|
|
56
66
|
}
|
|
57
|
-
if (!isEmpty(
|
|
58
|
-
|
|
67
|
+
if (!isEmpty(ignoreFields)) {
|
|
68
|
+
ignoreFields.forEach((o) => {
|
|
59
69
|
unset(context, o);
|
|
60
70
|
});
|
|
61
71
|
}
|
|
62
72
|
// 此时可能存在数据为空的字段,在数据组装完成后由转换方法移除空值字段
|
|
63
73
|
if (!isEmpty(params)) {
|
|
64
|
-
return { ...context, ...params };
|
|
74
|
+
return { ...context, ...params, trackingId };
|
|
75
|
+
} else {
|
|
76
|
+
return { ...context, trackingId };
|
|
65
77
|
}
|
|
66
|
-
return context;
|
|
67
78
|
};
|
|
68
79
|
}
|
|
69
80
|
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isNil
|
|
11
11
|
} from '@@/utils/glodash';
|
|
12
12
|
import { qsStringify } from '@@/utils/tools';
|
|
13
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
13
14
|
|
|
14
15
|
class AppEffects {
|
|
15
16
|
constructor(public growingIO: GrowingIOType) {}
|
|
@@ -24,14 +25,15 @@ class AppEffects {
|
|
|
24
25
|
uploader,
|
|
25
26
|
dataStore,
|
|
26
27
|
dataStore: {
|
|
28
|
+
trackersExecute,
|
|
27
29
|
shareOut,
|
|
28
|
-
keepAlive,
|
|
29
30
|
lastCloseTime,
|
|
30
31
|
eventHooks,
|
|
31
|
-
saveStorageInfo
|
|
32
|
+
saveStorageInfo,
|
|
33
|
+
setOriginalSource
|
|
32
34
|
}
|
|
33
35
|
}: GrowingIOType = this.growingIO;
|
|
34
|
-
emitter.emit(
|
|
36
|
+
emitter.emit(EMIT_MSG.MINIP_LIFECYCLE, {
|
|
35
37
|
event: `App ${event}`,
|
|
36
38
|
timestamp: eventTime,
|
|
37
39
|
params: args[0] ?? {}
|
|
@@ -41,7 +43,7 @@ class AppEffects {
|
|
|
41
43
|
}
|
|
42
44
|
const appListeners = platformConfig.listeners.app;
|
|
43
45
|
// 向插件广播事件
|
|
44
|
-
emitter.emit(
|
|
46
|
+
emitter.emit(EMIT_MSG.ON_COMPOSE_BEFORE, {
|
|
45
47
|
event: `App ${event}`,
|
|
46
48
|
params: args[0] ?? {}
|
|
47
49
|
});
|
|
@@ -54,25 +56,33 @@ class AppEffects {
|
|
|
54
56
|
const { path, query } = this.enterParamsParse(args[0]);
|
|
55
57
|
if (!shareOut && vdsConfig.originalSource) {
|
|
56
58
|
// 保存初始来源信息
|
|
57
|
-
|
|
59
|
+
trackersExecute((trackingId: string) => {
|
|
60
|
+
setOriginalSource(trackingId, { path, query });
|
|
61
|
+
});
|
|
58
62
|
}
|
|
59
63
|
// 以下条件均会被认为是一次新的访问
|
|
60
64
|
// 没有关闭时间说明是新访问
|
|
61
65
|
if (!lastCloseTime) {
|
|
62
66
|
// 保存进入小程序的参数
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
dataStore.lastVisitEvent = { path, query };
|
|
68
|
+
trackersExecute((trackingId: string) => {
|
|
69
|
+
this.buildVisitEvent(trackingId, { path, query });
|
|
70
|
+
});
|
|
65
71
|
} else if (
|
|
66
72
|
// 两次打开间隔时间超过keepAlive设定(默认5分钟)
|
|
67
|
-
Date.now() - lastCloseTime > keepAlive ||
|
|
73
|
+
Date.now() - lastCloseTime > vdsConfig.keepAlive ||
|
|
68
74
|
// 两次打开时的场景值不一样(即从不同的来源进入小程序)
|
|
69
75
|
(dataStore.lastScene && dataStore.scene !== dataStore.lastScene)
|
|
70
76
|
) {
|
|
71
77
|
// 重置sessionId
|
|
72
|
-
|
|
78
|
+
trackersExecute((trackingId: string) => {
|
|
79
|
+
userStore.setSessionId(trackingId);
|
|
80
|
+
});
|
|
73
81
|
// 需要按自然逻辑发visit时,清掉pagetime,防止取值错误(会在page中重新生成)
|
|
74
82
|
eventHooks.currentPage.time = undefined;
|
|
75
|
-
|
|
83
|
+
trackersExecute((trackingId: string) => {
|
|
84
|
+
this.buildVisitEvent(trackingId, { path, query });
|
|
85
|
+
});
|
|
76
86
|
}
|
|
77
87
|
break;
|
|
78
88
|
}
|
|
@@ -82,11 +92,14 @@ class AppEffects {
|
|
|
82
92
|
dataStore.lastCloseTime = Date.now();
|
|
83
93
|
saveStorageInfo();
|
|
84
94
|
userStore.saveUserInfo();
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
95
|
+
trackersExecute((trackingId: string) => {
|
|
96
|
+
this.buildCloseEvent(trackingId);
|
|
97
|
+
// forceLogin不生效时强制把请求队列中的事件全部发送
|
|
98
|
+
if (!vdsConfig.forceLogin) {
|
|
99
|
+
uploader.initiateRequest(trackingId, true);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
90
103
|
break;
|
|
91
104
|
}
|
|
92
105
|
default:
|
|
@@ -173,45 +186,51 @@ class AppEffects {
|
|
|
173
186
|
};
|
|
174
187
|
|
|
175
188
|
// 构建访问事件
|
|
176
|
-
buildVisitEvent = (
|
|
177
|
-
const { dataStore, vdsConfig, minipInstance } = this.growingIO;
|
|
189
|
+
buildVisitEvent = (trackingId: string, props?: any) => {
|
|
178
190
|
const {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
191
|
+
dataStore: {
|
|
192
|
+
getOriginalSource,
|
|
193
|
+
eventContextBuilder,
|
|
194
|
+
eventInterceptor,
|
|
195
|
+
eventHooks
|
|
196
|
+
},
|
|
197
|
+
minipInstance,
|
|
198
|
+
vdsConfig
|
|
199
|
+
} = this.growingIO;
|
|
200
|
+
const originalSource = getOriginalSource(trackingId);
|
|
185
201
|
// 生命周期中调用构建使用参数赋值,补发场景调用构建使用上一次的值
|
|
186
202
|
const query = props?.query || '';
|
|
187
203
|
let event = {
|
|
188
204
|
eventType: 'VISIT',
|
|
189
|
-
...eventContextBuilder({
|
|
205
|
+
...eventContextBuilder(trackingId, {
|
|
190
206
|
// params.path是生命周期值或者是已有的值
|
|
191
207
|
path: props?.path || '',
|
|
192
208
|
// params.query是对象说明是生命周期调用,否则是补发调用
|
|
193
|
-
query: typeOf(query) === 'string' ? query : qsStringify(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()
|
|
194
217
|
})
|
|
195
218
|
};
|
|
196
219
|
// 配置使用初始来源时,visit使用初始来源数据
|
|
197
220
|
if (vdsConfig.originalSource && !isNil(originalSource)) {
|
|
198
221
|
event = { ...event, ...originalSource };
|
|
199
|
-
// 采集开关开启状态下的第一个visit消费过初始来源信息后删除
|
|
200
|
-
if (vdsConfig.dataCollect) {
|
|
201
|
-
minipInstance.removeStorageSync(originalSourceName);
|
|
202
|
-
}
|
|
203
222
|
}
|
|
204
223
|
eventInterceptor(event);
|
|
205
224
|
};
|
|
206
225
|
|
|
207
226
|
// 构建关闭事件
|
|
208
|
-
buildCloseEvent = () => {
|
|
227
|
+
buildCloseEvent = (trackingId: string) => {
|
|
209
228
|
const {
|
|
210
229
|
dataStore: { eventContextBuilder, eventInterceptor }
|
|
211
230
|
} = this.growingIO;
|
|
212
231
|
const event = {
|
|
213
232
|
eventType: 'APP_CLOSED',
|
|
214
|
-
...eventContextBuilder()
|
|
233
|
+
...eventContextBuilder(trackingId)
|
|
215
234
|
};
|
|
216
235
|
eventInterceptor(event);
|
|
217
236
|
};
|
|
@@ -6,6 +6,7 @@ import { consoleText, getGlobal, niceTry } from '@@/utils/tools';
|
|
|
6
6
|
import AppEffects from './appEffects';
|
|
7
7
|
import MinipPage from './minipPage';
|
|
8
8
|
import PageEffects from './pageEffects';
|
|
9
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
9
10
|
|
|
10
11
|
class EventHooks implements EventHooksType {
|
|
11
12
|
private appHooked: boolean;
|
|
@@ -33,10 +34,6 @@ class EventHooks implements EventHooksType {
|
|
|
33
34
|
this.appHandlers = config.appHandlers;
|
|
34
35
|
this.pageHandlers = config.pageHandlers;
|
|
35
36
|
this.actionEventTypes = config.actionEventTypes;
|
|
36
|
-
this.originalApp = config.originalApp;
|
|
37
|
-
this.originalPage = config.originalPage;
|
|
38
|
-
this.originalComponent = config.originalComponent;
|
|
39
|
-
this.originalBehavior = config.originalBehavior ?? function () {}; // eslint-disable-line
|
|
40
37
|
this.appEffects = new AppEffects(this.growingIO);
|
|
41
38
|
this.pageEffects = new PageEffects(this.growingIO);
|
|
42
39
|
this.currentPage = new MinipPage(this.growingIO);
|
|
@@ -161,7 +158,7 @@ class EventHooks implements EventHooksType {
|
|
|
161
158
|
if (eventName !== 'onShareAppMessage') {
|
|
162
159
|
result = method.apply(this, args);
|
|
163
160
|
}
|
|
164
|
-
self.growingIO.emitter.emit(
|
|
161
|
+
self.growingIO.emitter.emit(EMIT_MSG.MINIP_LIFECYCLE, {
|
|
165
162
|
event: `${cType} ${eventName}End`,
|
|
166
163
|
timestamp: Date.now(),
|
|
167
164
|
params: { instance: this, arguments: Array.from(args) }
|
|
@@ -324,6 +321,7 @@ class EventHooks implements EventHooksType {
|
|
|
324
321
|
try {
|
|
325
322
|
// 重写App
|
|
326
323
|
if (platformHooks.App && !this.appHooked) {
|
|
324
|
+
this.originalApp = App || global.App || function () {};
|
|
327
325
|
App = function (...args) {
|
|
328
326
|
return self.growingApp(args[0]);
|
|
329
327
|
};
|
|
@@ -337,6 +335,7 @@ class EventHooks implements EventHooksType {
|
|
|
337
335
|
try {
|
|
338
336
|
// 重写Page
|
|
339
337
|
if (platformHooks.Page && !this.pageHooked) {
|
|
338
|
+
this.originalPage = Page || global.Page || function () {};
|
|
340
339
|
Page = function (...args) {
|
|
341
340
|
return self.growingPage(args[0]);
|
|
342
341
|
};
|
|
@@ -350,6 +349,8 @@ class EventHooks implements EventHooksType {
|
|
|
350
349
|
try {
|
|
351
350
|
// 重写Component
|
|
352
351
|
if (platformHooks.Component && !this.componentHooked) {
|
|
352
|
+
this.originalComponent =
|
|
353
|
+
Component || global.Component || function () {};
|
|
353
354
|
Component = function (...args) {
|
|
354
355
|
return self.growingComponent(args[0]);
|
|
355
356
|
};
|
|
@@ -363,6 +364,7 @@ class EventHooks implements EventHooksType {
|
|
|
363
364
|
try {
|
|
364
365
|
// 重写Behavior
|
|
365
366
|
if (platformHooks.Behavior && !this.behaviorHooked) {
|
|
367
|
+
this.originalBehavior = Behavior || global.Behavior || function () {};
|
|
366
368
|
Behavior = function (...args) {
|
|
367
369
|
return self.growingBehavior(args[0]);
|
|
368
370
|
};
|
|
@@ -11,8 +11,6 @@ class MinipPage implements MinipPageType {
|
|
|
11
11
|
public title: string;
|
|
12
12
|
// 通过调用wx.setNavigationBarTitle设置的title
|
|
13
13
|
public settedTitle: any;
|
|
14
|
-
// 当前页面参数中的分享id
|
|
15
|
-
public queryShareId: string;
|
|
16
14
|
// 页面级属性
|
|
17
15
|
public pageProps: any;
|
|
18
16
|
// 上一个执行的小程序生命周期
|
|
@@ -56,24 +54,17 @@ class MinipPage implements MinipPageType {
|
|
|
56
54
|
};
|
|
57
55
|
|
|
58
56
|
// 获取上一个页面路径
|
|
59
|
-
getReferralPage = () => {
|
|
57
|
+
getReferralPage = (trackingId: string) => {
|
|
60
58
|
const {
|
|
61
59
|
minipInstance,
|
|
62
60
|
dataStore: { lastPageEvent, scene }
|
|
63
61
|
} = this.growingIO;
|
|
64
62
|
return (
|
|
65
|
-
lastPageEvent?.path ||
|
|
63
|
+
lastPageEvent[trackingId]?.path ||
|
|
66
64
|
(scene ? `scn:${minipInstance.scnPrefix}${scene}` : null)
|
|
67
65
|
);
|
|
68
66
|
};
|
|
69
67
|
|
|
70
|
-
// 保存分享id(记录是从哪个用户id的分享来的)
|
|
71
|
-
saveShareId = (query: any) => {
|
|
72
|
-
if (query?.gioShareId) {
|
|
73
|
-
this.queryShareId = query.gioShareId;
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
68
|
// 处理分享参数
|
|
78
69
|
buildShareQuery(
|
|
79
70
|
result: PageShareResult // 客户自定义的参数
|