ipanel-rnapp-ajb-base 1.0.0

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.
Files changed (155) hide show
  1. package/app/.local_dev/DemoPage.js +46 -0
  2. package/app/.local_dev/env.js +1 -0
  3. package/app/.local_dev/polyfill.js +83 -0
  4. package/app/App.js +485 -0
  5. package/app/api/homedApi.js +42 -0
  6. package/app/api/index.js +2 -0
  7. package/app/api/ipanelCloudApi.js +796 -0
  8. package/app/assets/img/add.png +0 -0
  9. package/app/assets/img/add_img.png +0 -0
  10. package/app/assets/img/album.png +0 -0
  11. package/app/assets/img/album2.png +0 -0
  12. package/app/assets/img/album3.png +0 -0
  13. package/app/assets/img/album@2x.png +0 -0
  14. package/app/assets/img/album@3x.png +0 -0
  15. package/app/assets/img/audioRecordBar.png +0 -0
  16. package/app/assets/img/bootom_bar_bg.png +0 -0
  17. package/app/assets/img/close.png +0 -0
  18. package/app/assets/img/computer.png +0 -0
  19. package/app/assets/img/confirm.png +0 -0
  20. package/app/assets/img/delete_pic.png +0 -0
  21. package/app/assets/img/disabled.png +0 -0
  22. package/app/assets/img/goBack.png +0 -0
  23. package/app/assets/img/goBack2.png +0 -0
  24. package/app/assets/img/ischeck.png +0 -0
  25. package/app/assets/img/launch_bg.png +0 -0
  26. package/app/assets/img/launch_bg_panyu.png +0 -0
  27. package/app/assets/img/launch_logo.png +0 -0
  28. package/app/assets/img/launch_logo_panyu.png +0 -0
  29. package/app/assets/img/launch_text.png +0 -0
  30. package/app/assets/img/launch_text_panyu.png +0 -0
  31. package/app/assets/img/link.png +0 -0
  32. package/app/assets/img/login_bg.png +0 -0
  33. package/app/assets/img/login_bg_new.png +0 -0
  34. package/app/assets/img/login_left.png +0 -0
  35. package/app/assets/img/login_right.png +0 -0
  36. package/app/assets/img/nocheck.png +0 -0
  37. package/app/assets/img/personal.png +0 -0
  38. package/app/assets/img/photo.png +0 -0
  39. package/app/assets/img/photo@2x.png +0 -0
  40. package/app/assets/img/photo@3x.png +0 -0
  41. package/app/assets/img/protocol_checked.png +0 -0
  42. package/app/assets/img/qiehuan.png +0 -0
  43. package/app/assets/img/scan_border_bottom_left.png +0 -0
  44. package/app/assets/img/scan_border_bottom_right.png +0 -0
  45. package/app/assets/img/scan_border_top_left.png +0 -0
  46. package/app/assets/img/scan_border_top_right.png +0 -0
  47. package/app/assets/img/scan_move.png +0 -0
  48. package/app/assets/img/szjt.png +0 -0
  49. package/app/assets/img/tab.png +0 -0
  50. package/app/assets/img/tykz.png +0 -0
  51. package/app/assets/img/update_bg.png +0 -0
  52. package/app/assets/img/video.png +0 -0
  53. package/app/assets/img/video@2x.png +0 -0
  54. package/app/assets/img/video@3x.png +0 -0
  55. package/app/assets/img/worker.png +0 -0
  56. package/app/assets/img/wx.png +0 -0
  57. package/app/assets/img/ykq.png +0 -0
  58. package/app/assets/img/zfb.png +0 -0
  59. package/app/base.js +342 -0
  60. package/app/components/VersionUpdateConfirm.js +117 -0
  61. package/app/components/common/AccordionCell/index.js +67 -0
  62. package/app/components/common/ActionPicker/BasicPicker.js +136 -0
  63. package/app/components/common/ActionPicker/index.js +106 -0
  64. package/app/components/common/AddressPicker/index.js +211 -0
  65. package/app/components/common/Card/index.js +19 -0
  66. package/app/components/common/Cell/index.js +381 -0
  67. package/app/components/common/CustomDialog/index.js +120 -0
  68. package/app/components/common/CustomTabBar/index.js +157 -0
  69. package/app/components/common/CustomTabBar_bak/TabBarInput.js +210 -0
  70. package/app/components/common/CustomTabBar_bak/index.js +832 -0
  71. package/app/components/common/DateTimingPicker/index.js +254 -0
  72. package/app/components/common/Dialog/Notify.js +36 -0
  73. package/app/components/common/Dialog/baseDialog.js +146 -0
  74. package/app/components/common/Dialog/index.js +113 -0
  75. package/app/components/common/Dialog/prompt.js +145 -0
  76. package/app/components/common/Dialog/quickSelect.js +54 -0
  77. package/app/components/common/Dialog/select.js +125 -0
  78. package/app/components/common/Dialog/styles.js +167 -0
  79. package/app/components/common/Loading/index.js +71 -0
  80. package/app/components/common/LoginType/index.js +171 -0
  81. package/app/components/common/LoginType/protocol.js +160 -0
  82. package/app/components/common/Notify/index.js +68 -0
  83. package/app/components/common/OnceTouchable/index.js +33 -0
  84. package/app/components/common/PaymentPicker/index.js +264 -0
  85. package/app/components/common/ProductOrderPicker/index.js +524 -0
  86. package/app/components/common/ScreenBackHeader/index.js +144 -0
  87. package/app/components/common/ScrollPicker/index.js +232 -0
  88. package/app/components/common/SelectPicker/index.js +171 -0
  89. package/app/components/common/SmsCodeInput/index.js +93 -0
  90. package/app/components/common/SmsCodeInput/indexNew.js +101 -0
  91. package/app/components/common/Steps/index.js +126 -0
  92. package/app/components/common/Tag/index.js +17 -0
  93. package/app/components/common/Toast/index.js +103 -0
  94. package/app/components/common/WeekDaysPicker/index.js +196 -0
  95. package/app/components/index.js +8 -0
  96. package/app/components/iot/AddDeviceActionSheet/index.js +934 -0
  97. package/app/components/iot/AddressActionSheet/index.js +91 -0
  98. package/app/components/iot/RoomActionSheet/index.js +205 -0
  99. package/app/components/iot/ViewDeviceActionSheet/index.js +834 -0
  100. package/app/components/sheets.js +30 -0
  101. package/app/eventBus/index.js +54 -0
  102. package/app/hooks/checkLogin.js +30 -0
  103. package/app/hooks/shopMessageManager.js +308 -0
  104. package/app/hooks/useAddress.js +179 -0
  105. package/app/hooks/useAddress2.js +587 -0
  106. package/app/hooks/useDebounceFn.js +6 -0
  107. package/app/hooks/useDynamicPackages.js +22 -0
  108. package/app/hooks/useKeyboard.js +25 -0
  109. package/app/hooks/useLatest.js +10 -0
  110. package/app/hooks/useMessageManager.js +368 -0
  111. package/app/hooks/useNavigationFocus.js +19 -0
  112. package/app/hooks/useUser.js +56 -0
  113. package/app/screens/BaseScreen.js +389 -0
  114. package/app/screens/CommonScreens/BindPhoneScreen/index.js +179 -0
  115. package/app/screens/CommonScreens/BossScreen/index.js +138 -0
  116. package/app/screens/CommonScreens/DeviceAnswerDetailScreen/index.js +50 -0
  117. package/app/screens/CommonScreens/DeviceFeedbackScreen/index.js +365 -0
  118. package/app/screens/CommonScreens/EditInvoiceTitleScreen/index.js +279 -0
  119. package/app/screens/CommonScreens/FamilyDetailScreen/index.js +421 -0
  120. package/app/screens/CommonScreens/InvoiceTitleListScreen/index.js +118 -0
  121. package/app/screens/CommonScreens/OperatorSelectScreen/index.js +315 -0
  122. package/app/screens/CommonScreens/PersonalScreen/index.js +348 -0
  123. package/app/screens/CommonScreens/ScanQRCodeScreen/index.js +407 -0
  124. package/app/screens/CommonScreens/TvAlbumScreen/index.js +407 -0
  125. package/app/screens/LoginScreen/OpenLogSheet.js +241 -0
  126. package/app/screens/LoginScreen/index.js +920 -0
  127. package/app/screens/LoginScreen/indexNew.js +1354 -0
  128. package/app/screens/ResePassword/index.js +364 -0
  129. package/app/screens/SbkScreen.js +19 -0
  130. package/app/screens/WebviewScreen.js +41 -0
  131. package/app/storage/index.js +166 -0
  132. package/app/utils/EventEmitter.js +43 -0
  133. package/app/utils/RootNavigation.js +32 -0
  134. package/app/utils/SBK_plugin/convert.js +90 -0
  135. package/app/utils/SBK_plugin/convertStatus.js +250 -0
  136. package/app/utils/SBK_plugin/eventProcess.js +339 -0
  137. package/app/utils/SBK_plugin/index.js +32 -0
  138. package/app/utils/SBK_plugin/ipanelDeviceToSbkDevice.js +68 -0
  139. package/app/utils/SBK_plugin/sbk_defs.js +191 -0
  140. package/app/utils/StyleComposite.js +37 -0
  141. package/app/utils/applyPermissions.js +251 -0
  142. package/app/utils/bundleUpdater.js +46 -0
  143. package/app/utils/common.js +380 -0
  144. package/app/utils/config.js +47 -0
  145. package/app/utils/errCodes.js +3 -0
  146. package/app/utils/homedData.js +57 -0
  147. package/app/utils/http.js +178 -0
  148. package/app/utils/notice.js +15 -0
  149. package/app/utils/priceConversion.js +30 -0
  150. package/app/utils/registerDialog.js +90 -0
  151. package/app/utils/scaleSize.js +12 -0
  152. package/app/utils/soundPlayer.js +85 -0
  153. package/bin/local-dev.js +7 -0
  154. package/index.js +8 -0
  155. package/package.json +18 -0
