WWithdrawRecord.jsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. import styles from './styles.module.scss';
  2. import {useDispatch, useSelector} from "react-redux";
  3. import {getWithdrawRecord, getWithdrawRecordStatus} from "@features/paySlice";
  4. import React, {useEffect, useState} from "react";
  5. import {REQ_STATUS} from "@api/config";
  6. import SmallLoading from "@components/SmallLoading";
  7. import Spring from "@components/Spring";
  8. import {formatCash, formatDate} from "@utils/helpers";
  9. import {CopyToClipboard} from "react-copy-to-clipboard";
  10. import {toast} from "react-toastify";
  11. import SvgIcon from "@components/SvgIcon";
  12. import Popup from "@components/Popup";
  13. import {ReactComponent as SuccssLogo} from '@assets/singlesvg/succss.svg';
  14. import {ReactComponent as PendingLogo} from '@assets/singlesvg/pending.svg';
  15. import {ReactComponent as FailedLogo} from '@assets/singlesvg/failed.svg';
  16. import {ReactComponent as PixLogo} from '@assets/singlesvg/pix.svg';
  17. import {reqWithdrawRecord} from "@features/api";
  18. const i18n=global.i18n;
  19. const stateType = {
  20. ERROR: -1, // 订单错误
  21. CHECKING: 1, // 审核中
  22. SUCCESS: 2, // 提现成功
  23. FAIL: 3, // 提现失败
  24. RECALL: 4, // 订单撤回
  25. PROCESSING: 5, // 处理中
  26. TTP_ERROR: 6, // 三方订单异常
  27. };
  28. const WWithdrawRecord=({close})=>{
  29. const status=useSelector(getWithdrawRecordStatus);
  30. const recordList=useSelector(getWithdrawRecord);
  31. const [showDetails,setShowDetails]=useState(false);
  32. const [detailInfo,setDetailInfo]=useState(null);
  33. const dispatch =useDispatch();
  34. useEffect(()=>{
  35. dispatch(reqWithdrawRecord())
  36. },[])
  37. const getStateTxt=(state)=>{
  38. state=parseInt(state);
  39. switch(state) {
  40. case stateType.CHECKING: {
  41. return i18n.t("withdraw.record.wait");
  42. }
  43. case stateType.SUCCESS: {
  44. return i18n.t("withdraw.record.success");
  45. }
  46. case stateType.PROCESSING: {
  47. return i18n.t("withdraw.record.processing");
  48. }
  49. case stateType.ERROR:
  50. case stateType.FAIL:
  51. case stateType.TTP_ERROR:
  52. case stateType.RECALL: {
  53. return i18n.t("withdraw.record.fail");
  54. }
  55. default: return "error";
  56. }
  57. }
  58. const getStateCls=(state)=>{
  59. state=parseInt(state);
  60. switch(state) {
  61. case stateType.PROCESSING:
  62. case stateType.CHECKING: {
  63. return styles.status_pending;
  64. }
  65. case stateType.SUCCESS: {
  66. return styles.status_success;
  67. }
  68. case stateType.ERROR:
  69. case stateType.FAIL:
  70. case stateType.RECALL: {
  71. return styles.status_failed;
  72. }
  73. default: return styles.status_pending;
  74. }
  75. }
  76. const getStateLogo=(state)=>{
  77. state=parseInt(state);
  78. switch(state) {
  79. case stateType.PROCESSING:
  80. case stateType.CHECKING: {
  81. return PendingLogo;
  82. }
  83. case stateType.SUCCESS: {
  84. return SuccssLogo;
  85. }
  86. case stateType.ERROR:
  87. case stateType.FAIL:
  88. case stateType.RECALL: {
  89. return FailedLogo;
  90. }
  91. default: return PendingLogo;
  92. }
  93. }
  94. const renderContent=()=>{
  95. if (status===REQ_STATUS.LOADING)return (<SmallLoading></SmallLoading>);
  96. if (recordList==null)return (<></>);
  97. return (
  98. <Spring type="slideUp" className={styles.content}>
  99. {
  100. recordList.map((item,index)=>{
  101. let amount=Number(item.WithDraw)+Number(item.ServiceFee);
  102. let amount_str=global.DOLLAR+formatCash(amount);
  103. // let time_str=formatDate(item.CreateDate*1000);
  104. let time_str=item.CreateDate.split(".")[0];
  105. let statusTxt=getStateTxt(item.State);
  106. let status_cls=getStateCls(item.State);
  107. return (
  108. <button key={index} className={styles.item_con} onClick={()=>{
  109. setDetailInfo(item);
  110. setShowDetails(true);
  111. }}>
  112. <div className={styles.item}>
  113. <div className={`${styles.pay_type_con} ${styles.title}`}>
  114. <PixLogo className={styles.logo}></PixLogo>
  115. PIX
  116. </div>
  117. <div className={styles.title}>
  118. {amount_str}
  119. </div>
  120. </div>
  121. <div className={styles.item}>
  122. <div>{time_str}</div>
  123. </div>
  124. <div className={styles.item}>
  125. <CopyToClipboard text={item.OrderId} onCopy={() => {
  126. toast.success(i18n.t("copy_success"));
  127. }}>
  128. <div className={styles.payment_sn_con} onClick={(event) => {
  129. event.stopPropagation();
  130. }}>
  131. {item.OrderId}
  132. <SvgIcon className={styles.logo} herf={"icon_Copy"}/>
  133. </div>
  134. </CopyToClipboard>
  135. <div className={status_cls}>
  136. {statusTxt}
  137. </div>
  138. </div>
  139. </button>
  140. )
  141. })
  142. }
  143. </Spring>
  144. )
  145. }
  146. const renderDetails=()=>{
  147. let item=detailInfo;
  148. if (item==null)return (<></>);
  149. let ExchangeScore=Number(item.WithDraw);
  150. let Fee=Number(item.ServiceFee);
  151. let amount=ExchangeScore+Fee;
  152. let amount_str=global.DOLLAR+formatCash(amount);
  153. let status=parseInt(item.State);
  154. let statusTxt=getStateTxt(status);
  155. let status_cls=getStateCls(status);
  156. let Logo=getStateLogo(status);
  157. let time_str=item.CreateDate.split(".")[0];
  158. return (
  159. <Popup onClose={()=>{
  160. setShowDetails(false)
  161. }} open={showDetails}>
  162. <div className={styles.detail}>
  163. <div className={styles.top}>
  164. <div>{i18n.t("withdraw.record.detail_title")}</div>
  165. <div className={styles.status}>
  166. <Logo className={styles.logo}></Logo>
  167. <div className={status_cls}>
  168. {statusTxt}
  169. </div>
  170. </div>
  171. <div>{amount_str}</div>
  172. </div>
  173. <div className={styles.line}></div>
  174. <div className={styles.bottom}>
  175. <div className={styles.item}>
  176. <div
  177. className={styles.label}>{i18n.t("withdraw.record.exchage")}</div>
  178. <div>{global.DOLLAR + formatCash(ExchangeScore)}</div>
  179. </div>
  180. <div className={styles.item}>
  181. <div
  182. className={styles.label}>{i18n.t("withdraw.record.fee")}</div>
  183. <div>{global.DOLLAR + formatCash(Fee)}</div>
  184. </div>
  185. <div className={styles.item}>
  186. <div
  187. className={styles.label}>{i18n.t("withdraw.record.time")}</div>
  188. <div>{time_str}</div>
  189. </div>
  190. <div className={styles.item}>
  191. <div
  192. className={styles.label}>{i18n.t("withdraw.record.orderId")}</div>
  193. <CopyToClipboard text={item.OrderId} onCopy={() => {
  194. toast.success(i18n.t("copy_success"));
  195. }}>
  196. <div className={styles.number}>
  197. {item.OrderId}
  198. <SvgIcon className={styles.logo} herf={"icon_Copy"}/>
  199. </div>
  200. </CopyToClipboard>
  201. </div>
  202. </div>
  203. <div className={styles.line}></div>
  204. <button className={"button-green"} onClick={() => {
  205. setShowDetails(false);
  206. }}>
  207. {i18n.t("deposit.HistoryListPanel.details.btn_confirm")}
  208. </button>
  209. </div>
  210. </Popup>
  211. )
  212. }
  213. return (
  214. <div className={styles.container}>
  215. {renderContent()}
  216. {renderDetails()}
  217. </div>
  218. )
  219. }
  220. export default WWithdrawRecord;