index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. import React, {useEffect, useState} from 'react';
  2. import {API, isMobile, showError, showInfo, showSuccess} from '../../helpers';
  3. import {renderNumber, renderQuota} from '../../helpers/render';
  4. import {Col, Layout, Row, Typography, Card, Button, Form, Divider, Space, Modal} from "@douyinfe/semi-ui";
  5. import Title from "@douyinfe/semi-ui/lib/es/typography/title";
  6. const TopUp = () => {
  7. const [redemptionCode, setRedemptionCode] = useState('');
  8. const [topUpCode, setTopUpCode] = useState('');
  9. const [topUpCount, setTopUpCount] = useState(10);
  10. const [minTopupCount, setMinTopUpCount] = useState(1);
  11. const [amount, setAmount] = useState(0.0);
  12. const [minTopUp, setMinTopUp] = useState(1);
  13. const [topUpLink, setTopUpLink] = useState('');
  14. const [enableOnlineTopUp, setEnableOnlineTopUp] = useState(false);
  15. const [userQuota, setUserQuota] = useState(0);
  16. const [isSubmitting, setIsSubmitting] = useState(false);
  17. const [open, setOpen] = useState(false);
  18. const [payWay, setPayWay] = useState('');
  19. const topUp = async () => {
  20. if (redemptionCode === '') {
  21. showInfo('请输入兑换码!')
  22. return;
  23. }
  24. setIsSubmitting(true);
  25. try {
  26. const res = await API.post('/api/user/topup', {
  27. key: redemptionCode
  28. });
  29. const {success, message, data} = res.data;
  30. if (success) {
  31. showSuccess('兑换成功!');
  32. Modal.success({title: '兑换成功!', content: '成功兑换额度:' + renderQuota(data), centered: true});
  33. setUserQuota((quota) => {
  34. return quota + data;
  35. });
  36. setRedemptionCode('');
  37. } else {
  38. showError(message);
  39. }
  40. } catch (err) {
  41. showError('请求失败');
  42. } finally {
  43. setIsSubmitting(false);
  44. }
  45. };
  46. const openTopUpLink = () => {
  47. if (!topUpLink) {
  48. showError('超级管理员未设置充值链接!');
  49. return;
  50. }
  51. window.open(topUpLink, '_blank');
  52. };
  53. const preTopUp = async (payment) => {
  54. if (!enableOnlineTopUp) {
  55. showError('管理员未开启在线充值!');
  56. return;
  57. }
  58. if (amount === 0) {
  59. await getAmount();
  60. }
  61. if (topUpCount < minTopUp) {
  62. showInfo('充值数量不能小于' + minTopUp);
  63. return;
  64. }
  65. setPayWay(payment)
  66. setOpen(true);
  67. }
  68. const onlineTopUp = async () => {
  69. if (amount === 0) {
  70. await getAmount();
  71. }
  72. if (topUpCount < minTopUp) {
  73. showInfo('充值数量不能小于' + minTopUp);
  74. return;
  75. }
  76. setOpen(false);
  77. try {
  78. const res = await API.post('/api/user/pay', {
  79. amount: parseInt(topUpCount),
  80. top_up_code: topUpCode,
  81. payment_method: payWay
  82. });
  83. if (res !== undefined) {
  84. const {message, data} = res.data;
  85. // showInfo(message);
  86. if (message === 'success') {
  87. let params = data
  88. let url = res.data.url
  89. let form = document.createElement('form')
  90. form.action = url
  91. form.method = 'POST'
  92. // 判断是否为safari浏览器
  93. let isSafari = navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") < 1;
  94. if (!isSafari) {
  95. form.target = '_blank'
  96. }
  97. for (let key in params) {
  98. let input = document.createElement('input')
  99. input.type = 'hidden'
  100. input.name = key
  101. input.value = params[key]
  102. form.appendChild(input)
  103. }
  104. document.body.appendChild(form)
  105. form.submit()
  106. document.body.removeChild(form)
  107. } else {
  108. showError(data);
  109. // setTopUpCount(parseInt(res.data.count));
  110. // setAmount(parseInt(data));
  111. }
  112. } else {
  113. showError(res);
  114. }
  115. } catch (err) {
  116. console.log(err);
  117. } finally {
  118. }
  119. }
  120. const getUserQuota = async () => {
  121. let res = await API.get(`/api/user/self`);
  122. const {success, message, data} = res.data;
  123. if (success) {
  124. setUserQuota(data.quota);
  125. } else {
  126. showError(message);
  127. }
  128. }
  129. useEffect(() => {
  130. let status = localStorage.getItem('status');
  131. if (status) {
  132. status = JSON.parse(status);
  133. if (status.top_up_link) {
  134. setTopUpLink(status.top_up_link);
  135. }
  136. if (status.min_topup) {
  137. setMinTopUp(status.min_topup);
  138. }
  139. if (status.enable_online_topup) {
  140. setEnableOnlineTopUp(status.enable_online_topup);
  141. }
  142. }
  143. getUserQuota().then();
  144. }, []);
  145. const renderAmount = () => {
  146. // console.log(amount);
  147. return amount + '元';
  148. }
  149. const getAmount = async (value) => {
  150. if (value === undefined) {
  151. value = topUpCount;
  152. }
  153. try {
  154. const res = await API.post('/api/user/amount', {
  155. amount: parseFloat(value),
  156. top_up_code: topUpCode
  157. });
  158. if (res !== undefined) {
  159. const {message, data} = res.data;
  160. // showInfo(message);
  161. if (message === 'success') {
  162. setAmount(parseFloat(data));
  163. } else {
  164. showError(data);
  165. // setTopUpCount(parseInt(res.data.count));
  166. // setAmount(parseInt(data));
  167. }
  168. } else {
  169. showError(res);
  170. }
  171. } catch (err) {
  172. console.log(err);
  173. } finally {
  174. }
  175. }
  176. const handleCancel = () => {
  177. setOpen(false);
  178. }
  179. return (
  180. <div>
  181. <Layout>
  182. <Layout.Header>
  183. <h3>我的钱包</h3>
  184. </Layout.Header>
  185. <Layout.Content>
  186. <Modal
  187. title="确定要充值吗"
  188. visible={open}
  189. onOk={onlineTopUp}
  190. onCancel={handleCancel}
  191. maskClosable={false}
  192. size={'small'}
  193. centered={true}
  194. >
  195. <p>充值数量:{topUpCount}$</p>
  196. <p>实付金额:{renderAmount()}</p>
  197. <p>是否确认充值?</p>
  198. </Modal>
  199. <div style={{marginTop: 20, display: 'flex', justifyContent: 'center'}}>
  200. <Card
  201. style={{width: '500px', padding: '20px'}}
  202. >
  203. <Title level={3} style={{textAlign: 'center'}}>余额 {renderQuota(userQuota)}</Title>
  204. <div style={{marginTop: 20}}>
  205. <Divider>
  206. 兑换余额
  207. </Divider>
  208. <Form>
  209. <Form.Input
  210. field={'redemptionCode'}
  211. label={'兑换码'}
  212. placeholder='兑换码'
  213. name='redemptionCode'
  214. value={redemptionCode}
  215. onChange={(value) => {
  216. setRedemptionCode(value);
  217. }}
  218. />
  219. <Space>
  220. {
  221. topUpLink ?
  222. <Button type={'primary'} theme={'solid'} onClick={openTopUpLink}>
  223. 获取兑换码
  224. </Button> : null
  225. }
  226. <Button type={"warning"} theme={'solid'} onClick={topUp}
  227. disabled={isSubmitting}>
  228. {isSubmitting ? '兑换中...' : '兑换'}
  229. </Button>
  230. </Space>
  231. </Form>
  232. </div>
  233. <div style={{marginTop: 20}}>
  234. <Divider>
  235. 在线充值
  236. </Divider>
  237. <Form>
  238. <Form.Input
  239. disabled={!enableOnlineTopUp}
  240. field={'redemptionCount'}
  241. label={'实付金额:' + renderAmount()}
  242. placeholder={'充值数量,最低' + minTopUp + '$'}
  243. name='redemptionCount'
  244. type={'number'}
  245. value={topUpCount}
  246. suffix={'$'}
  247. min={minTopUp}
  248. defaultValue={minTopUp}
  249. max={100000}
  250. onChange={async (value) => {
  251. if (value < 1) {
  252. value = 1;
  253. }
  254. if (value > 100000) {
  255. value = 100000;
  256. }
  257. setTopUpCount(value);
  258. await getAmount(value);
  259. }}
  260. />
  261. <Space>
  262. <Button type={'primary'} theme={'solid'} onClick={
  263. async () => {
  264. preTopUp('zfb')
  265. }
  266. }>
  267. 支付宝
  268. </Button>
  269. <Button style={{backgroundColor: 'rgba(var(--semi-green-5), 1)'}}
  270. type={'primary'}
  271. theme={'solid'} onClick={
  272. async () => {
  273. preTopUp('wx')
  274. }
  275. }>
  276. 微信
  277. </Button>
  278. </Space>
  279. </Form>
  280. </div>
  281. </Card>
  282. </div>
  283. </Layout.Content>
  284. </Layout>
  285. </div>
  286. );
  287. };
  288. export default TopUp;