PaymentListV2.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /**
  2. * 新版支付方式选择器
  3. * @邠心vbe on 2021/04/13
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, StyleSheet, Pressable, ScrollView } from 'react-native';
  7. import BottomModal from '../../components/BottomModal';
  8. import BadgeSelectItem from '../../components/BadgeSelectItem';
  9. import { ChargeStyle } from './Charging';
  10. import { PAYTYPE, PaymentIcon } from '../payment/PaymentConfig';
  11. import TextView from '../../components/TextView';
  12. import apiCharge from '../../api/apiCharge';
  13. import Button from '../../components/Button';
  14. import Dialog from '../../components/Dialog';
  15. import app from '../../../app.json';
  16. export default class PaymentListV2 extends Component {
  17. constructor(props) {
  18. super(props);
  19. this.state = {
  20. visible: false,
  21. isSelect: true,
  22. options: [],
  23. selectIndex: 0,
  24. selectOptions: {}
  25. };
  26. }
  27. componentDidMount() {
  28. this.getPaymentOptions();
  29. this.setState({
  30. isSelect: (this.props.isSelect || true)
  31. })
  32. }
  33. componentDidUpdate() {
  34. if (this.props.isSelect != undefined && this.state.isSelect !== this.props.isSelect) {
  35. this.setState({
  36. isSelect: this.props.isSelect
  37. })
  38. }
  39. }
  40. getPaymentOptions() {
  41. apiCharge.getPaymentTypeOptions({
  42. chargeBoxId: this.props.chargeBoxId
  43. }).then(res => {
  44. if (res.data) {
  45. this.setState({
  46. options: res.data
  47. })
  48. if (this.props.payType && this.props.payType.code) {
  49. for (let i = 0; i < res.data.length; i++) {
  50. let type = res.data[i];
  51. if (type.code == this.props.payType.code) {
  52. this.changeMethod(i);
  53. break;
  54. }
  55. }
  56. } else {
  57. let index = 0;
  58. for (let i = 0; i < res.data.length; i++) {
  59. let type = res.data[i];
  60. if (type.def) {
  61. index = i;
  62. break;
  63. }
  64. }
  65. this.changeMethod(index);
  66. }
  67. }
  68. }).catch(err => {
  69. })
  70. }
  71. showDialog(visible) {
  72. if (this.state.isSelect) {
  73. this.setState({
  74. visible: visible
  75. })
  76. }
  77. }
  78. changeMethod(index) {
  79. const type = this.state.options[index];
  80. this.setState({
  81. selectIndex: index,
  82. selectOptions: type
  83. }, () => {
  84. if (this.props.onMethodChange) {
  85. this.props.onMethodChange(this.state.selectOptions);
  86. }
  87. })
  88. }
  89. setDefault() {
  90. const code = this.state.selectOptions?.code;
  91. if (code && !this.state.selectOptions.def) {
  92. Dialog.showProgressDialog();
  93. apiCharge.setDefaultPaymentType({
  94. defaultPaymentMethod: code
  95. }).then(res => {
  96. toastShort("success");
  97. this.getPaymentOptions();
  98. }).catch(err => {
  99. toastShort(err)
  100. }).finally(() => {
  101. Dialog.dismissLoading();
  102. })
  103. }
  104. }
  105. render() {
  106. return (
  107. <View>
  108. <BadgeSelectItem
  109. style={this.props.style ?? ChargeStyle.stationInfoView}
  110. borderColor={this.props.borderColor}
  111. checked={false}
  112. onPress={() => this.showDialog(true)}>
  113. { app.charge.version >= 4
  114. ? <MaterialIcons
  115. name="wallet"
  116. size={32}
  117. color={textPrimary}/>
  118. : <PaymentIcon
  119. method={"WALLET"}
  120. checked={true}
  121. size={35}/>
  122. }
  123. { (this.state.isSelect && this.state.options.length > 1) &&
  124. <TextView style={styles.numberDot}>{this.state.options.length}</TextView>
  125. }
  126. <View style={styles.paymentView}>
  127. <TextView
  128. style={styles.valueText}
  129. numberOfLines={1}>{this.state.selectOptions?.name}</TextView>
  130. <TextView
  131. style={styles.paymentText}
  132. numberOfLines={1}>{this.state.selectOptions?.desc}</TextView>
  133. </View>
  134. { this.state.selectOptions?.def &&
  135. <TextView style={styles.textDefault}>Default</TextView>
  136. }
  137. { this.state.isSelect &&
  138. <FontAwesome6
  139. name={"angle-right"}
  140. size={16}
  141. color={colorCancel}
  142. />
  143. }
  144. </BadgeSelectItem>
  145. <BottomModal
  146. visible={this.state.visible}
  147. onHide={() => this.showDialog(false)}>
  148. <View style={styles.dialogContent}>
  149. <TextView style={styles.titleText}>Payment Methods</TextView>
  150. <ScrollView style={styles.paymentList}>
  151. { this.state.options.map((item, index) => (
  152. <Pressable
  153. key={index}
  154. style={styles.itemPayment}
  155. onPress={() => this.changeMethod(index)}>
  156. <View style={ui.flex1}>
  157. <TextView style={styles.labelText}>{item.name}</TextView>
  158. <TextView style={styles.descText}>{item.desc}</TextView>
  159. </View>
  160. { item.def &&
  161. <TextView style={styles.tagDefault}>Default</TextView>
  162. }
  163. <MaterialCommunityIcons
  164. name={index == this.state.selectIndex ? "radiobox-marked" : "radiobox-blank"}
  165. size={24}
  166. color={index == this.state.selectIndex ? colorPrimary : textPrimary}
  167. />
  168. </Pressable>
  169. ))
  170. }
  171. </ScrollView>
  172. <EndView/><EndView/>
  173. <View style={ui.flexc}>
  174. <Button
  175. style={styles.defButton}
  176. text={"Set Default"}
  177. onClick={() => this.setDefault()}/>
  178. <EndView half/>
  179. <Button
  180. style={ui.flex1}
  181. text={"Confirm"}
  182. onClick={() => this.showDialog(false)}/>
  183. </View>
  184. </View>
  185. </BottomModal>
  186. </View>
  187. );
  188. }
  189. }
  190. const styles = StyleSheet.create({
  191. paymentView: {
  192. flex: 1,
  193. flexWrap: 'wrap',
  194. alignItems: 'center',
  195. flexDirection: 'row',
  196. justifyContent: 'space-around'
  197. },
  198. dialogContent: {
  199. padding: 16
  200. },
  201. paymentList: {
  202. height: $vh(50)
  203. },
  204. titleText: {
  205. fontSize: 16,
  206. fontWeight: 'bold',
  207. paddingBottom: 18
  208. },
  209. valueText: {
  210. flex: 1,
  211. color: textPrimary,
  212. fontSize: 14,
  213. fontWeight: 'bold',
  214. paddingLeft: 16
  215. },
  216. paymentText: {
  217. flex: 1,
  218. color: textSecondary,
  219. fontSize: 12,
  220. paddingLeft: 8,
  221. paddingRight: 16,
  222. textAlign: 'center'
  223. },
  224. labelText: {
  225. color: textPrimary,
  226. fontSize: 14,
  227. fontWeight: 'bold'
  228. },
  229. descText: {
  230. color: colorAccent,
  231. fontSize: 12,
  232. paddingTop: 2
  233. },
  234. itemPayment: {
  235. paddingTop: 8,
  236. paddingBottom: 8,
  237. alignItems: 'center',
  238. flexDirection: 'row'
  239. },
  240. tagDefault: {
  241. color: textLight,
  242. fontSize: 12,
  243. borderRadius: 4,
  244. ...$padding(4, 8),
  245. marginRight: 12,
  246. backgroundColor: colorAccent
  247. },
  248. textDefault: {
  249. color: colorAccent,
  250. fontSize: 12,
  251. marginRight: 8,
  252. fontWeight: 'bold'
  253. },
  254. defButton: {
  255. flex: 1,
  256. backgroundColor: colorPrimary
  257. },
  258. numberDot: {
  259. top: 10,
  260. left: 32,
  261. width: 16,
  262. height: 16,
  263. color: textButton,
  264. fontSize: 10,
  265. fontWeight: 'bold',
  266. borderRadius: 32,
  267. position: 'absolute',
  268. alignItems: 'center',
  269. justifyContent: 'center',
  270. backgroundColor: colorAccent
  271. }
  272. })