visual-buried-point-platform-uni 1.0.0-alpha.2 → 1.0.0-alpha.21

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/README.md CHANGED
@@ -1,25 +1,29 @@
1
1
  ## Uni版自定义埋点SDK集成文档
2
2
 
3
+ ### SDK更新日志
4
+ - v1.0.0-alpha.07 最新uni、终端通用埋点sdk;
5
+ - v1.0.0-alpha.08 自定义上报数据结构删除path字段;
6
+ - v2.0.0 调整SDK内部PVUV采集模式,分原有start方法采集及自动采集,支持获取埋点sdk内的跟踪id;
7
+
3
8
  ### 1、引入方式
4
9
 
5
10
  ```js
6
- npm install visual-buried-point-platform-uni -S --registry=http://verdaccio.gogdev.cn/
7
- 工具-构建npm
11
+ //内网npm链接:http://verdaccio.gogdev.cn/
12
+ npm install visual-buried-point-platform-uni
8
13
  ```
9
14
 
10
15
  ### 2、初始化方式
11
16
 
12
- **app.js**
13
-
14
17
  ```js
15
- //require引入
16
18
  import { init } from 'visual-buried-point-platform-uni'
17
19
  onLaunch: function() {
18
20
  //初始化sdk
19
21
  init({
20
22
  env: 'test', //环境变量 test production
21
23
  token: '3212414516342554624', //热果平台-可视化埋点管理端-创建对应的项目生成.
22
- sourceDomain: 'com.gzdzswy.onetravel', // 非必填,访问来源域名,取优先级:单次调用上报值 > 全局初始化值
24
+ domain: 'com.gzdzswy.onetravel', // 非必填,访问来源域名,取优先级:单次调用上报值 > 全局初始化值
25
+ isCompatible: true, // 是否兼容老方案埋点,默认兼容true,自动采集则改为false
26
+ signTrackArray: [], // 自动采集但需要单独埋点的页面path
23
27
  })
24
28
  }
25
29
  });
@@ -46,14 +50,18 @@ setUserId(123456);
46
50
  ```js
47
51
  setUserId("");
48
52
  ```
53
+ ## 4.获取埋点SDK内跟踪ID
49
54
 
55
+ ```js
56
+ import { getTrackId } from 'visual-buried-point-platform-uni'
57
+ buriedPoint.getTrackId()
58
+ ```
50
59
 
51
-
52
- ### 4、自定义事件上报
60
+ ## 5、自定义事件上报
53
61
 
54
62
  - sdk初始化后,可通过 ***setCustomEvent()*** 方法上报自定义埋点事件,并为事件添加属性值:
55
63
 
56
- #### 4.1 事件类型:
64
+ #### 5.1 事件类型:
57
65
 
58
66
  - 仅能选择埋点提供的事件类型,各事件类型的触发、上报由各业务平台埋点自行确认。事件类型如下:
59
67
  - **搜索事件【 search 】**
@@ -125,7 +133,7 @@ const params = {
125
133
  setCustomEvent(params)
126
134
  ```
127
135
 
128
- ### 5、流量上报
136
+ ## 6、流量上报
129
137
 
130
138
  - sdk初始化后,可通过**onStartTrack(params)** 方法注册上报流量,并为上报添加属性值:
131
139
 
@@ -180,13 +188,13 @@ onDestroyTrack()
180
188
 
181
189
  注: 上报数据是否成功可查看NetWork栏,调用流量上报 **track 接口** 和 自定义上报 **event 接口**的 response
182
190
 
183
- #### 6、埋点后台管理系统
191
+ ## 7、埋点后台管理系统
184
192
 
185
193
  ##### 云测管理端地址
186
194
 
187
195
  - chameleon.gcongo.com.cn
188
196
 
189
- #### 7、SDK 文档
197
+ ## 8、SDK 文档
190
198
 
191
199
  http://verdaccio.gogdev.cn/-/web/detail/visual-buried-point-platform-uni
192
200
 
