@tmsfe/tms-core 0.0.87 → 0.0.90
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 +1 -1
- package/src/index-proxy.js +4 -4
- package/src/index.js +2 -0
- package/src/report/proxy/app.ts +91 -0
- package/src/report/proxy/helper.ts +18 -8
- package/src/report/proxy/index.ts +5 -6
- package/src/report/proxy/page.ts +0 -53
- package/src/request.js +3 -3
- package/src/runtime/api.md +318 -0
- package/src/runtime/car.js +85 -0
- package/src/runtime/config.js +68 -0
- package/src/runtime/getopenapptrafficdata.js +71 -0
- package/src/runtime/index.js +228 -0
- package/src/runtime/login.js +208 -0
- package/src/utils/location/index.js +16 -4
package/package.json
CHANGED
package/src/index-proxy.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 由于需要把tms-core
|
|
2
|
+
* 由于需要把tms-core从主包中移到vendor分包中使用分包异步化加载,
|
|
3
3
|
* 但是很多分包中都会立即调用getApp().tms的接口,为了保证调用不出错,
|
|
4
4
|
* 特地新增此代理js,用于在app.js中先挂在到app.tms下,等vendor加载完再替换掉。
|
|
5
|
-
* 注意:tms-core
|
|
5
|
+
* 注意:tms-core有改动都要来这里确认proxy有没有问题。
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import syncApi from './syncfnmanager';
|
|
@@ -64,7 +64,7 @@ const asyncFuncs = {};
|
|
|
64
64
|
const asyncFuncNames = [
|
|
65
65
|
// 这行是tms-ui的
|
|
66
66
|
'showDrawer', 'hideDrawer', 'showModal', 'hideModal',
|
|
67
|
-
// 这行是
|
|
67
|
+
// 这行是runtime的
|
|
68
68
|
'getPhone', 'login', 'getLoginInfo', 'getOpenId', 'getMycarPubOpenId', 'getSinanPubOpenId',
|
|
69
69
|
// tms-core
|
|
70
70
|
'setAuthInfo', 'getConfig', 'navigateToWebview', 'callCloudFunc', 'getEncryptUserInfo',
|
|
@@ -94,7 +94,7 @@ objFuncNames.forEach((funcName) => {
|
|
|
94
94
|
};
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
//
|
|
97
|
+
// runtime
|
|
98
98
|
function getCarManager() {
|
|
99
99
|
return {
|
|
100
100
|
getCarInfo() {
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import runtime from './runtime/index';
|
|
1
2
|
import Request from './request';
|
|
2
3
|
import AutoReport from './report/proxy/index';
|
|
3
4
|
import Reporter from './report/index';
|
|
@@ -206,6 +207,7 @@ const api = {
|
|
|
206
207
|
...uiUtil,
|
|
207
208
|
throttle,
|
|
208
209
|
debounce,
|
|
210
|
+
...runtime,
|
|
209
211
|
};
|
|
210
212
|
|
|
211
213
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 负责小程序级的全埋点
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// / <reference path='./types.ts'/>
|
|
6
|
+
|
|
7
|
+
import helper from './helper';
|
|
8
|
+
|
|
9
|
+
// 劫持导航api
|
|
10
|
+
function proxyNavigateApi(api: string): void {
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
const originalApi = wx[api];
|
|
13
|
+
Object.defineProperty(wx, api, {
|
|
14
|
+
writable: true,
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
value(...args: any) {
|
|
18
|
+
const { url = '' } = args[0] || {};
|
|
19
|
+
const [path, params = ''] = url.split('?');
|
|
20
|
+
helper.reportData(`wx_${api}_before`, path, params);
|
|
21
|
+
|
|
22
|
+
originalApi.apply(this, args);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 劫持消息订阅接口
|
|
28
|
+
function proxySubscribeMessage(): void {
|
|
29
|
+
const originalApi = wx.requestSubscribeMessage;
|
|
30
|
+
Object.defineProperty(wx, 'requestSubscribeMessage', {
|
|
31
|
+
writable: true,
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
value(options: any) {
|
|
35
|
+
const { tmplIds } = options;
|
|
36
|
+
const originalSuccess = options.success || helper.emptyFunc;
|
|
37
|
+
const originalFail = options.fail || helper.emptyFunc;
|
|
38
|
+
// eslint-disable-next-line
|
|
39
|
+
options.success = function(res: any) {
|
|
40
|
+
for (const tmplId of tmplIds) {
|
|
41
|
+
const result = res[tmplId];
|
|
42
|
+
if (result) {
|
|
43
|
+
helper.reportData('wx_requestSubscribeMessage_result', tmplId, result);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
originalSuccess.call(this, res);
|
|
47
|
+
};
|
|
48
|
+
// eslint-disable-next-line
|
|
49
|
+
options.fail = function(err: any) {
|
|
50
|
+
helper.reportData('wx_requestSubscribeMessage_fail', tmplIds, err.errMsg);
|
|
51
|
+
originalFail.call(this, err);
|
|
52
|
+
};
|
|
53
|
+
originalApi.call(this, options);
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 监听onAppShow跟onAppHide
|
|
59
|
+
function listenerAppVisible(): void {
|
|
60
|
+
let showCount = 0; // 小程序切到前台次数(onAppShow)
|
|
61
|
+
let hideCount = 0; // 小程序切到后台次数(onAppHide)
|
|
62
|
+
let showTime = 0; // 触发onAppShow的时间
|
|
63
|
+
let hideTime = 0; // 触发onAppHide的时间
|
|
64
|
+
wx.onAppShow(() => {
|
|
65
|
+
showCount += 1;
|
|
66
|
+
showTime = Date.now();
|
|
67
|
+
// 距离onAppHide触发的时长
|
|
68
|
+
const lessHideTime = hideCount === 0 ? 0 : showTime - hideTime;
|
|
69
|
+
helper.reportData('App_onAppShow', { showCount, hideCount, lessHideTime });
|
|
70
|
+
});
|
|
71
|
+
wx.onAppHide(() => {
|
|
72
|
+
hideCount += 1;
|
|
73
|
+
hideTime = Date.now();
|
|
74
|
+
// 距离onAppShow触发的时长
|
|
75
|
+
const lessShowTime = hideTime - showTime;
|
|
76
|
+
helper.fastReportData('App_onAppHide', { showCount, hideCount, lessShowTime });
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 劫持App接口
|
|
81
|
+
function init(): void {
|
|
82
|
+
listenerAppVisible();
|
|
83
|
+
proxySubscribeMessage();
|
|
84
|
+
proxyNavigateApi('navigateTo');
|
|
85
|
+
proxyNavigateApi('redirectTo');
|
|
86
|
+
proxyNavigateApi('reLaunch');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default {
|
|
90
|
+
init,
|
|
91
|
+
};
|
|
@@ -4,17 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
// / <reference path='./types.ts'/>
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
function getReporter(): any {
|
|
8
|
+
// 如果是在app.js的onLaunch中调用,则没有getApp().tms为空
|
|
9
|
+
const tms = getApp()?.tms || wx.tms;
|
|
10
|
+
return tms.getReporter();
|
|
11
|
+
}
|
|
8
12
|
|
|
13
|
+
/**
|
|
14
|
+
* 聚合上报埋点
|
|
15
|
+
*/
|
|
9
16
|
function reportData(...args: any[]): any {
|
|
10
|
-
if (reporter === null) {
|
|
11
|
-
// 如果是在app.js的onLaunch中调用,则没有getApp().tms为空
|
|
12
|
-
// @ts-ignore
|
|
13
|
-
const tms = getApp()?.tms || wx.tms;
|
|
14
|
-
reporter = tms.getReporter();
|
|
15
|
-
}
|
|
16
17
|
console.log('自动埋点:', ...args);
|
|
17
|
-
|
|
18
|
+
getReporter().report2(...args);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 立即上报埋点
|
|
23
|
+
*/
|
|
24
|
+
function fastReportData(...args: any[]): any {
|
|
25
|
+
console.log('快速自动埋点:', ...args);
|
|
26
|
+
getReporter().fastReport2(...args);
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
let systemInfo: any = null;
|
|
@@ -90,6 +99,7 @@ function executeFunc(context: any, func: Function, args: any[], callback: Functi
|
|
|
90
99
|
export default {
|
|
91
100
|
emptyFunc,
|
|
92
101
|
reportData,
|
|
102
|
+
fastReportData,
|
|
93
103
|
executeFunc,
|
|
94
104
|
getSystemInfo,
|
|
95
105
|
getLastBindEvent,
|
|
@@ -2,17 +2,16 @@
|
|
|
2
2
|
* 负责页面和组件的全埋点
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import proxyApp from './app';
|
|
5
6
|
import proxyPage from './page';
|
|
6
7
|
import proxyComponent from './component';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
proxyApp.init();
|
|
10
|
+
proxyPage.init();
|
|
11
|
+
proxyComponent.init();
|
|
9
12
|
|
|
13
|
+
// 目前没有需要控制初始化时机的场景
|
|
10
14
|
function init(): void {
|
|
11
|
-
if (!isInit) {
|
|
12
|
-
isInit = true;
|
|
13
|
-
proxyPage.init();
|
|
14
|
-
proxyComponent.init();
|
|
15
|
-
}
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export default {
|
package/src/report/proxy/page.ts
CHANGED
|
@@ -122,62 +122,9 @@ function proxyPage(): void {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
// 劫持导航api
|
|
126
|
-
function proxyNavigateApi(api: string): void {
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
const originalApi = wx[api];
|
|
129
|
-
Object.defineProperty(wx, api, {
|
|
130
|
-
writable: true,
|
|
131
|
-
enumerable: true,
|
|
132
|
-
configurable: true,
|
|
133
|
-
value(...args: any) {
|
|
134
|
-
const { url = '' } = args[0] || {};
|
|
135
|
-
const [path, params = ''] = url.split('?');
|
|
136
|
-
helper.reportData(`wx_${api}_before`, path, params);
|
|
137
|
-
|
|
138
|
-
originalApi.apply(this, args);
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// 劫持消息订阅接口
|
|
144
|
-
function proxySubscribeMessage(): void {
|
|
145
|
-
const originalApi = wx.requestSubscribeMessage;
|
|
146
|
-
Object.defineProperty(wx, 'requestSubscribeMessage', {
|
|
147
|
-
writable: true,
|
|
148
|
-
enumerable: true,
|
|
149
|
-
configurable: true,
|
|
150
|
-
value(options: any) {
|
|
151
|
-
const { tmplIds } = options;
|
|
152
|
-
const originalSuccess = options.success || helper.emptyFunc;
|
|
153
|
-
const originalFail = options.fail || helper.emptyFunc;
|
|
154
|
-
// eslint-disable-next-line
|
|
155
|
-
options.success = function(res: any) {
|
|
156
|
-
for (const tmplId of tmplIds) {
|
|
157
|
-
const result = res[tmplId];
|
|
158
|
-
if (result) {
|
|
159
|
-
helper.reportData('wx_requestSubscribeMessage_result', tmplId, result);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
originalSuccess.call(this, res);
|
|
163
|
-
};
|
|
164
|
-
// eslint-disable-next-line
|
|
165
|
-
options.fail = function(err: any) {
|
|
166
|
-
helper.reportData('wx_requestSubscribeMessage_fail', tmplIds, err.errMsg);
|
|
167
|
-
originalFail.call(this, err);
|
|
168
|
-
};
|
|
169
|
-
originalApi.call(this, options);
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
125
|
// 劫持Page
|
|
175
126
|
function init(): void {
|
|
176
127
|
proxyPage();
|
|
177
|
-
proxySubscribeMessage();
|
|
178
|
-
proxyNavigateApi('navigateTo');
|
|
179
|
-
proxyNavigateApi('redirectTo');
|
|
180
|
-
proxyNavigateApi('reLaunch');
|
|
181
128
|
}
|
|
182
129
|
|
|
183
130
|
export default {
|
package/src/request.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @copyright 2021-present, Tencent, Inc. All rights reserved.
|
|
3
3
|
* @brief request.js用于发起网络请求.
|
|
4
|
-
* request模块作为基于 tms-core
|
|
5
|
-
* 目前支持在出行服务小程序或基于出行服务的小程序中调用。在后续
|
|
4
|
+
* request模块作为基于 tms-core 的应用的公共请求模块。
|
|
5
|
+
* 目前支持在出行服务小程序或基于出行服务的小程序中调用。在后续runtime支持公众号H5后,
|
|
6
6
|
* 将支持在H5中调用。
|
|
7
7
|
*
|
|
8
8
|
* 考虑到对不同运行环境的支持,强依赖运行环境的依赖,比如 wx.request,应通过注入的形式提供。
|
|
@@ -117,7 +117,7 @@ const modifyAuthParam = async (param, withAuth) => {
|
|
|
117
117
|
export default class Request {
|
|
118
118
|
/**
|
|
119
119
|
* 默认的request host域名
|
|
120
|
-
* defaultHost 在
|
|
120
|
+
* defaultHost 在runtime初始化时进行设置,为出行服务接入层域名
|
|
121
121
|
* 具体业务模块 new Request() 使用时,不指定自定义 host ,将使用defaultHost
|
|
122
122
|
*/
|
|
123
123
|
static defaultHost = '';
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
|
|
2
|
+
# runtime
|
|
3
|
+
|
|
4
|
+
目录
|
|
5
|
+
[TOC]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## **index**
|
|
9
|
+
|
|
10
|
+
### CarService()
|
|
11
|
+
> 维护整个小程序逻辑中的当前车概念,提供当前车信息与获取车列表接口
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### DO_NOT_NEED_REPORT_SCENES()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### string getOpenId$1()
|
|
24
|
+
> 获取用户在小程序中的openId
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
**返回值**
|
|
29
|
+
|
|
30
|
+
| 类型 | 说明 |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| <code>string</code> | openId获取成功时,返回resolved Promise,resolved数据为openId获取失败时,返回rejected Promise,rejected数据为错误对象 |
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Promise.<String> getMycarPubOpenId$1()
|
|
36
|
+
> 获取用户在我的车公众号下的openId
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
**返回值**
|
|
41
|
+
|
|
42
|
+
| 类型 | 说明 |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| <code>Promise.<String\></code> | 获取成功时,返回resolved Promise,resolved数据为用户在我的车公众号下的openId获取失败时,返回rejected Promise,rejected数据为错误对象 |
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Promise.<String> getSinanPubOpenId$1()
|
|
48
|
+
> 获取用户在出行服务公众号下的openId
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
**返回值**
|
|
53
|
+
|
|
54
|
+
| 类型 | 说明 |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| <code>Promise.<String\></code> | 获取成功时,返回resolved Promise,resolved数据为用户在出行服务公众号下的openId获取失败时,返回rejected Promise,rejected数据为错误对象 |
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### string getPhone$1()
|
|
60
|
+
> 获取用户手机号
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
**返回值**
|
|
65
|
+
|
|
66
|
+
| 类型 | 说明 |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| <code>string</code> | 手机号 |
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### promise getLoginInfo()
|
|
72
|
+
> 获取用户userId等登陆信息
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
**返回值**
|
|
77
|
+
|
|
78
|
+
| 类型 | 说明 |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| <code>promise</code> | 返回用户登录态promise,resolve后为用户的登录信息. |
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### promise getUserLocation$1(boolean)
|
|
84
|
+
> getUserLocation 方法 获取用户选择的城市位置信息 或者 用户真实的位置信息
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
**参数**
|
|
88
|
+
|
|
89
|
+
| 字段名 | 类型 | 说明 | 默认值 | 是否可选 |
|
|
90
|
+
| ----- | --- | --- | ----- | ----- |
|
|
91
|
+
| showModalWhenCloseAuth | <code>boolean</code> | 没有授权时是否展示授权弹窗 | --- | 否 |
|
|
92
|
+
|
|
93
|
+
**返回值**
|
|
94
|
+
|
|
95
|
+
| 类型 | 说明 |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| <code>promise</code> | 用户位置信息 |
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
### void setUserLocation$1(Object)
|
|
101
|
+
> setUserLocation 方法 设置用户位置(小程序生命周期内有效)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
**参数**
|
|
105
|
+
|
|
106
|
+
| 字段名 | 类型 | 说明 | 默认值 | 是否可选 |
|
|
107
|
+
| ----- | --- | --- | ----- | ----- |
|
|
108
|
+
| loc | <code>Object</code> | 用户手动选择的位置
|
|
109
|
+
loc参数示例:
|
|
110
|
+
{
|
|
111
|
+
province: '北京市',
|
|
112
|
+
cityName: '北京市',
|
|
113
|
+
cityCode: '100100',
|
|
114
|
+
latitude: 325.255333,
|
|
115
|
+
longitude: 116.2545454,
|
|
116
|
+
adCode: 1212144,
|
|
117
|
+
} | --- | 否 |
|
|
118
|
+
|
|
119
|
+
**返回值**
|
|
120
|
+
|
|
121
|
+
| 类型 | 说明 |
|
|
122
|
+
| --- | --- |
|
|
123
|
+
| <code>void</code> | |
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
### object CarService.getCarInfo()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
**返回值**
|
|
131
|
+
|
|
132
|
+
| 类型 | 说明 |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| <code>object</code> | 车信息对象 |
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
### void CarService.setCarInfo(object)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
**参数**
|
|
141
|
+
|
|
142
|
+
| 字段名 | 类型 | 说明 | 默认值 | 是否可选 |
|
|
143
|
+
| ----- | --- | --- | ----- | ----- |
|
|
144
|
+
| param | <code>object</code> | 要设置的当前车信息 | --- | 否 |
|
|
145
|
+
|
|
146
|
+
**返回值**
|
|
147
|
+
|
|
148
|
+
| 类型 | 说明 |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| <code>void</code> | |
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
### promise CarService.getCarList()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
**返回值**
|
|
158
|
+
|
|
159
|
+
| 类型 | 说明 |
|
|
160
|
+
| --- | --- |
|
|
161
|
+
| <code>promise</code> | 获取车列表的promise |
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## **car**
|
|
165
|
+
|
|
166
|
+
### CarService()
|
|
167
|
+
> 维护整个小程序逻辑中的当前车概念,提供当前车信息与获取车列表接口
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
### object getCarInfo()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
**返回值**
|
|
178
|
+
|
|
179
|
+
| 类型 | 说明 |
|
|
180
|
+
| --- | --- |
|
|
181
|
+
| <code>object</code> | 车信息对象 |
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
### void setCarInfo(object)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
**参数**
|
|
188
|
+
|
|
189
|
+
| 字段名 | 类型 | 说明 | 默认值 | 是否可选 |
|
|
190
|
+
| ----- | --- | --- | ----- | ----- |
|
|
191
|
+
| param | <code>object</code> | 要设置的当前车信息 | --- | 否 |
|
|
192
|
+
|
|
193
|
+
**返回值**
|
|
194
|
+
|
|
195
|
+
| 类型 | 说明 |
|
|
196
|
+
| --- | --- |
|
|
197
|
+
| <code>void</code> | |
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
### promise getCarList()
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
**返回值**
|
|
205
|
+
|
|
206
|
+
| 类型 | 说明 |
|
|
207
|
+
| --- | --- |
|
|
208
|
+
| <code>promise</code> | 获取车列表的promise |
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
## **index**
|
|
212
|
+
|
|
213
|
+
### promise getLoginInfo()
|
|
214
|
+
> 获取用户userId等登陆信息
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
**返回值**
|
|
219
|
+
|
|
220
|
+
| 类型 | 说明 |
|
|
221
|
+
| --- | --- |
|
|
222
|
+
| <code>promise</code> | 返回用户登录态promise,resolve后为用户的登录信息. |
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
## **location**
|
|
226
|
+
|
|
227
|
+
### promise getUserLocation(boolean)
|
|
228
|
+
> getUserLocation 方法 获取用户选择的城市位置信息 或者 用户真实的位置信息
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
**参数**
|
|
232
|
+
|
|
233
|
+
| 字段名 | 类型 | 说明 | 默认值 | 是否可选 |
|
|
234
|
+
| ----- | --- | --- | ----- | ----- |
|
|
235
|
+
| showModalWhenCloseAuth | <code>boolean</code> | 没有授权时是否展示授权弹窗 | --- | 否 |
|
|
236
|
+
|
|
237
|
+
**返回值**
|
|
238
|
+
|
|
239
|
+
| 类型 | 说明 |
|
|
240
|
+
| --- | --- |
|
|
241
|
+
| <code>promise</code> | 用户位置信息 |
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
### void setUserLocation(Object)
|
|
245
|
+
> setUserLocation 方法 设置用户位置(小程序生命周期内有效)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
**参数**
|
|
249
|
+
|
|
250
|
+
| 字段名 | 类型 | 说明 | 默认值 | 是否可选 |
|
|
251
|
+
| ----- | --- | --- | ----- | ----- |
|
|
252
|
+
| loc | <code>Object</code> | 用户手动选择的位置
|
|
253
|
+
loc参数示例:
|
|
254
|
+
{
|
|
255
|
+
province: '北京市',
|
|
256
|
+
cityName: '北京市',
|
|
257
|
+
cityCode: '100100',
|
|
258
|
+
latitude: 325.255333,
|
|
259
|
+
longitude: 116.2545454,
|
|
260
|
+
adCode: 1212144,
|
|
261
|
+
} | --- | 否 |
|
|
262
|
+
|
|
263
|
+
**返回值**
|
|
264
|
+
|
|
265
|
+
| 类型 | 说明 |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| <code>void</code> | |
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
## **login**
|
|
271
|
+
|
|
272
|
+
### string getOpenId()
|
|
273
|
+
> 获取用户在小程序中的openId
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
**返回值**
|
|
278
|
+
|
|
279
|
+
| 类型 | 说明 |
|
|
280
|
+
| --- | --- |
|
|
281
|
+
| <code>string</code> | openId获取成功时,返回resolved Promise,resolved数据为openId获取失败时,返回rejected Promise,rejected数据为错误对象 |
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
### Promise.<String> getMycarPubOpenId()
|
|
285
|
+
> 获取用户在我的车公众号下的openId
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
**返回值**
|
|
290
|
+
|
|
291
|
+
| 类型 | 说明 |
|
|
292
|
+
| --- | --- |
|
|
293
|
+
| <code>Promise.<String\></code> | 获取成功时,返回resolved Promise,resolved数据为用户在我的车公众号下的openId获取失败时,返回rejected Promise,rejected数据为错误对象 |
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
### Promise.<String> getSinanPubOpenId()
|
|
297
|
+
> 获取用户在出行服务公众号下的openId
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
**返回值**
|
|
302
|
+
|
|
303
|
+
| 类型 | 说明 |
|
|
304
|
+
| --- | --- |
|
|
305
|
+
| <code>Promise.<String\></code> | 获取成功时,返回resolved Promise,resolved数据为用户在出行服务公众号下的openId获取失败时,返回rejected Promise,rejected数据为错误对象 |
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
### string getPhone()
|
|
309
|
+
> 获取用户手机号
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
**返回值**
|
|
314
|
+
|
|
315
|
+
| 类型 | 说明 |
|
|
316
|
+
| --- | --- |
|
|
317
|
+
| <code>string</code> | 手机号 |
|
|
318
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
let carInfo = {}; // 当前车信息
|
|
2
|
+
let carList = []; // 缓存到的车列表信息
|
|
3
|
+
let getCarListProm = null;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class CarService
|
|
7
|
+
* @classdesc 维护整个小程序逻辑中的当前车概念,提供当前车信息与获取车列表接口
|
|
8
|
+
*/
|
|
9
|
+
export default class CarService {
|
|
10
|
+
/**
|
|
11
|
+
* @memberof CarService
|
|
12
|
+
* getCarInfo 方法 获取当前车信息
|
|
13
|
+
* @returns {object} 车信息对象
|
|
14
|
+
*/
|
|
15
|
+
static getCarInfo() {
|
|
16
|
+
if (carInfo?.wecarId) {
|
|
17
|
+
return carInfo;
|
|
18
|
+
}
|
|
19
|
+
carInfo = wx.getStorageSync('currentCar') || {};
|
|
20
|
+
return carInfo;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @memberof CarService
|
|
25
|
+
* setCarInfo 方法 设置当前车信息,必传 param.wecarId
|
|
26
|
+
* @param {object} param 要设置的当前车信息
|
|
27
|
+
* @returns {void}
|
|
28
|
+
*/
|
|
29
|
+
static setCarInfo(param = {}) {
|
|
30
|
+
let info = { ...param };
|
|
31
|
+
if (info.wecarId) {
|
|
32
|
+
carList.some((item) => {
|
|
33
|
+
if (item.wecarId === info.wecarId) {
|
|
34
|
+
info = { ...item, ...info };
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
carInfo = { ...info };
|
|
41
|
+
wx.setStorageSync('currentCar', { ...carInfo });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @memberof CarService
|
|
46
|
+
* getCarList 方法 获取用户车列表数据
|
|
47
|
+
* @returns {promise} 获取车列表的promise
|
|
48
|
+
*/
|
|
49
|
+
static getCarList() {
|
|
50
|
+
// 防止并发请求车列表
|
|
51
|
+
if (getCarListProm) {
|
|
52
|
+
return getCarListProm;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getCarListProm = new Promise(async (resolve, reject) => {
|
|
56
|
+
const app = getApp({ allowDefault: true });
|
|
57
|
+
app.tms.createRequest().post('user/carlist', {})
|
|
58
|
+
.then((res) => {
|
|
59
|
+
getCarListProm = null;
|
|
60
|
+
if (res.errCode === 0) {
|
|
61
|
+
carList = res.resData.list.map(car => ({
|
|
62
|
+
...car,
|
|
63
|
+
register: car.vin !== '' && car.plate !== '' && car.engineNo !== '' && car.v2ModelName !== '' && car.v2BrandName !== '',
|
|
64
|
+
}));
|
|
65
|
+
carList.some((item) => {
|
|
66
|
+
if (item.wecarId === carInfo.wecarId) {
|
|
67
|
+
carInfo = { ...item, ...carInfo };
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
});
|
|
72
|
+
resolve(carList);
|
|
73
|
+
} else {
|
|
74
|
+
reject(res);
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
.catch((res) => {
|
|
78
|
+
getCarListProm = null;
|
|
79
|
+
reject(res);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return getCarListProm;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright 2021-present, Tencent, Inc. All rights reserved.
|
|
3
|
+
* @brief runtime 的所有环境配置
|
|
4
|
+
* 这里维护运行时需要关注的全部配置,注意此处是一个全量的配置字典,具体业务模块不应再对同一项配置,
|
|
5
|
+
* 增加不同的字段和释义。
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// 小程序连接服务环境配置
|
|
10
|
+
export const APP_ENV = {
|
|
11
|
+
PROD: 'production', // 线上环境
|
|
12
|
+
TEST: 'test', // 测试环境
|
|
13
|
+
DEV: 'development', // 开发环境
|
|
14
|
+
PRE: 'predist', // 灰度(预发布)环境
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// 小程序appid配置
|
|
18
|
+
export const APP_ID = {
|
|
19
|
+
MOBILITY: 'wx65cc950f42e8fff1', // 出行服务小程序AppId
|
|
20
|
+
MOBILITY_DEMO: 'wxa7ce727b525f80b0', // 出行服务demo小程序AppId
|
|
21
|
+
MYCAR: 'wxbd56b62a13d242d2', // 我的车小程序AppId
|
|
22
|
+
MYCAR_DEMO: 'wx735359beafd78b9f', // 我的车demo小程序AppId
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// 小程序名配置
|
|
26
|
+
export const APP_NAME = {
|
|
27
|
+
[APP_ID.MOBILITY]: 'sinan', // 出行服务小程序名称
|
|
28
|
+
[APP_ID.MYCAR]: 'mycar', // 我的车小程序名称
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// 小程序云开发环境配置
|
|
32
|
+
export const CLOUD_ENV_ID = {
|
|
33
|
+
// 我的车小程序
|
|
34
|
+
[APP_ID.MYCAR]: {
|
|
35
|
+
[APP_ENV.PROD]: 'release-mycar',
|
|
36
|
+
[APP_ENV.TEST]: 'petegao-0o7om',
|
|
37
|
+
[APP_ENV.DEV]: 'petegao-0o7om',
|
|
38
|
+
[APP_ENV.PRE]: 'petegao-0o7om',
|
|
39
|
+
},
|
|
40
|
+
// 出行服务小程序
|
|
41
|
+
[APP_ID.MOBILITY]: {
|
|
42
|
+
[APP_ENV.PROD]: 'release-tim',
|
|
43
|
+
[APP_ENV.TEST]: 'test-tim',
|
|
44
|
+
[APP_ENV.DEV]: 'test-tim',
|
|
45
|
+
[APP_ENV.PRE]: 'test-tim',
|
|
46
|
+
},
|
|
47
|
+
// 我的车demo小程序
|
|
48
|
+
[APP_ID.MYCAR_DEMO]: {
|
|
49
|
+
[APP_ENV.TEST]: 'cloud-weapp-test-dev-154ff6',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// 服务端域名
|
|
54
|
+
export const SERVER_HOST = {
|
|
55
|
+
[APP_ENV.PROD]: 'tim.map.qq.com', // 出行服务正式环境域名
|
|
56
|
+
[APP_ENV.TEST]: 'tim.sparta.html5.qq.com', // 出行服务测试环境域名
|
|
57
|
+
[APP_ENV.DEV]: 'tim.sparta.html5.qq.com/dev', // 出行服务开发环境域名
|
|
58
|
+
[APP_ENV.PRE]: 'tim.sparta.html5.qq.com/pre', // 出行服务灰度环境域名
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// 微信爬虫 | 自动化测试打开小程序时对应的场景值
|
|
62
|
+
export const DO_NOT_NEED_REPORT_SCENES = [1030, 1129];
|
|
63
|
+
|
|
64
|
+
// 出行首页地址
|
|
65
|
+
export const SINAN_HOME = '/modules/home/pages/index/index';
|
|
66
|
+
|
|
67
|
+
// 我的车首页地址
|
|
68
|
+
export const MYCAR_HOME = '/modules/car/index/index';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 本文件负责对小程序调用wx同步方法的管理
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { DO_NOT_NEED_REPORT_SCENES } from './config';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 获取启动参数。同wx.getLaunchOptionsSync
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
let launchOptions = null; // 启动参数
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 获取小程序启动参数
|
|
16
|
+
* @private
|
|
17
|
+
* @returns {object} 小程序启动参数
|
|
18
|
+
*/
|
|
19
|
+
const getLaunchOptionsSync = () => {
|
|
20
|
+
if (launchOptions) {
|
|
21
|
+
return launchOptions;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
launchOptions = wx.getLaunchOptionsSync();
|
|
25
|
+
return launchOptions;
|
|
26
|
+
} catch (_) {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// 进入小程序来源from的key配置
|
|
32
|
+
// tuhu渠道:如果链接上from=tuhuviolation,则为途虎渠道用户(不推荐);
|
|
33
|
+
// 其他渠道:如果链接上trafficEntrence非空,则为特定渠道,具体来源可在运营平台查询(推荐)
|
|
34
|
+
const FROM_KEY_MAP = {
|
|
35
|
+
tuhuviolation: 1500,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 获取用户打开小程序时的流量入口来源和场景值,小程序onLaunch和onShow时的参数相同
|
|
40
|
+
* @private
|
|
41
|
+
* @param {object} appShowOptions 小程序onShow时参数
|
|
42
|
+
* @returns {object} { scene, trafficEntrence } scene: 场景值,trafficEntrence: 用户渠道标识
|
|
43
|
+
*/
|
|
44
|
+
const getOpenAppTrafficData = (appShowOptions) => {
|
|
45
|
+
const spiderScene = -9999; // 如果是微信爬虫打开的小程序,则使用-9999给用户打标签
|
|
46
|
+
|
|
47
|
+
let options = appShowOptions;
|
|
48
|
+
// 未传递参数的情况下,获取小程序启动时参数作为打开小程序时的参数
|
|
49
|
+
if (!options) {
|
|
50
|
+
options = getLaunchOptionsSync() || {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { query = {}, scene = 1001 } = options;
|
|
54
|
+
// 途虎渠道通过from字段来判断,如果from为tuhuviolation,则为途虎渠道
|
|
55
|
+
const { from = '' } = query;
|
|
56
|
+
const isTuhu = !!FROM_KEY_MAP[from];
|
|
57
|
+
let trafficEntrence = 0;
|
|
58
|
+
if (DO_NOT_NEED_REPORT_SCENES.includes(scene)) {
|
|
59
|
+
trafficEntrence = spiderScene;
|
|
60
|
+
} else {
|
|
61
|
+
// 途虎渠道特殊判断
|
|
62
|
+
trafficEntrence = isTuhu ? FROM_KEY_MAP[from] : (Number(query.trafficEntrence || '') || 0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
scene,
|
|
67
|
+
trafficEntrence,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default getOpenAppTrafficData;
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/* eslint no-underscore-dangle: 0 */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @copyright 2021-present, Tencent, Inc. All rights reserved.
|
|
5
|
+
* @brief runtime.js is used to initialize a tms based app.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import Login from './login';
|
|
9
|
+
import Car from './car';
|
|
10
|
+
import getOpenAppTrafficData from './getopenapptrafficdata';
|
|
11
|
+
|
|
12
|
+
const { loginFn, getOpenId, getMycarPubOpenId, getSinanPubOpenId, getPhone } = Login;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* __resolver__ 用于维护 app.tms.fn 中数据的填充
|
|
16
|
+
* app.tms.fn 中的部分数据依赖初始化流程完成,属于异步获取,
|
|
17
|
+
* __resolver__ 属于内部变量,不应在运行时初始化流程外部使用,不做导出。
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
const __resolver__ = {};
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* tms.getLoginInfo 用于提供给业务模块获取当前运行时的登录信息
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
const loginInfoPromise = new Promise(resolver => __resolver__.getLoginInfo = resolver);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
* @description 获取用户userId等登录信息
|
|
32
|
+
* @returns {Promise<UserInfo>} 返回用户登录信息
|
|
33
|
+
* @returns {UserInfo.userId} 用户userId
|
|
34
|
+
* @returns {UserInfo.token} 用户token
|
|
35
|
+
* @returns {UserInfo.openId} 用户openId
|
|
36
|
+
* @returns {UserInfo.firstLogin} 用户登录类型:0-非首次登录,1-首次登录
|
|
37
|
+
* @example
|
|
38
|
+
* getApp().tms.getLoginInfo().then((res) => {
|
|
39
|
+
* // res {Object} 返回数据
|
|
40
|
+
* // {
|
|
41
|
+
* // userId {String} 用户userId
|
|
42
|
+
* // token {String} 用户token
|
|
43
|
+
* // openId {String} 用户openId
|
|
44
|
+
* // firstLogin {Boolean} 是否首次登录
|
|
45
|
+
* // }
|
|
46
|
+
* });
|
|
47
|
+
*/
|
|
48
|
+
const getLoginInfo = () => loginInfoPromise;
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* tms.getCarManager 用户获取小程序统一维护的车信息管理器
|
|
53
|
+
* @private
|
|
54
|
+
* @returns {object} 车信息管理器
|
|
55
|
+
*/
|
|
56
|
+
const getCarManager = () => Car;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* login方法用于完成小程序登录
|
|
60
|
+
* @private
|
|
61
|
+
* @returns {object} 登录成功后的用户信息
|
|
62
|
+
* 返回数据示意
|
|
63
|
+
* {
|
|
64
|
+
* userId: "1135608",
|
|
65
|
+
* token: "a209e79c667d8711ec7564c1bf86f327",
|
|
66
|
+
* firstLogin: 0,
|
|
67
|
+
* },
|
|
68
|
+
*/
|
|
69
|
+
const login = async () => {
|
|
70
|
+
const res = await loginFn();
|
|
71
|
+
const loginInfo = { ...res, userId: res.uid };
|
|
72
|
+
__resolver__.getLoginInfo(loginInfo);
|
|
73
|
+
return loginInfo;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 获取微信支付分授权
|
|
78
|
+
* @param { param.traceSource ? } 请求来源: 1-订单 2-支付网关 3-车机网关 4-开放平台 6-分账
|
|
79
|
+
* @param { param.subMchId ? } 商户id
|
|
80
|
+
* @param { param.bussClassify ? } 请求来源: 1-洗车 2-停车 12-代驾 24-租车 13-保养 3-加油
|
|
81
|
+
* @param { param.payChannel ? } 请求来源: 1-小程序 2-车机 3-小场景 4-开放平台 5-H5
|
|
82
|
+
* @param { param.wechaId ? } 公众号id,支付分授权相关一般都用我的车的车公众号
|
|
83
|
+
* @param { param.subAppId ? } 小程序的id,支付分授权相关一般都用我的车小程序id
|
|
84
|
+
* @param { param.openId ? } 用户在我的车公众号下面的id
|
|
85
|
+
* @returns { object } { state: 1, errMsg: 200, errMsg: '', errData: '' }
|
|
86
|
+
*/
|
|
87
|
+
async function setPaypointAuth(param = {}) {
|
|
88
|
+
const request = getRequestInstnce();
|
|
89
|
+
const userInfo = await getLoginInfo();
|
|
90
|
+
|
|
91
|
+
const req = {
|
|
92
|
+
traceSource: param.traceSource || 1, // 请求类型
|
|
93
|
+
subMchId: param.subMchId || '1602483333', // 子商户号
|
|
94
|
+
bussClassify: param.bussClassify || 24, // 业务类型
|
|
95
|
+
payChannel: param.payChannel || 1, // 请求来源
|
|
96
|
+
subAppId: param.appId || 'wx735359beafd78b9f', // 默认使用我的车的小程序号发布号发布
|
|
97
|
+
appId: param.wechaId || 'wx29d15d946a7f2351', // 默认使用我的车的公众号id
|
|
98
|
+
...userInfo,
|
|
99
|
+
openId: userInfo.mycarPubOpenId,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const res = await request.post('paypoint/setpayauth', req);
|
|
103
|
+
|
|
104
|
+
if (res.errCode === 0) {
|
|
105
|
+
try {
|
|
106
|
+
await wx.navigateToMiniProgram({
|
|
107
|
+
appId: 'wxd8f3793ea3b935b8',
|
|
108
|
+
path: 'pages/use/enable',
|
|
109
|
+
extraData: {
|
|
110
|
+
apply_permissions_token: res.resData.token,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
return { status: 0, err };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return { status: 1, ...res };
|
|
118
|
+
}
|
|
119
|
+
return { status: 0, ...res };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 获取项目中初始化的request实例
|
|
123
|
+
function getRequestInstnce() {
|
|
124
|
+
const { tms } = getApp();
|
|
125
|
+
const request = tms.createRequest();
|
|
126
|
+
|
|
127
|
+
return request;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* 获取微信支付分授权
|
|
133
|
+
* @param { param.traceSource ? } 请求来源: 1-订单 2-支付网关 3-车机网关 4-开放平台 6-分账
|
|
134
|
+
* @param { param.payChannel ? } 请求来源: 1-小程序 2-车机 3-小场景 4-开放平台 5-H5
|
|
135
|
+
* @returns { object } { errMsg: 200, errMsg: '', errData: '' }
|
|
136
|
+
*/
|
|
137
|
+
async function getPermissionList(param = {}) {
|
|
138
|
+
const request = getRequestInstnce();
|
|
139
|
+
this.userInfo = await getLoginInfo();
|
|
140
|
+
|
|
141
|
+
const data = {
|
|
142
|
+
traceSource: param.traceSource || 1, // 请求来源
|
|
143
|
+
payChannel: param.payChannel || 1, // 请求来源
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const res = await request.post('paypoint/getpermissionlist', data);
|
|
147
|
+
|
|
148
|
+
return res;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 获取微信支付分授权
|
|
153
|
+
* @param { param.traceSource ? } 请求来源: 1-订单 2-支付网关 3-车机网关 4-开放平台 6-分账
|
|
154
|
+
* @param { param.subMchId ? } 商户id
|
|
155
|
+
* @param { param.bussClassify ? } 请求来源: 1-洗车 2-停车 12-代驾 24-租车 13-保养 3-加油
|
|
156
|
+
* @param { param.payChannel ? } 请求来源: 1-小程序 2-车机 3-小场景 4-开放平台 5-H5
|
|
157
|
+
* @param { param.wechaId ? } 公众号id,支付分授权相关一般都用我的车的车公众号
|
|
158
|
+
* @param { param.subAppId ? } 小程序的id,支付分授权相关一般都用我的车小程序id
|
|
159
|
+
* @param { param.openId ? } 用户在我的车公众号下面的id
|
|
160
|
+
* @returns { object } { state: 1, errMsg: 200, errMsg: '', errData: '' }
|
|
161
|
+
*/
|
|
162
|
+
async function terminatePaypointPermisson(param = {}) {
|
|
163
|
+
const request = getRequestInstnce();
|
|
164
|
+
const userInfo = await getLoginInfo();
|
|
165
|
+
|
|
166
|
+
const data = {
|
|
167
|
+
traceSource: param.traceSource || 1, // 请求来源
|
|
168
|
+
subMchId: param.subMchId || '1602483333', // 子商户号
|
|
169
|
+
bussClassify: param.bussClassify || 24, // 业务类型
|
|
170
|
+
payChannel: param.payChannel || 1, // 请求来源
|
|
171
|
+
subAppId: param.appId || 'wx735359beafd78b9f',
|
|
172
|
+
appId: param.wechaId || 'wx29d15d946a7f2351',
|
|
173
|
+
reason: param.reason || '其他',
|
|
174
|
+
serviceId: param.serviceId,
|
|
175
|
+
...userInfo,
|
|
176
|
+
openId: userInfo.mycarPubOpenId,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const res = await request.post('paypoint/terminatePaypointPermisson', data);
|
|
180
|
+
|
|
181
|
+
return res;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* 获取用户在某个业务中是否授权
|
|
186
|
+
* @param { param.traceSource ? } 请求来源: 1-订单 2-支付网关 3-车机网关 4-开放平台 6-分账
|
|
187
|
+
* @param { param.bussClassify ? } 请求来源: 1-洗车 2-停车 12-代驾 24-租车 13-保养 3-加油
|
|
188
|
+
* @param { param.payChannel ? } 请求来源: 1-小程序 2-车机 3-小场景 4-开放平台 5-H5
|
|
189
|
+
* @returns { object } { state: 1, errMsg: 200, errMsg: '', errData: '' }
|
|
190
|
+
*/
|
|
191
|
+
async function queryServicePermissions(param = {}) {
|
|
192
|
+
const request = getRequestInstnce();
|
|
193
|
+
this.userInfo = await getLoginInfo();
|
|
194
|
+
|
|
195
|
+
const data = {
|
|
196
|
+
traceSource: param.traceSource || 1, // 请求来源
|
|
197
|
+
payChannel: param.payChannel || 1, // 请求来源
|
|
198
|
+
bussClassify: param.payChannel || 24, // 业务类型
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const res = await request.post('paypoint/queryServicePermissions', data);
|
|
202
|
+
|
|
203
|
+
return res;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const api = {
|
|
207
|
+
getPhone,
|
|
208
|
+
login,
|
|
209
|
+
getLoginInfo,
|
|
210
|
+
getOpenId,
|
|
211
|
+
getMycarPubOpenId,
|
|
212
|
+
getSinanPubOpenId,
|
|
213
|
+
getCarManager,
|
|
214
|
+
setPaypointAuth,
|
|
215
|
+
getPermissionList,
|
|
216
|
+
terminatePaypointPermisson,
|
|
217
|
+
getOpenAppTrafficData,
|
|
218
|
+
queryServicePermissions,
|
|
219
|
+
/**
|
|
220
|
+
* 对外暴露__resolver__变量,在主项目未完成迁移时,登录完成后,将登录态同步给runtime
|
|
221
|
+
* 注意这并不是架构升级的最终态,在完成主项目的迁移后,我们将不在对外暴露__resolver__
|
|
222
|
+
* @private
|
|
223
|
+
*/
|
|
224
|
+
__resolver__,
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
export default api;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/* eslint-disable valid-jsdoc */
|
|
2
|
+
/**
|
|
3
|
+
* @copyright 2021-present, Tencent, Inc. All rights reserved.
|
|
4
|
+
* @brief login.js 用于维护 runtime 框架的用户登录流程,获取用户的登录的可信凭证.
|
|
5
|
+
* runtime初始化时,会调用登录流程,基于runtime的后续业务代码,不必关注用户的登录状态,
|
|
6
|
+
* 当前,登录流程仅支持【腾讯出行服务小程序】,我们计划支持出行服务公众号的H5开发,基于runtime的
|
|
7
|
+
* 微信H5开发,不必关注微信的授权登录流程(即重定向微信页面,换取token等),H5的登录流程也收敛到
|
|
8
|
+
* login.js中。
|
|
9
|
+
* 另外,runtime 对【我的车小程序】的支持,以及后续对其他基于出行服务架构的小程序支持,都在我们规划之内。
|
|
10
|
+
*
|
|
11
|
+
*
|
|
12
|
+
* getOpenAppTrafficData, 此方法用于获取登录用户来源,用于给用户打标签等,打标签耦合在登录接口中,
|
|
13
|
+
* 因此这部分代码迁移到了 tms-rumtine 中,
|
|
14
|
+
* 从 runtime 的角度考虑,登录流程应尽量纯粹,打标签应属于业务流程范畴,与 runtime 无关。
|
|
15
|
+
* 后续我们拓展 runtime,使之适用于不同小程序和H5项目时,其登录流程不一定有打标签这一动作。
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import getOpenAppTrafficData from './getopenapptrafficdata';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 调用wx.login获取登录code
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
const getCode = () => new Promise((resolve, reject) => {
|
|
26
|
+
wx.login({ success: ({ code }) => resolve(code), fail: reject });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
let loginProcessing = false; // 是否有进行中的登录流程
|
|
30
|
+
/**
|
|
31
|
+
* login 方法 获取用户信息
|
|
32
|
+
* @private
|
|
33
|
+
* @return {object} userInfo
|
|
34
|
+
*/
|
|
35
|
+
const loginFn = async () => {
|
|
36
|
+
if (loginProcessing) return;
|
|
37
|
+
loginProcessing = true;
|
|
38
|
+
|
|
39
|
+
let userInfo = {};
|
|
40
|
+
try {
|
|
41
|
+
let userData = await login();
|
|
42
|
+
|
|
43
|
+
if (userData.errCode === 10 || !userData.resData.userInfo || !userData.resData.userInfo.uid) {
|
|
44
|
+
userData = await login();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (userData.errCode === 0) {
|
|
48
|
+
wx.setStorageSync('userInfo', userData.resData.userInfo);
|
|
49
|
+
userInfo = userData.resData.userInfo;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
loginProcessing = false;
|
|
53
|
+
} catch (e) {
|
|
54
|
+
loginProcessing = false;
|
|
55
|
+
}
|
|
56
|
+
return userInfo;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 登录重试接口
|
|
61
|
+
* @private
|
|
62
|
+
* @returns { object } errCode 接口返回错误码
|
|
63
|
+
* @returns { object } resData 用户信息
|
|
64
|
+
*/
|
|
65
|
+
async function login() {
|
|
66
|
+
let userData = {};
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const code = await getCode();
|
|
70
|
+
|
|
71
|
+
const { trafficEntrence: registerSource, scene: sceneId } = getOpenAppTrafficData();
|
|
72
|
+
|
|
73
|
+
userData = await getApp().tms.createRequest({ withAuth: false }).post('user/login', { code, registerSource, sceneId });
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.error(e); // eslint-disable-line
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
errCode: userData.errCode,
|
|
80
|
+
resData: userData.resData || {},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let getOpenIdProm; // 获取用户在小程序中的openId状态
|
|
85
|
+
/**
|
|
86
|
+
* @return {string} openId
|
|
87
|
+
* 获取成功时,返回resolved Promise,resolved数据为openId
|
|
88
|
+
* 获取失败时,返回rejected Promise,rejected数据为错误对象
|
|
89
|
+
* @description 获取用户在小程序中的openId
|
|
90
|
+
*/
|
|
91
|
+
const getOpenId = async () => {
|
|
92
|
+
if (getOpenIdProm) { // 避免重复获取
|
|
93
|
+
return getOpenIdProm;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getOpenIdProm = new Promise(async (resolve, reject) => {
|
|
97
|
+
getApp().tms.callCloudFunc('user', { $url: 'user/getOpenId' })
|
|
98
|
+
.then((res) => {
|
|
99
|
+
const openId = res?.result?.resData?.openId;
|
|
100
|
+
if (openId) {
|
|
101
|
+
resolve(openId);
|
|
102
|
+
}
|
|
103
|
+
getOpenIdProm = null;
|
|
104
|
+
reject(new Error('No openId found in cloud function res'));
|
|
105
|
+
})
|
|
106
|
+
.catch((res) => {
|
|
107
|
+
getOpenIdProm = null;
|
|
108
|
+
reject(res);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return getOpenIdProm;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 获取用户在指定公众号下的openId
|
|
117
|
+
* @private
|
|
118
|
+
* @return {Promise<String>}
|
|
119
|
+
* 获取成功时,返回resolved Promise,resolved数据为用户在指定公众号下的openId
|
|
120
|
+
* 获取失败时,返回rejected Promise,rejected数据为错误对象
|
|
121
|
+
*/
|
|
122
|
+
const getOaPubOpenId = oaName => getApp().tms.createRequest({ withAuth: true }).post('user/getpubopenid', { oaName })
|
|
123
|
+
.then((res) => {
|
|
124
|
+
const { errCode, resData } = res;
|
|
125
|
+
if (errCode !== 0) {
|
|
126
|
+
return Promise.reject(res);
|
|
127
|
+
}
|
|
128
|
+
const { mycarPubOpenId, sinanPubOpenId } = resData;
|
|
129
|
+
if (oaName === 'sinan') {
|
|
130
|
+
return sinanPubOpenId
|
|
131
|
+
|| Promise.reject(new Error(`No sinanPubOpenId found in response ${JSON.stringify(res)}`));
|
|
132
|
+
}
|
|
133
|
+
return mycarPubOpenId || Promise.reject(new Error(`No mycarPubOpenId found in response ${JSON.stringify(res)}`));
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
let getSinanPubOpenIdProm;
|
|
137
|
+
let getMycarPubOpenIdProm;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @description 获取用户在我的车公众号下的openId
|
|
141
|
+
* @return {Promise<String>}
|
|
142
|
+
* 获取成功时,返回resolved Promise,resolved数据为用户在我的车公众号下的openId
|
|
143
|
+
* 获取失败时,返回rejected Promise,rejected数据为错误对象
|
|
144
|
+
*/
|
|
145
|
+
const getMycarPubOpenId = () => {
|
|
146
|
+
if (getMycarPubOpenIdProm) { // 避免重复获取
|
|
147
|
+
return getMycarPubOpenIdProm;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getMycarPubOpenIdProm = getOaPubOpenId('mycar')
|
|
151
|
+
.then(openId => openId || Promise.reject(new Error('No mycarPubOpenId found')))
|
|
152
|
+
.catch((e) => {
|
|
153
|
+
getMycarPubOpenIdProm = null;
|
|
154
|
+
return Promise.reject(e);
|
|
155
|
+
});
|
|
156
|
+
return getMycarPubOpenIdProm;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @description 获取用户在出行服务公众号下的openId
|
|
161
|
+
* @return {Promise<String>}
|
|
162
|
+
* 获取成功时,返回resolved Promise,resolved数据为用户在出行服务公众号下的openId
|
|
163
|
+
* 获取失败时,返回rejected Promise,rejected数据为错误对象
|
|
164
|
+
*/
|
|
165
|
+
const getSinanPubOpenId = () => {
|
|
166
|
+
if (getSinanPubOpenIdProm) { // 避免重复获取
|
|
167
|
+
return getSinanPubOpenIdProm;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
getSinanPubOpenIdProm = getOaPubOpenId('sinan')
|
|
171
|
+
.then(openId => openId || Promise.reject(new Error('No sinanPubOpenId found')))
|
|
172
|
+
.catch((e) => {
|
|
173
|
+
getSinanPubOpenIdProm = null;
|
|
174
|
+
return Promise.reject(e);
|
|
175
|
+
});
|
|
176
|
+
return getSinanPubOpenIdProm;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @public
|
|
181
|
+
* @description 获取用户手机号
|
|
182
|
+
* @return {Promise<String|Object>} 手机号
|
|
183
|
+
* @example
|
|
184
|
+
* getApp().tms.getPhone()
|
|
185
|
+
* .then((phone) => {
|
|
186
|
+
* // ...
|
|
187
|
+
* })
|
|
188
|
+
* .catch((e) => {
|
|
189
|
+
* // ...
|
|
190
|
+
* });
|
|
191
|
+
*/
|
|
192
|
+
const getPhone = () => getApp().tms.createRequest({ withAuth: true }).post('user/phone/fetch')
|
|
193
|
+
.then((res) => {
|
|
194
|
+
if (res && res.errCode === 0) {
|
|
195
|
+
return (res.resData && res.resData.phoneno) || '';
|
|
196
|
+
}
|
|
197
|
+
return Promise.reject(res);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const runtimeObj = {
|
|
201
|
+
loginFn,
|
|
202
|
+
getOpenId,
|
|
203
|
+
getPhone,
|
|
204
|
+
getMycarPubOpenId,
|
|
205
|
+
getSinanPubOpenId,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export default runtimeObj;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @author: fenggangsun
|
|
4
4
|
* @date: 2022-06-27 11:46:25
|
|
5
5
|
* @lastEditors: fenggangsun
|
|
6
|
-
* @lastEditTime: 2022-
|
|
6
|
+
* @lastEditTime: 2022-07-27 02:35:10
|
|
7
7
|
* @copyright 2022-present, Tencent, Inc. All rights reserved.
|
|
8
8
|
*/
|
|
9
9
|
const defaultLoc = {
|
|
@@ -52,8 +52,7 @@ const getPrioritizedLocation = async (typeOrders, option) => {
|
|
|
52
52
|
.then((data) => {
|
|
53
53
|
const { ad_info: { adcode, cityCode, province, city }, location: { lng, lat } } = data;
|
|
54
54
|
return {
|
|
55
|
-
adCode: adcode, cityCode,
|
|
56
|
-
province, cityName: city, longitude: lng, latitude: lat,
|
|
55
|
+
adCode: adcode, province, cityCode, cityName: city, longitude: lng, latitude: lat,
|
|
57
56
|
...data,
|
|
58
57
|
};
|
|
59
58
|
});
|
|
@@ -70,11 +69,24 @@ const getPrioritizedLocation = async (typeOrders, option) => {
|
|
|
70
69
|
default: break;
|
|
71
70
|
}
|
|
72
71
|
const loc = await Promise.resolve(getLocProm).catch(() => null);
|
|
73
|
-
if (loc) return {
|
|
72
|
+
if (loc) return {
|
|
73
|
+
locType,
|
|
74
|
+
loc: {
|
|
75
|
+
...loc,
|
|
76
|
+
provinceCode: parseProvinceCode(loc),
|
|
77
|
+
},
|
|
78
|
+
};
|
|
74
79
|
}
|
|
75
80
|
return Promise.reject('按照参数指定的类型未能获取到位置');
|
|
76
81
|
};
|
|
77
82
|
|
|
83
|
+
const parseProvinceCode = (loc) => {
|
|
84
|
+
if (!loc) return '';
|
|
85
|
+
const { provinceCode, cityCode } = loc;
|
|
86
|
+
if (provinceCode) return provinceCode;
|
|
87
|
+
return cityCode ? cityCode.slice(0, 2).padEnd(6, 0) : '';
|
|
88
|
+
};
|
|
89
|
+
|
|
78
90
|
/**
|
|
79
91
|
* 按优先级获取用户位置
|
|
80
92
|
* @param {Boolean} visitedIndex 是否打开过首页
|