ipanel-rnapp-ajb-base 1.0.36 → 1.0.38
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/app/api/ipanelCloudApi.js +55 -62
- package/app/components/common/Cell/index.js +2 -2
- package/app/components/common/Dialog/index.js +9 -8
- package/app/components/common/Dialog/styles.js +7 -6
- package/app/hooks/useDynamicPackages.js +21 -11
- package/app/hooks/useMessageManager.js +50 -3
- package/app/screens/BaseScreen.js +26 -6
- package/app/screens/LoginScreen/indexNew.js +10 -8
- package/app/screens/SbkScreen.js +12 -0
- package/app/screens/SimpleBaseScreen.js +4 -2
- package/app/utils/common.js +10 -9
- package/app/utils/config.js +18 -7
- package/app/utils/http.js +20 -15
- package/package.json +3 -3
|
@@ -5,9 +5,9 @@ import { homedHttp } from "../utils/http";
|
|
|
5
5
|
|
|
6
6
|
const appName = NativeModules?.RNToNativeEmitter?.appName;
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
`${config.IPANEL_CLOUD_BASE_URI}/s/invoice`;
|
|
8
|
+
const INVOICE_SERVICE = ["吉柿果"].includes(appName)
|
|
9
|
+
? "https://icloud.homed.jishimedia.com:50443/s/invoice"
|
|
10
|
+
: `${config.IPANEL_CLOUD_BASE_URI}/s/invoice`;
|
|
11
11
|
const IOT_SERVICE = `${config.IPANEL_CLOUD_BASE_URI}/s/iot`;
|
|
12
12
|
const IR_433_DISCOVER_SERVICE = `${config.IPANEL_CLOUD_BASE_URI}/s/ir433discover`;
|
|
13
13
|
const JINPENG_URL = `${config.IPANEL_CLOUD_BASE_URI}/s/smart_home/jinpeng`;
|
|
@@ -18,7 +18,6 @@ export const ADG_SERVICE = `${config.IPANEL_CLOUD_BASE_ADG_URI}/s/install_ea`;
|
|
|
18
18
|
|
|
19
19
|
export const APARTMENT_SERVICE = `${config.IPANEL_CLOUD_BASE_URI}/s/smart_home_manage/admin-api`;
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
// todo 云端获取token服务:https://ai.baidu.com/ai-doc/SPEECH/Mk38lxpgn
|
|
23
22
|
export const baiduAsr = (cuid, len, speechBase64) => {
|
|
24
23
|
return request({
|
|
@@ -39,14 +38,7 @@ export const baiduAsr = (cuid, len, speechBase64) => {
|
|
|
39
38
|
};
|
|
40
39
|
|
|
41
40
|
export const getAreaOperatorModules = async (params) => {
|
|
42
|
-
let url
|
|
43
|
-
if (["禺乐慧家", "悦慧家"].includes(appName)) {
|
|
44
|
-
url = `${config.PANYU_MODULE_VERSION_URI}/jshomeapp/api/getAreaOperatorModules`
|
|
45
|
-
} else if ('吉柿果' === appName) {
|
|
46
|
-
url = `${config.JILIN_MODULE_VERSION_URI}/jshomeapp/api/getAreaOperatorModules`
|
|
47
|
-
} else {
|
|
48
|
-
url = `${config.IPANEL_CLOUD_BASE_URI}/jshomeapp/api/getAreaOperatorModules`
|
|
49
|
-
}
|
|
41
|
+
let url = `${config.MODULE_VERSION_URI}/jshomeapp/api/getAreaOperatorModules`;
|
|
50
42
|
|
|
51
43
|
// todo 本地调试测试临时处理,本地调试时模块列表暂时对接的是dev集群
|
|
52
44
|
if (!NativeModules?.RNToNativeEmitter?.serverCluster) {
|
|
@@ -69,19 +61,12 @@ export const getAreaOperatorModules = async (params) => {
|
|
|
69
61
|
: "",
|
|
70
62
|
...params,
|
|
71
63
|
},
|
|
72
|
-
timeout: 10 * 1000
|
|
64
|
+
timeout: 10 * 1000,
|
|
73
65
|
});
|
|
74
66
|
};
|
|
75
67
|
|
|
76
68
|
export const getModuleVersionInfo = async (params) => {
|
|
77
|
-
let url
|
|
78
|
-
if (["禺乐慧家", "悦慧家"].includes(appName)) {
|
|
79
|
-
url = `${config.PANYU_MODULE_VERSION_URI}/jshomeapp/api/moduleVersionInfo`
|
|
80
|
-
} else if ('吉柿果' === appName) {
|
|
81
|
-
url = `${config.JILIN_MODULE_VERSION_URI}/jshomeapp/api/moduleVersionInfo`
|
|
82
|
-
} else {
|
|
83
|
-
url = `${config.IPANEL_CLOUD_BASE_URI}/jshomeapp/api/moduleVersionInfo`
|
|
84
|
-
}
|
|
69
|
+
let url = `${config.MODULE_VERSION_URI}/jshomeapp/api/moduleVersionInfo`;
|
|
85
70
|
|
|
86
71
|
// todo 本地调试测试临时处理,本地调试时模块列表暂时对接的是dev集群
|
|
87
72
|
if (!NativeModules?.RNToNativeEmitter?.serverCluster) {
|
|
@@ -125,6 +110,8 @@ export const obtainSmscode = (data, type) => {
|
|
|
125
110
|
};
|
|
126
111
|
if (["吉柿果"].includes(appName)) {
|
|
127
112
|
params.operator_id = "061aa081306a455da811639160763190";
|
|
113
|
+
} else if (["智慧中原"].includes(appName)) {
|
|
114
|
+
params.operator_id = "1478a670efb7085b0b29e7367c5c4f87";
|
|
128
115
|
}
|
|
129
116
|
return request({
|
|
130
117
|
url: type === "adg" ? ADG_SERVICE : ACCOUNT_SERVICE,
|
|
@@ -141,6 +128,8 @@ export const smscodeLogin = (data, type) => {
|
|
|
141
128
|
};
|
|
142
129
|
if (["吉柿果"].includes(appName)) {
|
|
143
130
|
params.operator_id = "061aa081306a455da811639160763190";
|
|
131
|
+
} else if (["智慧中原"].includes(appName)) {
|
|
132
|
+
params.operator_id = "1478a670efb7085b0b29e7367c5c4f87";
|
|
144
133
|
}
|
|
145
134
|
return request({
|
|
146
135
|
url: type === "adg" ? ADG_SERVICE : ACCOUNT_SERVICE,
|
|
@@ -157,6 +146,8 @@ export const accountLogin = (data, type) => {
|
|
|
157
146
|
};
|
|
158
147
|
if (["吉柿果"].includes(appName)) {
|
|
159
148
|
params.operator_id = "061aa081306a455da811639160763190";
|
|
149
|
+
} else if (["智慧中原"].includes(appName)) {
|
|
150
|
+
params.operator_id = "1478a670efb7085b0b29e7367c5c4f87";
|
|
160
151
|
}
|
|
161
152
|
return request({
|
|
162
153
|
url: type === "adg" ? ADG_SERVICE : ACCOUNT_SERVICE,
|
|
@@ -267,7 +258,7 @@ export const delAddress = (data) => {
|
|
|
267
258
|
};
|
|
268
259
|
|
|
269
260
|
export const addRoom = async (data) => {
|
|
270
|
-
const apartmentData = await storage.get(
|
|
261
|
+
const apartmentData = await storage.get("apartmentData");
|
|
271
262
|
return request({
|
|
272
263
|
url:
|
|
273
264
|
apartmentData && apartmentData?.userType
|
|
@@ -316,12 +307,13 @@ export const getAddressRooms = (data) => {
|
|
|
316
307
|
};
|
|
317
308
|
|
|
318
309
|
export const adjustRoom = async (data) => {
|
|
319
|
-
const apartmentData = await storage.get(
|
|
310
|
+
const apartmentData = await storage.get("apartmentData");
|
|
320
311
|
return request({
|
|
321
|
-
url:
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
312
|
+
url:
|
|
313
|
+
apartmentData && apartmentData?.userType
|
|
314
|
+
? `${APARTMENT_SERVICE}/houseRoom/edit`
|
|
315
|
+
: IOT_SERVICE,
|
|
316
|
+
method: apartmentData && apartmentData?.userType ? "PUT" : "POST",
|
|
325
317
|
data: {
|
|
326
318
|
action: "adjust_room",
|
|
327
319
|
...data,
|
|
@@ -330,11 +322,12 @@ export const adjustRoom = async (data) => {
|
|
|
330
322
|
};
|
|
331
323
|
|
|
332
324
|
export const delRoom = async (data) => {
|
|
333
|
-
const apartmentData = await storage.get(
|
|
325
|
+
const apartmentData = await storage.get("apartmentData");
|
|
334
326
|
return request({
|
|
335
|
-
url:
|
|
336
|
-
|
|
337
|
-
|
|
327
|
+
url:
|
|
328
|
+
apartmentData && apartmentData?.userType
|
|
329
|
+
? `${APARTMENT_SERVICE}/houseRoom/del`
|
|
330
|
+
: IOT_SERVICE,
|
|
338
331
|
method: "POST",
|
|
339
332
|
data: {
|
|
340
333
|
action: "del_room",
|
|
@@ -426,18 +419,18 @@ export const adjustDevice = async (data) => {
|
|
|
426
419
|
// ...data,
|
|
427
420
|
// },
|
|
428
421
|
// });
|
|
429
|
-
const apartmentData = await storage.get(
|
|
430
|
-
let url =
|
|
422
|
+
const apartmentData = await storage.get("apartmentData");
|
|
423
|
+
let url = "";
|
|
431
424
|
let params = {
|
|
432
|
-
path:
|
|
425
|
+
path: "device/adjust_device",
|
|
433
426
|
...data,
|
|
434
427
|
};
|
|
435
|
-
let method =
|
|
428
|
+
let method = "POST";
|
|
436
429
|
// 公寓的设备
|
|
437
430
|
if (apartmentData && apartmentData?.userType) {
|
|
438
431
|
url = `${APARTMENT_SERVICE}/houseFamilyDevice/edit`;
|
|
439
432
|
params.instanceName = await global.base.getHomeCloudServiceInstanceName();
|
|
440
|
-
method =
|
|
433
|
+
method = "PUT";
|
|
441
434
|
} else {
|
|
442
435
|
url = await getCurrentAddrRoomkeeperServiceBaseUri();
|
|
443
436
|
}
|
|
@@ -449,10 +442,10 @@ export const adjustDevice = async (data) => {
|
|
|
449
442
|
};
|
|
450
443
|
|
|
451
444
|
export const addDevice = async (data) => {
|
|
452
|
-
const apartmentData = await storage.get(
|
|
453
|
-
let url =
|
|
445
|
+
const apartmentData = await storage.get("apartmentData");
|
|
446
|
+
let url = "";
|
|
454
447
|
let params = {
|
|
455
|
-
path:
|
|
448
|
+
path: "device/add_device",
|
|
456
449
|
...data,
|
|
457
450
|
};
|
|
458
451
|
// 公寓的设备添加调志豪的接口
|
|
@@ -464,25 +457,25 @@ export const addDevice = async (data) => {
|
|
|
464
457
|
}
|
|
465
458
|
return request({
|
|
466
459
|
url: url,
|
|
467
|
-
method:
|
|
460
|
+
method: "POST",
|
|
468
461
|
data: params,
|
|
469
462
|
});
|
|
470
463
|
};
|
|
471
464
|
|
|
472
465
|
export const moveDevice = async (data) => {
|
|
473
|
-
const apartmentData = await storage.get(
|
|
474
|
-
let url =
|
|
466
|
+
const apartmentData = await storage.get("apartmentData");
|
|
467
|
+
let url = "";
|
|
475
468
|
let params = {
|
|
476
|
-
path:
|
|
469
|
+
path: "device/move_device",
|
|
477
470
|
...data,
|
|
478
471
|
};
|
|
479
|
-
let method =
|
|
472
|
+
let method = "POST";
|
|
480
473
|
// const ROOMKEEPER_SERVICE = await getCurrentAddrRoomkeeperServiceBaseUri();
|
|
481
474
|
// 公寓的设备添加调志豪的接口
|
|
482
475
|
if (apartmentData && apartmentData?.userType) {
|
|
483
476
|
url = `${APARTMENT_SERVICE}/houseFamilyDevice/move`;
|
|
484
477
|
params.instanceName = await global.base.getHomeCloudServiceInstanceName();
|
|
485
|
-
method =
|
|
478
|
+
method = "PUT";
|
|
486
479
|
} else {
|
|
487
480
|
url = await getCurrentAddrRoomkeeperServiceBaseUri();
|
|
488
481
|
}
|
|
@@ -502,8 +495,8 @@ export const getsn = (data) => {
|
|
|
502
495
|
};
|
|
503
496
|
|
|
504
497
|
export const delDevice = async (data) => {
|
|
505
|
-
const apartmentData = await storage.get(
|
|
506
|
-
let url =
|
|
498
|
+
const apartmentData = await storage.get("apartmentData");
|
|
499
|
+
let url = "";
|
|
507
500
|
let params = {};
|
|
508
501
|
// 公寓的设备添加调志豪的接口
|
|
509
502
|
if (apartmentData && apartmentData?.userType) {
|
|
@@ -514,13 +507,13 @@ export const delDevice = async (data) => {
|
|
|
514
507
|
} else {
|
|
515
508
|
url = await getCurrentAddrRoomkeeperServiceBaseUri();
|
|
516
509
|
params = {
|
|
517
|
-
path:
|
|
510
|
+
path: "device/delete_device",
|
|
518
511
|
...data,
|
|
519
512
|
};
|
|
520
513
|
}
|
|
521
514
|
return request({
|
|
522
515
|
url: url,
|
|
523
|
-
method:
|
|
516
|
+
method: "POST",
|
|
524
517
|
data: params,
|
|
525
518
|
});
|
|
526
519
|
};
|
|
@@ -885,14 +878,14 @@ export const switchToken = async (params) => {
|
|
|
885
878
|
export const getHouseType = async () => {
|
|
886
879
|
return request({
|
|
887
880
|
url: `${APARTMENT_SERVICE}/house/account/getType`,
|
|
888
|
-
method:
|
|
881
|
+
method: "GET",
|
|
889
882
|
});
|
|
890
883
|
};
|
|
891
884
|
// 通过用户类型登录
|
|
892
885
|
export const loginByType = async (id, params) => {
|
|
893
886
|
return request({
|
|
894
887
|
url: `${APARTMENT_SERVICE}/house/account/loginByType?userType=${id}`,
|
|
895
|
-
method:
|
|
888
|
+
method: "POST",
|
|
896
889
|
data: params,
|
|
897
890
|
});
|
|
898
891
|
};
|
|
@@ -976,14 +969,14 @@ export const checkCaptcha = (data) => {
|
|
|
976
969
|
};
|
|
977
970
|
|
|
978
971
|
//查询绑定情况
|
|
979
|
-
export const getJinpengBindList = async (params)=>{
|
|
980
|
-
return request({
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
}
|
|
972
|
+
export const getJinpengBindList = async (params) => {
|
|
973
|
+
return request({
|
|
974
|
+
url: `${JINPENG_URL}/get_bind_list`,
|
|
975
|
+
method: "POST",
|
|
976
|
+
data: {
|
|
977
|
+
page: 1,
|
|
978
|
+
page_size: 100,
|
|
979
|
+
...params,
|
|
980
|
+
},
|
|
981
|
+
});
|
|
982
|
+
};
|
|
@@ -80,7 +80,7 @@ const Index = ({
|
|
|
80
80
|
multiline={multiline}
|
|
81
81
|
style={[styles.valueInput, inputStyle]}
|
|
82
82
|
placeholder={placeholder}
|
|
83
|
-
|
|
83
|
+
placeholderTextColor="#999"
|
|
84
84
|
onChangeText={onChangeText}
|
|
85
85
|
editable={editable}
|
|
86
86
|
keyboardType={keyboardType}
|
|
@@ -218,7 +218,7 @@ const Index = ({
|
|
|
218
218
|
multiline={false}
|
|
219
219
|
style={styles.valueInput}
|
|
220
220
|
placeholder={placeholder}
|
|
221
|
-
|
|
221
|
+
placeholderTextColor="#999"
|
|
222
222
|
onChangeText={onChangeText}
|
|
223
223
|
returnKeyType="done"
|
|
224
224
|
onSubmitEditing={({nativeEvent}) => {
|
|
@@ -60,12 +60,13 @@ const Index = ({steps, active, onRef}) => {
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
modalVisible && (
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
<Modal
|
|
64
|
+
animationType="fade"
|
|
65
|
+
transparent={true}
|
|
66
|
+
statusBarTranslucent={modelRef.current?.statusBarTranslucent}
|
|
67
|
+
visible={modalVisible}
|
|
68
|
+
onRequestClose={() => {}}>
|
|
69
|
+
<View style={styles.backgroundView}>
|
|
69
70
|
<TouchableOpacity
|
|
70
71
|
style={styles.centeredView}
|
|
71
72
|
activeOpacity={1}
|
|
@@ -102,8 +103,8 @@ const Index = ({steps, active, onRef}) => {
|
|
|
102
103
|
/>
|
|
103
104
|
)}
|
|
104
105
|
</TouchableOpacity>
|
|
105
|
-
</
|
|
106
|
-
</
|
|
106
|
+
</View>
|
|
107
|
+
</Modal>
|
|
107
108
|
)
|
|
108
109
|
);
|
|
109
110
|
};
|
|
@@ -5,12 +5,13 @@ const { fontStyle } = global.base.styles;
|
|
|
5
5
|
|
|
6
6
|
const styles = StyleSheet.create({
|
|
7
7
|
backgroundView: {
|
|
8
|
-
position: 'absolute',
|
|
9
|
-
top: 0,
|
|
10
|
-
bottom: 0,
|
|
11
|
-
// opacity: 0.5,
|
|
12
|
-
left: 0,
|
|
13
|
-
right: 0,
|
|
8
|
+
// position: 'absolute',
|
|
9
|
+
// top: 0,
|
|
10
|
+
// bottom: 0,
|
|
11
|
+
// // opacity: 0.5,
|
|
12
|
+
// left: 0,
|
|
13
|
+
// right: 0,
|
|
14
|
+
flex:1,
|
|
14
15
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
15
16
|
},
|
|
16
17
|
centeredView: {
|
|
@@ -1,22 +1,32 @@
|
|
|
1
|
-
import React, {useState,
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
const useDynamicPackages = () => {
|
|
4
4
|
const [DynamicStackScreens, setDynamicScreens] = useState({});
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
const addDynamicScreens = screens => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const addDynamicScreens = (screens) => {
|
|
8
|
+
// 使用函数式更新,可以确保我们总是基于最新的状态进行更新
|
|
9
|
+
setDynamicScreens((currentScreens) => {
|
|
10
|
+
const allScreens = {
|
|
11
|
+
...currentScreens,
|
|
12
|
+
...screens,
|
|
13
|
+
};
|
|
14
|
+
return allScreens;
|
|
11
15
|
});
|
|
12
16
|
};
|
|
13
|
-
global.base.eventBus.removeAllListeners('addDynamicScreens');
|
|
14
|
-
global.base.eventBus.addListener('addDynamicScreens', addDynamicScreens);
|
|
15
|
-
}, [DynamicStackScreens]);
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
global.base.eventBus.addListener("addDynamicScreens", addDynamicScreens);
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
// useEffect 的清理函数:在组件卸载时移除监听,防止内存泄漏
|
|
21
|
+
return () => {
|
|
22
|
+
global.base.eventBus.removeListener(
|
|
23
|
+
"addDynamicScreens",
|
|
24
|
+
addDynamicScreens
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
}, []); // 空依赖数组意味着这个 effect 只在组件挂载时运行一次
|
|
28
|
+
|
|
29
|
+
return { DynamicStackScreens };
|
|
20
30
|
};
|
|
21
31
|
|
|
22
32
|
export default useDynamicPackages;
|
|
@@ -40,6 +40,9 @@ let manualCustomServiceTimer;
|
|
|
40
40
|
|
|
41
41
|
// TODO 定期轮询检查消息过期
|
|
42
42
|
|
|
43
|
+
// 智能客服聊天AI模型: CUSTOMER_SERVICE=客服智能体
|
|
44
|
+
let aiModel = "CUSTOMER_SERVICE";
|
|
45
|
+
|
|
43
46
|
const UseMessageManager = () => {
|
|
44
47
|
const ws = useRef(null);
|
|
45
48
|
|
|
@@ -68,6 +71,11 @@ const UseMessageManager = () => {
|
|
|
68
71
|
"lat=",
|
|
69
72
|
];
|
|
70
73
|
|
|
74
|
+
// 设置智能客服AI大模型
|
|
75
|
+
if (aiModel) {
|
|
76
|
+
connectParams.push(`model=${aiModel}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
// 缓存全局智能客服websocket连接
|
|
72
80
|
global.base.messageManager.wsRef = ws;
|
|
73
81
|
global.base.messageManager.connectMsgServer = connectMsgServer;
|
|
@@ -79,13 +87,33 @@ const UseMessageManager = () => {
|
|
|
79
87
|
ws.current.onopen = () => {
|
|
80
88
|
console.log("useMessageManager ws open");
|
|
81
89
|
connectStatus = 0;
|
|
90
|
+
tryConnectTimes = 0;
|
|
82
91
|
eventBus.emit(EVENTS.MESSAGE.CONNECT_STATUS_CHANGE, connectStatus);
|
|
83
92
|
|
|
84
93
|
connectSuccessCallback && connectSuccessCallback();
|
|
85
94
|
};
|
|
86
95
|
ws.current.onmessage = ({ data }) => {
|
|
87
|
-
|
|
88
|
-
|
|
96
|
+
try {
|
|
97
|
+
const msg = JSON.parse(data);
|
|
98
|
+
if (msg.MsgType === "chat" && msg.Chat.type === "tool_call_begin") {
|
|
99
|
+
const toolCallId = msg.Chat.payload.tool_calls[0].id;
|
|
100
|
+
if (
|
|
101
|
+
global.base.messageManager.messages.find(
|
|
102
|
+
(msg) =>
|
|
103
|
+
msg.MsgType === "chat" &&
|
|
104
|
+
msg.Chat.type === "end" &&
|
|
105
|
+
msg.Chat.payload.message.tool_calls &&
|
|
106
|
+
msg.Chat.payload.message.tool_calls[0].id === toolCallId
|
|
107
|
+
)
|
|
108
|
+
) {
|
|
109
|
+
// 如果前面已经有AI返回相同id的 tool_calls 了(正常来说都会有),则忽略当前 tool_call_begin 消息,避免业务处理两次"开始调用工具"消息
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
eventBus.emit(EVENTS.MESSAGE.ADD, msg);
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.log("msg不合法", e);
|
|
116
|
+
}
|
|
89
117
|
};
|
|
90
118
|
ws.current.onerror = (err) => {
|
|
91
119
|
console.log("useMessageManager ws onerror", err);
|
|
@@ -200,7 +228,15 @@ const UseMessageManager = () => {
|
|
|
200
228
|
useEffect(() => {
|
|
201
229
|
// 新增并显示一条消息
|
|
202
230
|
const onMessageAdd = (msg) => {
|
|
203
|
-
|
|
231
|
+
// 如果msg.MsgId已存在,则直接更新,而不是push
|
|
232
|
+
const oldMsgIndex = global.base.messageManager.messages.findIndex(
|
|
233
|
+
(m) => m.MsgId === msg.MsgId
|
|
234
|
+
);
|
|
235
|
+
if (oldMsgIndex === -1) {
|
|
236
|
+
global.base.messageManager.messages.push(msg);
|
|
237
|
+
} else {
|
|
238
|
+
global.base.messageManager.messages.splice(oldMsgIndex, 1, msg);
|
|
239
|
+
}
|
|
204
240
|
// save to local
|
|
205
241
|
storage.set(
|
|
206
242
|
"messageList",
|
|
@@ -334,6 +370,15 @@ const UseMessageManager = () => {
|
|
|
334
370
|
|
|
335
371
|
const getManualCustomServiceActiveFlag = () => isManualCustomServiceActive;
|
|
336
372
|
|
|
373
|
+
const getAiModel = () => aiModel;
|
|
374
|
+
const setAiModel = (model) => {
|
|
375
|
+
aiModel = model;
|
|
376
|
+
|
|
377
|
+
// 触发重新连接
|
|
378
|
+
global.base.messageManager.wsRef.current &&
|
|
379
|
+
global.base.messageManager.wsRef.current.close();
|
|
380
|
+
};
|
|
381
|
+
|
|
337
382
|
return {
|
|
338
383
|
sendMessage,
|
|
339
384
|
handleTextSubmit,
|
|
@@ -341,6 +386,8 @@ const UseMessageManager = () => {
|
|
|
341
386
|
requestManualCustomService,
|
|
342
387
|
exitManualCustomService,
|
|
343
388
|
getManualCustomServiceActiveFlag,
|
|
389
|
+
getAiModel,
|
|
390
|
+
setAiModel,
|
|
344
391
|
};
|
|
345
392
|
};
|
|
346
393
|
|
|
@@ -110,11 +110,17 @@ async function getNavigationPackages() {
|
|
|
110
110
|
console.log("网络加载底部导航模块成功!");
|
|
111
111
|
const packagesPre = res.data || [];
|
|
112
112
|
if (appName.includes("悦慧家")) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
try {
|
|
114
|
+
const params = { phone_number: accountData.user.phone };
|
|
115
|
+
const res = await getJinpengBindList(params);
|
|
116
|
+
if (res?.resultCode === 0 && res?.response_obj?.list.length > 0) {
|
|
117
|
+
packages = packagesPre;
|
|
118
|
+
} else {
|
|
119
|
+
packages = packagesPre.filter((item) => {
|
|
120
|
+
return item.moduleName !== "jinpeng";
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {
|
|
118
124
|
packages = packagesPre.filter((item) => {
|
|
119
125
|
return item.moduleName !== "jinpeng";
|
|
120
126
|
});
|
|
@@ -219,7 +225,17 @@ const HomeTabScreen = forwardRef(function ({ navigation, route }, ref) {
|
|
|
219
225
|
global.toast.showToast("加载失败");
|
|
220
226
|
console.log("加载失败");
|
|
221
227
|
} else {
|
|
222
|
-
|
|
228
|
+
// 如果家居模块有默认选中,则将默认选中传给公寓模块
|
|
229
|
+
const defaultActive = packages[index]?.defaultActive || 0;
|
|
230
|
+
let apartmentApackage = result.data.packages;
|
|
231
|
+
if (
|
|
232
|
+
apartmentApackage &&
|
|
233
|
+
apartmentApackage.length &&
|
|
234
|
+
apartmentApackage[0]?.defaultActive === undefined
|
|
235
|
+
) {
|
|
236
|
+
apartmentApackage[0].defaultActive = defaultActive;
|
|
237
|
+
}
|
|
238
|
+
console.log(apartmentApackage, "apartmentApackage");
|
|
223
239
|
packages.splice(index, 1, ...apartmentApackage);
|
|
224
240
|
}
|
|
225
241
|
}
|
|
@@ -552,6 +568,8 @@ const HomeTabScreen = forwardRef(function ({ navigation, route }, ref) {
|
|
|
552
568
|
requestManualCustomService,
|
|
553
569
|
exitManualCustomService,
|
|
554
570
|
getManualCustomServiceActiveFlag,
|
|
571
|
+
getAiModel,
|
|
572
|
+
setAiModel,
|
|
555
573
|
} = UseMessageManager();
|
|
556
574
|
global.base.messageManager.handleTextSubmit = handleTextSubmit;
|
|
557
575
|
global.base.messageManager.handleMediaSelect = handleMediaSelect;
|
|
@@ -560,6 +578,8 @@ const HomeTabScreen = forwardRef(function ({ navigation, route }, ref) {
|
|
|
560
578
|
global.base.messageManager.exitManualCustomService = exitManualCustomService;
|
|
561
579
|
global.base.messageManager.getManualCustomServiceActiveFlag =
|
|
562
580
|
getManualCustomServiceActiveFlag;
|
|
581
|
+
global.base.messageManager.getAiModel = getAiModel;
|
|
582
|
+
global.base.messageManager.setAiModel = setAiModel;
|
|
563
583
|
|
|
564
584
|
// 商城客服
|
|
565
585
|
const {
|
|
@@ -582,11 +582,11 @@ function LoginScreen({ navigation, route }) {
|
|
|
582
582
|
console.log(defaultAddr.address_id, "defaultAddr.address_id");
|
|
583
583
|
await storage.set("activeAddr", defaultAddr);
|
|
584
584
|
await storage.set("addressList", addressList);
|
|
585
|
-
await updateHomedToken();
|
|
586
585
|
} else {
|
|
587
586
|
await storage.set("activeAddr", {});
|
|
588
587
|
await storage.set("addressList", []);
|
|
589
588
|
}
|
|
589
|
+
await updateHomedToken();
|
|
590
590
|
}
|
|
591
591
|
delete res.result.address;
|
|
592
592
|
await storage.set("accountData", res.result);
|
|
@@ -832,7 +832,9 @@ function LoginScreen({ navigation, route }) {
|
|
|
832
832
|
global.toast.showToast(message);
|
|
833
833
|
if (res.code === 10430) {
|
|
834
834
|
loginCaptchaToken.current = await checkGraphSmscode();
|
|
835
|
-
|
|
835
|
+
if(loginWay===0){//手机登录方式才需要重发送手机号
|
|
836
|
+
handleGetSmsId();
|
|
837
|
+
}
|
|
836
838
|
}
|
|
837
839
|
}
|
|
838
840
|
};
|
|
@@ -1103,15 +1105,15 @@ function LoginScreen({ navigation, route }) {
|
|
|
1103
1105
|
styles.passBox,
|
|
1104
1106
|
{
|
|
1105
1107
|
justifyContent:
|
|
1106
|
-
appName === "吉柿果" ||
|
|
1108
|
+
/* appName === "吉柿果" ||
|
|
1107
1109
|
currentOperatorName === "番禺有线" ||
|
|
1108
1110
|
appName === "悦慧家"
|
|
1109
|
-
?
|
|
1110
|
-
|
|
1111
|
+
? */"flex-end"
|
|
1112
|
+
/* : "space-between" */,
|
|
1111
1113
|
},
|
|
1112
1114
|
]}
|
|
1113
1115
|
>
|
|
1114
|
-
{appName !== "吉柿果" &&
|
|
1116
|
+
{/* {appName !== "吉柿果" &&
|
|
1115
1117
|
appName !== "悦慧家" &&
|
|
1116
1118
|
currentOperatorName !== "番禺有线" && (
|
|
1117
1119
|
<TouchableOpacity
|
|
@@ -1130,7 +1132,7 @@ function LoginScreen({ navigation, route }) {
|
|
|
1130
1132
|
注册
|
|
1131
1133
|
</Text>
|
|
1132
1134
|
</TouchableOpacity>
|
|
1133
|
-
)}
|
|
1135
|
+
)} */}
|
|
1134
1136
|
<TouchableOpacity
|
|
1135
1137
|
style={styles.forgotPassword}
|
|
1136
1138
|
onPress={() => {
|
|
@@ -1155,7 +1157,7 @@ function LoginScreen({ navigation, route }) {
|
|
|
1155
1157
|
</>
|
|
1156
1158
|
)}
|
|
1157
1159
|
|
|
1158
|
-
{smsCodeResendTime !== 0 && (
|
|
1160
|
+
{loginWay===0&&smsCodeResendTime !== 0 && (
|
|
1159
1161
|
<TouchableOpacity
|
|
1160
1162
|
style={{
|
|
1161
1163
|
alignSelf: "flex-end",
|
package/app/screens/SbkScreen.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
TouchableOpacity,
|
|
8
8
|
} from "react-native";
|
|
9
9
|
import { Icon, Button } from "@rneui/themed";
|
|
10
|
+
import { checkToken } from "../utils/common";
|
|
10
11
|
|
|
11
12
|
const { storage, replace } = global.base;
|
|
12
13
|
|
|
@@ -17,6 +18,17 @@ const SbkPage = ({ navigation }) => {
|
|
|
17
18
|
|
|
18
19
|
useEffect(() => {
|
|
19
20
|
initAddressList();
|
|
21
|
+
|
|
22
|
+
// 定时刷新登录状态
|
|
23
|
+
checkToken();
|
|
24
|
+
clearInterval(global.SBK_CHECK_TOKEN_INTERVAL);
|
|
25
|
+
global.SBK_CHECK_TOKEN_INTERVAL = setInterval(async () => {
|
|
26
|
+
const accessToken = await storage.get("accessToken");
|
|
27
|
+
if (accessToken) {
|
|
28
|
+
console.log("SBK_CHECK_TOKEN_INTERVAL checkToken");
|
|
29
|
+
checkToken();
|
|
30
|
+
}
|
|
31
|
+
}, 1000 * 60 * 60 * 24); // 每 24 小时刷新一次登录状态
|
|
20
32
|
}, []);
|
|
21
33
|
|
|
22
34
|
const initAddressList = async () => {
|
|
@@ -53,15 +53,17 @@ async function getNavigationPackages() {
|
|
|
53
53
|
const currentOperator = await storage.get(
|
|
54
54
|
`${accountData?.account?.account_id || ""}currentOperator`
|
|
55
55
|
);
|
|
56
|
-
let areaOperatorId =
|
|
57
|
-
currentOperator && currentOperator.id ? currentOperator.id : "common";
|
|
56
|
+
let areaOperatorId = "650ee8c59f534b189c8607f498564515";//A1-天威视讯
|
|
57
|
+
// currentOperator && currentOperator.id ? currentOperator.id : "common";
|
|
58
58
|
console.log("currentOperator", currentOperator);
|
|
59
|
+
let appcode = 'jiaobian';//APK固定配置一款APP带一个appcode不能重复
|
|
59
60
|
|
|
60
61
|
// 从网络加载最新导航模块
|
|
61
62
|
const res = await retryAsync(() => {
|
|
62
63
|
return getAreaOperatorModules({
|
|
63
64
|
platform: Platform.OS,
|
|
64
65
|
areaOperatorId,
|
|
66
|
+
appcode
|
|
65
67
|
})
|
|
66
68
|
}).catch((err) => {
|
|
67
69
|
console.log(err);
|
package/app/utils/common.js
CHANGED
|
@@ -26,13 +26,14 @@ async function updateHomedToken() {
|
|
|
26
26
|
const activeAddr = await storage.get("activeAddr");
|
|
27
27
|
const res = await getUserInfo();
|
|
28
28
|
console.log(res, "getUserInfo");
|
|
29
|
+
console.log(accountData?.user, "accountData?.user");
|
|
29
30
|
const userList = res.result?.user_list || [];
|
|
30
31
|
const currentUser = userList.find(
|
|
31
|
-
|
|
32
|
+
item => item.user_id === accountData?.user.user_id
|
|
32
33
|
);
|
|
33
34
|
const bindList = currentUser?.bind_list || [];
|
|
34
35
|
console.log(bindList, "bindList");
|
|
35
|
-
const homedConfig = bindList.find(
|
|
36
|
+
const homedConfig = bindList.find(item => item.third_type === "homed");
|
|
36
37
|
let domain = activeAddr?.domain || (await global.base.getHomedDomain());
|
|
37
38
|
// if (!["禺乐慧家", "悦慧家"].includes(appName)) {
|
|
38
39
|
// domain = 'homed.tv'
|
|
@@ -62,7 +63,7 @@ async function updateHomedToken() {
|
|
|
62
63
|
const homedLoginResult = await mobileRelationLogin(
|
|
63
64
|
mobileRelationLoginParams,
|
|
64
65
|
domain
|
|
65
|
-
).catch(
|
|
66
|
+
).catch(err => {});
|
|
66
67
|
if (homedLoginResult && homedLoginResult.ret === 0) {
|
|
67
68
|
homedToken = homedLoginResult.access_token;
|
|
68
69
|
await storage.set("homedLoginResult", homedLoginResult);
|
|
@@ -78,7 +79,7 @@ async function updateHomedToken() {
|
|
|
78
79
|
deviceType: 1,
|
|
79
80
|
},
|
|
80
81
|
domain
|
|
81
|
-
).catch(
|
|
82
|
+
).catch(err => {});
|
|
82
83
|
console.log(tokenRes, "tokenRes");
|
|
83
84
|
if (tokenRes && tokenRes.ret === 0) {
|
|
84
85
|
homedToken = tokenRes.access_token;
|
|
@@ -93,7 +94,7 @@ async function updateHomedToken() {
|
|
|
93
94
|
const list = userListRes.user_list || [];
|
|
94
95
|
await storage.set(
|
|
95
96
|
"homedHomeMembers",
|
|
96
|
-
list.filter(
|
|
97
|
+
list.filter(item => item.user_id !== userListRes.bind_user_id)
|
|
97
98
|
);
|
|
98
99
|
}
|
|
99
100
|
} else {
|
|
@@ -152,7 +153,7 @@ async function initOperatorHomedTouristAccount(opHomedConfig) {
|
|
|
152
153
|
accounttype: 1,
|
|
153
154
|
iconid: 1,
|
|
154
155
|
pwd: "1bbd886460827015e5d605ed44252251", // md5("11111111")
|
|
155
|
-
}).catch(
|
|
156
|
+
}).catch(e => {
|
|
156
157
|
console.log("Error: homed游客注册请求失败", e);
|
|
157
158
|
});
|
|
158
159
|
|
|
@@ -176,7 +177,7 @@ async function updateHomedTouristToken() {
|
|
|
176
177
|
devicetype: 3,
|
|
177
178
|
accounttype: 2,
|
|
178
179
|
pwd: "1bbd886460827015e5d605ed44252251", // md5("11111111")
|
|
179
|
-
}).catch(
|
|
180
|
+
}).catch(e => {
|
|
180
181
|
console.log("Error: homed游客登录请求失败", e);
|
|
181
182
|
});
|
|
182
183
|
|
|
@@ -392,7 +393,7 @@ async function appReport(tag, extraData = {}) {
|
|
|
392
393
|
...extraData,
|
|
393
394
|
};
|
|
394
395
|
|
|
395
|
-
const res = await reportBigData(tag, appID, data).catch(
|
|
396
|
+
const res = await reportBigData(tag, appID, data).catch(err => {
|
|
396
397
|
console.log("reportBigData", err);
|
|
397
398
|
});
|
|
398
399
|
console.log("reportBigData", tag, res);
|
|
@@ -423,7 +424,7 @@ const checkToken = async () => {
|
|
|
423
424
|
]);
|
|
424
425
|
};
|
|
425
426
|
|
|
426
|
-
return new Promise(async
|
|
427
|
+
return new Promise(async resolve => {
|
|
427
428
|
try {
|
|
428
429
|
const accountType = await storage.get("accountType");
|
|
429
430
|
const res = await refreshToken(
|
package/app/utils/config.js
CHANGED
|
@@ -30,19 +30,30 @@ if (["禺乐慧家", "悦慧家"].includes(appName)) {
|
|
|
30
30
|
}
|
|
31
31
|
// console.log(IPANEL_CLOUD_DOMAIN)
|
|
32
32
|
|
|
33
|
+
const IPANEL_CLOUD_BASE_URI = `https://${IPANEL_CLOUD_DOMAIN}:50443`;
|
|
34
|
+
|
|
35
|
+
const MODULE_VERSION_URI_MAP = {
|
|
36
|
+
悦慧家: "https://szjtyfw.panyu.gd.cn:50443",
|
|
37
|
+
吉柿果: "http://rnupgrade.homed.jishimedia.com:50080",
|
|
38
|
+
智慧中原: "https://sccloud.hnzhzy.com:50443",
|
|
39
|
+
};
|
|
40
|
+
|
|
33
41
|
const config = {
|
|
34
42
|
IPANEL_CLOUD_DOMAIN,
|
|
35
|
-
IPANEL_CLOUD_BASE_URI
|
|
43
|
+
IPANEL_CLOUD_BASE_URI,
|
|
36
44
|
IPANEL_CLOUD_WSS_URI: `wss://${IPANEL_CLOUD_DOMAIN}:50443`,
|
|
37
45
|
IPANEL_CLOUD_BASE_ADG_URI:
|
|
38
46
|
envVersion === "dev"
|
|
39
47
|
? `http://${IPANEL_CLOUD_DOMAIN}:50080`
|
|
40
|
-
:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
: IPANEL_CLOUD_BASE_URI,
|
|
49
|
+
|
|
50
|
+
// RN模块 API 路径
|
|
51
|
+
MODULE_VERSION_URI: MODULE_VERSION_URI_MAP[appName] || IPANEL_CLOUD_BASE_URI,
|
|
52
|
+
|
|
53
|
+
// 该配置项已废弃,请用 MODULE_VERSION_URI
|
|
54
|
+
PANYU_MODULE_VERSION_URI: MODULE_VERSION_URI_MAP["悦慧家"],
|
|
55
|
+
// 该配置项已废弃,请用 MODULE_VERSION_URI
|
|
56
|
+
JILIN_MODULE_VERSION_URI: MODULE_VERSION_URI_MAP["吉柿果"],
|
|
46
57
|
|
|
47
58
|
// 模拟配置本地测试用的app版本号,用于模拟执行一些依赖app版本的逻辑
|
|
48
59
|
LOCALTEST_APP_VERSION: "9.9.9",
|
package/app/utils/http.js
CHANGED
|
@@ -37,7 +37,7 @@ async function http(options) {
|
|
|
37
37
|
);
|
|
38
38
|
const apartmentToken = await storage.get("apartmentToken");
|
|
39
39
|
const apartmentData = await storage.get("apartmentData");
|
|
40
|
-
|
|
40
|
+
const accountData = await storage.get("accountData");
|
|
41
41
|
if (method === "post" || method === "put") {
|
|
42
42
|
if (options.data instanceof FormData || typeof options.data !== "object") {
|
|
43
43
|
config.body = options.data;
|
|
@@ -59,7 +59,8 @@ async function http(options) {
|
|
|
59
59
|
url.includes("/admin-api/house/account/login") ||
|
|
60
60
|
url.includes("/admin-api/house/account/loginByType")
|
|
61
61
|
) {
|
|
62
|
-
config.headers.homedToken =
|
|
62
|
+
config.headers.homedToken =
|
|
63
|
+
accountData?.account?.phone || accountData?.user?.phone || TOKEN;
|
|
63
64
|
}
|
|
64
65
|
} else if (method === "get" || method === "delete") {
|
|
65
66
|
let query = [];
|
|
@@ -67,7 +68,7 @@ async function http(options) {
|
|
|
67
68
|
if (TOKEN) {
|
|
68
69
|
data.access_token = TOKEN;
|
|
69
70
|
}
|
|
70
|
-
Object.keys(data).forEach(
|
|
71
|
+
Object.keys(data).forEach(key => {
|
|
71
72
|
query.push(`${key}=${data[key]}`);
|
|
72
73
|
});
|
|
73
74
|
if (query.length > 0) {
|
|
@@ -75,7 +76,8 @@ async function http(options) {
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
if (url.includes("/admin-api/house/account/getType")) {
|
|
78
|
-
config.headers.homedToken =
|
|
79
|
+
config.headers.homedToken =
|
|
80
|
+
accountData?.account?.phone || accountData?.user?.phone || TOKEN;
|
|
79
81
|
} else if (
|
|
80
82
|
url.includes("/smart_home_manage/admin-api") &&
|
|
81
83
|
!url.includes("/smart_home_manage/admin-api/house/account/loginByType") &&
|
|
@@ -86,14 +88,16 @@ async function http(options) {
|
|
|
86
88
|
config.headers.Authorization = `Bearer ${apartmentToken}`;
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
const reqid = Date.now() + "-" + Math.floor(Math.random() * 1000000);
|
|
92
|
+
|
|
93
|
+
console.log("req:", url, config, "reqid=", reqid);
|
|
90
94
|
|
|
91
95
|
return fetch(url, config)
|
|
92
|
-
.then(
|
|
93
|
-
console.log(response, "url");
|
|
96
|
+
.then(response => {
|
|
97
|
+
// console.log(response, "url");
|
|
94
98
|
return response.json();
|
|
95
99
|
})
|
|
96
|
-
.then(
|
|
100
|
+
.then(json => {
|
|
97
101
|
if (
|
|
98
102
|
typeof json.error_code !== "undefined" &&
|
|
99
103
|
typeof json.code === "undefined"
|
|
@@ -109,17 +113,18 @@ async function http(options) {
|
|
|
109
113
|
// );
|
|
110
114
|
}
|
|
111
115
|
}
|
|
116
|
+
console.log("res:", url, config, "reqid=", reqid, "json=", json);
|
|
112
117
|
|
|
113
118
|
return json;
|
|
114
119
|
})
|
|
115
|
-
.catch(
|
|
116
|
-
console.log(err);
|
|
120
|
+
.catch(err => {
|
|
121
|
+
console.log("req error:", url, config, "reqid=", reqid, "error=", err);
|
|
117
122
|
throw err;
|
|
118
123
|
// Alert.alert('服务繁忙,请稍候重试');
|
|
119
124
|
});
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
export const homedHttp = async
|
|
127
|
+
export const homedHttp = async options => {
|
|
123
128
|
let url = options.url;
|
|
124
129
|
const method = options.method.toLowerCase();
|
|
125
130
|
|
|
@@ -169,7 +174,7 @@ export const homedHttp = async (options) => {
|
|
|
169
174
|
if (TOKEN) {
|
|
170
175
|
data.accesstoken = TOKEN;
|
|
171
176
|
}
|
|
172
|
-
Object.keys(data).forEach(
|
|
177
|
+
Object.keys(data).forEach(key => {
|
|
173
178
|
query.push(`${key}=${data[key]}`);
|
|
174
179
|
});
|
|
175
180
|
if (query.length > 0) {
|
|
@@ -180,13 +185,13 @@ export const homedHttp = async (options) => {
|
|
|
180
185
|
console.log(url, config);
|
|
181
186
|
|
|
182
187
|
return fetch(url, config)
|
|
183
|
-
.then(
|
|
188
|
+
.then(response => {
|
|
184
189
|
return response.json();
|
|
185
190
|
})
|
|
186
|
-
.then(
|
|
191
|
+
.then(json => {
|
|
187
192
|
return json;
|
|
188
193
|
})
|
|
189
|
-
.catch(
|
|
194
|
+
.catch(err => {
|
|
190
195
|
console.log(err);
|
|
191
196
|
// Alert.alert('服务繁忙,请稍候重试');
|
|
192
197
|
return Promise.reject(err);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ipanel-rnapp-ajb-base",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"ipanelVersion": "1.0.
|
|
3
|
+
"version": "1.0.38",
|
|
4
|
+
"ipanelVersion": "1.0.515",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"keywords": [
|
|
@@ -13,4 +13,4 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"postinstall": "node bin/local-dev.js"
|
|
15
15
|
}
|
|
16
|
-
}
|
|
16
|
+
}
|