@@ -0,0 +1,389 @@
1
+ import React, {useState, useEffect} from 'react';
2
+ import {
3
+ Alert,
4
+ View,
5
+ Text,
6
+ StyleSheet,
7
+ Platform,
8
+ ActivityIndicator,
9
+ NativeModules,
10
+ ImageBackground,
11
+ Image,
12
+ } from 'react-native';
13
+ import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
14
+
15
+ // 线上本地调试环境文件
16
+ import env from '../.local_dev/env';
17
+ import LocalDevPage from '../.local_dev/DemoPage';
18
+
19
+ import CustomTabBar from '../components/common/CustomTabBar';
20
+ import UseMessageManager from '../hooks/useMessageManager';
21
+ import ShopMessageManager from '../hooks/shopMessageManager';
22
+
23
+ import {getAreaOperatorModules, refreshToken} from '../api';
24
+ import {replace} from '../utils/RootNavigation';
25
+ import useAddress2 from '../hooks/useAddress2';
26
+ import {useSafeArea} from 'react-native-safe-area-context';
27
+
28
+ const {storage, px} = global.base;
29
+ const appName = NativeModules?.RNToNativeEmitter?.appName;
30
+
31
+ const Tab = createBottomTabNavigator();
32
+
33
+ async function getNavigationPackages() {
34
+ let packages = [];
35
+
36
+ // 根据currentOperator动态返回packages
37
+ const accountData = await storage.get('accountData');
38
+ const accountType = await storage.get('accountType');
39
+ const currentOperator = await storage.get(
40
+ `${accountData?.account?.account_id || ''}currentOperator`,
41
+ );
42
+ let areaOperatorId =
43
+ currentOperator && currentOperator.id ? currentOperator.id : 'common';
44
+ console.log('currentOperator', currentOperator);
45
+
46
+ if (appName?.includes('安电工') || accountType === 'adg') {
47
+ // 写死特殊区域运营商adg,加载安电工专属模块
48
+ areaOperatorId = 'adg';
49
+ }
50
+
51
+ // 从网络加载最新导航模块
52
+ const res = await getAreaOperatorModules({
53
+ platform: Platform.OS,
54
+ areaOperatorId,
55
+ }).catch(err => {
56
+ console.log(err);
57
+ });
58
+ if (!res || res.code !== 0) {
59
+ console.log('warn: 网络加载底部导航模块失败,取storage中存的上次的版本');
60
+ // 从网络加载失败则取storage中存的上次的版本
61
+ packages = await global.base.storage.get('base.navigationPackages');
62
+ } else {
63
+ console.log('网络加载底部导航模块成功!');
64
+ packages = res.data || [];
65
+ await storage.set(
66
+ 'areaOperatorModules',
67
+ packages.map(item => {
68
+ return {
69
+ moduleName: item.moduleName,
70
+ moduleChineseName: item.moduleChineseName,
71
+ version: item.version,
72
+ };
73
+ }),
74
+ );
75
+ packages.forEach(pack => {
76
+ switch (pack.moduleName) {
77
+ case 'tvShare':
78
+ pack.icon = 'tv-outline';
79
+ pack.activeIcon = 'tv';
80
+ break;
81
+ case 'smartHome':
82
+ pack.icon = 'ios-home-outline';
83
+ pack.activeIcon = 'ios-home';
84
+ break;
85
+ case 'shop':
86
+ pack.icon = 'card-outline';
87
+ pack.activeIcon = 'card';
88
+ break;
89
+ case 'panYuGovData':
90
+ pack.icon = 'newspaper-outline';
91
+ pack.activeIcon = 'newspaper';
92
+ break;
93
+ case 'myProfile':
94
+ pack.icon = 'person-outline';
95
+ pack.activeIcon = 'person';
96
+ break;
97
+ }
98
+ });
99
+ }
100
+
101
+ if (packages.length > 0) {
102
+ // global.base.navigationPackages = packages;
103
+ // console.log('成功从网络中读取最新底部导航模块');
104
+ // save to local
105
+ await global.base.storage.set('base.navigationPackages', packages);
106
+ } else {
107
+ // 兜底
108
+ console.log('warn: 网络和本地加载底部导航模块都异常,加载兜底模块...');
109
+ packages = global.base.initialNavigationPackages;
110
+ }
111
+
112
+ return packages;
113
+ }
114
+
115
+ function HomeTabScreen({navigation, route}) {
116
+ const [tabScreens, setTabScreens] = useState([]);
117
+ const [initialRouteName, setInitialRouteName] = useState('');
118
+ const {updateDataFromNetwork} = useAddress2();
119
+ const redirect = route.params?.redirect;
120
+
121
+ const init = async () => {
122
+ let tabs = [];
123
+
124
+ console.log('env:', env);
125
+
126
+ if (env !== '__LOCAL_DEV__') {
127
+ let packages = await getNavigationPackages();
128
+
129
+ const flag = await global.base
130
+ .loadPackages({
131
+ packages,
132
+ })
133
+ .catch(errors => {
134
+ console.log(JSON.stringify(errors));
135
+ });
136
+
137
+ if (!flag) {
138
+ // 加载包失败
139
+ Alert.alert('网络繁忙');
140
+ return;
141
+ }
142
+
143
+ const componentPromises = packages.map(pack => {
144
+ return global.base.getRemoteComponentByName(pack.moduleName);
145
+ });
146
+
147
+ const components = await Promise.all(componentPromises);
148
+ components.forEach(component => {
149
+ typeof component?.registerStackScreens === 'function' &&
150
+ component.registerStackScreens();
151
+ });
152
+
153
+ tabs = packages.map((pack, index) => {
154
+ return {
155
+ name: pack.moduleName,
156
+ component: components[index],
157
+ options: {
158
+ title: pack.moduleChineseName,
159
+ headerShown: false,
160
+ icon: pack.icon || 'menu-outline',
161
+ activeIcon: pack.activeIcon || 'menu',
162
+ iconUri: pack.moduleIcon,
163
+ activeIconUri: pack.moduleFocusIcon,
164
+ moduleAlias: pack.moduleAlias,
165
+ },
166
+ };
167
+ });
168
+ } else {
169
+ // 单业务包开发调试环境
170
+ const component = await global.base.getRemoteComponentByName('app');
171
+ typeof component?.registerStackScreens === 'function' &&
172
+ component.registerStackScreens();
173
+ tabs = [
174
+ {
175
+ name: 'asJumpPage',
176
+ component: LocalDevPage,
177
+ options: {
178
+ title: '作为独立页面',
179
+ headerShown: false,
180
+ },
181
+ },
182
+ {
183
+ name: 'asMenuPage',
184
+ component: component,
185
+ options: {
186
+ title: '作为导航页面',
187
+ headerShown: false,
188
+ },
189
+ },
190
+ ];
191
+ }
192
+
193
+ setInitialRouteName('');
194
+ setTabScreens([]);
195
+ setTimeout(() => {
196
+ // 智能家居tab index
197
+ global.base.smartHomeTabIndex = tabs.findIndex(
198
+ screen => screen.name === 'smartHome',
199
+ );
200
+ if (tabs.find(screen => screen.name === 'panYuGovData')) {
201
+ setInitialRouteName('panYuGovData');
202
+ } else if (tabs.find(screen => screen.name === 'apartment')) {
203
+ setInitialRouteName('apartment');
204
+ } else if (global.base.smartHomeTabIndex > -1) {
205
+ setInitialRouteName(tabs[global.base.smartHomeTabIndex].name);
206
+ } else {
207
+ setInitialRouteName(tabs[0].name);
208
+ }
209
+ setTabScreens(tabs);
210
+ }, 70);
211
+ };
212
+
213
+ global.base.reloadNavigation = init;
214
+
215
+ useEffect(() => {
216
+ console.log(redirect ? '重定向进来' : '登录进来');
217
+ (async () => {
218
+ if (redirect) {
219
+ await checkToken();
220
+ }
221
+
222
+ if (env === '__LOCAL_DEV__') {
223
+ // 单业务包开发调试环境
224
+ global.base.navigateModule({
225
+ operatorId: 'ipanel',
226
+ moduleName: 'app',
227
+ });
228
+ }
229
+
230
+ const accountType = await storage.get('accountType');
231
+ global.base.accountType = accountType;
232
+ if (accountType !== 'adg' && redirect) {
233
+ await updateDataFromNetwork({
234
+ refreshAddress: true,
235
+ }).catch(err => {});
236
+ }
237
+ init();
238
+ })();
239
+ }, []);
240
+
241
+ // 刷新token
242
+ const checkToken = async () => {
243
+ const access_token = await storage.get('accessToken');
244
+ const refresh_token = await storage.get('refreshToken');
245
+ const logout = () => {
246
+ Alert.alert('登录过期,请重新登录!', '', [
247
+ {
248
+ text: '好',
249
+ onPress: async () => {
250
+ await storage.set('accessToken', null);
251
+ await storage.set('refreshToken', null);
252
+ await storage.set('homedAccessToken', null);
253
+ replace('Login');
254
+ },
255
+ },
256
+ ]);
257
+ };
258
+ try {
259
+ const accountType = await storage.get('accountType');
260
+ const res = await refreshToken(
261
+ {
262
+ access_token,
263
+ refresh_token,
264
+ },
265
+ accountType,
266
+ );
267
+ if (res.code === 0) {
268
+ console.log('刷新token', res);
269
+ await storage.set('accessToken', res.result.access_token);
270
+ await storage.set('refreshToken', res.result.refresh_token);
271
+ } else {
272
+ logout();
273
+ }
274
+ } catch (e) {
275
+ // logout();
276
+ }
277
+ };
278
+
279
+ // smartHome专用
280
+ const {
281
+ handleTextSubmit,
282
+ handleMediaSelect,
283
+ requestManualCustomService,
284
+ exitManualCustomService,
285
+ getManualCustomServiceActiveFlag,
286
+ } = UseMessageManager();
287
+ global.base.messageManager.handleTextSubmit = handleTextSubmit;
288
+ global.base.messageManager.handleMediaSelect = handleMediaSelect;
289
+ global.base.messageManager.requestManualCustomService =
290
+ requestManualCustomService;
291
+ global.base.messageManager.exitManualCustomService = exitManualCustomService;
292
+ global.base.messageManager.getManualCustomServiceActiveFlag =
293
+ getManualCustomServiceActiveFlag;
294
+
295
+ // 商城客服
296
+ const {handleShopTextSubmit, handleShopMediaSelect, getOnlineUser} =
297
+ ShopMessageManager();
298
+ global.base.shopMessageManager.handleShopTextSubmit = handleShopTextSubmit;
299
+ global.base.shopMessageManager.handleShopMediaSelect = handleShopMediaSelect;
300
+ global.base.shopMessageManager.getOnlineUser = getOnlineUser;
301
+ const renderCustomTabBar = props => {
302
+ return <CustomTabBar {...props} />;
303
+ };
304
+ const insets = useSafeArea();
305
+ return (
306
+ <View style={{flex: 1}}>
307
+ {tabScreens.length > 0 ? (
308
+ <View
309
+ style={{
310
+ paddingBottom: insets.bottom,
311
+ backgroundColor: '#fff',
312
+ flex: 1,
313
+ }}>
314
+ <Tab.Navigator
315
+ initialRouteName={initialRouteName}
316
+ backBehavior="initialRoute"
317
+ tabBar={props => renderCustomTabBar(props)}
318
+ screenOptions={{
319
+ headerTitleAlign: 'center',
320
+ }}>
321
+ {tabScreens.map((item, index) => (
322
+ <Tab.Screen
323
+ name={item.name}
324
+ component={item.component}
325
+ key={index}
326
+ options={item.options}
327
+ />
328
+ ))}
329
+ </Tab.Navigator>
330
+ </View>
331
+ ) : (
332
+ <ImageBackground
333
+ style={styles.loadingView}
334
+ source={
335
+ appName === '禺乐慧家'
336
+ ? require('../assets/img/launch_bg_panyu.png')
337
+ : require('../assets/img/launch_bg.png')
338
+ }>
339
+ {/*<Text style={styles.loadingText}>*/}
340
+ {/* 欢迎使用{appName.includes('安电工') ? '安电工' : '爱家宝'}*/}
341
+ {/*</Text>*/}
342
+ {/*<ActivityIndicator size="large" />*/}
343
+ <Image
344
+ source={
345
+ appName === '禺乐慧家'
346
+ ? require('../assets/img/launch_logo_panyu.png')
347
+ : require('../assets/img/launch_logo.png')
348
+ }
349
+ style={{
350
+ width: px(231),
351
+ height: px(231),
352
+ marginBottom: px(80),
353
+ }}
354
+ resizeMode="contain"
355
+ />
356
+ <Image
357
+ source={
358
+ appName === '禺乐慧家'
359
+ ? require('../assets/img/launch_text_panyu.png')
360
+ : require('../assets/img/launch_text.png')
361
+ }
362
+ style={{
363
+ width: px(687),
364
+ height: px(60),
365
+ marginBottom: px(80),
366
+ }}
367
+ resizeMode="contain"
368
+ />
369
+ <ActivityIndicator size="large" />
370
+ </ImageBackground>
371
+ )}
372
+ </View>
373
+ );
374
+ }
375
+
376
+ const styles = StyleSheet.create({
377
+ loadingView: {
378
+ flex: 1,
379
+ alignItems: 'center',
380
+ justifyContent: 'center',
381
+ // backgroundColor: '#fff',
382
+ },
383
+ loadingText: {
384
+ fontSize: 20,
385
+ marginBottom: 10,
386
+ },
387
+ });
388
+
389
+ export default HomeTabScreen;
@@ -0,0 +1,179 @@
1
+ import React, {useState, useEffect, useRef} from 'react';
2
+ import {
3
+ ScrollView,
4
+ View,
5
+ Text,
6
+ StyleSheet,
7
+ NativeModules,
8
+ Alert,
9
+ Platform,
10
+ StatusBar,
11
+ } from 'react-native';
12
+ import {Button, Icon, Input} from '@rneui/themed';
13
+ import {useSafeArea} from 'react-native-safe-area-context';
14
+ import {obtainSmscode, authSmscode} from '../../../api';
15
+ import {showToast} from '../../../utils/notice';
16
+ import useLatest from '../../../hooks/useLatest';
17
+ import {merge} from 'lodash';
18
+
19
+ const {storage} = global.base;
20
+
21
+ function BindPhoneScreen({navigation}) {
22
+ const insets = useSafeArea();
23
+
24
+ const [phone, setPhone] = useState('');
25
+ const [sms, setSms] = useState('');
26
+ const [isSmsRequested, setIsSmsRequested] = useState(false);
27
+ const [smsId, setSmsId] = useState('');
28
+ const [sendSmsCodeDisabled, setSendSmsCodeDisabled] = useState(false);
29
+ const [second, setSecond] = useState(60);
30
+ const latestSecondRef = useLatest(second);
31
+
32
+ useEffect(() => {
33
+ storage.get('accountData').then(res => {
34
+ setPhone(res.user.phone);
35
+ });
36
+
37
+ return () => {
38
+ clearInterval(interval.current);
39
+ };
40
+ }, []);
41
+
42
+ const bind = async () => {
43
+ const res = await authSmscode({
44
+ sms_id: smsId,
45
+ sms_code: sms,
46
+ });
47
+ if (res.code === 0) {
48
+ showToast('绑定成功');
49
+ // todo update accountData res.user.phone
50
+ const accountData = await storage.get('accountData');
51
+ await storage.set(
52
+ 'accountData',
53
+ merge(accountData, {
54
+ user: {
55
+ phone: phone,
56
+ },
57
+ }),
58
+ );
59
+ navigation.goBack();
60
+ } else {
61
+ showToast('绑定失败');
62
+ }
63
+ };
64
+
65
+ const interval = useRef(null);
66
+
67
+ const handlerInterval = () => {
68
+ setSendSmsCodeDisabled(true);
69
+ interval.current = setInterval(() => {
70
+ if (latestSecondRef.current === 0) {
71
+ clearInterval(interval.current);
72
+ setSendSmsCodeDisabled(false);
73
+ return;
74
+ }
75
+ setSecond(latestSecondRef.current - 1);
76
+ }, 1000);
77
+ };
78
+
79
+ const requestSms = async () => {
80
+ try {
81
+ const res = await obtainSmscode({
82
+ phone_number: phone,
83
+ length: 4,
84
+ type: 2, // 该短信验证码为绑定手机号用途
85
+ });
86
+
87
+ if (res.code === 0) {
88
+ setSmsId(res.result.sms_id);
89
+ handlerInterval();
90
+
91
+ showToast('验证码已发送');
92
+ } else {
93
+ showToast('发送验证码失败');
94
+ }
95
+ } catch (e) {
96
+ showToast('发送验证码失败');
97
+ }
98
+ };
99
+
100
+ return (
101
+ <View
102
+ style={[
103
+ styles.container,
104
+ {
105
+ paddingTop: Platform.OS === 'ios' ? insets.top : 0,
106
+ },
107
+ ]}>
108
+ <View style={{height: StatusBar.currentHeight}} />
109
+ <View style={styles.row}>
110
+ <Text style={styles.label}>手机号</Text>
111
+ <Input
112
+ value={phone}
113
+ onChangeText={text => setPhone(text)}
114
+ maxLength={11}
115
+ containerStyle={styles.inputBox}
116
+ inputContainerStyle={styles.inputContainer}
117
+ inputStyle={{
118
+ color: '#333',
119
+ }}
120
+ />
121
+ <Button
122
+ title={sendSmsCodeDisabled ? `已发送 ${second}` : '发送验证码'}
123
+ disabled={sendSmsCodeDisabled}
124
+ onPress={requestSms}
125
+ size="sm"
126
+ />
127
+ </View>
128
+ <View style={styles.row}>
129
+ <Text style={styles.label}>短信验证码</Text>
130
+ <Input
131
+ value={sms}
132
+ onChangeText={text => setSms(text)}
133
+ maxLength={4}
134
+ containerStyle={styles.inputBox}
135
+ inputContainerStyle={styles.inputContainer}
136
+ inputStyle={{
137
+ color: '#333',
138
+ }}
139
+ />
140
+ </View>
141
+ <Button
142
+ onPress={bind}
143
+ title="绑定手机号"
144
+ disabled={phone.length !== 11 || sms.length !== 4 || !smsId}
145
+ />
146
+ </View>
147
+ );
148
+ }
149
+
150
+ const styles = StyleSheet.create({
151
+ container: {
152
+ flex: 1,
153
+ backgroundColor: '#fff',
154
+ paddingHorizontal: 10,
155
+ },
156
+ row: {
157
+ flexDirection: 'row',
158
+ alignItems: 'center',
159
+ paddingVertical: 10,
160
+ },
161
+ label: {
162
+ width: 80,
163
+ },
164
+ inputBox: {
165
+ height: 40,
166
+ padding: 0,
167
+ borderWidth: 0,
168
+ flex: 1,
169
+ },
170
+ inputContainer: {
171
+ height: '100%',
172
+ width: '100%',
173
+ padding: 0,
174
+ margin: 0,
175
+ borderBottomWidth: 0,
176
+ },
177
+ });
178
+
179
+ export default BindPhoneScreen;
@@ -0,0 +1,138 @@
1
+ import React, {useEffect, useState} from 'react';
2
+ import {View} from 'react-native';
3
+ import {WebView} from 'react-native-webview';
4
+ import {bindBossAccount, getUserInfo, getAssets} from '../../../api';
5
+ const {ScreenBackHeader} = global.base.commonComponents;
6
+ const {storage} = global.base;
7
+
8
+ export default ({navigation, route}) => {
9
+ const module = route?.params?.module;
10
+ const [uri, setUri] = useState('');
11
+ const [state, setState] = useState('');
12
+ useEffect(() => {
13
+ init();
14
+ global.loading.showLoading('加载中...');
15
+ }, []);
16
+ const init = async () => {
17
+ const accountData = await storage.get('accountData');
18
+ const binding = 1; // 1:绑定,0:解绑
19
+ const redirect_uri =
20
+ 'https://ipanelcloud2.ipanel.cn:50443/iapp/ajbstatic/bind_boss_account/'; // 绑定后跳转地址
21
+ const state2 = generateRandomString(8);
22
+ setState(state2);
23
+ setUri(
24
+ `https://boss.ipanel.cn/ipanelTask/api/cas_open/isport/Isport_cloud_mall_c/binding?agentid=119&oauth2_id=2a90c35712f488009a53bffe956195e5&redirect_uri=${redirect_uri}&open_id=${accountData.account_id}&binding=${binding}&scope=snsapi_base&response_type=code&state=${state2}`,
25
+ );
26
+ };
27
+
28
+ const onMessage = async e => {
29
+ const data = JSON.parse(e.nativeEvent.data);
30
+ console.log('onMessage', data);
31
+ if (data.ret === 0 && data.code && data.state === state) {
32
+ global.loading.showLoading('正在绑定...');
33
+ const res = await bindBossAccount({
34
+ code: data.code,
35
+ oauth2: '2a90c35712f488009a53bffe956195e5',
36
+ });
37
+ global.loading.hideLoading('正在绑定...');
38
+ if (res.code === 0) {
39
+ global.toast.showToast('绑定成功');
40
+ get_user_info();
41
+ // navigation.goBack();
42
+ } else {
43
+ navigation.goBack();
44
+ }
45
+ } else {
46
+ navigation.goBack();
47
+ }
48
+ };
49
+
50
+ const get_user_info = async () => {
51
+ const res = await getUserInfo();
52
+ if (
53
+ res?.code === 0 &&
54
+ res.result?.user_list &&
55
+ res.result?.user_list.length
56
+ ) {
57
+ // const accountData = await storage.get('accountData');
58
+ // accountData.user.bind_list = res.result?.user_list[0].bind_list;
59
+ // await storage.set('accountData', accountData);
60
+ // const bossData = accountData.user.bind_list
61
+ const bossData = res.result?.user_list[0].bind_list.filter(item => {
62
+ return item.third_type === 'boss';
63
+ });
64
+ console.log(bossData[0]);
65
+ if (bossData[0]) {
66
+ await storage.set('bossData', bossData[0]);
67
+ }
68
+ }
69
+ if (module === 'shop') {
70
+ get_assets();
71
+ } else {
72
+ navigation.goBack();
73
+ }
74
+ };
75
+
76
+ // 获取iSoprt积分
77
+ const get_assets = async () => {
78
+ // 获取iSport积分。如果我的模块需要显示积分则应该在登录之后去获取这接口
79
+ const appID = await global.base.getAppId();
80
+ const params = {
81
+ action: 'get_assets',
82
+ currency: 0, // 0是获取全部,20000是获取iSport积分
83
+ };
84
+ if (appID) {
85
+ params.appid = appID;
86
+ }
87
+ getAssets(params).then(res => {
88
+ if (res?.code === 0) {
89
+ if (
90
+ res?.result &&
91
+ res?.result?.asset_list &&
92
+ res?.result?.asset_list?.length
93
+ ) {
94
+ const current = res.result?.asset_list.filter(item => {
95
+ return item.currency === 20000;
96
+ });
97
+ if (current.length) {
98
+ storage.set('isportData', current[0]);
99
+ }
100
+ }
101
+ }
102
+ navigation.goBack();
103
+ });
104
+ };
105
+
106
+ const generateRandomString = length => {
107
+ const characters =
108
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // Add any additional special characters you want to include
109
+ let result = '';
110
+ for (let i = 0; i < length; i++) {
111
+ const randomIndex = Math.floor(Math.random() * characters.length);
112
+ result += characters.charAt(randomIndex);
113
+ }
114
+ return result;
115
+ };
116
+
117
+ return (
118
+ <View style={{flex: 1}}>
119
+ <ScreenBackHeader title="BOSS登录" />
120
+ <View style={{flex: 1}}>
121
+ <WebView
122
+ bounces={false}
123
+ domStorageEnabled={false}
124
+ javaScriptEnabled
125
+ useWebKit
126
+ source={{
127
+ uri: uri,
128
+ headers: {'Cache-Control': 'no-store'},
129
+ }}
130
+ incognito={true}
131
+ onMessage={onMessage}
132
+ onLoadEnd={() => global.loading.hideLoading()}
133
+ onError={() => global.loading.hideLoading()}
134
+ />
135
+ </View>
136
+ </View>
137
+ );
138
+ };