index.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. import React, { Component } from 'react';
  2. import './index.less';
  3. import Assets from '@src/components/Assets';
  4. import { formatMoney, formatDate } from '@src/services/Tools';
  5. import Modal from '../Modal';
  6. import Tabs from '../Tabs';
  7. import { SpecialRadioGroup } from '../Radio';
  8. import Invite from '../Invite';
  9. import Button from '../Button';
  10. import QrCode from '../QrCode';
  11. import { PayMVipEndModal } from '../PayModal';
  12. import { Main } from '../../stores/main';
  13. import { Order } from '../../stores/order';
  14. import { My } from '../../stores/my';
  15. import { User } from '../../stores/user';
  16. import { ServiceParamMap } from '../../../Constant';
  17. export default class extends Component {
  18. constructor(props) {
  19. super(props);
  20. this.state = { tab: '2', pay: '', select: null };
  21. }
  22. componentWillReceiveProps(nextProps) {
  23. if (nextProps.show && !this.init) {
  24. this.init = true;
  25. Main.getService('vip')
  26. .then(result => {
  27. result.package = result.package.map((row, index) => {
  28. row.label = `${row.title}: ¥${formatMoney(row.price)}`;
  29. row.value = ServiceParamMap.vip[index].value;
  30. return row;
  31. });
  32. this.setState({ service: result });
  33. });
  34. }
  35. }
  36. changeTab(key) {
  37. if (key === '1') {
  38. // 自动选择第一个
  39. this.select(ServiceParamMap.vip[0].value);
  40. }
  41. this.setState({ tab: key });
  42. }
  43. select(key) {
  44. Order.speedPay({ productType: 'service', service: 'vip', param: key }).then(result => {
  45. User.formatOrder(result);
  46. const [checkout] = result.checkouts;
  47. this.setState({ order: result, checkout });
  48. this.changePay('alipay');
  49. });
  50. this.setState({ select: key });
  51. }
  52. changePay(key) {
  53. const { order } = this.state;
  54. if (!order) return;
  55. this.setState({ payInfo: {}, pay: key });
  56. let handler = null;
  57. switch (key) {
  58. case 'wechatpay':
  59. handler = Order.wechatQr(order.id)
  60. .then((result) => {
  61. result.qr = Main.qrCode(result.request);
  62. this.setState({ payInfo: result });
  63. });
  64. break;
  65. case 'alipay':
  66. default:
  67. handler = Order.alipayQr(order.id)
  68. .then((result) => {
  69. result.qr = Main.qrCode(result.request);
  70. this.setState({ payInfo: result });
  71. });
  72. }
  73. handler.then(() => {
  74. this.queryPay();
  75. });
  76. }
  77. queryPay() {
  78. const { onClose, show } = this.props;
  79. const { order } = this.state;
  80. if (this.time) {
  81. clearTimeout(this.time);
  82. }
  83. this.time = setTimeout(() => {
  84. Order.query(order.id)
  85. .then(result => {
  86. if (result) {
  87. // 支付成功
  88. this.paySuccess();
  89. onClose();
  90. } else if (show) {
  91. this.queryPay();
  92. } else {
  93. this.setState({ tab: '2', select: null, pay: null, order: {}, checkout: {} });
  94. }
  95. });
  96. }, 1000);
  97. }
  98. paySuccess() {
  99. const { order } = this.state;
  100. const { data } = this.props;
  101. Order.getOrder(order.id).then(result => {
  102. User.formatOrder(result);
  103. // 确保开通用的是record记录id
  104. const [checkout] = result.checkouts;
  105. checkout.info.result = checkout.info.result.replace('{email}', data.email).replace('{useExpireDays}', checkout.useExpireDays).replace('{title}', checkout.title);
  106. if (checkout.service === 'vip') {
  107. // 查询最后有效期
  108. My.getVipInfo().then(vip => {
  109. checkout.info.result = checkout.info.result.replace('{endTime}', formatDate(vip.expireTime, 'YYYY-MM-DD'));
  110. User.refreshToken();
  111. this.setState({ show: false, showEnd: true, order: result, checkout });
  112. });
  113. } else {
  114. this.setState({ show: false, showEnd: true, order: result, checkout });
  115. }
  116. });
  117. }
  118. close() {
  119. const { onClose } = this.props;
  120. const { showEnd } = this.state;
  121. this.setState({ tab: '2', showEnd: false, select: null, pay: null, order: {}, checkout: {} });
  122. onClose(showEnd);
  123. }
  124. render() {
  125. const { show } = this.props;
  126. const { order, checkout, showEnd } = this.state;
  127. const { tab } = this.state;
  128. return [
  129. <Modal className="vip-renew-modal" show={show && !showEnd} width={630} title="VIP续期" onClose={() => this.close()}>
  130. <div className="vip-renew-wrapper">
  131. <Tabs
  132. border
  133. size="small"
  134. active={tab}
  135. width={80}
  136. tabs={[{ key: '1', title: '购买' }, { key: '2', title: '免费领取' }]}
  137. onChange={key => this.changeTab(key)}
  138. />
  139. {this[`renderTab${tab}`]()}
  140. </div>
  141. </Modal>,
  142. showEnd && <PayMVipEndModal show={showEnd} order={order} checkout={checkout} onConfirm={() => this.close()} />,
  143. ];
  144. }
  145. renderTab1() {
  146. const { pay, select, service = {}, order = {}, checkout = {}, payInfo = {} } = this.state;
  147. const { info = {} } = checkout;
  148. return (
  149. <div className="tab-1-layout">
  150. <div className="pay-modal-wrapper">
  151. <div className="select-layout">
  152. <SpecialRadioGroup
  153. list={service.package || []}
  154. value={select}
  155. width={100}
  156. space={10}
  157. onChange={key => this.select(key)}
  158. />
  159. <div className="info-layout">
  160. <div className="desc">
  161. 服务: {info.description}
  162. <br />
  163. 开通有效期: {checkout.expireDays ? `${checkout.expireDays}天` : '付款后立即生效'}
  164. <br />
  165. 使用有效期: {checkout.useExpireDays ? `${checkout.useExpireDays}天` : '永久'}
  166. <br />
  167. 退款政策: {info.refund_policy}
  168. <br />
  169. 版权说明: {info.copyright_notes}
  170. </div>
  171. <div className="money">
  172. <div className="t-2">应付金额:</div>
  173. <div className="t-1 f-w-b t-s-24">¥ {order.money}</div>
  174. </div>
  175. </div>
  176. </div>
  177. <div className="pay-layout">
  178. <Tabs
  179. border
  180. size="small"
  181. active={pay}
  182. width={80}
  183. tabs={[{ key: 'alipay', title: '支付宝' }, { key: 'wechatpay', title: '微信' }]}
  184. render={item => <Assets name={item.key} />}
  185. onChange={key => this.changePay(key)}
  186. />
  187. <div className="qrcode">
  188. <QrCode width={140} height={140} qrCode={payInfo.qr} refresh onRefresh={() => this.changePay(pay)} />
  189. </div>
  190. <div className="t">请使用手机微信或支付宝扫码付款</div>
  191. {order && <div className="t">支付金额: ¥ {order.money}</div>}
  192. </div>
  193. <div style={{ bottom: 20, left: 0 }} className="p-a t-3 t-s-14">
  194. *若在购买过程中遇到问题
  195. </div>
  196. <div style={{ bottom: 0, left: 0 }} className="p-a t-3 t-s-14">
  197. 请联系千行小助手:0193191safad 协助解决。
  198. </div>
  199. </div>
  200. </div>
  201. );
  202. }
  203. renderTab2() {
  204. const { data, onReal, onPrepare } = this.props;
  205. const { showInvite } = this.state;
  206. return (
  207. <div className="tab-2-layout">
  208. <div className="list">
  209. <div className="item">
  210. {data.bindReal && <span className="over">已完成</span>}
  211. <Assets className="icon" name={`realname2${data.bindReal ? '' : '_gray'}`} />
  212. <div className="t">
  213. <Assets name={data.bindReal ? 'gift_active' : 'gift'} />
  214. 6个月
  215. </div>
  216. <Button size="small" radius disabled={data.bindReal} onClick={() => {
  217. onReal();
  218. }}>
  219. 实名认证
  220. </Button>
  221. </div>
  222. <div className="item">
  223. <Assets className="icon" name={`invite${data.inviteNumber > 0 ? '' : '_gray'}`} />
  224. <div className="t">
  225. <Assets name={data.inviteNumber > 0 ? 'gift_active' : 'gift'} />
  226. {data.inviteNumber > 0 ? `7天 X ${data.inviteNumber}位好友` : '7天/每位好友'}
  227. </div>
  228. <Button size="small" radius onClick={() => {
  229. this.setState({ showInvite: true });
  230. }}>
  231. 邀请好友
  232. </Button>
  233. </div>
  234. <div className="item">
  235. {data.bindPrepare && <span className="over">已完成</span>}
  236. <Assets className="icon" name={`information2${data.bindPrepare ? '' : '_gray'}`} />
  237. <div className="t">
  238. <Assets name={data.bindPrepare ? 'gift_active' : 'gift'} />
  239. 1个月
  240. </div>
  241. <Button size="small" radius disabled={data.bindPrepare} onClick={() => {
  242. onPrepare();
  243. }}>
  244. 完善信息
  245. </Button>
  246. </div>
  247. </div>
  248. {showInvite && <Invite data={data} />}
  249. </div>
  250. );
  251. }
  252. }