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,50 @@
1
+ import React, {useEffect, useState} from 'react';
2
+ import {View, StyleSheet, Text} from 'react-native';
3
+ import {getProductAnswers} from '../../../api';
4
+
5
+ const {ScreenBackHeader} = global.base.commonComponents;
6
+
7
+ const px = global.base.scaleSize;
8
+
9
+ export default ({route, navigation}) => {
10
+ const [answer, setAnswer] = useState(
11
+ route.params?.answer?.replace(/<br\/>/g, ''),
12
+ );
13
+ const [question, setQuestion] = useState(route.params?.question || '解答');
14
+ useEffect(() => {
15
+ const id = route.params?.id;
16
+ const product_id = route.params?.product_id;
17
+ if (id && product_id) {
18
+ getProductAnswers(product_id).then(res => {
19
+ const list = res.result || [];
20
+ const index = list.findIndex(item => item.id === id);
21
+ if (index > -1) {
22
+ setAnswer(list[index].product_question_answer);
23
+ setQuestion(list[index].product_question_name);
24
+ }
25
+ });
26
+ }
27
+ }, []);
28
+ return (
29
+ <View style={styles.container}>
30
+ <ScreenBackHeader title={question} backgroundColor="#fff" />
31
+ <View style={{flex: 1, padding: px(30)}}>
32
+ <Text
33
+ style={{
34
+ fontSize: px(55),
35
+ color: '#333',
36
+ fontWeight: '400',
37
+ }}>
38
+ {answer}
39
+ </Text>
40
+ </View>
41
+ </View>
42
+ );
43
+ };
44
+
45
+ const styles = StyleSheet.create({
46
+ container: {
47
+ flex: 1,
48
+ backgroundColor: '#eee',
49
+ },
50
+ });
@@ -0,0 +1,365 @@
1
+ import React, {useEffect, useMemo, useState, useLayoutEffect} from 'react';
2
+ import {
3
+ View,
4
+ StyleSheet,
5
+ Image,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ Platform,
9
+ TextInput,
10
+ KeyboardAvoidingView,
11
+ Keyboard,
12
+ } from 'react-native';
13
+ import {Divider, Icon, Input, Slider, Text} from '@rneui/themed';
14
+ import {launchImageLibrary} from 'react-native-image-picker';
15
+ import useKeyboard from '../../../hooks/useKeyboard';
16
+
17
+ const {ScreenBackHeader} = global.base.commonComponents;
18
+
19
+ const px = global.base.scaleSize;
20
+
21
+ import {getProductAnswers} from '../../../api';
22
+
23
+ // 设备类型对应题库
24
+ const DEVICE_TO_QUESTION = {
25
+ itee: 2,
26
+ igot: 3,
27
+ curtain: 4,
28
+ light: 5,
29
+ ifree: 6,
30
+ thermostat: 7,
31
+ windowpusher: 8,
32
+ ac: 9,
33
+ scale: 10,
34
+ hematometer: 11,
35
+ tv: 12,
36
+ istickiot: 13,
37
+ skiprope: 14,
38
+ rowmachine: 15,
39
+ oximeter: 16,
40
+ };
41
+
42
+ export default ({route, navigation}) => {
43
+ const {device_type} = route.params;
44
+ const [questionList, setQuestionList] = useState([]);
45
+ const [feedbackText, setFeedbackText] = useState('');
46
+ // 用于反馈的图片列表
47
+ const [imgList, setImgList] = useState([]);
48
+ const buttonDisabled = useMemo(() => {
49
+ return !feedbackText;
50
+ }, [feedbackText]);
51
+ const [showQuestion, setShowQuestion] = useState(true);
52
+ const {keyboardShow} = useKeyboard();
53
+
54
+ useLayoutEffect(() => {
55
+ init();
56
+ }, []);
57
+
58
+ // 获取设备对应题库
59
+ const init = async () => {
60
+ const questionId =
61
+ route.params.questionId || DEVICE_TO_QUESTION[device_type];
62
+ if (questionId) {
63
+ const res = await getProductAnswers(questionId);
64
+ if (res.error_code === 0) {
65
+ setQuestionList(res.result || []);
66
+ }
67
+ }
68
+ };
69
+
70
+ // 选择相册图片
71
+ const handleSelectPicture = async () => {
72
+ const result = await launchImageLibrary({
73
+ mediaType: 'mixed',
74
+ selectionLimit: 5,
75
+ // includeBase64: true,
76
+ });
77
+ if (result.didCancel) {
78
+ console.log('cancel');
79
+ } else if (result.errorCode) {
80
+ console.log('error', result);
81
+ } else {
82
+ const files = result.assets;
83
+ setImgList([...imgList, ...files]);
84
+ }
85
+ };
86
+
87
+ // 提交反馈
88
+ const submitFeedback = () => {
89
+ const formData = new FormData();
90
+ formData.append(
91
+ 'productId',
92
+ route.params.questionId || DEVICE_TO_QUESTION[device_type] + '',
93
+ );
94
+ formData.append('questionDescription', feedbackText);
95
+ imgList.forEach(img => {
96
+ formData.append('file', {
97
+ uri: Platform.OS === 'ios' ? img.uri.replace('file://', '') : img.uri,
98
+ type: 'multipart/form-data',
99
+ name: img.fileName,
100
+ // name: img.type,
101
+ });
102
+ });
103
+ global.loading.showLoading('提交中...');
104
+ console.log(formData, 'formData');
105
+ fetch('https://api.cloud.ipanel.cn/vgatehelp/ajb/problemFeedback', {
106
+ method: 'POST',
107
+ headers: {
108
+ 'Content-Type': 'multipart/form-data',
109
+ },
110
+ body: formData,
111
+ })
112
+ .then(res => {
113
+ global.loading.hideLoading();
114
+ return res.json();
115
+ })
116
+ .then(data => {
117
+ console.log(data);
118
+ if (data.error_code === 0) {
119
+ global.toast.showToast('提交成功');
120
+ } else {
121
+ global.toast.showToast('提交失败');
122
+ }
123
+ })
124
+ .catch(err => {
125
+ console.log(err);
126
+ global.loading.hideLoading();
127
+ global.toast.showToast('提交失败');
128
+ });
129
+ };
130
+
131
+ // 删除图片
132
+ const deleteImg = index => {
133
+ return setImgList([...imgList.filter((item, i) => i !== index)]);
134
+ };
135
+
136
+ return (
137
+ <View style={styles.container}>
138
+ <ScreenBackHeader title="帮助与反馈" backgroundColor="#fff" />
139
+ <View style={{flex: 1}}>
140
+ <ScrollView showsVerticalScrollIndicator={false}>
141
+ <View style={styles.titleBox}>
142
+ <Text style={styles.title}>常见问题</Text>
143
+ </View>
144
+
145
+ <View
146
+ style={{
147
+ backgroundColor: '#fff',
148
+ }}>
149
+ {questionList.map(item => (
150
+ <React.Fragment key={item.id}>
151
+ <TouchableOpacity
152
+ style={styles.cellBox}
153
+ onPress={() =>
154
+ navigation.navigate('DeviceAnswerDetailScreen', {
155
+ question: item.product_question_name,
156
+ answer: item.product_question_answer,
157
+ })
158
+ }>
159
+ <Text style={styles.cellLabel}>
160
+ {item.product_question_name}
161
+ </Text>
162
+ {/*<Icon*/}
163
+ {/* name="chevron-right"*/}
164
+ {/* type="material"*/}
165
+ {/* size={20}*/}
166
+ {/* color="#aaa"*/}
167
+ {/*/>*/}
168
+ <Image
169
+ source={require('../../../assets/img/link.png')}
170
+ style={{
171
+ width: px(30),
172
+ height: px(30),
173
+ }}
174
+ resizeMode="contain"
175
+ />
176
+ </TouchableOpacity>
177
+ <Divider color="#eee" width={1} />
178
+ </React.Fragment>
179
+ ))}
180
+ </View>
181
+
182
+ <View style={styles.titleBox}>
183
+ <Text style={styles.title}>问题反馈</Text>
184
+ </View>
185
+ <View style={styles.feedbackBox}>
186
+ <TextInput
187
+ value={feedbackText}
188
+ onChangeText={setFeedbackText}
189
+ // numberOfLines={4}
190
+ multiline={true}
191
+ containerStyle={{
192
+ height: px(350),
193
+ padding: 0,
194
+ margin: 0,
195
+ borderWidth: 0,
196
+ }}
197
+ inputContainerStyle={{
198
+ height: '100%',
199
+ width: '100%',
200
+ padding: 0,
201
+ margin: 0,
202
+ borderBottomWidth: 0,
203
+ }}
204
+ style={{
205
+ fontSize: px(44),
206
+ paddingLeft: px(82),
207
+ // height: px(350),
208
+ justifyContent: 'flex-start',
209
+ alignItems: 'flex-start',
210
+ color: '#333',
211
+ }}
212
+ placeholder="请详细描述问题~"
213
+ placeholderTextColor="#999"
214
+ />
215
+ <View
216
+ style={{
217
+ paddingLeft: px(82),
218
+ flexDirection: 'row',
219
+ alignItems: 'center',
220
+ position: 'absolute',
221
+ bottom: px(38),
222
+ left: 0,
223
+ right: 0,
224
+ }}>
225
+ <TouchableOpacity
226
+ style={styles.addImgBox}
227
+ onPress={handleSelectPicture}>
228
+ <Image
229
+ source={require('../../../assets/img/add_img.png')}
230
+ style={styles.addImg}
231
+ />
232
+ </TouchableOpacity>
233
+ <View style={styles.imgList}>
234
+ <ScrollView
235
+ showsHorizontalScrollIndicator={true}
236
+ horizontal={true}>
237
+ {imgList.map((img, index) => (
238
+ <View style={styles.imgBox} key={img.fileName}>
239
+ <Image
240
+ source={{uri: img.uri}}
241
+ style={styles.imgItem}
242
+ resizeMode="contain"
243
+ />
244
+ <TouchableOpacity
245
+ style={styles.deleteImgButton}
246
+ onPress={() => deleteImg(index)}>
247
+ <Image
248
+ source={require('../../../assets/img/delete_pic.png')}
249
+ resizeMode="contain"
250
+ style={styles.deleteImg}
251
+ />
252
+ </TouchableOpacity>
253
+ </View>
254
+ ))}
255
+ </ScrollView>
256
+ </View>
257
+ </View>
258
+ </View>
259
+ <TouchableOpacity
260
+ onPress={submitFeedback}
261
+ style={{
262
+ ...styles.button,
263
+ backgroundColor: buttonDisabled
264
+ ? 'rgba(234, 96, 0, 0.3)'
265
+ : 'rgba(234, 96, 0, 1)',
266
+ }}
267
+ disabled={buttonDisabled}>
268
+ <Text style={styles.buttonText}>提交反馈</Text>
269
+ </TouchableOpacity>
270
+ </ScrollView>
271
+ </View>
272
+ </View>
273
+ );
274
+ };
275
+
276
+ const styles = StyleSheet.create({
277
+ container: {
278
+ flex: 1,
279
+ backgroundColor: '#eee',
280
+ },
281
+ titleBox: {
282
+ paddingTop: px(25),
283
+ paddingBottom: px(22),
284
+ paddingLeft: px(38),
285
+ },
286
+ title: {
287
+ fontSize: px(38),
288
+ color: '#333',
289
+ fontWeight: '400',
290
+ },
291
+
292
+ cellBox: {
293
+ paddingVertical: px(30),
294
+ minHeight: px(150),
295
+ flexDirection: 'row',
296
+ justifyContent: 'space-between',
297
+ alignItems: 'center',
298
+ paddingLeft: px(38),
299
+ paddingRight: px(44),
300
+ },
301
+
302
+ cellLabel: {
303
+ fontSize: px(49),
304
+ color: '#333',
305
+ fontWeight: '400',
306
+ marginRight: px(50),
307
+ flex: 1,
308
+ },
309
+
310
+ feedbackBox: {
311
+ backgroundColor: '#fff',
312
+ height: px(555),
313
+ position: 'relative',
314
+ },
315
+
316
+ addImgBox: {
317
+ // paddingLeft: px(82),
318
+ },
319
+ addImg: {
320
+ width: px(148),
321
+ height: px(148),
322
+ },
323
+
324
+ // 反馈图片列表
325
+ imgList: {
326
+ flexDirection: 'row',
327
+ alignItems: 'center',
328
+ },
329
+ imgBox: {
330
+ marginLeft: px(38),
331
+ width: px(148 + 11),
332
+ height: px(148 + 11),
333
+ justifyContent: 'center',
334
+ alignItems: 'center',
335
+ position: 'relative',
336
+ },
337
+ imgItem: {
338
+ width: px(148),
339
+ height: px(148),
340
+ borderRadius: px(16),
341
+ },
342
+ deleteImgButton: {
343
+ position: 'absolute',
344
+ right: px(0),
345
+ top: px(0),
346
+ },
347
+ deleteImg: {
348
+ width: px(55),
349
+ height: px(55),
350
+ },
351
+
352
+ button: {
353
+ marginHorizontal: px(82),
354
+ marginVertical: px(115),
355
+ backgroundColor: '#EA6000',
356
+ paddingVertical: px(33),
357
+ borderRadius: px(69),
358
+ },
359
+ buttonText: {
360
+ fontSize: px(49),
361
+ color: '#fff',
362
+ textAlign: 'center',
363
+ fontWeight: '500',
364
+ },
365
+ });
@@ -0,0 +1,279 @@
1
+ import React, {useMemo, useState} from 'react';
2
+ import {View, Text, StyleSheet, TouchableOpacity, Keyboard} from 'react-native';
3
+ import {Divider} from '@rneui/themed';
4
+ import {addInvoiceTitle, adjustInvoiceTitle} from '../../../api';
5
+
6
+ const {commonComponents, scaleSize: px} = global.base;
7
+ const fontStyle = global.base.styles.fontStyle;
8
+
9
+ const {ScreenBackHeader, Cell} = commonComponents;
10
+
11
+ export default ({navigation, route}) => {
12
+ const {usage = 0, invoiceTitle = {}} = route?.params || {};
13
+ const title = usage === 0 ? '添加发票抬头' : '编辑发票抬头';
14
+ const [unitInvoiceTitle, setUnitInvoiceTitle] = useState([
15
+ {
16
+ label: '名称',
17
+ name: 'name',
18
+ value: invoiceTitle?.name || '',
19
+ placeholder: '单位名称',
20
+ },
21
+ {
22
+ label: '税号',
23
+ name: 'tax_no',
24
+ value: invoiceTitle?.tax_no || '',
25
+ placeholder: '纳税人识别号',
26
+ },
27
+ {
28
+ label: '单位地址',
29
+ name: 'address',
30
+ value: invoiceTitle?.address || '',
31
+ placeholder: '单位地址信息',
32
+ },
33
+ {
34
+ label: '电话号码',
35
+ name: 'telephone',
36
+ value: invoiceTitle?.telephone || '',
37
+ placeholder: '电话号码',
38
+ },
39
+ {
40
+ label: '开户银行',
41
+ name: 'bank_name',
42
+ value: invoiceTitle?.bank_name || '',
43
+ placeholder: '开户银行名称',
44
+ },
45
+ {
46
+ label: '银行帐号',
47
+ name: 'bank_num',
48
+ value: invoiceTitle?.bank_num || '',
49
+ placeholder: '银行账户号码',
50
+ },
51
+ ]);
52
+ const [personInvoiceTitle, setPersonInvoiceTitle] = useState([
53
+ {
54
+ label: '名称',
55
+ name: 'name',
56
+ value: invoiceTitle?.name || '',
57
+ },
58
+ ]);
59
+
60
+ const unitInvoiceTitleObj = useMemo(() => {
61
+ const obj = {};
62
+ unitInvoiceTitle.forEach(item => {
63
+ obj[item.name] = item.value;
64
+ });
65
+ return obj;
66
+ }, [unitInvoiceTitle]);
67
+
68
+ const personInvoiceTitleObj = useMemo(() => {
69
+ const obj = {};
70
+ personInvoiceTitle.forEach(item => {
71
+ obj[item.name] = item.value;
72
+ });
73
+ return obj;
74
+ }, [personInvoiceTitle]);
75
+
76
+ // 抬头类型
77
+ const [invoiceTitleType, setInvoiceTitleType] = useState(
78
+ invoiceTitle?.type || '01',
79
+ );
80
+
81
+ const headerRight = () => {
82
+ return (
83
+ <TouchableOpacity onPress={save} disabled={saveDisabled}>
84
+ <Text
85
+ style={{
86
+ fontSize: px(44),
87
+ color: saveDisabled ? '#999' : '#333',
88
+ }}>
89
+ 确定
90
+ </Text>
91
+ </TouchableOpacity>
92
+ );
93
+ };
94
+
95
+ const saveDisabled = useMemo(() => {
96
+ if (invoiceTitleType === '01') {
97
+ return unitInvoiceTitle.filter(item => !item.value).length > 0;
98
+ } else {
99
+ return personInvoiceTitle.filter(item => !item.value).length > 0;
100
+ }
101
+ }, [invoiceTitleType, unitInvoiceTitle, personInvoiceTitle]);
102
+
103
+ const save = () => {
104
+ usage === 0 ? add() : edit();
105
+ };
106
+
107
+ const add = async () => {
108
+ const res = await addInvoiceTitle({
109
+ buyer: {
110
+ type: invoiceTitleType,
111
+ ...(invoiceTitleType === '01'
112
+ ? unitInvoiceTitleObj
113
+ : personInvoiceTitleObj),
114
+ },
115
+ });
116
+ console.log(res, 'addInvoiceTitle');
117
+ if (res.code === 0) {
118
+ global.toast?.showToast('新建成功');
119
+ navigation.goBack();
120
+ } else {
121
+ global.toast?.showToast('新建失败');
122
+ }
123
+ };
124
+
125
+ const edit = async () => {
126
+ const res = await adjustInvoiceTitle({
127
+ title_id: invoiceTitle.title_id,
128
+ buyer: {
129
+ type: invoiceTitleType,
130
+ ...(invoiceTitleType === '01'
131
+ ? unitInvoiceTitleObj
132
+ : personInvoiceTitleObj),
133
+ },
134
+ });
135
+ if (res.code === 0) {
136
+ global.toast?.showToast('修改成功');
137
+ navigation.goBack();
138
+ } else {
139
+ global.toast?.showToast('修改失败');
140
+ }
141
+ };
142
+
143
+ const onChangeText = (key, value) => {
144
+ if (invoiceTitleType === '01') {
145
+ setUnitInvoiceTitle(
146
+ unitInvoiceTitle.map(item => {
147
+ if (item.name === key) {
148
+ return {
149
+ ...item,
150
+ value,
151
+ };
152
+ } else {
153
+ return {
154
+ ...item,
155
+ };
156
+ }
157
+ }),
158
+ );
159
+ } else {
160
+ setPersonInvoiceTitle(
161
+ personInvoiceTitle.map(item => {
162
+ if (item.name === key) {
163
+ return {
164
+ ...item,
165
+ value,
166
+ };
167
+ } else {
168
+ return {
169
+ ...item,
170
+ };
171
+ }
172
+ }),
173
+ );
174
+ }
175
+ };
176
+
177
+ return (
178
+ <TouchableOpacity
179
+ style={styles.container}
180
+ onPress={Keyboard.dismiss}
181
+ activeOpacity={1}>
182
+ <ScreenBackHeader title={title} headerRight={headerRight} />
183
+ <Divider color="#eee" />
184
+ <View style={styles.content}>
185
+ <Cell
186
+ label="抬头类型"
187
+ type="custom"
188
+ labelTextStyle={{
189
+ ...fontStyle(44, '#333', 500),
190
+ }}
191
+ rightComponent={
192
+ <View style={styles.switchBox}>
193
+ <TouchableOpacity
194
+ activeOpacity={0.5}
195
+ onPress={() => setInvoiceTitleType('01')}
196
+ style={[
197
+ styles.switchItem,
198
+ invoiceTitleType === '01' && styles.activeSwitchItem,
199
+ ]}>
200
+ <Text
201
+ style={[
202
+ styles.switchItemText,
203
+ invoiceTitleType === '01' && styles.activeSwitchItemText,
204
+ ]}>
205
+ 单位
206
+ </Text>
207
+ </TouchableOpacity>
208
+ <TouchableOpacity
209
+ activeOpacity={0.5}
210
+ onPress={() => setInvoiceTitleType('02')}
211
+ style={[
212
+ styles.switchItem,
213
+ invoiceTitleType === '02' && styles.activeSwitchItem,
214
+ ]}>
215
+ <Text
216
+ style={[
217
+ styles.switchItemText,
218
+ invoiceTitleType === '02' && styles.activeSwitchItemText,
219
+ ]}>
220
+ 个人
221
+ </Text>
222
+ </TouchableOpacity>
223
+ </View>
224
+ }
225
+ />
226
+ {(invoiceTitleType === '01'
227
+ ? unitInvoiceTitle
228
+ : personInvoiceTitle
229
+ ).map(item => (
230
+ <Cell
231
+ key={item.name}
232
+ type="input"
233
+ label={item.label}
234
+ labelTextStyle={{
235
+ ...fontStyle(44, '#333', 500),
236
+ }}
237
+ value={item.value}
238
+ onChangeText={value => onChangeText(item.name, value)}
239
+ placeholder={item.placeholder}
240
+ />
241
+ ))}
242
+ </View>
243
+ </TouchableOpacity>
244
+ );
245
+ };
246
+
247
+ const styles = StyleSheet.create({
248
+ container: {
249
+ flex: 1,
250
+ backgroundColor: '#fff',
251
+ },
252
+ content: {
253
+ flex: 1,
254
+ },
255
+ switchBox: {
256
+ borderRadius: px(49),
257
+ backgroundColor: '#F2F2F2',
258
+ width: px(330),
259
+ flexDirection: 'row',
260
+ marginRight: px(38),
261
+ },
262
+ switchItem: {
263
+ flex: 1,
264
+ justifyContent: 'center',
265
+ alignItems: 'center',
266
+ borderRadius: px(49),
267
+ height: px(99),
268
+ // height: '100%',
269
+ },
270
+ activeSwitchItem: {
271
+ backgroundColor: '#ea6000',
272
+ },
273
+ switchItemText: {
274
+ ...fontStyle(44),
275
+ },
276
+ activeSwitchItemText: {
277
+ color: '#fff',
278
+ },
279
+ });