zhejiushizhuce 2 年之前
父节点
当前提交
c4c213bb18

+ 4 - 1
src/api/config.js

@@ -125,4 +125,7 @@ export const APP_PROTECT_CHECK=BASE_PREFIX+"protect/check";
 export const APP_PROTECT_GET=BASE_PREFIX+"protect/get";
 
 //apk load
-export const APP_APK_LOADNEW=BASE_PREFIX+"apk/loadnew"
+export const APP_APK_LOADNEW=BASE_PREFIX+"apk/loadnew";
+
+//save cpf
+export const APP_SAVE_CPF=BASE_PREFIX+"withDraw/savecpf";

二进制
src/assets/pay/cpf_card.png


+ 18 - 3
src/features/api.js

@@ -37,7 +37,7 @@ import {
     APP_REDPACK_CONFIG,
     APP_REDPACK_RECEIVE,
     APP_REGISTER,
-    APP_ROUTES,
+    APP_ROUTES, APP_SAVE_CPF,
     APP_SEND_CODE,
     APP_SMS_LOGIN,
     APP_TURNPLATE_BONUS,
@@ -334,7 +334,7 @@ export const reqGetAccountsPayInfo=createAsyncThunk(
 export const reqPaymentOrder=createAsyncThunk(
     APP_PAYMENT_ORDER,
     async (arg,thunkAPI)=>{
-        let {user,price,goodsName,payType,GiftsID,eventType}=arg;
+        let {user,price,goodsName,payType,GiftsID,eventType,cpf_first}=arg;
         let params={
             url:APP_PAYMENT_ORDER,
             params:{
@@ -351,7 +351,8 @@ export const reqPaymentOrder=createAsyncThunk(
                 userName:user.NickName,
                 userEmail:user.Email,
                 userPhone:user.Phone,
-                rand_str:Date.now()
+                rand_str:Date.now(),
+                cpf_first:cpf_first?cpf_first:0
             }
         }
         const response=await Http.get(params);
@@ -372,6 +373,20 @@ export const reqPayOrderList=createAsyncThunk(
         return response;
     }
 )
+//save cpf
+export const reqCPFSave=createAsyncThunk(
+    APP_SAVE_CPF,
+    async (arg,thunkAPI)=>{
+        let params= {
+            url: APP_SAVE_CPF,
+            params:{
+                PixNum:arg.PixNum
+            }
+        }
+        const response=await Http.get(params);
+        return response;
+    }
+)
 //pay
 //withdraw
 export const reqWithdrawTax=createAsyncThunk(

+ 30 - 2
src/features/paySlice.js

@@ -2,7 +2,7 @@ import {createSlice} from "@reduxjs/toolkit";
 import {REQ_STATUS} from "@api/config";
 import {
     buildReqReducer,
-    reqChangePayPass,
+    reqChangePayPass, reqCPFSave,
     reqFirstPayConfig, reqForgetPayPass,
     reqGetAccountsPayInfo, reqMexWithdrawSetInfo,
     reqPaymentOrder,
@@ -25,6 +25,7 @@ const reducerRechargeConfig=(state,action,arg)=>{
         if (data.list){
             state.config=data.list;
             state.showBonus=data.bonus_show;
+            state.cpfFirst=data.cpf_first;
             // state.showBonus=true;
         }
     }
@@ -231,6 +232,24 @@ const reducerWithdrawPayout=(state,action,arg)=>{
 const withdrawPayoutStatus=(state,status,arg)=>{
     state.status.WithdrawPayout=status;
 }
+const reducerSaveCPF=(state,action,arg)=>{
+    let payload=action.payload;
+    let msg=getHttpMsg(payload);
+    if (payload&&payload.code===200){
+        state.cpfFirst=false;
+        toast.success(msg);
+    }
+    else
+    {
+        toast.error(msg);
+    }
+    if (arg&&arg.callback!=null){
+        arg.callback(payload);
+    }
+}
+const saveCPFStatus=(state,status,arg)=>{
+    state.status.SaveCPF=status;
+}
 export const Pay=createSlice({
     name: 'pay',
     initialState: {
@@ -247,6 +266,7 @@ export const Pay=createSlice({
             WithdrawSetInfo:REQ_STATUS.NONE,
             WithdrawPayout:REQ_STATUS.NONE,
             ForgetPayPass:REQ_STATUS.NONE,
+            SaveCPF:REQ_STATUS.NONE,
         },
         config:[],
         payconfig:null,
@@ -259,7 +279,8 @@ export const Pay=createSlice({
         payOrderList:null,
         withdrawRecord:null,
         changePayPassType:0,
-        showBonus:false
+        showBonus:false,
+        cpfFirst:false
     },
     reducers: {
         updatePayFinish:((state, action) => {
@@ -291,6 +312,7 @@ export const Pay=createSlice({
         buildReqReducer(builder,reqWithdrawPayout,reducerWithdrawPayout,withdrawPayoutStatus);
         buildReqReducer(builder,reqForgetPayPass,reducerChangePayPass,changePayPassStatus);
         buildReqReducer(builder,reqMexWithdrawSetInfo,reducerWithdrawSetInfo,withdrawSetInfoStatus);
+        buildReqReducer(builder,reqCPFSave,reducerSaveCPF,saveCPFStatus);
     },
 })
 export const {updatePayFinish,setChangePayPassType} = Pay.actions;
@@ -395,6 +417,12 @@ export const getPayConfigStatus=(state)=>{
 export const getForgetPayPassStatus=(state)=>{
     return state.pay.status.ForgetPayPass;
 }
+export const getCPFFirst=(state)=>{
+    return state.pay.cpfFirst;
+}
+export const getSaveCPFStatus=(state)=>{
+    return state.pay.status.SaveCPF;
+}
 export default Pay.reducer;
 
 export const reqPayConfig=(dispatch,userInfo)=>{

+ 8 - 0
src/locales/languages/en_US.json

@@ -286,6 +286,14 @@
         "label_number": "Request Number",
         "btn_confirm": "Confirm"
       }
+    },
+    "cpf_save_br": {
+      "cpf": "Enter CPF",
+      "modifyInfoTitle": "Recharge Information",
+      "cpfTips": "To ensure successful recharge, fill in the CPF",
+      "cpfTips_1": "Please fill in the correct information to ensure the efficiency of your wallet service.",
+      "cpf_error": "Please enter a valid CPF",
+      "btn_confirm": "Confirm"
     }
   },
   "game": {

+ 8 - 0
src/locales/languages/es_MX.json

@@ -283,6 +283,14 @@
         "label_number": "Número de solicitud",
         "btn_confirm": "Confirmar"
       }
+    },
+    "cpf_save_br": {
+      "cpf": "Introduce el nombre",
+      "modifyInfoTitle": "Información de recarga",
+      "cpfTips": "Rellena RFC para garantizar la recarga",
+      "cpfTips_1": "Por favor, rellene la información correcta para garantizar la eficiencia de su servicio de billetera.",
+      "cpf_error": "Por favor ingrese un CPF válido",
+      "btn_confirm": "Confirmar"
     }
   },
   "game": {

+ 8 - 0
src/locales/languages/pt_BR.json

@@ -283,6 +283,14 @@
         "label_number": "Número do pedido",
         "btn_confirm": "Confirmar"
       }
+    },
+    "cpf_save_br": {
+      "cpf": "Insira CPF",
+      "modifyInfoTitle": "informações De Recarga",
+      "cpfTips": "Para garantir a recarga bem-sucedida, preencha o CPF",
+      "cpfTips_1": "Preencha as informações corretas para garantir a eficiência do seu serviço de carteira.",
+      "cpf_error": "Por favor, insira um CPF válido",
+      "btn_confirm": "Confirmar"
     }
   },
   "game": {

+ 8 - 0
src/locales/languages/ru_RU.json

@@ -283,6 +283,14 @@
         "label_number": "Номер заказа",
         "btn_confirm": "Подтвердить"
       }
+    },
+    "cpf_save_br": {
+      "cpf": "Введите CPF",
+      "modifyInfoTitle": "Информация о пополнении счета",
+      "cpfTips": "Для обеспечения успешного пополнения счета заполните CPF",
+      "cpfTips_1": "Пожалуйста, заполните правильную информацию, чтобы обеспечить эффективность обслуживания вашего кошелька.",
+      "cpf_error": "Введите действительный CPF",
+      "btn_confirm": "Подтвердить"
     }
   },
   "game": {

+ 8 - 0
src/locales/languages/zh_TW.json

@@ -283,6 +283,14 @@
         "label_number": "訂單號",
         "btn_confirm": "確認"
       }
+    },
+    "cpf_save_br": {
+      "cpf": "輸入CPF",
+      "modifyInfoTitle": "儲值資訊",
+      "cpfTips": "為確保儲值成功,請填寫CPF",
+      "cpfTips_1": "請填寫正確的訊息,以確保您的錢包服務的效率。",
+      "cpf_error": "請輸入有效的CPF",
+      "btn_confirm": "確認"
     }
   },
   "game": {

+ 40 - 0
src/utils/helpers.js

@@ -472,4 +472,44 @@ export const getDomainSuffix=()=>{
 export const validateEmail=(value)=>{
     const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
     return emailPattern.test(value);
+}
+export const validateCPF=(cpf)=>{
+    cpf = cpf.replace(/[^\d]/g, '');
+
+    if (cpf.length !== 11) {
+        return false;
+    }
+
+    if (/^(\d)\1{10}$/.test(cpf)) {
+        return false;
+    }
+
+    let sum = 0;
+    let rest;
+
+    for (let i = 1; i <= 9; i++) {
+        sum += parseInt(cpf.charAt(i - 1)) * (11 - i);
+    }
+    rest = (sum * 10) % 11;
+    if (rest === 10 || rest === 11) {
+        rest = 0;
+    }
+    if (rest !== parseInt(cpf.charAt(9))) {
+        return false;
+    }
+
+    sum = 0;
+    for (let i = 1; i <= 10; i++) {
+        sum += parseInt(cpf.charAt(i - 1)) * (12 - i);
+    }
+    rest = (sum * 10) % 11;
+    if (rest === 10 || rest === 11) {
+        rest = 0;
+    }
+    if (rest !== parseInt(cpf.charAt(10))) {
+        return false;
+    }
+
+    return true;
+
 }

+ 99 - 0
src/widgets/WDeposit/BR/BRCPFSave/BRCPFSave.jsx

@@ -0,0 +1,99 @@
+import React, {useEffect, useState} from "react";
+import Popup from "@components/Popup";
+import styles from "./styles.module.scss";
+import {Controller, useForm} from "react-hook-form";
+import classNames from "classnames";
+import cpf_card_img from "@assets/pay/cpf_card.png";
+import {REQ_STATUS} from "@api/config";
+import SmallLoading from "@components/SmallLoading";
+import {useDispatch, useSelector} from "react-redux";
+import {getSaveCPFStatus} from "@features/paySlice";
+import {validateCPF} from "@utils/helpers";
+import {toast} from "react-toastify";
+import {reqCPFSave} from "@features/api";
+const i18n=global.i18n;
+const BRCPFSave = ({}) => {
+    const [isShow, setIsShow] = useState(false);
+    const saveCPFStatus=useSelector(getSaveCPFStatus);
+    const dispatch = useDispatch();
+    const {register, handleSubmit, formState: {errors}, control} = useForm({
+        defaultValues: {
+            PixNum:''
+        }
+    });
+    const show=(callback)=>{
+        // setChoiceCB(callback);
+        global.brCPFSave.saveCB=callback;
+        setIsShow(true);
+    }
+    const hide=()=>{
+        setIsShow(false);
+    }
+    const onCallback=(payload)=>{
+        if (payload&&payload.code===200){
+            if (global.brCPFSave.saveCB)global.brCPFSave.saveCB();
+            hide();
+        }
+    }
+    const onSubmitCPF=(data)=>{
+        if (saveCPFStatus===REQ_STATUS.LOADING)return;
+        if (!validateCPF(data.PixNum)){
+            toast.error(i18n.t("deposit.cpf_save_br.cpf_error"))
+            return;
+        }
+        // data.callback=onCallback;
+        dispatch(reqCPFSave(data)).then((data)=>{
+            onCallback(data.payload)
+        });
+    }
+    useEffect(()=>{
+        global.brCPFSave={
+            show,
+            hide
+        };
+    },[])
+    return (
+        <Popup onClose={() => {
+            hide();
+        }} open={isShow}>
+            <div className={styles.container}>
+                <span className={styles.title}>{i18n.t("deposit.cpf_save_br.modifyInfoTitle")}</span>
+                <span className={styles.tips}>{i18n.t("deposit.cpf_save_br.cpfTips")}</span>
+                <form autoComplete="off" className={styles.l_form} onSubmit={handleSubmit((data) => {
+                    onSubmitCPF(data);
+                })}>
+                    <Controller control={control}
+                                name="PixNum"
+                                rules={{required: true}}
+                                render={({field: {ref, onChange, value}, fieldState: {error}}) => (
+                                    <div className={styles.form_item}>
+                                        <div className={styles.cpf_input}>
+                                            <div className={styles.title}>
+                                                <img src={cpf_card_img}/>
+                                                CPF:
+                                            </div>
+                                            <div
+                                                className={classNames("input-control flex-1", {'input-control--error': error})}>
+                                                <input
+                                                    value={value}
+                                                    ref={ref}
+                                                    onChange={(e) => {
+                                                        onChange(e.target.value);
+                                                    }}
+                                                    placeholder={i18n.t('deposit.cpf_save_br.cpf')}
+                                                />
+                                            </div>
+                                        </div>
+                                    </div>
+                                )}
+                    />
+                    <button className={"button-green"}>
+                        {saveCPFStatus===REQ_STATUS.LOADING?(<SmallLoading fill={"#fff"}/>):i18n.t("deposit.cpf_save_br.btn_confirm")}
+                    </button>
+                </form>
+                <span className={styles.tips}>{i18n.t("deposit.cpf_save_br.cpfTips_1")}</span>
+            </div>
+        </Popup>
+    )
+}
+export default BRCPFSave;

+ 50 - 0
src/widgets/WDeposit/BR/BRCPFSave/styles.module.scss

@@ -0,0 +1,50 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  gap: 1.2rem;
+  pointer-events: auto;
+
+  & .title {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    color: var(--header);
+    font-weight: 600;
+    font-size: 1.05rem;
+  }
+  & .tips{
+    color: var(--coin-yellow);
+    text-align: center;
+  }
+  & .l_form {
+    display: flex;
+    flex-direction: column;
+    gap: 2rem;
+    width: 100%;
+    & .form_item{
+      display: flex;
+      flex-direction: column;
+      gap: 0.5rem;
+      & .cpf_input{
+        display: flex;
+        align-items: center;
+        flex-direction: row;
+        width: 100%;
+        gap: 0.5rem;
+        & .title{
+          display: flex;
+          flex-direction: row;
+          gap: 0.5rem;
+          font-size: 1rem;
+          color: var(--header);
+          img{
+            width: 1.3rem;
+            height: auto;
+          }
+        }
+      }
+    }
+  }
+}

+ 27 - 1
src/widgets/WDeposit/BR/BRDeposit.jsx

@@ -1,7 +1,7 @@
 import styles from './styles.module.scss';
 import {useDispatch, useSelector} from "react-redux";
 import {getUserInfo, isLogined} from "@features/mainSlice";
-import {getConfig, getFirstPay, getPaymentOrderStatus, getShowBonus} from "@features/paySlice";
+import {getConfig, getCPFFirst, getFirstPay, getPaymentOrderStatus, getShowBonus} from "@features/paySlice";
 import fpayimg from "@assets/pay/fpayimg.png";
 import img_sc from "@assets/pay/img_sc_66.png";
 import React, {useState} from "react";
@@ -17,6 +17,7 @@ import styled from 'styled-components/macro';
 import {stringFormat} from "@utils/helpers";
 import {APP_COUNTRY_CODE} from "@constants/app";
 import RUPaytypeSelect from "@widgets/WDeposit/RU/RUPaytypeSelect";
+import BRCPFSave from "@widgets/WDeposit/BR/BRCPFSave/BRCPFSave";
 const i18n=global.i18n;
 const PPBanner=styled.div`
     background: url(${img_bonus});
@@ -33,6 +34,7 @@ const BRDeposit=()=>{
     const isLogin=useSelector(isLogined);
     const [selectedPromotion,setSelectedPromotion]=useState(false);
     const showBonus=useSelector(getShowBonus);
+    const cpfFirst=useSelector(getCPFFirst);
     const areaItem=global.getLocalAreaItem();
     const getSelectedConfig=()=>{
         let selected=null;
@@ -69,6 +71,20 @@ const BRDeposit=()=>{
                 });
             }
         }
+        else if (areaItem.code===APP_COUNTRY_CODE.BR){
+            if (cpfFirst){
+                if (global.brCPFSave!=null){
+                    global.brCPFSave.show(()=>{
+                        data.cpf_first=1;
+                        reqOrder();
+                    })
+                }
+            }
+            else
+            {
+                reqOrder();
+            }
+        }
         else{
             reqOrder();
         }
@@ -293,6 +309,15 @@ const BRDeposit=()=>{
             return (<></>);
         }
     }
+    const renderCPFSave=()=>{
+        if (areaItem.code===APP_COUNTRY_CODE.BR){
+            return (<BRCPFSave/>)
+        }
+        else
+        {
+            return (<></>)
+        }
+    }
     return (
         <Spring type="slideUp" className={styles.container}>
             {renderFirst()}
@@ -300,6 +325,7 @@ const BRDeposit=()=>{
             {renderPromotions()}
             {renderDepositBtn()}
             {renderPaytypeSelect()}
+            {renderCPFSave()}
         </Spring>
     )
 }