index.js 15 KB

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