package/autoutils.js ADDED
@@ -0,0 +1,177 @@
1
+ import { reportTrackEventServer } from "./index.js";
2
+ import {
3
+ sdkTrackIdVal,
4
+ Global,
5
+ pagesArray,
6
+ timeToStr,
7
+ randomUUID,
8
+ } from "./tools.js";
9
+
10
+ export const AUTOTRACKTYPE = {
11
+ ENTER: "enter",
12
+ LOOP: "loop",
13
+ LEAVE: "leave",
14
+ };
15
+ // PVUV存储的key值
16
+ const BPNPVUV = "UNIBPNPVUVSrcData";
17
+ const BPNPVUVFail = "UNIBPNPVUVFailData";
18
+ // 采集数据
19
+ let atDuration;
20
+ let atEnterTimeLong;
21
+ let atLoopTimeLong;
22
+ let cirtemp;
23
+ let atObj;
24
+ let atInterval = null;
25
+ let cUUId = null;
26
+
27
+ function clearUAData() {
28
+ clearInterval(atInterval);
29
+ atDuration = 0;
30
+ atEnterTimeLong = 0;
31
+ atLoopTimeLong = 0;
32
+ cirtemp = 1;
33
+ atObj = null;
34
+ atInterval = null;
35
+ cUUId = 0;
36
+ }
37
+
38
+ export const uAutoStartTrackPVData = (objParams) => {
39
+ if (atInterval) {
40
+ autoStopTrackPVUV();
41
+ } else {
42
+ clearUAData();
43
+ atObj = objParams;
44
+ autoTrackData(AUTOTRACKTYPE.ENTER);
45
+ atInterval = setInterval(() => {
46
+ autoTrackData(AUTOTRACKTYPE.LOOP);
47
+ }, 15000);
48
+ }
49
+ };
50
+
51
+ export const autoStopTrackPVUV = () => {
52
+ autoTrackData(AUTOTRACKTYPE.LEAVE);
53
+ clearInterval(atInterval);
54
+ };
55
+
56
+ function autoTrackData(type) {
57
+ if (type === AUTOTRACKTYPE.ENTER) {
58
+ cirtemp = 1;
59
+ atDuration = 0;
60
+ atEnterTimeLong = Date.now();
61
+ atLoopTimeLong = atEnterTimeLong;
62
+ cUUId = randomUUID();
63
+ } else if (type === AUTOTRACKTYPE.LOOP) {
64
+ cirtemp = 2;
65
+ atDuration = 15;
66
+ atLoopTimeLong = Date.now();
67
+ } else if (type === AUTOTRACKTYPE.LEAVE) {
68
+ cirtemp = 3;
69
+ atDuration = Math.ceil((Date.now() - atLoopTimeLong) / 1000);
70
+ }
71
+ if (atObj) {
72
+ const puvData = {
73
+ busSegment: atObj.busSegment || "",
74
+ circulation: cirtemp,
75
+ domain: atObj.domain,
76
+ duration: atDuration,
77
+ module: atObj.module || "",
78
+ path: atObj.path,
79
+ url: atObj.url,
80
+ sourceDomain: atObj.sourceDomain,
81
+ sourceUrl: atObj.sourceUrl,
82
+ properties: atObj.properties,
83
+ title: atObj.title,
84
+ traceId: "",
85
+ trackId: sdkTrackIdVal(),
86
+ visitPage: atObj.visitPage,
87
+ visitTime: timeToStr(atEnterTimeLong),
88
+ pageUUId: cUUId,
89
+ };
90
+ if (puvData) {
91
+ insertPVUVData(puvData, cUUId);
92
+ }
93
+ }
94
+ }
95
+
96
+ // 插入数据
97
+ export function insertPVUVData(pData, pUUId) {
98
+ let td = uni.getStorageSync(BPNPVUV);
99
+ let mPVData = td ? JSON.parse(td) : [];
100
+ if (mPVData.length > 0) {
101
+ const index = mPVData.findIndex((obj) => obj.pageUUId === pUUId);
102
+ if (index !== -1) {
103
+ mPVData[index] = { ...mPVData[index], ...pData };
104
+ } else {
105
+ mPVData.push(pData);
106
+ }
107
+ } else {
108
+ mPVData.push(pData);
109
+ }
110
+ uni.setStorageSync(BPNPVUV, JSON.stringify(mPVData));
111
+ }
112
+
113
+ // 自动采集对象
114
+ export function autoPageObj(cpath, clength, cpages) {
115
+ let _pObj = pagesArray.find((obj) => obj.path === cpath);
116
+ let pf = Global.platform;
117
+ let url = "";
118
+ let domain = "";
119
+ let srcUrl = "";
120
+ let srcDomain = "";
121
+ if (pf) {
122
+ if (pf === "web" || pf === "h5") {
123
+ url = window.location.href;
124
+ domain = window.location.hostname;
125
+ if (document.referrer) {
126
+ let parsedUrl = new URL(document.referrer);
127
+ srcUrl = parsedUrl || "";
128
+ srcDomain = parsedUrl.hostname || "";
129
+ }
130
+ } else {
131
+ url = cpath;
132
+ if (clength > 1) {
133
+ let beforePage = cpages[clength - 2];
134
+ srcUrl = beforePage.route;
135
+ }
136
+ domain = Global.domain ? Global.domain : cpath;
137
+ }
138
+ }
139
+ return {
140
+ path: _pObj && _pObj.path ? _pObj.path : cpath,
141
+ busSegment:
142
+ _pObj && _pObj.busSegment ? _pObj.busSegment : Global.busSegment || "",
143
+ module: _pObj && _pObj.module ? _pObj.module : Global.module || "",
144
+ properties: _pObj && _pObj.properties ? _pObj.properties : "",
145
+ domain: domain,
146
+ url: url,
147
+ visitPage: clength,
148
+ sourceDomain: srcDomain,
149
+ sourceUrl: srcUrl,
150
+ title: _pObj && _pObj.title ? _pObj.title : "",
151
+ };
152
+ }
153
+
154
+ /**
155
+ * 查询数据
156
+ * 0 未上报 2上报失败
157
+ */
158
+ export function queryTrackDataUpload() {
159
+ let td = uni.getStorageSync(BPNPVUV);
160
+ uni.setStorageSync(BPNPVUV, "");
161
+ const arr = td ? JSON.parse(td) : [];
162
+ let uploadArray = [];
163
+ let ftd = uni.getStorageSync(BPNPVUVFail);
164
+ const failArr = ftd ? JSON.parse(ftd) : [];
165
+ if (arr.length) {
166
+ uploadArray.push(...arr);
167
+ }
168
+ if (failArr.length) {
169
+ uploadArray.push(...failArr);
170
+ }
171
+ if (uploadArray && uploadArray.length) {
172
+ uploadArray.forEach((item) => {
173
+ delete item.pageUUId;
174
+ });
175
+ reportTrackEventServer("track", uploadArray, BPNPVUVFail);
176
+ }
177
+ }
package/eventutils.js ADDED
@@ -0,0 +1,91 @@
1
+ import MD5 from "md5";
2
+ import { addCache, clearCache, getCache } from "./cache.js";
3
+ import { reportTrackEventServer } from "./index.js";
4
+ import { getUtmObj, sdkTrackIdVal, timeToStr } from "./tools.js";
5
+
6
+ //Event存储的key值
7
+ const BPNEvent = "UNIBPNEventSrcData";
8
+ const BPNEventFail = "UNIBPNEventFailData";
9
+ let timerCustom;
10
+
11
+ function getCurPath() {
12
+ const pages = getCurrentPages();
13
+ const gcp = pages[pages.length - 1];
14
+ return gcp ? gcp.route : "/";
15
+ }
16
+
17
+ // 自定义部分 type=>custom event=>到四种具体事件类型 extend_param 扩展字段
18
+ export function eventCommonStore(data) {
19
+ if (!data) return;
20
+ const _page = data.$page ? data.$page : "";
21
+ const _path = _page.path ? _page.path : getCurPath();
22
+ let reportEventData = {
23
+ utm: data.$utm ? data.$utm : getUtmObj(),
24
+ duration: "",
25
+ element: data.$element ? data.$element : null,
26
+ eventId: data.$event_id ? data.$event_id : "",
27
+ event: data.$event_code ? data.$event_code : "",
28
+ groupId: "",
29
+ busSegment: data.$busSegment ? data.$busSegment : "",
30
+ module: data.$module ? data.$module : "",
31
+ page: {
32
+ domain: _page.domain ? _page.domain : "",
33
+ pageId: MD5(_path),
34
+ path: _path || "",
35
+ title: _page.title || "",
36
+ url: _path || "",
37
+ },
38
+ properties: data.$extend_param ? JSON.stringify(data.$extend_param) : "",
39
+ traceId: "",
40
+ trackId: sdkTrackIdVal(),
41
+ triggerTime: timeToStr(Date.now()),
42
+ };
43
+
44
+ if (reportEventData) {
45
+ addCache(reportEventData);
46
+ clearTimeout(timerCustom);
47
+ timerCustom = setTimeout(() => {
48
+ const data = getCache();
49
+ if (data.length) {
50
+ insertEventData(data);
51
+ clearCache();
52
+ }
53
+ }, 2000);
54
+ }
55
+ }
56
+
57
+ /**
58
+ * 插入Event数据合并
59
+ */
60
+ export function insertEventData(cData) {
61
+ const cd = uni.getStorageSync(BPNEvent);
62
+ let allEventData = cd ? JSON.parse(cd) : [];
63
+ if (cData && cData.length) {
64
+ // concat方法
65
+ allEventData.concat(cData);
66
+ uni.setStorageSync(BPNEvent, JSON.stringify(allEventData));
67
+ }
68
+ }
69
+
70
+ /**
71
+ * 查询自定义数据
72
+ * 0 未上报/上报失败
73
+ */
74
+ export function queryEventDataUpload() {
75
+ let cd = uni.getStorageSync(BPNEvent);
76
+ uni.setStorageSync(BPNEvent, "");
77
+ const arr = cd ? JSON.parse(cd) : [];
78
+ let uploadArray = [];
79
+ let fcd = uni.getStorageSync(BPNEventFail);
80
+ const failArr = fcd ? JSON.parse(fcd) : [];
81
+ if (arr.length) {
82
+ uploadArray.push(...arr);
83
+ }
84
+ if (failArr.length) {
85
+ uploadArray.push(...failArr);
86
+ }
87
+ if (uploadArray && uploadArray.length) {
88
+ console.log("queryEventDataUpload");
89
+ reportTrackEventServer("event", uploadArray, BPNEventFail);
90
+ }
91
+ }
package/index.js CHANGED
@@ -1,61 +1,34 @@
1
1
  import MD5 from "md5";
