@tmsfe/tms-core 0.0.1 → 0.0.5
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 +19 -1
- package/src/cloudService.js +43 -0
- package/src/config.js +86 -0
- package/src/env.js +116 -0
- package/src/eventDispatcher.js +95 -0
- package/src/fastreport.js +77 -0
- package/src/index-proxy.js +214 -0
- package/src/index-proxy.test.js +19 -0
- package/src/index.js +181 -0
- package/src/ipxHelper.js +75 -0
- package/src/location/base.ts +236 -0
- package/src/location/index.ts +286 -0
- package/src/location/utils.ts +168 -0
- package/src/log.js +171 -0
- package/src/log.test.js +16 -0
- package/src/md5.js +190 -0
- package/src/mpInfo.js +38 -0
- package/src/navigator.js +52 -0
- package/src/objUtils.js +26 -0
- package/src/report.js +434 -0
- package/src/request.js +322 -0
- package/src/rpx.js +17 -0
- package/src/stringUtils.js +171 -0
- package/src/syncfnmanager.js +106 -0
- package/src/timeUtils.js +149 -0
- package/src/types/object.d.ts +12 -0
- package/tsconfig.json +26 -0
- package/dist/cloudService.js +0 -1
- package/dist/env-b76a9d75.js +0 -1
- package/dist/index.js +0 -1
- package/dist/request-f9eddadc.js +0 -1
- package/dist/request.js +0 -1
- package/publish.config.json +0 -25
package/package.json
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@tmsfe/tms-core",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "tms运行时框架",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "http://git.code.oa.com/lbsweb/tms/tms-arch.git"
|
|
8
|
+
},
|
|
9
|
+
"main": "src/index",
|
|
10
|
+
"miniprogram": "src",
|
|
11
|
+
"buildOptions": {
|
|
12
|
+
"formats": [
|
|
13
|
+
"esm"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"scripts": {},
|
|
17
|
+
"author": "tms·web",
|
|
18
|
+
"gitHead": "72bf52451594b49a1c9f78edbad5956d414a66ca"
|
|
19
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getEnvInfo, getAuthInfo } from './env';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* callCloudFunc 方法 调用云函数
|
|
5
|
+
* @param {String} name 要调用的云函数
|
|
6
|
+
* @param {Object} data 需要传给云函数的参数
|
|
7
|
+
* @param {Boolean} withAuth 是否需要补充userId,token参数,当云函数需要调用SinanServer时,需要这些参数来完成鉴权
|
|
8
|
+
* @returns {viod} 云函数
|
|
9
|
+
*/
|
|
10
|
+
export const callCloudFunc = async (name = '', data = {}, withAuth = true) => {
|
|
11
|
+
const { cloudEnvId, appVersion } = getEnvInfo();
|
|
12
|
+
const timestamp = Date.now();
|
|
13
|
+
const random = Math.random()
|
|
14
|
+
.toString()
|
|
15
|
+
.slice(2, 7);
|
|
16
|
+
const sourceId = 7; // 6 未知 7 云函数 8 出行 9 我的车
|
|
17
|
+
|
|
18
|
+
const mergedData = {
|
|
19
|
+
...data,
|
|
20
|
+
timestamp,
|
|
21
|
+
seqId: `${timestamp}${sourceId}${random}`, // 补充seqId参数
|
|
22
|
+
appVersion, // 补充appVersion参数
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (withAuth) { // 补充userId, token参数
|
|
26
|
+
const { userId, token } = await getAuthInfo();
|
|
27
|
+
Object.assign(mergedData, { userId, token });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const res = await new Promise((resolve, reject) => {
|
|
31
|
+
wx.cloud.callFunction({
|
|
32
|
+
name,
|
|
33
|
+
data: mergedData,
|
|
34
|
+
config: { env: cloudEnvId },
|
|
35
|
+
success: resolve,
|
|
36
|
+
fail: (err) => {
|
|
37
|
+
reject({ err, name, mergedData });
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return res;
|
|
43
|
+
};
|
package/src/config.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 小程序云控配置实现
|
|
3
|
+
*/
|
|
4
|
+
import Request from './request';
|
|
5
|
+
import { getEnvInfo } from './env';
|
|
6
|
+
|
|
7
|
+
const parseAllCfgs = (configPaths, resData, defaultCfgs) => configPaths.map((path, index) => {
|
|
8
|
+
const found = resData.find(cfg => cfg.configPath === path);
|
|
9
|
+
if (found) {
|
|
10
|
+
return JSON.parse(found.configValue);
|
|
11
|
+
}
|
|
12
|
+
if (defaultCfgs && defaultCfgs[index]) {
|
|
13
|
+
return defaultCfgs[index];
|
|
14
|
+
}
|
|
15
|
+
return {}; // 没找到配置,返回一个空对象
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* getConfig 批量拉取配置
|
|
20
|
+
* @description 拉取运营平台上的配置内容。关于运营平台的具体用法,参见{@link https://iwiki.woa.com/pages/viewpage.action?pageId=527948584}
|
|
21
|
+
* @category 配置相关
|
|
22
|
+
* @example <caption>拉取单个配置</caption>
|
|
23
|
+
* const cfg = await app.tms.getConfig('/${client}/violation/subscribe', {}, { title: '当前城市不支持订阅'})
|
|
24
|
+
* console.log(cfg); // 成功则返回服务端存储的配置,失败返回默认值
|
|
25
|
+
* @example <caption>批量拉取配置</caption>
|
|
26
|
+
const cfgs = await app.tms.getConfig([
|
|
27
|
+
'/${client}/home/service',
|
|
28
|
+
'/${client}/home/navbar',
|
|
29
|
+
], {}, [
|
|
30
|
+
[
|
|
31
|
+
{ caption: '违章代缴', icon: 'violation.png' }
|
|
32
|
+
],
|
|
33
|
+
{ title: '晚上好,欢迎~' }
|
|
34
|
+
]);
|
|
35
|
+
console.log(cfgs); // 成功则返回服务端存储的配置,失败返回默认值
|
|
36
|
+
* @param {String|Array} configPath 配置路径,单个路径或配置路径数组,支持替换${client}为当前小程序。例如在出行小程序,${client}会变替换为sinan
|
|
37
|
+
* @param {Object} extendAttr 扩展属性,传给配置服务用于检索哪个版本的配置适用于当前用户。
|
|
38
|
+
* @param {Object} [defaultCfg] 默认配置,请求失败返回默认值。
|
|
39
|
+
* @returns {Promise<Object|Array<Object>>}
|
|
40
|
+
* 有默认值时,请求失败返回默认值。无默认值时,请求失败返回Promise.reject
|
|
41
|
+
*/
|
|
42
|
+
function getConfig(configPath, extendAttr = {}, defaultCfg) {
|
|
43
|
+
if (Array.isArray(configPath)) { // 复数形式
|
|
44
|
+
if (defaultCfg) { // 有默认值
|
|
45
|
+
if (!Array.isArray(defaultCfg) || configPath.length !== defaultCfg.length) {
|
|
46
|
+
throw new Error('配置路径和默认值的数组长度不一致');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const configPaths = Array.isArray(configPath) ? configPath : [configPath];
|
|
51
|
+
const defaultCfgs = (defaultCfg && (Array.isArray(defaultCfg) ? defaultCfg : [defaultCfg])) || null;
|
|
52
|
+
const { client } = getEnvInfo();
|
|
53
|
+
configPaths.forEach((path, index) => {
|
|
54
|
+
configPaths[index] = path.replace(/\$\{client\}/, client);
|
|
55
|
+
});
|
|
56
|
+
const extendAttrs = typeof extendAttr === 'string' ? extendAttr : JSON.stringify(extendAttr);
|
|
57
|
+
const api = new Request();
|
|
58
|
+
return api.post('marketing/config', {
|
|
59
|
+
extendAttrs,
|
|
60
|
+
configPaths,
|
|
61
|
+
})
|
|
62
|
+
.then((res = {}) => {
|
|
63
|
+
const { errCode, resData } = res || {};
|
|
64
|
+
if (resData && resData.length > 0) {
|
|
65
|
+
const parsed = parseAllCfgs(configPaths, resData, defaultCfgs);
|
|
66
|
+
if (Array.isArray(configPath)) {
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
return parsed[0];
|
|
70
|
+
}
|
|
71
|
+
if (defaultCfgs) {
|
|
72
|
+
return Array.isArray(configPath) ? defaultCfgs : defaultCfgs[0];
|
|
73
|
+
}
|
|
74
|
+
return Promise.reject({ errCode, resData, msg: `获取${configPaths.join(',')}配置失败,接口调用出错` });
|
|
75
|
+
})
|
|
76
|
+
.catch((e) => {
|
|
77
|
+
if (defaultCfgs) {
|
|
78
|
+
return Promise.resolve(Array.isArray(configPath) ? defaultCfgs : defaultCfgs[0]);
|
|
79
|
+
}
|
|
80
|
+
return Promise.reject({ err: e, msg: `获取${configPaths.join(',')}配置失败,接口调用出错` });
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
getConfig,
|
|
86
|
+
};
|
package/src/env.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
|
|
2
|
+
const env = {
|
|
3
|
+
wxAppId: '', // 当前运行时小程序的appId
|
|
4
|
+
appVersion: '', // 当前运行时所在项目的版本号
|
|
5
|
+
appEnv: '', // 运行环境 test - 测试、production - 正式
|
|
6
|
+
client: '', // 运行时项目名,sinan - 腾讯出行服务; mycar - 我的车小程序
|
|
7
|
+
cloudEnvId: '', // 运行云函数的环境id
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let baseAuthInfo = undefined;
|
|
11
|
+
const getAuthInfoQueue = [];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @description 设置用户信息
|
|
15
|
+
* @param {Object} authInfo 用户信息
|
|
16
|
+
* @param {Object} err err
|
|
17
|
+
* @returns {Void} 无返回值
|
|
18
|
+
*/
|
|
19
|
+
export const setAuthInfo = (authInfo, err) => {
|
|
20
|
+
baseAuthInfo = authInfo;
|
|
21
|
+
while (getAuthInfoQueue.length) {
|
|
22
|
+
const pro = getAuthInfoQueue.shift();
|
|
23
|
+
if (err) {
|
|
24
|
+
pro.reject(err);
|
|
25
|
+
} else {
|
|
26
|
+
pro.resolve(baseAuthInfo);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* 获取登录状态信息
|
|
32
|
+
* @returns {Object} 当前用户状态参数
|
|
33
|
+
*/
|
|
34
|
+
export const getAuthInfo = async () => {
|
|
35
|
+
if (baseAuthInfo !== undefined) {
|
|
36
|
+
return baseAuthInfo;
|
|
37
|
+
}
|
|
38
|
+
return new Promise((resolve, reject) => getAuthInfoQueue.push({ resolve, reject }));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* tms.getEnvInfo 用于获取运行时所在的环境信息
|
|
43
|
+
* @returns {object} 运行时环境信息.
|
|
44
|
+
*/
|
|
45
|
+
export const getEnvInfo = () => env;
|
|
46
|
+
/**
|
|
47
|
+
* 设置环境变量
|
|
48
|
+
* @param {object} envInfo 环境变量
|
|
49
|
+
* @returns {undefined} 无.
|
|
50
|
+
*/
|
|
51
|
+
export const setEnvInfo = (envInfo) => {
|
|
52
|
+
const { wxAppId, appVersion, appEnv, client, cloudEnvId } = envInfo;
|
|
53
|
+
env.wxAppId = wxAppId;
|
|
54
|
+
env.appVersion = appVersion;
|
|
55
|
+
env.appEnv = appEnv;
|
|
56
|
+
env.client = client;
|
|
57
|
+
env.cloudEnvId = cloudEnvId;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
let appPagePaths = []; // app页面路径集合
|
|
61
|
+
let homePageInfo = null; // 首页信息 { isTab, path, tabs }
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 获取app内所有页面的路径
|
|
65
|
+
* @returns {Array<String>} 页面路径集合
|
|
66
|
+
*/
|
|
67
|
+
export const getAppPagePaths = () => appPagePaths;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 设置app内所有页面的路径
|
|
71
|
+
* @param {Array<String>} paths 页面路径集合
|
|
72
|
+
* @param {Object|null} homePage 首页信息
|
|
73
|
+
* @param {Boolean} homePath.isTab 首页是否tab页
|
|
74
|
+
* @param {String} homePath.path 首页页面路径(isTab=false时使用此字段)
|
|
75
|
+
* @param {Array<String>} homePath.tabs tab页面路径列表(isTab=true时使用自此段)
|
|
76
|
+
* @returns {void}
|
|
77
|
+
*/
|
|
78
|
+
export const setAppPagePaths = (paths, homePage) => {
|
|
79
|
+
appPagePaths = paths;
|
|
80
|
+
const { isTab = false, path = '', tabs = [] } = homePage || {};
|
|
81
|
+
homePageInfo = { isTab, path, tabs };
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 判断页面是否存在于当前app中
|
|
86
|
+
* @param {String} page 页面路径
|
|
87
|
+
* @returns {Boolean} 页面是否存在app中
|
|
88
|
+
*/
|
|
89
|
+
export const isAppPageExist = (page) => {
|
|
90
|
+
const route = !page ? '' : String(page).split('?')[0];
|
|
91
|
+
if (!route || !Array.isArray(appPagePaths)) return false;
|
|
92
|
+
const routeWithoutPrefixSlash = route[0] === '/' ? route.substring(1) : route;
|
|
93
|
+
return appPagePaths.some(path => path === routeWithoutPrefixSlash || path === `/${routeWithoutPrefixSlash}`);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// 以下变量标识各小程序appId
|
|
97
|
+
const MOBILITY_APPID = 'wx65cc950f42e8fff1'; // 出行服务小程序AppId
|
|
98
|
+
const MOBILITY_DEMO_APPID = 'wxa7ce727b525f80b0'; // 出行服务demo小程序AppId
|
|
99
|
+
const SINAN_HOME = '/modules/index/carlife/pages/index/index'; // 出行首页地址
|
|
100
|
+
const MYCAR_HOME = '/modules/car/index/index'; // 我的车首页地址
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 获取首页信息
|
|
104
|
+
* @returns {Object|null} homePage 首页信息
|
|
105
|
+
* @returns {Boolean} homePath.isTab 首页是否tab页
|
|
106
|
+
* @returns {String} homePath.path 首页页面路径(isTab=false时使用此字段)
|
|
107
|
+
* @returns {Array<String>} homePath.tabs tab页面路径列表(isTab=true时使用自此段)
|
|
108
|
+
*/
|
|
109
|
+
export const getHomePage = () => {
|
|
110
|
+
if (homePageInfo) return homePageInfo;
|
|
111
|
+
// 返回默认信息
|
|
112
|
+
const mpAppId = wx.getAccountInfoSync()?.miniProgram?.appId;
|
|
113
|
+
const homePagePath = [MOBILITY_APPID, MOBILITY_DEMO_APPID].indexOf(mpAppId) > -1 ? SINAN_HOME : MYCAR_HOME;
|
|
114
|
+
homePageInfo = { isTab: false, path: homePagePath, tabs: [] };
|
|
115
|
+
return homePageInfo;
|
|
116
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* eslint-disable require-jsdoc */
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2017-present, Tencent, Inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
*
|
|
6
|
+
* @desc: 自定义事件机制
|
|
7
|
+
* @author: kexinwu@tencent.com
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* EventDispatcher 类 事件监听器
|
|
13
|
+
* @class EventDispatcher
|
|
14
|
+
* @classdesc 用于统一维护小程序的事件
|
|
15
|
+
*/
|
|
16
|
+
export default class EventDispatcher {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.handlers = [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @memberof EventDispatcher
|
|
23
|
+
* @param {String} type 事件名
|
|
24
|
+
* @param {Function} handler 事件处理函数
|
|
25
|
+
* @returns {Function} handler 事件处理函数
|
|
26
|
+
*/
|
|
27
|
+
bind(type, handler) {
|
|
28
|
+
if (typeof this.handlers[type] === 'undefined') {
|
|
29
|
+
this.handlers[type] = [];
|
|
30
|
+
}
|
|
31
|
+
this.handlers[type].push(handler);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @memberof EventDispatcher
|
|
36
|
+
* @param {String} type 事件名
|
|
37
|
+
* @param {Function} handler 事件处理函数
|
|
38
|
+
* @returns {Function} handler 事件处理函数
|
|
39
|
+
*/
|
|
40
|
+
bindOnce(type, handler) {
|
|
41
|
+
if (typeof this.handlers[type] === 'undefined') {
|
|
42
|
+
this.handlers[type] = [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const isBinded = this.handlers[type].length === 0;
|
|
46
|
+
|
|
47
|
+
if (isBinded) {
|
|
48
|
+
this.handlers[type].push(handler);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @memberof EventDispatcher
|
|
54
|
+
* @param {String} type 事件名
|
|
55
|
+
* @returns {Void} 无返回值
|
|
56
|
+
*/
|
|
57
|
+
remove(type) {
|
|
58
|
+
this.handlers[type] = [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @memberof EventDispatcher
|
|
63
|
+
* @param {String} type 事件名
|
|
64
|
+
* @param {Function} handler 事件处理函数
|
|
65
|
+
* @returns {Void} 无返回值
|
|
66
|
+
*/
|
|
67
|
+
unbind(type, handler) {
|
|
68
|
+
if (this.handlers[type] instanceof Array) {
|
|
69
|
+
const handlers = this.handlers[type];
|
|
70
|
+
|
|
71
|
+
let i = 0;
|
|
72
|
+
const l = handlers.length;
|
|
73
|
+
for (; i < l; i += 1) {
|
|
74
|
+
if (handlers[i] === handler) {
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
handlers.splice(i, 1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @memberof EventDispatcher
|
|
85
|
+
* @param {Object} evt 事件描述
|
|
86
|
+
* @param {String} evt.type 事件类型
|
|
87
|
+
* @returns {Function} handler 事件处理函数
|
|
88
|
+
*/
|
|
89
|
+
dispatch(evt) {
|
|
90
|
+
if (this.handlers[evt.type] instanceof Array) {
|
|
91
|
+
const handlers = this.handlers[evt.type];
|
|
92
|
+
handlers.forEach(handler => handler(evt));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2020-present, Tencent, Inc. All rights reserved.
|
|
3
|
+
* @author Fenggang.Sun <fenggangsun@tencent.com>
|
|
4
|
+
* @file 快速上报数据,不处理过多逻辑,保证快速上报
|
|
5
|
+
*/
|
|
6
|
+
import Request from './request';
|
|
7
|
+
import { getEnvInfo } from './env';
|
|
8
|
+
import Sync from './syncfnmanager';
|
|
9
|
+
|
|
10
|
+
let simulatedUserIdCache; // 模拟用户id在内存里的缓存
|
|
11
|
+
|
|
12
|
+
const getSystemInfo = () => {
|
|
13
|
+
const system = Sync.getSystemInfoSync();
|
|
14
|
+
const { model = '', version: wxVersion = '', platform = '', SDKVersion = '', host = '' } = system;
|
|
15
|
+
|
|
16
|
+
return { model, wxVersion, platform, SDKVersion, host };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @class FastReport
|
|
21
|
+
* @classdesc 快速上报模块,不依赖用户标识和位置
|
|
22
|
+
*/
|
|
23
|
+
export default class FastReport {
|
|
24
|
+
/**
|
|
25
|
+
* @memberof FastReport
|
|
26
|
+
* @description 快速上报
|
|
27
|
+
* @param {Object} param 埋点数据
|
|
28
|
+
* @param {Boolean} simulatedUserId 是否上报模拟用户Id
|
|
29
|
+
* @param {Number} simulatedUserIdIndex 上报模拟用户ID时放在哪个字段
|
|
30
|
+
* @param {Boolean} reportShowScene 是否上报小程序onShow场景值
|
|
31
|
+
* @param {Boolean} appVer 是否上报小程序版本
|
|
32
|
+
* @returns {Promsie} 返回上报结果
|
|
33
|
+
*/
|
|
34
|
+
static report(param, simulatedUserId = true, simulatedUserIdIndex = 40, reportShowScene = true, appVer = true) {
|
|
35
|
+
if (!param?.[27]) return Promise.reject('invalid report param');
|
|
36
|
+
const data = new Array(41);
|
|
37
|
+
const env = getEnvInfo();
|
|
38
|
+
Object.keys(param).forEach((key) => {
|
|
39
|
+
data[key] = param[key] === null ? '' : JSON.stringify(param[key]);
|
|
40
|
+
});
|
|
41
|
+
data[9] = '2';
|
|
42
|
+
data[33] = getSystemInfo();
|
|
43
|
+
appVer && !data[10] && (data[10] = env.appVersion);
|
|
44
|
+
if (!data[26]) data[26] = data[27]?.[0];
|
|
45
|
+
data[28] = env.client;
|
|
46
|
+
if (reportShowScene && !data[29]) {
|
|
47
|
+
const appShowScene = wx.getStorageSync('appShowScene');
|
|
48
|
+
if (appShowScene) data[29] = String(appShowScene);
|
|
49
|
+
}
|
|
50
|
+
if (simulatedUserId && !data[simulatedUserIdIndex]) {
|
|
51
|
+
data[simulatedUserIdIndex] = FastReport.getSimulatedUserId();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return new Request({ withAuth: false }).post('basic/event/upload', { batch: [data] })
|
|
55
|
+
.catch(() => null);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @memberof FastReport
|
|
60
|
+
* @description 获取模拟的用户身份标识
|
|
61
|
+
* @returns {String} 用户的临时标识
|
|
62
|
+
*/
|
|
63
|
+
static getSimulatedUserId() {
|
|
64
|
+
// 优先使用内存级缓存
|
|
65
|
+
if (simulatedUserIdCache) return simulatedUserIdCache;
|
|
66
|
+
const key = 'SimulatedUserKey';
|
|
67
|
+
// 读取本地缓存记录的值
|
|
68
|
+
simulatedUserIdCache = wx.getStorageSync(key);
|
|
69
|
+
if (simulatedUserIdCache) return simulatedUserIdCache;
|
|
70
|
+
// 生成新的值
|
|
71
|
+
const nonce = Math.random().toString(36)
|
|
72
|
+
.substr(2, 10);
|
|
73
|
+
simulatedUserIdCache = `${Date.now()}_${nonce}`;
|
|
74
|
+
wx.setStorage({ key, data: simulatedUserIdCache });
|
|
75
|
+
return simulatedUserIdCache;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 由于需要把tms-core、tms-runtime从主包中移到vendor分包中使用分包异步化加载,
|
|
3
|
+
* 但是很多分包中都会立即调用getApp().tms的接口,为了保证调用不出错,
|
|
4
|
+
* 特地新增此代理js,用于在app.js中先挂在到app.tms下,等vendor加载完再替换掉。
|
|
5
|
+
* 注意:tms-core、tms-runtime有改动都要来这里确认proxy有没有问题。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import syncApi from './syncfnmanager';
|
|
9
|
+
import md5 from './md5';
|
|
10
|
+
import { rpxToPx } from './rpx';
|
|
11
|
+
import { serialize } from './objUtils';
|
|
12
|
+
import * as stringUtils from './stringUtils';
|
|
13
|
+
import * as timeUtils from './timeUtils';
|
|
14
|
+
import * as ipxHelper from './ipxHelper';
|
|
15
|
+
|
|
16
|
+
let app = null;
|
|
17
|
+
let initOptions = null;
|
|
18
|
+
let tmsPromise = null;
|
|
19
|
+
let tms = null;
|
|
20
|
+
let logger = null;
|
|
21
|
+
|
|
22
|
+
function invoke(obj, funcName, args) {
|
|
23
|
+
if (obj[funcName]) {
|
|
24
|
+
return obj[funcName](...args);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 非法调用的时候就要及时上报日志,方便解决问题
|
|
28
|
+
if (!logger) {
|
|
29
|
+
logger = wx.getRealtimeLogManager();
|
|
30
|
+
}
|
|
31
|
+
const msg = `tms-proxy: Cannot read property ${funcName}`;
|
|
32
|
+
logger.addFilterMsg('tms-proxy');
|
|
33
|
+
logger.error(msg);
|
|
34
|
+
console.error(msg);
|
|
35
|
+
return Promise.reject(msg);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function initProxy(appObj, options) {
|
|
39
|
+
app = appObj;
|
|
40
|
+
initOptions = options;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function awaitTMS() {
|
|
44
|
+
if (tmsPromise === null) {
|
|
45
|
+
tmsPromise = new Promise((resolve) => {
|
|
46
|
+
app.initPromise.then((res) => {
|
|
47
|
+
tms = res;
|
|
48
|
+
resolve(res);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return tmsPromise;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 返回Promise的函数,无返回结果的也可以放这里
|
|
56
|
+
const asyncFuncs = {};
|
|
57
|
+
const asyncFuncNames = [
|
|
58
|
+
// 这行是tms-ui的
|
|
59
|
+
'showDrawer', 'hideDrawer', 'showModal', 'hideModal',
|
|
60
|
+
// 这行是tms-runtime的
|
|
61
|
+
'getPhone', 'login', 'getLoginInfo', 'getOpenId', 'getMycarPubOpenId', 'getSinanPubOpenId',
|
|
62
|
+
// tms-core
|
|
63
|
+
'setAuthInfo', 'getConfig', 'navigateToWebview', 'callCloudFunc',
|
|
64
|
+
'setUserLocation', 'getUserLocation', 'getMpOpenId', 'getOuterOpenId',
|
|
65
|
+
];
|
|
66
|
+
asyncFuncNames.forEach((funcName) => {
|
|
67
|
+
asyncFuncs[funcName] = function (...args) {
|
|
68
|
+
return awaitTMS().then(tms => invoke(tms, funcName, args));
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 返回对象的函数,并且对象的所有接口都可以以promise的形式返回
|
|
73
|
+
const objFuncs = {};
|
|
74
|
+
const objFuncNames = [
|
|
75
|
+
'getLogManager', 'getRealtimeLogManager', 'getReporter',
|
|
76
|
+
'getFastReporter', 'getEventDispatcher',
|
|
77
|
+
];
|
|
78
|
+
objFuncNames.forEach((funcName) => {
|
|
79
|
+
objFuncs[funcName] = function (...args1) {
|
|
80
|
+
const ps = awaitTMS().then(tms => invoke(tms, funcName, args1));
|
|
81
|
+
return new Proxy({}, {
|
|
82
|
+
get(obj, name) {
|
|
83
|
+
return function (...args2) {
|
|
84
|
+
return ps.then(funcObj => invoke(funcObj, name, args2));
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// tms-runtime
|
|
92
|
+
function getCarManager() {
|
|
93
|
+
return {
|
|
94
|
+
getCarInfo() {
|
|
95
|
+
if (tms) {
|
|
96
|
+
return tms.getCarManager().getCarInfo();
|
|
97
|
+
}
|
|
98
|
+
return wx.getStorageSync('currentCar') || {};
|
|
99
|
+
},
|
|
100
|
+
setCarInfo(param = {}) {
|
|
101
|
+
awaitTMS().then(tms => tms.getCarManager().setCarInfo(param));
|
|
102
|
+
},
|
|
103
|
+
getCarList() {
|
|
104
|
+
return awaitTMS().then(tms => tms.getCarManager().getCarList());
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function getLocationManager() {
|
|
110
|
+
let manager = null;
|
|
111
|
+
const ps = awaitTMS().then((tms) => {
|
|
112
|
+
manager = tms.getLocationManager();
|
|
113
|
+
});
|
|
114
|
+
let currLoc = null;
|
|
115
|
+
const getUserLocation = () => {
|
|
116
|
+
if (manager) {
|
|
117
|
+
return manager.getUserLocation();
|
|
118
|
+
}
|
|
119
|
+
return currLoc;
|
|
120
|
+
};
|
|
121
|
+
const setUserLocation = (loc) => {
|
|
122
|
+
if (manager) {
|
|
123
|
+
manager.setUserLocation(loc);
|
|
124
|
+
} else if (loc && (typeof loc === 'object')) {
|
|
125
|
+
currLoc = loc;
|
|
126
|
+
ps.then(() => manager.setUserLocation(loc));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return new Proxy({}, {
|
|
130
|
+
get(obj, name) {
|
|
131
|
+
if (name === 'getUserLocation') {
|
|
132
|
+
return getUserLocation;
|
|
133
|
+
}
|
|
134
|
+
if (name === 'setUserLocation') {
|
|
135
|
+
return setUserLocation;
|
|
136
|
+
}
|
|
137
|
+
return function (...args) {
|
|
138
|
+
return ps.then(() => invoke(manager, name, args));
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function createRequest(config = {}) {
|
|
145
|
+
let request = null;
|
|
146
|
+
const ps = awaitTMS().then((tms) => {
|
|
147
|
+
request = tms.createRequest(config);
|
|
148
|
+
});
|
|
149
|
+
const makeUrl = (path) => {
|
|
150
|
+
if (request) {
|
|
151
|
+
return request.makeUrl(path);
|
|
152
|
+
}
|
|
153
|
+
if ((/^http/i).test(path)) {
|
|
154
|
+
return path;
|
|
155
|
+
}
|
|
156
|
+
const host = config?.host || initOptions.defaultHost;
|
|
157
|
+
const validHost = (/^http/i).test(host) ? host : `https://${host}`;
|
|
158
|
+
return `${validHost}/${path}`;
|
|
159
|
+
};
|
|
160
|
+
return new Proxy({}, {
|
|
161
|
+
get(obj, name) {
|
|
162
|
+
if (name === 'makeUrl') {
|
|
163
|
+
return makeUrl;
|
|
164
|
+
}
|
|
165
|
+
return function (...args) {
|
|
166
|
+
return ps.then(() => invoke(request, name, args));
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function getEnvInfo() {
|
|
173
|
+
if (tms) {
|
|
174
|
+
return tms.getEnvInfo();
|
|
175
|
+
}
|
|
176
|
+
const { wxAppId, appVersion, appEnv, client } = initOptions;
|
|
177
|
+
return { wxAppId, appVersion, appEnv, client };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function isAppPageExist(...args) {
|
|
181
|
+
if (tms) {
|
|
182
|
+
return tms.isAppPageExist(...args);
|
|
183
|
+
}
|
|
184
|
+
return true; // todo: 可能不正确
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function getHomePage() {
|
|
188
|
+
if (tms) {
|
|
189
|
+
return tms.getHomePage();
|
|
190
|
+
}
|
|
191
|
+
return initOptions.homePage;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const api = {
|
|
195
|
+
isProxy: true, // 方便定位问题时判断是否proxy
|
|
196
|
+
initProxy,
|
|
197
|
+
md5,
|
|
198
|
+
getCarManager,
|
|
199
|
+
getLocationManager,
|
|
200
|
+
rpxToPx,
|
|
201
|
+
serialize,
|
|
202
|
+
createRequest,
|
|
203
|
+
getEnvInfo,
|
|
204
|
+
isAppPageExist,
|
|
205
|
+
getHomePage,
|
|
206
|
+
...asyncFuncs,
|
|
207
|
+
...objFuncs,
|
|
208
|
+
...syncApi,
|
|
209
|
+
...stringUtils,
|
|
210
|
+
...timeUtils,
|
|
211
|
+
...ipxHelper,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export default api;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import tmsProxy from './index-proxy';
|
|
2
|
+
|
|
3
|
+
describe('tmsProxy', () => {
|
|
4
|
+
beforeAll(() => {
|
|
5
|
+
tmsProxy.initProxy({
|
|
6
|
+
initPromise: new Promise(() => {}),
|
|
7
|
+
}, {});
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('tmsProxy.getCarManager test', () => {
|
|
11
|
+
const car = tmsProxy.getCarManager();
|
|
12
|
+
expect(car).toBeInstanceOf(Object);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('tmsProxy.createRequest test', () => {
|
|
16
|
+
const request = tmsProxy.createRequest();
|
|
17
|
+
expect(request).toBeInstanceOf(Object);
|
|
18
|
+
});
|
|
19
|
+
});
|