buy.js 11 KB

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