2
+ import { queryTrackDataUpload } from "./autoutils.js";
3
+ import { setReportUrl } from "./config.js";
4
+ import { eventCommonStore, queryEventDataUpload } from "./eventutils.js";
5
+ import { uStopTrackPVData, uStartTrackPVData } from "./manualutils.js";
2
6
  import pk from "./package.json";
3
- import { addCache, getCache, clearCache } from "./cache.js";
4
- import { addSData, getSData, delSData } from "./bpstorage.js";
7
+ import { uniInterceptorListener } from "./pageListener.js";
5
8
  import {
6
- randomUUID,
7
- webH5Info,
8
- wxInfo,
9
9
  getAppInfo,
10
10
  getDeviceInfo,
11
11
  getDeviceInfoError,
12
- timeToStr,
13
- getTrackObj,
12
+ getWebH5Info,
13
+ getWXInfo,
14
+ Global,
15
+ randomUUID,
16
+ sdkTrackIdVal,
17
+ uUpdatePageExtraArray,
14
18
  } from "./tools.js";
15
- import { setReportUrl } from "./config.js";
16
19
 
17
20
  const localLsi = pk.lsi;
18
- let platform = "";
19
- let uAgent = "";
20
- let reportUrl = "";
21
- let reportTrackUrl = "";
22
- let trackId = "";
23
21
  let _comInfo = { distinctId: "", anonymousId: "" };
24
22
  let appData = {};
25
23
  let deviceData = {};
26
- let _config = {
27
- env: "production",
28
- token: "",
29
- srcDomain: "",
30
- flushInterval: 15,
31
- };
32
- //track upload interval
33
- let tInterval = null;
34
- let busObj = null;
35
- let startTime = 0;
36
- let startTimeLong = 0;
37
-
38
24
  //common global upload interval
39
- let cInterval = null;
40
-
25
+ let uglInterval = null;
41
26
  export function init(config) {
42
27
  if (config) {
43
28
  let _cf = setReportUrl(config.env ? config.env : "");
44
- reportUrl = _cf.reportUrl;
45
- reportTrackUrl = _cf.reportTrackUrl;
46
- if (config.flushInterval) {
47
- if (config.flushInterval < 5) {
48
- config.flushInterval = 15;
49
- }
50
- } else {
51
- config.flushInterval = 15;
52
- }
53
- _config = {
54
- env: config.env,
55
- token: config.token ? config.token : "",
56
- srcDomain: config.sourceDomain ? config.sourceDomain : "",
57
- flushInterval: config.flushInterval,
58
- };
29
+ Global.upEventUrl = _cf.reportUrl;
30
+ Global.upTrackUrl = _cf.reportTrackUrl;
31
+ Object.assign(Global, config);
59
32
  getBaseicInfo();
60
33
  _comInfo.distinctId = uni.getStorageSync("v_userId")
61
34
  ? uni.getStorageSync("v_userId")
@@ -65,26 +38,23 @@ export function init(config) {
65
38
  _comInfo.anonymousId = randomUUID();
66
39
  uni.setStorageSync("v_anonId", _comInfo.anonymousId);
67
40
  }
68
- if (!trackId) {
69
- trackId = Date.now().toString();
70
- }
41
+ sdkTrackIdVal();
71
42
  } else {
72
43
  console.log("init config error, please check config!");
73
44
  }
45
+ // Enabling a global timer
74
46
  startGlobalTime();
47
+ // Monitor page loading and unloading
48
+ uniInterceptorListener();
75
49
  }
