index.js 8.2 KB

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