index.js 8.3 KB

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