buy.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /*
  2. *
  3. */
  4. import React, { Component } from 'react';
  5. import {
  6. Platform,
  7. StyleSheet,
  8. Text,
  9. View,
  10. Image,
  11. TouchableOpacity,
  12. FlatList,
  13. TouchableHighlight,
  14. DeviceEventEmitter,
  15. ScrollView,
  16. BackHandler,
  17. ToastAndroid,
  18. StatusBar,
  19. Modal,
  20. Animated,
  21. TextInput
  22. } from 'react-native';
  23. import BasePage from '../BasePage';
  24. import Dimensions from '../utils/dimensions';
  25. import TopicTitle from '../components/TopicTitle';
  26. import CourseTitle from '../components/CourseTitle';
  27. import wechat from '../utils/wechat';
  28. import PayUtil from '../services/PayUtil';
  29. import Alipay from 'react-native-yunpeng-alipay';
  30. export default class Buy extends BasePage {
  31. state = {
  32. shopData: [
  33. {
  34. appCode: '',
  35. days: 0,
  36. gmtCreated: 0,
  37. gmtModified: 0,
  38. id: 0,
  39. title: '',
  40. originalPrice: '',
  41. payType: 1,
  42. price: '',
  43. sort: 0
  44. }
  45. ],
  46. currentTapindex: 0,
  47. slideAnim: new Animated.Value(-150),
  48. ifDialogShow: false,
  49. payType: 1,
  50. ticketPrice: 0,
  51. useTicket: false
  52. };
  53. itemTap = (index) => {
  54. this.setState({
  55. currentTapindex: index
  56. });
  57. };
  58. renderItem = (item, index) => {
  59. return (
  60. <TouchableOpacity
  61. style={this.state.currentTapindex === index ? styles.itemWrapperTap : styles.itemWrapperNormal}
  62. onPress={() => {
  63. this.itemTap(index);
  64. }}
  65. key={index}
  66. >
  67. <Text style={this.state.currentTapindex === index ? styles.timeLengthTap : styles.timeLength}>
  68. {item.title}
  69. </Text>
  70. <Text style={this.state.currentTapindex === index ? styles.priceTap : styles.price}>
  71. ¥{item.price}元
  72. </Text>
  73. <Text style={this.state.currentTapindex === index ? styles.originPriceTap : styles.originPrice}>
  74. 原价:¥{item.originalPrice}
  75. </Text>
  76. </TouchableOpacity>
  77. );
  78. };
  79. dialogComeout = (index) => {
  80. if (index) {
  81. this.setState(
  82. {
  83. ifDialogShow: true
  84. },
  85. () => {
  86. Animated.timing(this.state.slideAnim, {
  87. toValue: 0,
  88. duration: 100
  89. }).start();
  90. }
  91. );
  92. } else {
  93. Animated.timing(this.state.slideAnim, {
  94. toValue: -150,
  95. duration: 100
  96. }).start();
  97. setTimeout(() => {
  98. this.setState({
  99. ifDialogShow: false
  100. });
  101. }, 210);
  102. }
  103. };
  104. setPayMethod = (type) => {
  105. this.setState(
  106. {
  107. payType: type
  108. },
  109. () => {
  110. setTimeout(() => {
  111. this.dialogComeout(false);
  112. }, 100);
  113. }
  114. );
  115. };
  116. componentWillMount() {
  117. //获取订购数据信息
  118. this.getMember();
  119. BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
  120. }
  121. componentWillUnmount() {
  122. BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
  123. }
  124. onBackAndroid = () => {
  125. if (this.state.ifDialogShow) {
  126. this.dialogComeout(false);
  127. } else {
  128. this.goBack();
  129. }
  130. return true;
  131. };
  132. async getMember() {
  133. await PayUtil.getMember().then((result) => {
  134. console.log('====================================');
  135. console.log('result', result);
  136. console.log('====================================');
  137. this.setState({
  138. shopData: result.data
  139. });
  140. });
  141. }
  142. choseTicket = () => {
  143. this.toNextPage('Ticket', { choseTicketCallBack: this.choseTicketCallBack.bind(this) });
  144. };
  145. choseTicketCallBack(item) {
  146. /**item参数
  147. * type: 1,
  148. price: 12,
  149. num: 6,
  150. time: '2019-12-12'
  151. *
  152. */
  153. this.setState({
  154. ticketPrice: item.price,
  155. useTicket: true
  156. });
  157. }
  158. getPrice(old_price) {
  159. return parseInt(old_price) - parseInt(this.state.ticketPrice) < 0
  160. ? 0
  161. : parseInt(old_price) - parseInt(this.state.ticketPrice);
  162. }
  163. pay = () => {
  164. let data = this.state.shopData[this.state.currentTapindex];
  165. switch (this.state.payType) {
  166. case 1:
  167. let params = {
  168. productCode: data.id,
  169. type: '0',
  170. preferentialIds: '',
  171. useVoucher: this.state.useTicket
  172. };
  173. PayUtil.payByWechat(params).then((result) => {
  174. wechat.pay(
  175. result.data.partnerid,
  176. result.data.prepayid,
  177. result.data.noncestr,
  178. result.data.timestamp,
  179. result.data.package,
  180. result.data.sign,
  181. (result) => {
  182. ToastAndroid.show('支付成功', ToastAndroid.SHORT);
  183. // console.log('wechat result', result);
  184. }
  185. );
  186. });
  187. break;
  188. case 2:
  189. //阿里支付
  190. let params_ali = {
  191. productCode: data.id,
  192. type: '0',
  193. preferentialIds: '',
  194. useVoucher: this.state.useTicket
  195. };
  196. //先请求后台给支付数据
  197. PayUtil.payByAli(params_ali).then((result) => {
  198. Alipay.pay(result.data.response).then(
  199. function(data) {
  200. //成功
  201. console.log(data);
  202. },
  203. function(err) {
  204. //失败
  205. console.log(err);
  206. }
  207. );
  208. });
  209. break;
  210. }
  211. };
  212. render() {
  213. return (
  214. <View style={{ flex: 1 }}>
  215. <StatusBar barStyle={'dark-content'} backgroundColor={'white'} translucent={true} />
  216. <View
  217. style={{
  218. height: 50,
  219. backgroundColor: 'white',
  220. marginTop: 30
  221. }}
  222. >
  223. <CourseTitle
  224. width={this.getWindowWidth()}
  225. title="VIP购买"
  226. lefttype={1}
  227. textcolor={'#231F20'}
  228. backPress={() => this.goBack()}
  229. // backPress={() => alert("左侧按钮")}
  230. />
  231. </View>
  232. <View style={{ flex: 0.02, backgroundColor: 'rgba(242, 242, 242, 1)' }} />
  233. <View style={styles.top}>
  234. <Text style={styles.title}>套餐选择</Text>
  235. <View>{this.state.shopData.map((item, index) => this.renderItem(item, index))}</View>
  236. </View>
  237. <View style={{ flex: 0.01, backgroundColor: 'rgba(242, 242, 242, 1)' }} />
  238. <TouchableOpacity style={styles.payment} activeOpacity={1} onPress={this.choseTicket.bind(this)}>
  239. <Text style={styles.left}>使用抵用券</Text>
  240. <View style={styles.right}>
  241. <Text style={styles.method}>-¥{this.state.ticketPrice}元</Text>
  242. <Image source={require('../images/common/arrowRight.png')} />
  243. </View>
  244. </TouchableOpacity>
  245. <TouchableOpacity style={styles.payment} activeOpacity={1} onPress={() => this.dialogComeout(true)}>
  246. <Text style={styles.left}>支付方式</Text>
  247. <View style={styles.right}>
  248. {this.state.payType === 1 ? (
  249. <Text style={styles.method}>微信支付</Text>
  250. ) : (
  251. <Text style={styles.method}>支付宝支付</Text>
  252. )}
  253. <Image source={require('../images/common/arrowRight.png')} />
  254. </View>
  255. </TouchableOpacity>
  256. <View style={{ flex: 0.01, backgroundColor: 'rgba(242, 242, 242, 1)' }} />
  257. <View>
  258. <Text style={{ fontSize: 14, width: '100%', textAlignVertical: 'center', textAlign: 'center' }}>
  259. 开通会员即时生效,有任何问题请联系我们。
  260. </Text>
  261. </View>
  262. <View style={styles.bottom}>
  263. {this.state.ticketPrice > 0 ? (
  264. (price = (
  265. <Text style={styles.bottomLeft}>
  266. ¥{this.getPrice(this.state.shopData[this.state.currentTapindex].price)}元
  267. </Text>
  268. ))
  269. ) : (
  270. <Text style={styles.bottomLeft}>¥{this.state.shopData[this.state.currentTapindex].price}元</Text>
  271. )}
  272. <TouchableOpacity style={styles.bottomRight} onPress={this.pay.bind(this)}>
  273. <Text style={styles.bottomRightText}>支付</Text>
  274. </TouchableOpacity>
  275. </View>
  276. {this.state.ifDialogShow ? (
  277. <TouchableHighlight
  278. onPress={() => {
  279. this.dialogComeout(false);
  280. }}
  281. style={{ ...styles.dialog }}
  282. underlayColor={0.1}
  283. >
  284. <Animated.View style={{ ...styles.payMethod, bottom: this.state.slideAnim }} onPress={() => {}}>
  285. <Text style={styles.payText}>选择支付方式</Text>
  286. <TouchableOpacity
  287. activeOpacity={0.9}
  288. style={styles.payDialog}
  289. onPress={() => this.setPayMethod(1)}
  290. >
  291. <View style={styles.dialogRow}>
  292. <Image style={styles.payIcon} source={require('../images/common/wxPay.png')} />
  293. <Text>微信支付</Text>
  294. </View>
  295. {this.state.payType === 1 ? (
  296. <Image source={require('../images/common/check.png')} />
  297. ) : null}
  298. </TouchableOpacity>
  299. <TouchableOpacity
  300. activeOpacity={0.9}
  301. style={styles.payDialog}
  302. onPress={() => this.setPayMethod(2)}
  303. >
  304. <View style={styles.dialogRow}>
  305. <Image style={styles.payIcon} source={require('../images/common/aliPay.png')} />
  306. <Text>支付宝支付</Text>
  307. </View>
  308. {this.state.payType === 2 ? (
  309. <Image source={require('../images/common/check.png')} />
  310. ) : null}
  311. </TouchableOpacity>
  312. {/* <TextInput style={styles.payDialog} /> */}
  313. <View style={{ flex: 0.2 }} />
  314. </Animated.View>
  315. </TouchableHighlight>
  316. ) : null}
  317. {/* <Modal
  318. animationType="none "
  319. transparent={true}
  320. visible={true}
  321. onRequestClose={() => {
  322. alert("Modal has been closed.");
  323. }}
  324. ></Modal> */}
  325. </View>
  326. );
  327. }
  328. }
  329. const styles = StyleSheet.create({
  330. top: {
  331. width: Dimensions.width,
  332. flexDirection: 'column',
  333. alignItems: 'center',
  334. paddingBottom: 20
  335. },
  336. title: {
  337. fontSize: 20,
  338. color: '#a8674d',
  339. marginTop: 22
  340. },
  341. itemWrapperNormal: {
  342. borderWidth: 1,
  343. borderColor: '#a8674d',
  344. borderRadius: 27,
  345. backgroundColor: '#fff',
  346. flexDirection: 'row',
  347. alignItems: 'center',
  348. justifyContent: 'space-around',
  349. width: '86%',
  350. height: Dimensions.getHeight(53),
  351. marginTop: 20
  352. },
  353. itemWrapperTap: {
  354. // borderWidth: 1,
  355. // borderColor: '#a8674d',
  356. borderRadius: 27,
  357. backgroundColor: '#ff7525',
  358. flexDirection: 'row',
  359. alignItems: 'center',
  360. justifyContent: 'space-around',
  361. width: '86%',
  362. height: Dimensions.getHeight(53),
  363. marginTop: 20
  364. },
  365. originPriceTap: {
  366. fontSize: 14,
  367. color: '#fff',
  368. textDecorationLine: 'line-through'
  369. },
  370. originPrice: {
  371. fontSize: 14,
  372. color: '#a8674d',
  373. textDecorationLine: 'line-through'
  374. },
  375. priceTap: {
  376. fontSize: 20,
  377. color: '#fff'
  378. },
  379. price: {
  380. fontSize: 20,
  381. color: '#a8674d'
  382. },
  383. timeLengthTap: {
  384. fontSize: 18,
  385. color: '#fff'
  386. },
  387. timeLength: {
  388. fontSize: 18,
  389. color: '#a8674d'
  390. },
  391. payment: {
  392. flexDirection: 'row',
  393. alignItems: 'center',
  394. width: Dimensions.width,
  395. height: 60,
  396. justifyContent: 'space-between',
  397. alignItems: 'center',
  398. borderColor: '#f3f2f7',
  399. borderTopWidth: 6,
  400. borderBottomWidth: 6,
  401. paddingHorizontal: 33
  402. },
  403. left: {
  404. fontSize: 16
  405. },
  406. right: {
  407. flexDirection: 'row',
  408. alignItems: 'center'
  409. },
  410. method: {
  411. color: '#a8674d',
  412. fontSize: 16,
  413. marginRight: 7
  414. },
  415. bottom: {
  416. width: Dimensions.width,
  417. height: 60,
  418. flexDirection: 'row',
  419. position: 'absolute',
  420. bottom: 0
  421. },
  422. bottomLeft: {
  423. width: '58%',
  424. textAlign: 'center',
  425. lineHeight: 60,
  426. color: '#a8674d',
  427. fontSize: 20
  428. },
  429. bottomRight: {
  430. width: '42%',
  431. fontSize: 16,
  432. color: '#fff',
  433. backgroundColor: '#f5880d',
  434. alignItems: 'center'
  435. },
  436. bottomRightText: {
  437. fontSize: 20,
  438. color: '#fff',
  439. textAlign: 'center',
  440. lineHeight: 60
  441. },
  442. dialog: {
  443. width: Dimensions.width,
  444. height: Dimensions.height,
  445. position: 'absolute',
  446. backgroundColor: 'rgba(0,0,0,0.4)'
  447. },
  448. payMethod: {
  449. width: Dimensions.width,
  450. height: 150,
  451. position: 'absolute',
  452. // bottom: 0,
  453. backgroundColor: '#fff',
  454. flexDirection: 'column',
  455. alignItems: 'center',
  456. justifyContent: 'flex-start'
  457. },
  458. payDialog: {
  459. width: '90%',
  460. borderTopWidth: 1,
  461. borderColor: '#e4e4e4',
  462. flexDirection: 'row',
  463. alignItems: 'center',
  464. justifyContent: 'space-between',
  465. flex: 1
  466. },
  467. dialogRow: {
  468. flex: 1,
  469. flexDirection: 'row',
  470. alignItems: 'center'
  471. },
  472. payIcon: {
  473. marginRight: 17
  474. },
  475. payText: {
  476. fontSize: 16,
  477. color: '#191919',
  478. alignContent: 'center',
  479. flex: 1,
  480. lineHeight: 50
  481. }
  482. });