Browse Source

fix: update gengxon

Before 8 months ago
parent
commit
cb5112520f

+ 6 - 0
messages/en.json

@@ -98,6 +98,12 @@
     "title": "Change the Contrasinha",
     "complete": "Complete"
   },
+  "changePasswordPage": {
+    "title": "Alterar senha",
+    "oldPwd": "Atual senha",
+    "newPwd": "Nova senha",
+    "button": "Mudar"
+  },
   "ResetPhonePage": {
     "enterCorrectphone":"Please enter a valid mobile phone numbe",
     "h2": "Encontre sua conta",

+ 2 - 0
src/api/depositsApi.ts

@@ -37,6 +37,8 @@ export interface DepositsTypes {
      *  是否进行过充值,配合product中存在充值优惠,标识是首充还是惠充优惠
      */
     has_pay: boolean;
+
+    num: number;
 }
 export interface Product {
     /**

+ 44 - 11
src/app/[locale]/(TabBar)/deposit/DepositData.tsx

@@ -8,10 +8,11 @@ import { neReg } from "@/utils";
 import { Form, Input, Toast } from "antd-mobile";
 import { FormInstance } from "antd-mobile/es/components/form";
 import { useTranslations } from "next-intl";
-import { FC, Fragment, useRef, useState } from "react";
+import { FC, Fragment, useLayoutEffect, useRef, useState } from "react";
 
 import actions from "@/app/[locale]/(TabBar)/deposit/actions";
 import "@/styles/deposit.scss";
+import { server } from "@/utils/client";
 interface Props {
     deposits: DepositsTypes[];
 }
@@ -59,11 +60,26 @@ const RewardsText: FC<RewardsProps> = (props) => {
         </div>
     );
 };
+
+const getDepositApi = async () => {
+    return server
+        .request<DepositsTypes[]>({
+            url: "/v1/api/user/user_deposit_config",
+            method: "post",
+            data: { activity_type: 0 },
+        })
+        .then((res) => {
+            if (res.code === 200) return res.data;
+            return [];
+        });
+};
 const DepositData: FC<Props> = (props) => {
     const { deposits } = props;
     const t = useTranslations();
     const userInfo = useUserInfoStore((state) => state.userInfo);
-    const [activeType, setActiveType] = useState<DepositsTypes>(deposits[0]);
+    const [depositState, setDepositState] = useState<DepositsTypes[]>([]);
+
+    const [activeType, setActiveType] = useState<Partial<DepositsTypes>>({});
 
     const formInstanceRef = useRef<FormInstance>(null);
     let [amount, setAmount] = useState<number | undefined>(undefined);
@@ -86,6 +102,9 @@ const DepositData: FC<Props> = (props) => {
                 if (res.data.pay_url) {
                     window.open(res.data.pay_url);
                 }
+                const data = await getDepositApi();
+                setDepositState(data);
+                setActiveType(data[0]);
                 await actions();
             })
             .catch((error) => {
@@ -103,28 +122,35 @@ const DepositData: FC<Props> = (props) => {
     };
     const amountValidator = (rules: any, value: any) => {
         if (!value) return Promise.reject(new Error(t("form.amount")));
-        if (+value < activeType.min_amount)
+        if (+value < activeType.min_amount!)
             return Promise.reject(
                 new Error(t("form.amountMinReg", { amount: activeType.min_amount }))
             );
-        if (+value > activeType.max_amount)
+        if (+value > activeType.max_amount!)
             return Promise.reject(
                 new Error(t("form.amountMaxReg", { amount: activeType.max_amount }))
             );
         return Promise.resolve();
     };
+
+    useLayoutEffect(() => {
+        getDepositApi().then((data) => {
+            setDepositState(data);
+            setActiveType(data[0]);
+        });
+    }, []);
     return (
         <div className="deposit-box">
             <div className="img-box"></div>
 
             <div className={"flex flex-wrap"}>
-                {deposits.map((item, index) => {
+                {depositState.map((item, index) => {
                     return (
                         <Fragment key={item.id}>
                             <p
                                 className="btn-box truncate"
                                 style={{
-                                    borderColor: activeType.id === item.id ? "#ff9323" : "#333",
+                                    borderColor: activeType?.id === item.id ? "#ff9323" : "#333",
                                 }}
                                 onClick={() => titleChangeHandler(item, index)}
                             >
@@ -178,16 +204,16 @@ const DepositData: FC<Props> = (props) => {
                         rules={[{ required: true, type: "number", validator: amountValidator }]}
                     >
                         <Input
-                            placeholder={`${t("DepositPage.Montante")}(BRL): Mín. ${activeType.min_amount}`}
+                            placeholder={`${t("DepositPage.Montante")}(BRL): Mín. ${activeType?.min_amount}`}
                             type={"number"}
-                            maxLength={activeType.max_amount}
+                            maxLength={activeType?.max_amount}
                         />
                     </Form.Item>
 
                     <div className={"flex flex-col"}>
                         <div className={"flex-1"}>
                             <ul className="ul-box">
-                                {activeType.products.map((item, index) => (
+                                {activeType?.products?.map((item, index) => (
                                     <li
                                         className={amount == item.amount ? "active" : ""}
                                         key={index}
@@ -200,8 +226,15 @@ const DepositData: FC<Props> = (props) => {
                                             <span> {item.amount}</span>
                                         </div>
 
-                                        {!activeType.has_pay && item.rewards && (
-                                            <RewardsText rewards={item.rewards} />
+                                        {item.rewards && (
+                                            <RewardsText
+                                                rewards={
+                                                    item.rewards &&
+                                                    item.rewards.sort(
+                                                        (p, n) => p.coin_type - n.coin_type
+                                                    )
+                                                }
+                                            />
                                         )}
                                     </li>
                                 ))}

+ 3 - 1
src/app/[locale]/(TabBar)/deposit/actions.ts

@@ -2,7 +2,9 @@
 import { revalidatePath } from "next/cache";
 
 const actions = async () => {
-    return revalidatePath(`/profile`, "page");
+    revalidatePath(`/profile`, "page");
+    revalidatePath(`/deposit`, "page");
+    return Promise.resolve();
 };
 
 export default actions;

+ 1 - 4
src/app/[locale]/(TabBar)/profile/ProfileHeader.tsx

@@ -339,10 +339,7 @@ export const ProfileHeader = (props: Props) => {
                         </div>
                     </div>
 
-                    <Link
-                        className="goto iconfont icon-xiangzuo1"
-                        href={`/confirmPassword?userPhone=${userInfo.user_phone}&code=123456&alter=true`}
-                    ></Link>
+                    <Link className="goto iconfont icon-xiangzuo1" href={`/changePassword`}></Link>
                 </div>
                 {/*vipcard*/}
                 <VipCard userVip={userVip} />

+ 85 - 0
src/app/[locale]/(enter)/changePassword/page.scss

@@ -0,0 +1,85 @@
+.confirmPassword-box {
+    width: 100%;
+    min-height: 100vh;
+    background-color: rgb(31, 31, 31);
+    display: flex;
+    flex-direction: column;
+
+  .main {
+    background-color: #1f1f1f;
+    padding: .72rem .18rem 0;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    .title {
+      font-size: .18rem;
+      text-align: center;
+      margin-bottom: .4rem;
+      h2 {
+        color: #fcde26;
+        line-height: .22rem;
+      }
+      div {
+        color: #fff;
+        font-size: .12rem;
+        margin: .06rem 0;
+        line-height: .2rem;
+      }
+    }
+    .phoneInput {
+      width: 100%;
+      height: auto;
+      background-color: #494949;
+      border-radius: 4px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      overflow: hidden;
+      margin-top: 0.2rem;
+      position: relative;
+
+      .after {
+          color: #fcde26;
+          font-size: .14rem;
+          border: .01rem solid #fcde26;
+          position: absolute;
+          height: .26rem;
+          line-height: .26rem;
+          padding: 0 .08rem;
+          text-align: center;
+          right: .1rem;
+          top: .11rem;
+          border-radius: .13rem;
+      }
+
+      //input {
+      //  padding-left: .14rem;
+      //  -webkit-box-sizing: border-box;
+      //  box-sizing: border-box;
+      //}
+
+    }
+
+    //input {
+    //  flex: 1;
+    //  background-color: #494949;
+    //  height: .48rem;
+    //  color: #868686;
+    //  font-size: .14rem;
+    //  outline: none;
+    //  &::placeholder {
+    //    color: #868686;
+    //  }
+    //}
+
+    .tips {
+      width: 100%;
+      color: #e53535;
+      font-size: 0.12rem;
+      margin-top: .02rem;
+    }
+
+    .btnContent {
+      margin: .29rem 0 .19rem;
+    }
+  }
+}

+ 150 - 0
src/app/[locale]/(enter)/changePassword/page.tsx

@@ -0,0 +1,150 @@
+"use client";
+import ButtonOwn from "@/components/ButtonOwn";
+import DomainFooter from "@/components/DomainFooter";
+import HeaderBack from "@/components/HeaderBack";
+import { Link } from "@/i18n/routing";
+import { Form, Input, Toast } from "antd-mobile";
+import { FormInstance } from "antd-mobile/es/components/form";
+import clsx from "clsx";
+import { useTranslations } from "next-intl";
+import { FC, useRef, useState } from "react";
+
+import { useLogout } from "@/hooks/useLogout";
+import { server } from "@/utils/client";
+import "./page.scss";
+
+interface Props {}
+
+interface ChangePwdType {
+    old_pwd: string;
+    pwd: string;
+}
+
+const changePwdApi = (data: ChangePwdType) => {
+    return server.post({
+        url: "/v1/api/user/update_pwd",
+        data: data,
+    });
+};
+const ChangePassword: FC<Props> = () => {
+    const t = useTranslations();
+    const { logout } = useLogout();
+
+    /**
+     * @description
+     */
+    const [visible, setVisible] = useState(false);
+    const [oldVisible, setOldVisible] = useState(false);
+    const spanClassName = clsx("iconfont", {
+        "icon-kejian": visible,
+        "icon-bukejian": !visible,
+    });
+    const oldClassName = clsx("iconfont", {
+        "icon-kejian": oldVisible,
+        "icon-bukejian": !oldVisible,
+    });
+    const formRef = useRef<FormInstance>(null);
+    const onFinish = (values: ChangePwdType) => {
+        Toast.show({ icon: "loading" });
+        changePwdApi(values)
+            .then(async (res) => {
+                Toast.show(t("code.200"));
+                await logout();
+                Toast.clear();
+            })
+            .catch((error) => {
+                Toast.show(t(`code.${error.data.code}`));
+            });
+    };
+    const onValuesChange = (changeValue: { pwd: string; old_pwd: string }) => {
+        if (changeValue.pwd) {
+            formRef.current?.setFieldValue("pwd", changeValue.pwd.replace(/[^\w\.\/]/gi, ""));
+        }
+        if (changeValue.old_pwd) {
+            formRef.current?.setFieldValue(
+                "old_pwd",
+                changeValue.old_pwd.replace(/[^\w\.\/]/gi, "")
+            );
+        }
+    };
+    const checkValidator = (rules: any, value: string) => {
+        const password = formRef.current?.getFieldValue("pwd");
+        if (value === password) {
+            return Promise.reject(new Error(t("form.checkPwdReg")));
+        }
+        return Promise.resolve();
+    };
+
+    return (
+        <div className="confirmPassword-box">
+            <HeaderBack />
+            <div className="main custom-form">
+                <div className="title">
+                    <h2>{t("changePasswordPage.title")}</h2>
+                </div>
+                <Form
+                    style={{
+                        "--border-bottom": "none",
+                        "--border-top": "none",
+                        "--border-inner": "none",
+                    }}
+                    onFinish={onFinish}
+                    ref={formRef}
+                    onValuesChange={onValuesChange}
+                    footer={<ButtonOwn active>{t("changePasswordPage.button")}</ButtonOwn>}
+                >
+                    <Form.Item
+                        name="old_pwd"
+                        label=""
+                        extra={
+                            <span
+                                className={oldClassName}
+                                onClick={() => setOldVisible(!oldVisible)}
+                            ></span>
+                        }
+                        rules={[
+                            { required: true, message: t("form.passwordReg") },
+                            { min: 6, max: 20, message: t("form.passwordMinReg") },
+                        ]}
+                    >
+                        <Input
+                            placeholder={t("changePasswordPage.oldPwd")}
+                            maxLength={20}
+                            type={oldVisible ? "text" : "password"}
+                        />
+                    </Form.Item>
+
+                    <Form.Item
+                        name="pwd"
+                        label=""
+                        extra={
+                            <span
+                                className={spanClassName}
+                                onClick={() => setVisible(!visible)}
+                            ></span>
+                        }
+                        rules={[
+                            { required: true, message: t("form.passwordReg") },
+                            { min: 6, max: 20, message: t("form.passwordMinReg") },
+                        ]}
+                    >
+                        <Input
+                            placeholder={t("changePasswordPage.newPwd")}
+                            maxLength={20}
+                            type={visible ? "text" : "password"}
+                        />
+                    </Form.Item>
+                </Form>
+                <div className={"text-right"}>
+                    <Link href={"/resetPhone"} className={"text-[#fff]"}>
+                        {t("LoginPage.forgetPwd")}
+                    </Link>
+                </div>
+            </div>
+
+            <DomainFooter />
+        </div>
+    );
+};
+
+export default ChangePassword;

+ 21 - 19
src/app/[locale]/(enter)/resetPhone/page.tsx

@@ -1,10 +1,10 @@
 "use client";
-import { getCheckUserPhoneExistApi } from "@/api/user";
+import { getSendCodeApi } from "@/api/user";
 import ButtonOwn from "@/components/ButtonOwn";
 import DomainFooter from "@/components/DomainFooter";
 import HeaderBack from "@/components/HeaderBack";
 import { useRouter } from "@/i18n/routing";
-import { Toast } from "antd-mobile";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { useTranslations } from "next-intl";
 import { FC, useState } from "react";
 import "./page.scss";
@@ -13,8 +13,12 @@ interface Props {}
 
 const ResetPhone: FC<Props> = () => {
     const t = useTranslations("ResetPhonePage");
-    const router: any = useRouter();
-    let [userPhone, setUserPhone] = useState("");
+    const tCode = useTranslations();
+    const router = useRouter();
+
+    const userInfo = useUserInfoStore((state) => state.userInfo);
+
+    let [userPhone, setUserPhone] = useState(userInfo.user_phone);
     const changeUserPhone = (e: { target: { value: any } }) => {
         const value = e.target.value.replace(/[^0-9]/g, "");
         setUserPhone(value);
@@ -23,10 +27,6 @@ const ResetPhone: FC<Props> = () => {
     const blurVerifyPhone = (e: { target: { value: any } }) => {
         const { value } = e.target;
         if (value == "") {
-            setMsgError("");
-            return;
-        }
-        if (value) {
             setMsgError(t("enterCorrectphone"));
             return;
         }
@@ -34,16 +34,15 @@ const ResetPhone: FC<Props> = () => {
     };
     const checkUserPhoneRequest = async () => {
         // if (!phoneRegex(userPhone)) return;
-        let { code, msg, data } = await getCheckUserPhoneExistApi({ user_phone: userPhone });
-        if (code == 200) {
-            if (data) {
-                router.push(`/verification?userPhone=${userPhone}`);
-                return;
-            } else {
-                Toast.show(t("notPhone"));
-            }
-            setMsgError(msg);
-        }
+        getSendCodeApi({ user_phone: userPhone })
+            .then(({ code, data }) => {
+                if (data) {
+                    router.push(`/verification?userPhone=${userPhone}`);
+                }
+            })
+            .catch((err) => {
+                setMsgError(tCode(`code.${err.data.code}`));
+            });
     };
     return (
         <div className="resetPhone-box">
@@ -66,7 +65,10 @@ const ResetPhone: FC<Props> = () => {
                 </div>
                 {msgError && <div className="tips"> {msgError} </div>}
                 <div className="btnContent">
-                    <ButtonOwn active callbackFun={checkUserPhoneRequest}>
+                    <ButtonOwn
+                        active={userPhone && userPhone.length > 10}
+                        callbackFun={checkUserPhoneRequest}
+                    >
                         {t("Continuar")}
                     </ButtonOwn>
                 </div>

+ 36 - 9
src/app/[locale]/(navbar)/doings/discount/DepositData.tsx

@@ -7,10 +7,11 @@ import { neReg } from "@/utils";
 import { Form, Input, Toast } from "antd-mobile";
 import { FormInstance } from "antd-mobile/es/components/form";
 import { useTranslations } from "next-intl";
-import { FC, Fragment, useRef, useState } from "react";
+import { FC, Fragment, useLayoutEffect, useRef, useState } from "react";
 
 import ButtonOwn from "@/components/ButtonOwn";
 import "@/styles/deposit.scss";
+import { server } from "@/utils/client";
 import Image from "next/image";
 interface Props {
     deposits: DepositsTypes[];
@@ -58,14 +59,29 @@ const RewardsText: FC<RewardsProps> = (props) => {
         </div>
     );
 };
+
+const getDepositApi = async () => {
+    return server
+        .request<DepositsTypes[]>({
+            url: "/v1/api/user/user_deposit_config",
+            method: "post",
+            data: { activity_type: 2 },
+        })
+        .then((res) => {
+            if (res.code === 200) return res.data;
+            return [];
+        });
+};
 const DepositData: FC<Props> = (props) => {
-    const { deposits } = props;
+    // const { deposits } = props;
     const t = useTranslations();
     const userInfo = useUserInfoStore((state) => state.userInfo);
 
-    const count = 3;
     // 选中类型
-    const [activeType, setActiveType] = useState<DepositsTypes>(deposits[0]);
+
+    const [depositState, setDepositState] = useState<DepositsTypes[]>([]);
+    const [activeType, setActiveType] = useState<Partial<DepositsTypes>>({});
+    const count = activeType.num || 0;
 
     const formInstanceRef = useRef<FormInstance>(null);
     let [amount, setAmount] = useState<number | undefined>(undefined);
@@ -80,10 +96,14 @@ const DepositData: FC<Props> = (props) => {
     const onFinish = (values: any) => {
         const params = { ...values, channel_id: activeType.id, amount: +values.amount };
         getUserRechargeApi(params)
-            .then((res) => {
+            .then(async (res) => {
                 formInstanceRef.current?.resetFields();
                 Toast.show({ icon: "success", content: t("code.200"), maskClickable: false });
                 setAmount(undefined);
+
+                const data = await getDepositApi();
+                setDepositState(data);
+                setActiveType(data[0]);
                 if (res.data.pay_url) {
                     window.open(res.data.pay_url);
                 }
@@ -103,17 +123,24 @@ const DepositData: FC<Props> = (props) => {
     };
     const amountValidator = (rules: any, value: any) => {
         if (!value) return Promise.reject(new Error(t("form.amount")));
-        if (+value < activeType.min_amount)
+        if (+value < activeType.min_amount!)
             return Promise.reject(
                 new Error(t("form.amountMinReg", { amount: activeType.min_amount }))
             );
-        if (+value > activeType.max_amount)
+        if (+value > activeType.max_amount!)
             return Promise.reject(
                 new Error(t("form.amountMaxReg", { amount: activeType.max_amount }))
             );
         return Promise.resolve();
     };
 
+    useLayoutEffect(() => {
+        getDepositApi().then((data) => {
+            setDepositState(data);
+            setActiveType(data[0]);
+        });
+    }, []);
+
     return (
         <>
             <Image src={"/doings/recharge.jpg"} alt={"deposit"} width={1950} height={10} />
@@ -129,7 +156,7 @@ const DepositData: FC<Props> = (props) => {
                 </div>
 
                 <div className={"flex flex-wrap"}>
-                    {deposits.map((item, index) => {
+                    {depositState.map((item, index) => {
                         return (
                             <Fragment key={item.id}>
                                 <p
@@ -206,7 +233,7 @@ const DepositData: FC<Props> = (props) => {
                         <div className={"flex flex-col"}>
                             <div className={"flex-1"}>
                                 <ul className="ul-box">
-                                    {activeType.products.map((item, index) => (
+                                    {activeType?.products?.map((item, index) => (
                                         <li
                                             className={amount == item.amount ? "active" : ""}
                                             key={index}

+ 22 - 14
src/app/[locale]/verification/page.tsx

@@ -4,6 +4,7 @@ import ButtonOwn from "@/components/ButtonOwn";
 import DomainFooter from "@/components/DomainFooter";
 import HeaderBack from "@/components/HeaderBack";
 import { useRouter } from "@/i18n/routing";
+import { useCountDown } from "ahooks";
 import { useTranslations } from "next-intl";
 import { useSearchParams } from "next/navigation";
 import { FC, useEffect, useRef, useState } from "react";
@@ -13,7 +14,14 @@ interface Props {}
 
 const ResetPhone: FC<Props> = () => {
     const t = useTranslations("VerificationPage");
-    const router: any = useRouter();
+    const router = useRouter();
+    let [time, setTime] = useState<number>();
+    const [countdown] = useCountDown({
+        time,
+        onEnd: () => {
+            alert("End of the time");
+        },
+    });
     let [code, setCode] = useState("");
     const changeCode = (e: { target: { value: any } }) => {
         setCode(e.target.value.replace(/[^0-9]/g, ""));
@@ -36,19 +44,19 @@ const ResetPhone: FC<Props> = () => {
     }, []);
 
     let [isNote, setIsNote] = useState(true);
-    let [time, setTime] = useState(60);
+
     let timeRef: any = useRef();
     useEffect(() => {
-        if (time && time != 0) {
-            timeRef.current = setTimeout(() => {
-                setTime((time) => time - 1);
-            }, 1000);
-        } else {
-            setIsNote(false);
-        }
-        return () => {
-            timeRef.current && clearInterval(timeRef.current);
-        };
+        // if (time && time != 0) {
+        //     timeRef.current = setTimeout(() => {
+        //         setTime((time) => time - 1);
+        //     }, 1000);
+        // } else {
+        //     setIsNote(false);
+        // }
+        // return () => {
+        //     timeRef.current && clearInterval(timeRef.current);
+        // };
     }, [time]);
     const sendCodeFun = () => {
         if (isNote) return;
@@ -57,7 +65,7 @@ const ResetPhone: FC<Props> = () => {
 
     const goPage = () => {
         if (!code || code.length < 6) return;
-        router.push(`/confirmPassword?userPhone=${user_phone}&code=${code}`);
+        router.push(`/confirmPassword`);
     };
 
     return (
@@ -79,7 +87,7 @@ const ResetPhone: FC<Props> = () => {
                         maxLength={6}
                     />
                     <span className="after" onClick={sendCodeFun}>
-                        {isNote ? `${time}s` : t("Envie")}
+                        {isNote ? `${countdown}s` : t("Envie")}
                     </span>
                 </div>
                 <div className="btnContent">

+ 6 - 1
src/components/ButtonOwn/index.tsx

@@ -32,7 +32,12 @@ const ButtonOwn: FC<PropsWithChildren<ButtonOwnProps>> = ({
         className,
     });
     return (
-        <button style={style} className={divClassName} {...other} onClick={callbackFun}>
+        <button
+            style={style}
+            className={divClassName}
+            {...other}
+            onClick={() => active && callbackFun && callbackFun()}
+        >
             {children}
         </button>
     );

+ 33 - 0
src/hooks/useLogout.ts

@@ -0,0 +1,33 @@
+import { getLogoutApi } from "@/api/user";
+import { useRouter } from "@/i18n/routing";
+import { useSearchStore } from "@/stores/useSearchStore";
+import { useUserInfoStore } from "@/stores/useUserInfoStore";
+import { useWalletStore } from "@/stores/useWalletStore";
+import dayjs from "dayjs";
+import Cookies from "js-cookie";
+
+export const useLogout = () => {
+    const restGlobal = useUserInfoStore((state) => state.reset);
+    const resetSearch = useSearchStore((state) => state.reset);
+    const restWalletStore = useWalletStore((state) => state.reset);
+    const router = useRouter();
+    const logout = async () => {
+        let res = await getLogoutApi();
+        const isClearPromotion = dayjs().isSame(sessionStorage.getItem("isClosePromotion"), "days");
+        if (res.code == 200) {
+            restGlobal();
+            resetSearch();
+            restWalletStore();
+            localStorage.clear();
+            Cookies.remove("Token");
+            router.replace("/login");
+        }
+        if (!isClearPromotion) {
+            sessionStorage.clear();
+        }
+        return Promise.resolve(res);
+    };
+    return {
+        logout,
+    };
+};