index.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. import React, { Component } from 'react';
  2. import './index.less';
  3. import { Checkbox, Icon } from 'antd';
  4. import Assets from '@src/components/Assets';
  5. import { formatDate } from '@src/services/Tools';
  6. import Tabs from '../Tabs';
  7. import Modal from '../Modal';
  8. import { Order } from '../../stores/order';
  9. import { Main } from '../../stores/main';
  10. import { My } from '../../stores/my';
  11. import { User } from '../../stores/user';
  12. export class PayModal extends Component {
  13. constructor(props) {
  14. super(props);
  15. this.state = { show: true };
  16. Main.getContract('course')
  17. .then((result) => {
  18. this.setState({ contract: result });
  19. });
  20. }
  21. changePay(key) {
  22. const { order } = this.props.user;
  23. if (!order) return;
  24. this.setState({ info: {}, pay: key });
  25. let handler = null;
  26. switch (key) {
  27. case 'wechatpay':
  28. handler = Order.wechatQr(order.id)
  29. .then((result) => {
  30. this.setState({ info: result });
  31. });
  32. break;
  33. case 'alipay':
  34. handler = Order.alipayQr(order.id)
  35. .then((result) => {
  36. this.setState({ info: result });
  37. });
  38. break;
  39. default:
  40. return;
  41. }
  42. handler.then(() => {
  43. this.queryPay();
  44. });
  45. }
  46. queryPay(force) {
  47. const { order, needPay } = this.props.user;
  48. if (this.time) {
  49. clearTimeout(this.time);
  50. }
  51. if (force) {
  52. this.times = 0;
  53. } else {
  54. this.times = (this.times || 0) + 1;
  55. }
  56. this.time = setTimeout(() => {
  57. Order.query(order.id)
  58. .then(result => {
  59. if (result) {
  60. // 支付成功
  61. this.paySuccess();
  62. } else if (needPay) {
  63. this.queryPay();
  64. } else {
  65. this.setState({ select: null, pay: null, order: null, info: null });
  66. }
  67. });
  68. }, 1000);
  69. }
  70. paySuccess() {
  71. const { order } = this.props.user;
  72. const { info } = this.props.user;
  73. Order.getOrder(order.id).then(result => {
  74. User.formatOrder(result);
  75. // 确保开通用的是record记录id
  76. const [checkout] = result.checkouts;
  77. checkout.info.result = checkout.info.result.replace('{email}', info.email).replace('{useExpireDays}', checkout.useExpireDays).replace('{title}', checkout.title);
  78. if (checkout.service === 'vip') {
  79. // 查询最后有效期
  80. My.getVipInfo().then(vip => {
  81. checkout.info.result = checkout.info.result.replace('{endTime}', formatDate(vip.expireTime, 'YYYY-MM-DD'));
  82. this.setState({ show: false, showVipEnd: true, order: result, checkout });
  83. });
  84. } else if (order.checkouts.length === 1 && checkout.productType === 'data') {
  85. this.setState({ show: false, showDataEnd: true, order: result, checkout });
  86. } else if (order.checkouts.length === 1) {
  87. this.setState({ show: false, showEnd: true, order: result, checkout });
  88. } else {
  89. User.closePay();
  90. }
  91. });
  92. }
  93. confirm() {
  94. const { pay } = this.state;
  95. if (pay === 'bank') {
  96. this.setState({ showBank: true, show: false });
  97. } else {
  98. //
  99. }
  100. }
  101. open() {
  102. const { checkout } = this.state;
  103. Order.useRecord(checkout.id)
  104. .then(() => {
  105. User.closePay();
  106. this.setState({ show: true, pay: null });
  107. });
  108. }
  109. read() {
  110. User.closePay();
  111. linkTo('/my/data');
  112. }
  113. close() {
  114. const { showEnd, showBank } = this.state;
  115. User.closePay(showEnd || showBank ? null : new Error('支付失败'));
  116. this.setState({ show: true, pay: null, showEnd: false, showBank: false });
  117. }
  118. render() {
  119. const { needPay, order } = this.props.user;
  120. const { show, showBank, showEnd, showDataEnd, showVipEnd, contract } = this.state;
  121. if (!needPay) return [];
  122. return [
  123. showBank && <PayKBankModal
  124. show
  125. order={order}
  126. checkout={order.checkouts[0]}
  127. onConfirm={() => this.close()}
  128. />,
  129. showEnd && <PayMEndModal
  130. show
  131. order={order}
  132. checkout={order.checkouts[0]}
  133. onCancel={() => this.close()}
  134. onClose={() => this.close()}
  135. onConfirm={() => this.open()}
  136. />,
  137. showDataEnd && <PayMDataEndModal
  138. show
  139. order={order}
  140. checkout={order.checkouts[0]}
  141. onCancel={() => this.close()}
  142. onClose={() => this.close()}
  143. onConfirm={() => this.read()}
  144. />,
  145. showVipEnd && <PayMVipEndModal
  146. show
  147. order={order}
  148. checkout={order.checkouts[0]}
  149. onConfirm={() => this.close()}
  150. />,
  151. show && order.checkouts.length > 1 && <PayMutilModal
  152. show
  153. contract={contract}
  154. order={order}
  155. onChangePay={(key) => this.changePay(key)}
  156. onCancel={() => this.close()}
  157. onClose={() => this.close()}
  158. onConfirm={() => this.confirm()}
  159. />,
  160. show && order.checkouts.length === 1 && <PayMModal
  161. show
  162. contract={contract}
  163. order={order}
  164. checkout={order.checkouts[0]}
  165. productType={order.productTypes[0]}
  166. onChangePay={(key) => this.changePay(key)}
  167. onCancel={() => this.close()}
  168. onClose={() => this.close()}
  169. onConfirm={() => this.confirm()}
  170. />,
  171. ];
  172. }
  173. }
  174. export class PayMModal extends Component {
  175. constructor(props) {
  176. super(props);
  177. const payList = [{ key: 'alipay', title: '支付宝' }, { key: 'wechatpay', title: '微信' }];
  178. if (props.productType === 'course') {
  179. payList.push({ key: 'bank', title: '银行转账' });
  180. }
  181. this.state = { pay: 'alipay', payList, checked: true, showChecked: props.productType === 'course' };
  182. setTimeout(() => {
  183. props.onChangePay('alipay');
  184. }, 100);
  185. }
  186. render() {
  187. const { show, checkout, onClose, onConfirm, onChangePay, order, contract = {}, productType } = this.props;
  188. const { info } = checkout;
  189. const { pay, payList, checked, showChecked } = this.state;
  190. return (
  191. <Modal
  192. className="pay-modal"
  193. show={show}
  194. width={760}
  195. title={`购买${checkout.title}`}
  196. confirmText={pay === 'bank' ? '确认' : '支付成功'}
  197. onConfirm={pay === 'bank' ? onConfirm : null}
  198. // cancelText="稍后开通"
  199. // onCancel={onCancel}
  200. onClose={onClose}
  201. >
  202. <div className="pay-modal-wrapper">
  203. <div className="info-layout">
  204. <div className="desc">
  205. 商品: {productType === 'data' ? info.title : checkout.title}<br />
  206. 服务: {productType === 'data' ? checkout.title : info.description}<br />
  207. 开通有效期: {checkout.expireDays ? `${checkout.expireDays}天` : '付款后立即生效'}
  208. <br />
  209. 使用有效期: {checkout.useExpireDays ? `${checkout.useExpireDays}天` : '永久'}
  210. <br />
  211. 退款政策: {info.refund_policy}
  212. <br />
  213. 版权说明: {info.copyright_notes}
  214. </div>
  215. <div className="money">
  216. <div className="t-2">应付金额:</div>
  217. <div className="t-1 f-w-b t-s-24">¥ {order.money}</div>
  218. </div>
  219. </div>
  220. <div className="pay-layout">
  221. <Tabs
  222. border
  223. size="small"
  224. active={pay}
  225. width={80}
  226. tabs={payList}
  227. render={item => <Assets name={item.key} />}
  228. onChange={key => {
  229. this.setState({ pay: key });
  230. onChangePay(key);
  231. }}
  232. />
  233. <div hidden={pay === 'bank'} className="pay">
  234. <div className="qrcode">
  235. <Assets name="qrcode" src={checked ? '' : '模糊'} />
  236. </div>
  237. <div className="t">请使用手机微信或支付宝扫码付款</div>
  238. <div className="t">支付金额: ¥ {order.money}</div>
  239. </div>
  240. <div hidden={pay !== 'bank'} className="bank">
  241. <div className="t">汇款银行:中国工商银行上海市浦东支行</div>
  242. <div className="t">汇款账号:6100 0000 0000 000</div>
  243. </div>
  244. <div className="agree" hidden={!showChecked}>
  245. <Checkbox className="m-r-1" checked={checked} onClick={() => {
  246. this.setState({ showChecked: checked, checked: !checked });
  247. }} />
  248. 我已阅读并同意<a href={`/contract/${contract.key}`} target="_blank">{contract.title}</a>
  249. </div>
  250. </div>
  251. <div style={{ bottom: 20, left: 0 }} className="p-a t-3 t-s-14">
  252. *若在购买过程中遇到问题
  253. </div>
  254. <div style={{ bottom: 0, left: 0 }} className="p-a t-3 t-s-14">
  255. 请联系千行小助手:0193191safad 协助解决。
  256. </div>
  257. </div>
  258. </Modal>
  259. );
  260. }
  261. }
  262. export class PayMutilModal extends Component {
  263. constructor(props) {
  264. super(props);
  265. this.state = { pay: 'alipay', checked: true, showChecked: true };
  266. setTimeout(() => {
  267. props.onChangePay('alipay');
  268. }, 100);
  269. }
  270. render() {
  271. const { show, onConfirm, onClose, onChangePay, order, contract = {} } = this.props;
  272. const { pay, checked, showChecked } = this.state;
  273. return (
  274. <Modal
  275. className="pay-modal"
  276. show={show}
  277. width={760}
  278. title={'购物车结账'}
  279. confirmText={pay === 'bank' ? '确认' : '支付成功'}
  280. onConfirm={pay === 'bank' ? onConfirm : null}
  281. // onCancel={onCancel}
  282. onClose={onClose}
  283. >
  284. <div className="pay-modal-wrapper">
  285. <div className="info-layout">
  286. <div className="desc">
  287. 商品: 购物车结账<br />
  288. 服务: 见<a href={`/contract/${contract.key}`} target="_blank">{contract.title}</a><br />
  289. 开通有效期: 见订单详情
  290. <br />
  291. 使用有效期: 见订单详情
  292. <br />
  293. 退款政策: 本商品为虚拟产品,购买成功后不支持退款。<br />
  294. 版权说明: 本商品为虚拟产品,购买成功后不支持退款。
  295. </div>
  296. <div className="money">
  297. <div className="t-2">应付金额:</div>
  298. <div className="t-1 f-w-b t-s-24">¥ {order.money}</div>
  299. </div>
  300. </div>
  301. <div className="pay-layout">
  302. <Tabs
  303. border
  304. size="small"
  305. active={pay}
  306. width={80}
  307. tabs={[
  308. { key: 'alipay', title: '支付宝' },
  309. { key: 'wechatpay', title: '微信' },
  310. { key: 'bank', title: '银行转账' },
  311. ]}
  312. render={item => <Assets name={item.key} />}
  313. onChange={key => {
  314. this.setState({ pay: key });
  315. onChangePay(key);
  316. }}
  317. />
  318. <div hidden={pay === 'bank'} className="pay">
  319. <div className="qrcode">
  320. <Assets name="qrcode" src={checked ? '' : '模糊'} />
  321. </div>
  322. <div className="t">请使用手机微信或支付宝扫码付款</div>
  323. <div className="t">支付金额: ¥ {order.money}</div>
  324. </div>
  325. <div hidden={pay !== 'bank'} className="bank">
  326. <div className="t">汇款银行:中国工商银行上海市浦东支行</div>
  327. <div className="t">汇款账号:6100 0000 0000 000</div>
  328. </div>
  329. <div className="agree" hidden={!showChecked}>
  330. <Checkbox className="m-r-1" checked={checked} onClick={() => {
  331. this.setState({ showChecked: checked, checked: !checked });
  332. }} />
  333. 我已阅读并同意<a href={`/contract/${contract.key}`} target="_blank">{contract.title}</a>
  334. </div>
  335. </div>
  336. <div style={{ bottom: 20, left: 0 }} className="p-a t-3 t-s-14">
  337. *若在购买过程中遇到问题
  338. </div>
  339. <div style={{ bottom: 0, left: 0 }} className="p-a t-3 t-s-14">
  340. 请联系千行小助手:0193191safad 协助解决。
  341. </div>
  342. </div>
  343. </Modal>
  344. );
  345. }
  346. }
  347. export class PayKBankModal extends Component {
  348. render() {
  349. const { show, onConfirm } = this.props;
  350. return (
  351. <Modal
  352. show={show}
  353. width={630}
  354. title="银行汇款"
  355. btnAlign="center"
  356. confirmText="好的,知道了"
  357. onConfirm={onConfirm}
  358. >
  359. <div style={{ width: 400 }} className="t-2 t-s-18 m-b-2">
  360. 汇款成功后,请添加微信号XXX或扫描二维码联系小助手,进行核实。
  361. </div>
  362. <div className="p-a" style={{ right: 0, top: 50 }}>
  363. <Assets name="qrcode" />
  364. </div>
  365. </Modal>
  366. );
  367. }
  368. }
  369. export class PayMEndModal extends Component {
  370. render() {
  371. const { show, onConfirm, onCancel, checkout = {} } = this.props;
  372. const { info } = checkout;
  373. return (
  374. <Modal
  375. show={show}
  376. width={630}
  377. title="付款成功"
  378. confirmText="立即开通"
  379. cancelText="稍后开通"
  380. onConfirm={onConfirm}
  381. onCancel={onCancel}
  382. >
  383. <div className="t-2 ws-pl">
  384. <Icon className="t-5 m-r-5" type="check" />{info.result}
  385. </div>
  386. {info.tips && <div style={{ bottom: 10, left: 0 }} className="p-a t-3 t-s-14">
  387. *{info.tips}
  388. </div>}
  389. </Modal>
  390. );
  391. }
  392. }
  393. export class PayMDataEndModal extends Component {
  394. render() {
  395. const { show, onConfirm, onCancel, checkout = {} } = this.props;
  396. const { info } = checkout;
  397. return (
  398. <Modal
  399. show={show}
  400. width={630}
  401. title="付款成功"
  402. confirmText="立即查看"
  403. cancelText="暂不查看"
  404. onConfirm={onConfirm}
  405. onCancel={onCancel}
  406. >
  407. <div className="t-2 ws-pl">
  408. <Icon className="t-5 m-r-5" type="check" />{info.result}
  409. </div>
  410. {info.tips && <div style={{ bottom: 10, left: 0 }} className="p-a t-3 t-s-14">
  411. *{info.tips}
  412. </div>}
  413. </Modal>
  414. );
  415. }
  416. }
  417. export class PayMVipEndModal extends Component {
  418. render() {
  419. const { show, onConfirm, checkout = {} } = this.props;
  420. const { info } = checkout;
  421. return (
  422. <Modal
  423. show={show}
  424. width={630}
  425. title="付款成功"
  426. confirmText="知道了"
  427. // cancelText="稍后开通"
  428. onConfirm={onConfirm}
  429. // onCancel={onCancel}
  430. >
  431. <div className="t-2 ws-pl">
  432. <Icon className="t-5 m-r-5" type="check" />{info.result}
  433. </div>
  434. {info.tips && <div style={{ bottom: 10, left: 0 }} className="p-a t-3 t-s-14">
  435. *{info.tips}
  436. </div>}
  437. </Modal>
  438. );
  439. }
  440. }