index.js 8.4 KB

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