index.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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. this.setState({ payInfo: result });
  70. });
  71. }
  72. handler.then(() => {
  73. this.queryPay();
  74. });
  75. }
  76. queryPay() {
  77. const { onClose, show } = this.props;
  78. const { order } = this.state;
  79. if (this.time) {
  80. clearTimeout(this.time);
  81. }
  82. this.time = setTimeout(() => {
  83. Order.query(order.id)
  84. .then(result => {
  85. if (result) {
  86. // 支付成功
  87. this.paySuccess();
  88. onClose();
  89. } else if (show) {
  90. this.queryPay();
  91. } else {
  92. this.setState({ tab: '2', select: null, pay: null, order: {}, checkout: {} });
  93. }
  94. });
  95. }, 1000);
  96. }
  97. paySuccess() {
  98. const { order } = this.state;
  99. const { data } = this.props;
  100. Order.getOrder(order.id).then(result => {
  101. User.formatOrder(result);
  102. // 确保开通用的是record记录id
  103. const [checkout] = result.checkouts;
  104. checkout.info.result = checkout.info.result.replace('{email}', data.email).replace('{useExpireDays}', checkout.useExpireDays).replace('{title}', checkout.title);
  105. if (checkout.service === 'vip') {
  106. // 查询最后有效期
  107. My.getVipInfo().then(vip => {
  108. checkout.info.result = checkout.info.result.replace('{endTime}', formatDate(vip.expireTime, 'YYYY-MM-DD'));
  109. this.setState({ show: false, showEnd: true, order: result, checkout });
  110. });
  111. } else {
  112. this.setState({ show: false, showEnd: true, order: result, checkout });
  113. }
  114. });
  115. }
  116. close() {
  117. const { onClose } = this.props;
  118. this.setState({ tab: '2', showEnd: false, select: null, pay: null, order: {}, checkout: {} });
  119. onClose();
  120. }
  121. render() {
  122. const { show } = this.props;
  123. const { order, checkout, showEnd } = this.state;
  124. const { tab } = this.state;
  125. return [
  126. <Modal className="vip-renew-modal" show={show && !showEnd} width={630} title="VIP续期" onClose={() => this.close()}>
  127. <div className="vip-renew-wrapper">
  128. <Tabs
  129. border
  130. size="small"
  131. active={tab}
  132. width={80}
  133. tabs={[{ key: '1', title: '购买' }, { key: '2', title: '免费领取' }]}
  134. onChange={key => this.changeTab(key)}
  135. />
  136. {this[`renderTab${tab}`]()}
  137. </div>
  138. </Modal>,
  139. showEnd && <PayMVipEndModal show={showEnd} order={order} checkout={checkout} onConfirm={() => this.close()} />,
  140. ];
  141. }
  142. renderTab1() {
  143. const { pay, select, service = {}, order = {}, checkout = {}, payInfo = {} } = this.state;
  144. const { info = {} } = checkout;
  145. return (
  146. <div className="tab-1-layout">
  147. <div className="pay-modal-wrapper">
  148. <div className="select-layout">
  149. <SpecialRadioGroup
  150. list={service.package || []}
  151. value={select}
  152. width={100}
  153. space={10}
  154. onChange={key => this.select(key)}
  155. />
  156. <div className="info-layout">
  157. <div className="desc">
  158. 服务: {info.description}
  159. <br />
  160. 开通有效期: {checkout.expireDays ? `${checkout.expireDays}天` : '付款后立即生效'}
  161. <br />
  162. 使用有效期: {checkout.useExpireDays ? `${checkout.useExpireDays}天` : '永久'}
  163. <br />
  164. 退款政策: {info.refund_policy}
  165. <br />
  166. 版权说明: {info.copyright_notes}
  167. </div>
  168. <div className="money">
  169. <div className="t-2">应付金额:</div>
  170. <div className="t-1 f-w-b t-s-24">¥ {order.money}</div>
  171. </div>
  172. </div>
  173. </div>
  174. <div className="pay-layout">
  175. <Tabs
  176. border
  177. size="small"
  178. active={pay}
  179. width={80}
  180. tabs={[{ key: 'alipay', title: '支付宝' }, { key: 'wechatpay', title: '微信' }]}
  181. render={item => <Assets name={item.key} />}
  182. onChange={key => this.changePay(key)}
  183. />
  184. <div className="qrcode">
  185. <QrCode width={140} height={140} qrCode={payInfo.qr} refresh />
  186. </div>
  187. <div className="t">请使用手机微信或支付宝扫码付款</div>
  188. {order && <div className="t">支付金额: ¥ {order.money}</div>}
  189. </div>
  190. <div style={{ bottom: 20, left: 0 }} className="p-a t-3 t-s-14">
  191. *若在购买过程中遇到问题
  192. </div>
  193. <div style={{ bottom: 0, left: 0 }} className="p-a t-3 t-s-14">
  194. 请联系千行小助手:0193191safad 协助解决。
  195. </div>
  196. </div>
  197. </div>
  198. );
  199. }
  200. renderTab2() {
  201. const { data, onReal, onPrepare } = this.props;
  202. const { showInvite } = this.state;
  203. return (
  204. <div className="tab-2-layout">
  205. <div className="list">
  206. <div className="item">
  207. {data.bindReal && <span className="over">已完成</span>}
  208. <Assets className="icon" name={`realname2${data.bindReal ? '' : '_gray'}`} />
  209. <div className="t">
  210. <Assets name="gift" />
  211. 6个月
  212. </div>
  213. <Button size="small" radius disabled={data.bindReal} onClick={() => {
  214. onReal();
  215. }}>
  216. 实名认证
  217. </Button>
  218. </div>
  219. <div className="item">
  220. <Assets className="icon" name={`invite${data.inviteNumber > 0 ? '' : '_gray'}`} />
  221. <div className="t">
  222. <Assets name="gift" />
  223. {data.inviteNumber > 0 ? `7天 X ${data.inviteNumber}位好友` : '7天/每位好友'}
  224. </div>
  225. <Button size="small" radius onClick={() => {
  226. this.setState({ showInvite: true });
  227. }}>
  228. 邀请好友
  229. </Button>
  230. </div>
  231. <div className="item">
  232. {data.bindPrepare && <span className="over">已完成</span>}
  233. <Assets className="icon" name={`information2${data.bindPrepare ? '' : '_gray'}`} />
  234. <div className="t">
  235. <Assets name="gift" />
  236. 1个月
  237. </div>
  238. <Button size="small" radius disabled={data.bindPrepare} onClick={() => {
  239. onPrepare();
  240. }}>
  241. 完善信息
  242. </Button>
  243. </div>
  244. </div>
  245. {showInvite && <Invite data={data} />}
  246. </div>
  247. );
  248. }
  249. }