@tmsfe/tms-core 0.0.41 → 0.0.44

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmsfe/tms-core",
3
- "version": "0.0.41",
3
+ "version": "0.0.44",
4
4
  "description": "tms运行时框架",
5
5
  "repository": {
6
6
  "type": "git",
@@ -63,7 +63,7 @@ const asyncFuncNames = [
63
63
  // 这行是tms-runtime的
64
64
  'getPhone', 'login', 'getLoginInfo', 'getOpenId', 'getMycarPubOpenId', 'getSinanPubOpenId',
65
65
  // tms-core
66
- 'setAuthInfo', 'getConfig', 'navigateToWebview', 'callCloudFunc',
66
+ 'setAuthInfo', 'getConfig', 'navigateToWebview', 'callCloudFunc', 'getEncryptUserInfo',
67
67
  'setUserLocation', 'getUserLocation', 'getMpOpenId', 'getOuterOpenId',
68
68
  ];
69
69
  asyncFuncNames.forEach((funcName) => {
package/src/index.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  } from './ipxHelper';
38
38
  import getLocInstance from './location/index';
39
39
  import LocationBase from './location/base';
40
- import { getMpOpenId, getOuterOpenId } from './mpInfo';
40
+ import { getMpOpenId, getOuterOpenId, getEncryptUserInfo } from './mpInfo';
41
41
  import * as storage from './storage';
42
42
 
43
43
  /**
@@ -173,6 +173,9 @@ const api = {
173
173
  getMpOpenId, // 变更为 getOuterOpenId
174
174
  getOuterOpenId,
175
175
 
176
+ /* 获取加密的用户信息 */
177
+ getEncryptUserInfo,
178
+
176
179
  /** rpx转px */
177
180
  rpxToPx,
178
181
 
package/src/mpInfo.js CHANGED
@@ -32,7 +32,23 @@ async function getOuterOpenId(apiKey) {
32
32
  return openId;
33
33
  }
34
34
 
35
+ async function getEncryptUserInfo(mpId = '', queryTypes = '') {
36
+ if (!mpId) return Promise.reject('缺少服务标志mpId');
37
+ if (!queryTypes) return Promise.reject('缺少需要加密的用户信息字段描述');
38
+ return new Request().get('user/info/encrypt', { mpId, queryTypes })
39
+ .then((res) => {
40
+ const { resData, errCode, errMsg } = res || {};
41
+ if (errCode === 0) {
42
+ // 请求成功
43
+ return resData;
44
+ }
45
+ return Promise.reject(errMsg);
46
+ })
47
+ .catch(e => Promise.reject('请求发生错误,请重试'));
48
+ }
49
+
35
50
  export {
36
51
  getMpOpenId,
37
52
  getOuterOpenId,
53
+ getEncryptUserInfo,
38
54
  };
@@ -51,9 +51,9 @@ function getBaseData(deviceData: IDeviceData): { arr: DataItem[], nextIndex: num
51
51
  // 22: f22,小程序启动时的url和参数
52
52
  arr[22] = helper.getLaunchOptionsString();
53
53
  // 23: f23,当前页面的url
54
- arr[23] = page.route;
54
+ arr[23] = page?.route;
55
55
  // 24: f24,当前页面的query
56
- arr[24] = JSON.stringify(page.options);
56
+ arr[24] = JSON.stringify(page?.options);
57
57
  // 25 ~ 30: 预留字段给后续扩展使用
58
58
  // 31 ~ 40: 提供给开发自定义
59
59
  // --------------------------字段列表--------------------------
@@ -47,7 +47,7 @@ function getSystemInfo(): ISystemInfo {
47
47
  if (systemInfo === null) {
48
48
  const system = syncApi.getSystemInfoSync() as any;
49
49
  // eslint-disable-next-line
50
- const { model = '', version: wxVersion = '', platform = '', SDKVersion = '', host = '' } = system;
50
+ const { model = '', version: wxVersion = '', platform = '', SDKVersion = '', host } = system;
51
51
  systemInfo = { model, wxVersion, platform, SDKVersion, host };
52
52
  }
53
53
  return systemInfo;
@@ -70,6 +70,9 @@ function getSystemInfoString(): string {
70
70
  * @param value
71
71
  */
72
72
  function convert2String(value: any): string {
73
+ if (value === null || value === undefined) {
74
+ return '';
75
+ }
73
76
  const type = typeof value;
74
77
  if (type === 'string') {
75
78
  return value;
@@ -90,12 +93,8 @@ function getPageInfo(): IPage | null {
90
93
  const launch = syncApi.getLaunchOptionsSync() as any;
91
94
  return { route: launch.path, options: launch.query };
92
95
  }
93
- const page = pages.pop();
94
- // 插件页
95
- if (!page) {
96
- return null;
97
- }
98
- return page;
96
+ // 如果最后一个为空,则当前是在插件页,继续找上一个页面
97
+ return pages.reverse().find((t: IPage) => t);
99
98
  }
100
99
 
101
100
  let launchOptions: string | null = null;
@@ -139,11 +138,7 @@ function canReport(): boolean {
139
138
  isCrawler = scene === '1129' || scene === '1030';
140
139
  }
141
140
  // 小程序爬虫,不上报
142
- if (isCrawler) {
143
- return false;
144
- }
145
- // 插件页不上报埋点
146
- return getPageInfo() !== null;
141
+ return !isCrawler;
147
142
  }
148
143
 
149
144
  /**
@@ -6,15 +6,19 @@ import helper from './helper';
6
6
 
7
7
  let originalComponent: any = null;
8
8
 
9
- // 劫持其他事件
10
- function proxyHandle(componentName: string, methods: any, methodName: string): void {
9
+ // 劫持绑定事件
10
+ function proxyBindEvent(componentName: string, methods: any, methodName: string): void {
11
11
  const original = methods[methodName];
12
+ if (!original) {
13
+ return;
14
+ }
12
15
  // eslint-disable-next-line no-param-reassign
13
16
  methods[methodName] = function (...args: any[]): any {
17
+ const extend = helper.getEventExtend(args[0]) ; // 把触发事件附加数据也带上
14
18
  // 执行原函数之后再发埋点
15
19
  return helper.executeFunc(this, original, args, () => {
16
- const data = helper.serializeData(this.data);
17
- helper.reportData(`Component_${componentName}`, methodName, data);
20
+ const data = helper.deepClone(this.data);
21
+ helper.reportData(`Component_${componentName}`, methodName, data, extend);
18
22
  });
19
23
  };
20
24
  }
@@ -30,7 +34,7 @@ function init(): void {
30
34
  // tmsReportEvents是由工具在编译时分析出的要上报的事件列表
31
35
  const methods = options.methods || {};
32
36
  for (const name of options.tmsReportEvents) {
33
- proxyHandle(options.tmsComponentName, methods, name);
37
+ proxyBindEvent(options.tmsComponentName, methods, name);
34
38
  }
35
39
  }
36
40
  originalComponent(options);
@@ -45,7 +45,6 @@ function executeFunc(context: any, func: Function, args: any[], doneCallback: Fu
45
45
  });
46
46
  }
47
47
 
48
- const maxDepth = 5;
49
48
  const maxArrLen = 10;
50
49
  const maxStrLen = 30;
51
50
  const maxFieldLen = 20;
@@ -78,9 +77,10 @@ function isArrayType(obj: any): { isArray: boolean, value: any } {
78
77
  * 深表克隆
79
78
  * @param obj
80
79
  * @param depth 当前克隆的深度
80
+ * @param maxDepth 最大克隆深度
81
81
  */
82
- function deepClone(obj: any, depth: number): any {
83
- if (depth >= maxDepth) {
82
+ function deepClone(obj: any, depth = 0, maxDepth = 5): any {
83
+ if (depth > maxDepth) {
84
84
  return undefined;
85
85
  }
86
86
  const res1 = isBasicsType(obj);
@@ -89,7 +89,7 @@ function deepClone(obj: any, depth: number): any {
89
89
  }
90
90
  const res2 = isArrayType(obj);
91
91
  if (res2.isArray) {
92
- return res2.value.map((t: any) => deepClone(t, depth + 1));
92
+ return res2.value.map((t: any) => deepClone(t, depth + 1, maxDepth));
93
93
  }
94
94
  const names = Object.getOwnPropertyNames(obj).slice(0, maxFieldLen);
95
95
  const newObj = {};
@@ -107,27 +107,44 @@ function deepClone(obj: any, depth: number): any {
107
107
  const res2 = isArrayType(value);
108
108
  if (res2.isArray) {
109
109
  // @ts-ignore
110
- newObj[name] = res2.value.map((t: any) => deepClone(t, depth + 1));
110
+ newObj[name] = res2.value.map((t: any) => deepClone(t, depth + 1, maxDepth));
111
111
  continue;
112
112
  }
113
113
  // @ts-ignore
114
- newObj[name] = deepClone(value, depth + 1);
114
+ newObj[name] = deepClone(value, depth + 1, maxDepth);
115
115
  }
116
116
  return newObj;
117
117
  }
118
118
 
119
119
  /**
120
- * 序列化data
121
- * @param data
120
+ * 获取触发绑定事件的携带数据
121
+ * @param event
122
122
  */
123
- function serializeData(data: any): string {
124
- const obj = deepClone(data, 0);
125
- return JSON.stringify(obj);
123
+ function getEventExtend(event: any): string {
124
+ if (!event) {
125
+ return '';
126
+ }
127
+ const { currentTarget, mark, detail } = event;
128
+ const obj = {};
129
+ // 一般把数据放在dataset或者mark中
130
+ const dataset = currentTarget?.dataset;
131
+ if (dataset && Object.keys(dataset).length) {
132
+ Object.assign(obj, { dataset });
133
+ }
134
+ if (mark && Object.keys(mark).length) {
135
+ Object.assign(obj, { mark });
136
+ }
137
+ // 如果以上都没有,那可能就是在detail中
138
+ if (detail && Object.keys(obj).length === 0) {
139
+ Object.assign(obj, { detail });
140
+ }
141
+ return deepClone(obj);
126
142
  }
127
143
 
128
144
  export default {
129
145
  reportData,
130
146
  emptyFunc,
131
147
  executeFunc,
132
- serializeData,
148
+ deepClone,
149
+ getEventExtend,
133
150
  };
@@ -23,34 +23,41 @@ function proxyLifeMethod(pageOptions: any, methodName: string): void {
23
23
  const original = pageOptions[methodName] || helper.emptyFunc;
24
24
  // eslint-disable-next-line no-param-reassign
25
25
  pageOptions[methodName] = function (...args: any[]): any {
26
- let elapsed: number | '' = ''; // 页面曝光时间
27
- let showCount: number | '' = ''; // 曝光次数
26
+ let exposureTime = 0; // 页面曝光时长
27
+ let showCount = 0; // 曝光次数
28
28
  if (methodName === 'onShow') {
29
29
  this.tmsPageShowCount = (this.tmsPageShowCount || 0) + 1;
30
30
  this.tmsPageShowTime = Date.now();
31
31
  showCount = this.tmsPageShowCount;
32
32
  } else if (methodName === 'onHide' || methodName === 'onUnload') {
33
- elapsed = Date.now() - this.tmsPageShowTime;
33
+ exposureTime = Date.now() - this.tmsPageShowTime;
34
34
  this.tmsPageShowTime = 0;
35
35
  showCount = this.tmsPageShowCount;
36
36
  }
37
- // 执行原函数之后再发埋点
38
- return helper.executeFunc(this, original, args, () => {
39
- const data = helper.serializeData(this.data);
40
- helper.reportData(`Page_${methodName}`, data, showCount, elapsed);
41
- });
37
+
38
+ // 生命周期函数先发埋点,避免次过程用户退出而丢失埋点
39
+ const options = helper.deepClone(args[0], 0, 1);
40
+ const showInfo = showCount ? { showCount, exposureTime } : null;
41
+ helper.reportData(`Page_${methodName}`, options, showInfo);
42
+
43
+ // 执行原函数
44
+ return helper.executeFunc(this, original, args, helper.emptyFunc);
42
45
  };
43
46
  }
44
47
 
45
- // 劫持其他事件
46
- function proxyHandle(pageOptions: any, methodName: string): void {
47
- const original = pageOptions[methodName] || helper.emptyFunc;
48
+ // 劫持绑定事件
49
+ function proxyBindEvent(pageOptions: any, methodName: string): void {
50
+ const original = pageOptions[methodName];
51
+ if (!original) {
52
+ return;
53
+ }
48
54
  // eslint-disable-next-line no-param-reassign
49
55
  pageOptions[methodName] = function (...args: any[]): any {
56
+ const extend = helper.getEventExtend(args[0]) ; // 把触发事件附加数据也带上
50
57
  // 执行原函数之后再发埋点
51
58
  return helper.executeFunc(this, original, args, () => {
52
- const data = helper.serializeData(this.data);
53
- helper.reportData(`Page_${methodName}`, data);
59
+ const data = helper.deepClone(this.data);
60
+ helper.reportData(`Page_${methodName}`, data, extend);
54
61
  });
55
62
  };
56
63
  }
@@ -68,7 +75,7 @@ function init(): void {
68
75
  }
69
76
  // tmsReportEvents是由工具在编译时分析出的要上报的事件列表
70
77
  for (const methodName of options.tmsReportEvents) {
71
- proxyHandle(options, methodName);
78
+ proxyBindEvent(options, methodName);
72
79
  }
73
80
  }
74
81
  originalPage(options);
@@ -30,7 +30,8 @@ interface ISystemInfo {
30
30
  wxVersion: string,
31
31
  platform: string,
32
32
  SDKVersion: string,
33
- host: object | '',
33
+ // 开发环境下为空
34
+ host: object,
34
35
  }
35
36
 
36
37
  interface ILocation {