76
50
 
77
51
  //the general custom reportCustom interval is enabled
78
52
  function startGlobalTime() {
79
- clearInterval(cInterval);
80
- cInterval = setInterval(() => {
81
- let cData = getSData();
82
- console.log("storage data " + JSON.stringify(cData));
83
- if (cData) {
84
- reportCustom(cData);
85
- delSData();
86
- }
87
- }, _config.flushInterval * 1000);
53
+ clearInterval(uglInterval);
54
+ uglInterval = setInterval(() => {
55
+ queryEventDataUpload();
56
+ queryTrackDataUpload();
57
+ }, 15000);
88
58
  }
89
59
 
90
60
  //bind userID
@@ -98,195 +68,97 @@ export function setUserId(userId) {
98
68
  }
99
69
  }
100
70
 
101
- //set custom event
102
- export function setCustomEvent(data) {
103
- let reportData = null;
104
- const _page = data.$page ? data.$page : "";
105
- const _path = _page.path ? _page.path : getCurPath();
106
- reportData = {
107
- ctk: data.$ctk ? data.$ctk : "",
108
- duration: "",
109
- element: null,
110
- eventId: data.$event_id ? data.$event_id : "",
111
- event: data.$event_code ? data.$event_code : "",
112
- groupId: "",
113
- busSegment: data.$busSegment,
114
- module: data.$module,
115
- page: {
116
- domain: _page.domain ? _page.domain : "",
117
- pageId: MD5(_path),
118
- path: _path,
119
- title: _page.title ? _page.title : "",
120
- },
121
- path: data.$path ? data.$path : "",
122
- properties: data.$extend_param ? JSON.stringify(data.$extend_param) : "",
123
- traceId: "",
124
- trackId: trackId,
125
- triggerTime: timeToStr(Date.now()),
126
- url: "",
127
- };
128
- if (reportData) {
129
- addCache(reportData);
130
- const data = getCache();
131
- if (data.length) {
132
- console.log("customData: ", JSON.stringify(data));
133
- addSData(data);
134
- clearCache();
135
- }
136
- }
71
+ // get trackId
72
+ export function getTrackId() {
73
+ return sdkTrackIdVal();
137
74
  }
138
75
 
139
- function reportCustom(data) {
140
- if (!reportUrl) {
141
- //console.error("please set upload data url");
142
- return;
143
- }
144
- const comData = commonData(data);
145
- const reportData = {
146
- ...comData,
147
- dataAbstract: MD5(JSON.stringify(comData)),
148
- };
149
- uni.request({
150
- url: reportUrl,
151
- method: "POST",
152
- header: {
153
- "Content-Type": "application/json",
154
- appKey: _config.token,
155
- projectId: _config.token,
156
- },
157
- data: reportData,
158
- success: function (res) {},
159
- fail: function (error) {
160
- console.error(error);
161
- },
162
- });
76
+ // set custom event
77
+ export function setCustomEvent(data) {
78
+ eventCommonStore(data);
163
79
  }
164
80
 
165
- //track upload-注册
81
+ //track upload-registry
166
82
  export function onStartTrack(tData) {
167
- busObj = null;
168
- startTime = 0;
169
- startTimeLong = Date.now();
170
- busObj = tData;
171
- clearInterval(tInterval);
172
- assemblyTrackData("start");
173
- tInterval = setInterval(() => {
174
- startTime += 15;
175
- startTimeLong = Date.now();
176
- assemblyTrackData("start");
177
- }, 15 * 1000);
83
+ uStartTrackPVData(tData);
178
84
  }
179
85
 
180
- //track upload-销毁
86
+ //track upload-Destroy
181
87
  export function onDestroyTrack() {
182
- assemblyTrackData("destroy");
183
- clearInterval(tInterval);
88
+ uStopTrackPVData();
184
89
  }
185
90
 
186
- function assemblyTrackData(type) {
187
- if (busObj) {
188
- let obj = getTrackObj(busObj);
189
- let trackData = null;
190
- if (type === "destroy") {
191
- startTime = (Date.now() - startTimeLong) / 1000;
192
- }
193
- trackData = {
194
- busSegment: busObj.busSegment,
195
- circulation: obj.circulation,
196
- ctk: busObj.ctk ? busObj.ctk : "",
197
- domain: obj.domain,
198
- duration: startTime === 0 ? 0 : startTime,
199
- module: busObj.module,
200
- path: obj.path,
201
- properties: busObj.extend_param
202
- ? JSON.stringify(busObj.extend_param)
203
- : "",
204
- sourceDomain: obj.sourceDomain ? obj.sourceDomain : _config.srcDomain,
205
- sourceUrl: obj.sourceUrl,
206
- title: obj.title,
207
- traceId: busObj.traceId ? busObj.traceId : "",
208
- trackId: trackId,
209
- url: obj.url,
210
- visitPage: obj.visitPage,
211
- visitTime: busObj.visitTime ? busObj.visitTime : timeToStr(Date.now()),
212
- };
213
- if (trackData) {
214
- reportTrack([trackData]);
215
- }
216
- }
91
+ // auto track Preset attribute
92
+ export function setPageExtraObj(tData) {
93
+ uUpdatePageExtraArray(tData);
217
94
  }
218
95
 
219
- // track upload data
220
- function reportTrack(data) {
221
- if (!reportTrackUrl) {
96
+ // data upload
97
+ export function reportTrackEventServer(upType, data, sFailKey) {
98
+ if (!upType) {
99
+ console.error("please set upload data upType");
222
100
  return;
223
101
  }
224
102
  const comData = commonData(data);
225
- const reportTrackData = {
103
+ const reportData = {
226
104
  ...comData,
227
105
  dataAbstract: MD5(JSON.stringify(comData)),
228
106
  };
229
107
  uni.request({
230
- url: reportTrackUrl,
108
+ url: upType === "event" ? Global.upEventUrl : Global.upTrackUrl,
231
109
  method: "POST",
232
110
  header: {
233
111
  "Content-Type": "application/json",
234
- appKey: _config.token,
235
- projectId: _config.token,
112
+ appKey: Global.token,
113
+ projectId: Global.token,
114
+ },
115
+ data: reportData,
116
+ success: function (res) {
117
+ if (res && res.data) {
118
+ uni.setStorageSync(sFailKey, JSON.stringify(data));
119
+ } else {
120
+ uni.setStorageSync(sFailKey, "");
121
+ }
236
122
  },
237
- data: reportTrackData,
238
- success: function (res) {},
239
123
  fail: function (error) {
240
- console.error(error);
124
+ console.log("error: ", error);
125
+ uni.setStorageSync(sFailKey, JSON.stringify(data));
241
126
  },
242
127
  });
243
128
  }
244
129
 
245
- function getCurPath() {
246
- if (platform) {
247
- if (platform == "wx") {
248
- let gcp = getCurrentPages();
249
- return gcp ? gcp[gcp.length - 1].route : "/";
250
- } else if (platform == "web") {
251
- return window.location.hostname;
252
- } else if (platform == "android" || platform === "ios") {
253
- return "";
254
- }
255
- }
256
- }
257
-
258
130
  function commonData(allData) {
259
131
  return {
260
132
  app: appData,
261
133
  data: allData,
262
- deviceData: deviceData,
134
+ device: deviceData,
263
135
  lsi: localLsi,
264
- projectId: _config.token,
265
- userAgent: uAgent ? uAgent : "",
136
+ projectId: Global.token,
137
+ userAgent: Global.uAgent || "",
266
138
  anonymousId: _comInfo.anonymousId,
267
139
  userId: _comInfo.distinctId,
268
140
  };
269
141
  }
270
142
 
271
- //获取基本信息
143
+ // get baseInfo
272
144
  function getBaseicInfo() {
273
145
  uni.getSystemInfo({
274
146
  success: function (res) {
275
- uAgent = res.ua;
147
+ Global.uAgent = res.ua;
276
148
  let uniPlatform = res.uniPlatform;
277
149
  if (uniPlatform.includes("app")) {
278
- platform = res.osName;
150
+ Global.platform = res.osName;
279
151
  appData = getAppInfo(res);
280
152
  } else if (uniPlatform.includes("web") || uniPlatform.includes("h5")) {
281
- platform = uniPlatform;
282
- let wh5Info = webH5Info(res);
153
+ Global.platform = uniPlatform;
154
+ let wh5Info = getWebH5Info(res);
283
155
  appData = {
284
156
  ...wh5Info,
285
- version: _config.version ? _config.version : "unknown",
157
+ version: Global.version ? Global.version : "unknown",
286
158
  };
287
159
  } else if (uniPlatform.includes("weixin")) {
288
- platform = "wx";
289
- appData = wxInfo();
160
+ Global.platform = "weixin";
161
+ appData = getWXInfo();
290
162
  }
291
163
  deviceData = getDeviceInfo(res);
292
164
  },
@@ -296,10 +168,7 @@ function getBaseicInfo() {
296
168
  complete: function () {
297
169
  uni.getNetworkType({
298
170
  success(res) {
299
- deviceData = {
300
- ...deviceData,
301
- network: res.networkType,
302
- };
171
+ deviceData.network = res.networkType;
303
172
  },
304
173
  });
305
174
  },
package/lsi-md5.js CHANGED
@@ -1,15 +1,16 @@
1
1
  // 此js在npm build,根据name + version + md5后会自动修改package.json中的lsi
2
2
  // 注:发给后端,作为标识依据和上报字段lsi值
3
- import fs from 'fs' ;
4
- import MD5 from 'md5' ;
5
- const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf-8'));
6
-
3
+ import fs from "fs";
4
+ import MD5 from "md5";
5
+ // const fs = require("fs");
6
+ // const MD5 = require("md5");
7
+ const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf-8"));
7
8
 
8
9
  const { name, version } = packageJson;
9
10
  // MD5
10
11
  const combinedString = name + "-" + version;
11
12
  const md5Str = MD5(combinedString);
12
- packageJson.lsi = md5Str;
13
+ packageJson.lsi = md5Str + "#" + version;
13
14
  //base64
14
15
  // const combinedString = name.substring(0, 16) + "v" + version;
15
16
  // const base64Str = btoa(combinedString);
package/manualutils.js ADDED
@@ -0,0 +1,87 @@
1
+ import { AUTOTRACKTYPE, insertPVUVData } from "./autoutils.js";
2
+ import {
3
+ getTrackObj,
4
+ getUtmObj,
5
+ randomUUID,
6
+ sdkTrackIdVal,
7
+ timeToStr,
8
+ } from "./tools.js";
9
+
10
+ // 流量上报采集
11
+ let startTime = 0;
12
+ let enterTimeLong = 0;
13
+ let loopTimeLong = 0;
14
+ let cirtemp = -1;
15
+ let mObj = null;
16
+ let umlInterval = null;
17
+ let cUUId = 0;
18
+
19
+ function clearUMlData() {
20
+ clearInterval(umlInterval);
21
+ startTime = 0;
22
+ enterTimeLong = 0;
23
+ loopTimeLong = 0;
24
+ cirtemp = 1;
25
+ mObj = null;
26
+ umlInterval = null;
27
+ cUUId = 0;
28
+ }
29
+
30
+ // start pv
31
+ export const uStartTrackPVData = (tData) => {
32
+ if (umlInterval) {
33
+ uStopTrackPVData();
34
+ } else {
35
+ if (tData) {
36
+ clearUMlData();
37
+ uTrackPVData(AUTOTRACKTYPE.ENTER, tData);
38
+ umlInterval = setInterval(() => {
39
+ uTrackPVData(AUTOTRACKTYPE.LOOP, null);
40
+ }, 15000);
41
+ }
42
+ }
43
+ };
44
+
45
+ // stop pv
46
+ export const uStopTrackPVData = () => {
47
+ uTrackPVData(AUTOTRACKTYPE.LEAVE);
48
+ clearUMlData();
49
+ };
50
+
51
+ function uTrackPVData(type, tData) {
52
+ if (type === AUTOTRACKTYPE.ENTER) {
53
+ cUUId = randomUUID();
54
+ enterTimeLong = Date.now();
55
+ loopTimeLong = enterTimeLong;
56
+ mObj = getTrackObj(tData);
57
+ } else if (type === AUTOTRACKTYPE.LOOP) {
58
+ cirtemp = 2;
59
+ startTime = 15;
60
+ loopTimeLong = Date.now();
61
+ } else if (type === AUTOTRACKTYPE.LEAVE) {
62
+ cirtemp = 3;
63
+ startTime = Math.ceil((Date.now() - loopTimeLong) / 1000);
64
+ }
65
+ const puvData = {
66
+ busSegment: mObj.busSegment,
67
+ circulation: cirtemp,
68
+ domain: mObj.domain,
69
+ duration: startTime,
70
+ module: mObj.module,
71
+ path: mObj.path,
72
+ properties: mObj.properties,
73
+ sourceDomain: mObj.sourceDomain,
74
+ sourceUrl: mObj.sourceUrl,
75
+ title: mObj.title,
76
+ traceId: "",
77
+ trackId: sdkTrackIdVal(),
78
+ url: mObj.url,
79
+ visitPage: mObj.visitPage,
80
+ visitTime: timeToStr(enterTimeLong),
81
+ utm: getUtmObj(),
82
+ pageUUId: cUUId,
83
+ };
84
+ if (puvData) {
85
+ insertPVUVData(puvData, cUUId);
86
+ }
87
+ }
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "visual-buried-point-platform-uni",
3
- "version": "1.0.0-alpha.02",
4
- "lsi": "f0ca171a9f641657370a83f2f7ed65c7",
3
+ "version": "1.0.0-alpha.21",
4
+ "lsi": "92ff1eea79405724febc2335b9a3a02a#1.0.0-alpha.21",
5
5
  "description": "To make it easy for you to get started with GitLab, here's a list of recommended next steps.",
6
6
  "main": "index.js",
7
7
  "scripts": {
8
8
  "test": "echo \"Error: no test specified\" && exit 1",
9
- "build": "webpack --mode production && npm run lsi-md5",
9
+ "build": "rimraf dist && webpack --mode production && npm run lsi-md5",
10
10
  "lsi-md5": "node lsi-md5.js"
11
11
  },
12
- "type": "module",
13
12
  "repository": {
14
13
  "type": "git",
15
14
  "url": ""
16
15
  },
16
+ "type": "module",
17
17
  "keywords": [],
18
18
  "author": "",
19
19
  "license": "MIT",
@@ -21,6 +21,7 @@
21
21
  "md5": "^2.3.0"
22
22
  },
23
23
  "devDependencies": {
24
+ "rimraf": "^6.0.1",
24
25
  "webpack": "^5.72.1",
25
26
  "webpack-cli": "4.9.2"
26
27
  }
@@ -0,0 +1,71 @@
1
+ import {
2
+ autoPageObj,
3
+ uAutoStartTrackPVData,
4
+ autoStopTrackPVUV
5
+ } from "./autoutils.js";
6
+ import { Global } from "./tools.js";
7
+
8
+ export function uniInterceptorListener() {
9
+ uni.addInterceptor("navigateTo", {
10
+ invoke(args) {
11
+ // {"url":"/pages/Home/Home/Home"}
12
+ routerMsgHandler("leave");
13
+ },
14
+ success(args) {
15
+ // {"errMsg":"switchTab:ok"}
16
+ routerMsgHandler("pv");
17
+ },
18
+ });
19
+ uni.addInterceptor("switchTab", {
20
+ invoke(args) {
21
+ routerMsgHandler("leave");
22
+ },
23
+ success(args) {
24
+ routerMsgHandler("pv");
25
+ },
26
+ });
27
+ uni.addInterceptor("navigateBack", {
28
+ invoke(args) {
29
+ routerMsgHandler("leave");
30
+ },
31
+ success(args) {
32
+ routerMsgHandler("pv");
33
+ },
34
+ });
35
+ // 切换到前台
36
+ // uni.onAppShow((res) => {
37
+ // console.log("-----onAppShow--");
38
+ // //routerMsgHandler("pv");
39
+ // });
40
+ // // 切换到后台
41
+ // uni.onAppHide(() => {
42
+ // console.log("-----onAppHide--");
43
+ // //routerMsgHandler("leave");
44
+ // });
45
+ }
46
+
47
+ // 路由消息统一处理
48
+ let pathExist = false;
49
+ function routerMsgHandler(msg) {
50
+ if (Global.isCompatible) {
51
+ } else {
52
+ if (msg === "pv") {
53
+ const pages = getCurrentPages();
54
+ const page = pages[pages.length - 1];
55
+ if (Global.signTrackArray && Global.signTrackArray.length) {
56
+ pathExist = Global.signTrackArray.find((obj) => obj === page.route);
57
+ if (pathExist) {
58
+ pathExist = true;
59
+ return;
60
+ }
61
+ }
62
+ pathExist = false;
63
+ const pageObj = autoPageObj(page.route, pages.length, pages);
64
+ uAutoStartTrackPVData(pageObj);
65
+ } else if (msg === "leave") {
66
+ if (!pathExist) {
67
+ autoStopTrackPVUV();
68
+ }
69
+ }
70
+ }
71
+ }
package/tools.js CHANGED
@@ -1,3 +1,52 @@
1
+ export const AUTOTRACKTYPE = {
2
+ ENTER: "enter",
3
+ LOOP: "loop",
4
+ LEAVE: "leave",
5
+ };
6
+
7
+ export let Global = {
8
+ // 项目的域名
9
+ domain: "",
10
+ // 全局业务类型
11
+ busSegment: "",
12
+ // 全局业务版本
13
+ module: "",
14
+ // 定时上报周期
15
+ flushInterval: "",
16
+ // 每个页面PV采集的周期
17
+ pageInterval: "",
18
+ // 项目id
19
+ token: "",
20
+ // 版本号(如果在H5使用,建议传)
21
+ version: "",
22
+ // 全局单次访问链路id
23
+ trackId: "",
24
+ // 当前平台
25
+ platform: "",
26
+ // 全局uAgent
27
+ uAgent: "",
28
+ // 上报的事件url
29
+ upEventUrl: "",
30
+ // 上报的流量url
31
+ upTrackUrl: "",
32
+ // 是否兼容老方案 默认true兼容
33
+ isCompatible: true,
34
+ // 需要单个采集的页面path
35
+ signTrackArray: [],
36
+ };
37
+
38
+ // 本地记录每个页面设置的属性值例如:module...
39
+ export let pagesArray = [];
40
+
41
+ export const sdkTrackIdVal = () => {
42
+ if (Global.trackId) {
43
+ return Global.trackId;
44
+ }
45
+ const tId = Date.now().toString();
46
+ Global.trackId = tId;
47
+ return tId;
48
+ };
49
+
1
50
  export function randomUUID() {
2
51
  let uuid = "xxxx-4xxx-yxxx-xxxx".replace(/[xy]/g, function (c) {
3
52
  let r = (Math.random() * 16) | 0,
@@ -25,7 +74,7 @@ export function timeToStr(timestamp) {
25
74
  }
26
75
 
27
76
  //web或者h5的appInfo
28
- export function webH5Info(result) {
77
+ export function getWebH5Info(result) {
29
78
  let ecology = "unknown";
30
79
  let ua = result.ua.toLowerCase();
31
80
  let hostname = window.location.hostname;
@@ -58,19 +107,22 @@ export function webH5Info(result) {
58
107
  packageName: hostname ? hostname : "",
59
108
  version: "",
60
109
  carrier: "h5",
61
- ecology: ecology,
110
+ ecology: "h5",
62
111
  };
63
112
  }
64
113
 
65
114
  //微信的appInfo
66
- export function wxInfo() {
67
- let accInfo = uni.getAccountInfoSync();
115
+ export function getWXInfo() {
116
+ const accInfo = uni.getAccountInfoSync();
117
+ const bInfo = uni.getAppBaseInfo();
68
118
  return {
69
- name: "",
70
- packageName: accInfo ? accInfo.appId : "",
71
- version: accInfo ? accInfo.envVersion + accInfo.version : "",
119
+ name: bInfo.appName ? bInfo.appName : "",
120
+ packageName: accInfo ? accInfo.miniProgram.appId : "",
121
+ version: accInfo
122
+ ? accInfo.miniProgram.envVersion + accInfo.miniProgram.version
123
+ : "",
72
124
  carrier: "mini",
73
- ecology: "wechat",
125
+ ecology: "mini",
74
126
  };
75
127
  }
76
128
 
@@ -81,49 +133,48 @@ export function getAppInfo(result) {
81
133
  name: result.appName,
82
134
  version: version ? version : "",
83
135
  carrier: "app",
136
+ packageName: "",
137
+ ecology: "",
84
138
  };
85
139
  if (result.platform === "android") {
86
- let osName = "android";
140
+ let osName = "Android";
87
141
  let pkName = plus.android.runtimeMainActivity().getPackageName();
88
142
  if (result.romName.includes("HarmonyOS")) {
89
- osName = "harmonyOS";
143
+ osName = "Harmony OS";
90
144
  }
91
- app = {
92
- ...app,
93
- packageName: pkName ? pkName : "",
94
- ecology: osName,
95
- };
145
+ app.packageName = pkName ? pkName : "";
146
+ app.ecology = osName;
96
147
  } else if (result.platform === "ios") {
97
148
  let pkName = plus.ios
98
149
  .importClass("NSBundle")
99
150
  .mainBundle()
100
151
  .bundleIdentifier();
101
- app = {
102
- ...app,
103
- packageName: pkName ? pkName : "",
104
- ecology: "ios",
105
- };
152
+ app.packageName = pkName ? pkName : "";
153
+ app.ecology = "iOS";
106
154
  } else {
107
- app = {
108
- ...app,
109
- packageName: "",
110
- version: "",
111
- ecology: "unknown",
112
- };
155
+ app.ecology = "unknown";
113
156
  }
114
157
  return app;
115
158
  }
116
159
 
117
- function getCurDeviceType(ua) {
118
- const userAgent = ua.toLowerCase();
119
- if (/(windows|win32|win64|wow64)/.test(userAgent)) {
120
- return 1;
121
- } else if (/(linux|android)/.test(userAgent)) {
122
- return 2;
123
- } else if (/(macintosh|mac os x|iphone|ipad|ipod)/.test(userAgent)) {
124
- return 2;
160
+ function getCurDeviceType(res) {
161
+ if (Global.platform === "web" || Global.platform === "h5") {
162
+ const userAgent = res.ua.toLowerCase();
163
+ if (/(windows|win32|win64|wow64)/.test(userAgent)) {
164
+ return 1;
165
+ } else if (/(linux|android)/.test(userAgent)) {
166
+ return 2;
167
+ } else if (/(macintosh|mac os x|iphone|ipad|ipod)/.test(userAgent)) {
168
+ return 2;
169
+ } else {
170
+ return 2;
171
+ }
125
172
  } else {
126
- return 2;
173
+ if (res.deviceType === "pc") {
174
+ return 1;
175
+ } else {
176
+ return 2;
177
+ }
127
178
  }
128
179
  }
129
180
 
@@ -132,14 +183,14 @@ export function getDeviceInfo(res) {
132
183
  let device = {
133
184
  lang: res.osLanguage ? res.osLanguage : res.hostLanguage,
134
185
  brand: res.deviceBrand + " " + res.deviceModel,
135
- os: res.os,
186
+ os: res.osName,
136
187
  osVersion: res.osVersion,
137
188
  resolution: res.screenWidth + "x" + res.screenHeight,
138
189
  browser: res.browserName,
139
190
  browserVersion: res.browserVersion,
140
191
  color: "",
141
192
  deviceId: res.deviceId,
142
- deviceType: getCurDeviceType(res.ua),
193
+ deviceType: getCurDeviceType(res),
143
194
  network: "",
144
195
  };
145
196
  return device;
@@ -162,36 +213,96 @@ export function getDeviceInfoError() {
162
213
  };
163
214
  }
164
215
 
165
- //流量上报H5环境
166
- export function getTrackObj(busObj) {
167
- //uni 通用h5、app、wx拿到当前路由栈
216
+ //uni 通用h5、app、wx拿到当前路由栈
217
+ export function getTrackObj(tData) {
168
218
  const pages = getCurrentPages();
169
219
  const gcp = pages[pages.length - 1];
170
- //h5
171
- // let wl = window.location;
172
- // let docTitle = document.title;
173
- // let refurl = document.referrer;
174
- let parsedUrl;
175
- if (refurl) {
176
- parsedUrl = new URL(refurl);
177
- } else {
178
- let busRefUrl = busObj.sourceUrl;
179
- if (busRefUrl) {
180
- parsedUrl = new URL(busRefUrl);
220
+ let pf = Global.platform;
221
+ let url = "";
222
+ let domain = "";
223
+ let srcUrl = "";
224
+ let srcDomain = "";
225
+ if (pf) {
226
+ if (pf === "web" || pf === "h5") {
227
+ url = window.location.href;
228
+ domain = window.location.hostname;
229
+ if (document.referrer) {
230
+ let parsedUrl = new URL(document.referrer);
231
+ srcUrl = parsedUrl || "";
232
+ srcDomain = parsedUrl.hostname || "";
233
+ }
181
234
  } else {
182
- parsedUrl = "";
235
+ url = gcp.route;
236
+ if (pages.length > 1) {
237
+ let beforePage = pages[pages.length - 2];
238
+ srcUrl = beforePage.route;
239
+ }
240
+ domain = Global.domain ? Global.domain : gcp.route;
183
241
  }
184
242
  }
185
243
  if (gcp) {
186
244
  return {
187
245
  path: gcp.route,
188
- domain: busObj.domain ? busObj.domain : "",
189
- url: busObj.url ? busObj.url : "",
190
- circulation: gcp.length > 1 ? 2 : 1,
191
- visitPage: gcp.length,
192
- sourceDomain: parsedUrl ? parsedUrl.hostname : "",
193
- sourceUrl: parsedUrl,
194
- title: docTitle ? docTitle : "",
246
+ busSegment: tData.busSegment ? tData.busSegment : "",
247
+ module: tData.module ? tData.module : "",
248
+ properties: tData.extend_param ? JSON.stringify(tData.extend_param) : "",
249
+ title: tData.title ? tData.title : "",
250
+ domain: domain,
251
+ url: url,
252
+ visitPage: pages.length,
253
+ sourceDomain: srcDomain,
254
+ sourceUrl: srcUrl,
195
255
  };
196
256
  }
197
257
  }
258
+
259
+ // 更新当前页的业务方设置的对象
260
+ export function uUpdatePageExtraArray(d) {
261
+ const pages = getCurrentPages();
262
+ let page = pages[pages.length - 1];
263
+ const index = pagesArray.findIndex((item) => item.path === page.route);
264
+ let temp = {
265
+ path: page.route,
266
+ properties: d.properties ? JSON.stringify(d.properties) : "",
267
+ busSegment: d.busSegment ? d.busSegment : "",
268
+ module: d.module ? d.module : "",
269
+ title: d.title ? d.title : "",
270
+ };
271
+ if (index !== -1) {
272
+ pagesArray[index] = temp;
273
+ } else {
274
+ pagesArray.push(temp);
275
+ }
276
+ }
277
+
278
+ // 得到utm
279
+ export function getUtmObj() {
280
+ if (Global.platform === "web" || Global.platform === "h5") {
281
+ let utm = {
282
+ utmSource: "",
283
+ utmCampaign: "",
284
+ utmTerm: "",
285
+ utmContent: "",
286
+ ctk: "",
287
+ };
288
+ if (window.location.href) {
289
+ const paramsUrl = window.location.href.split("?")[1] || "";
290
+ if (paramsUrl) {
291
+ const urlParams = new URLSearchParams(paramsUrl);
292
+ // 渠道来源
293
+ utm.utmSource = urlParams.get("utmSource") || "";
294
+ // 活动名称
295
+ utm.utmCampaign = urlParams.get("utmCampaign") || "";
296
+ // 渠道媒介
297
+ utm.utmTerm = urlParams.get("utmTerm") || "";
298
+ // 内容
299
+ utm.utmContent = urlParams.get("utmContent") || "";
300
+ // 关键词
301
+ utm.ctk = urlParams.get("ctk") || "";
302
+ }
303
+ }
304
+ return utm;
305
+ } else {
306
+ return null;
307
+ }
308
+ }
package/webpack.config.js CHANGED
@@ -1,17 +1,17 @@
1
- import path from "path";
2
- import { fileURLToPath } from 'url';
3
- const __filename = fileURLToPath(import.meta.url);
4
- const __dirname = path.dirname(__filename);
5
-
6
- export default {
7
- entry: "./index.js",
8
- output: {
9
- path: path.resolve(__dirname, "dist"),
10
- filename: "buried-point-uni.js",
11
- libraryTarget: "umd",
12
- },
13
- resolve: {
14
- extensions: [".js"],
15
- },
16
- mode: "production",
17
- };
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ const __filename = fileURLToPath(import.meta.url);
4
+ const __dirname = path.dirname(__filename);
5
+
6
+ export default {
7
+ entry: "./index.js",
8
+ output: {
9
+ path: path.resolve(__dirname, "dist"),
10
+ filename: "buried-point-uni.js",
11
+ libraryTarget: "umd",
12
+ },
13
+ resolve: {
14
+ extensions: [".js"],
15
+ },
16
+ mode: "production",
17
+ };