Bladeren bron

fix: 更新弹窗

Before 8 maanden geleden
bovenliggende
commit
714f6130a5

+ 149 - 22
src/api/promo.ts

@@ -1,39 +1,166 @@
 import { server } from "@/utils/client";
 
 export interface RedPacketParams {
-  /**
-   * 活动id
-   */
-  id: number;
-  // 红包索引
-  index: number;
+    /**
+     * 活动id
+     */
+    id: number;
+    // 红包索引
+    index: number;
 }
 
 // 未登陆的红包信息
 export const redPacketApi = () => {
-  return server.request<any>({
-      url: "/v1/api/front/activity/red_packet",
-      data: {renter_id:'10000'},
-      method: "POST",
-  });
+    return server.request<any>({
+        url: "/v1/api/front/activity/red_packet",
+        data: { renter_id: "10000" },
+        method: "POST",
+    });
 };
 
 // 登陆后的红包状态信息
 export const lredPacketApi = () => {
-  return server.request<any>({
-      url: "/v1/api/user/activity/red_packet",
-      data: {renter_id:'10000'},
-      method: "POST",
-  });
+    return server.request<any>({
+        url: "/v1/api/user/activity/red_packet",
+        data: { renter_id: "10000" },
+        method: "POST",
+    });
 };
 
+export const receiveRedPacketApi = (data: RedPacketParams) => {
+    return server.request<any>({
+        url: "/v1/api/user/receive_red_packet",
+        data,
+        method: "POST",
+    });
+};
 
+export interface PayDataType {
+    first_pay: FirstPay[];
+    pay: Pay[];
+}
 
+export interface FirstPay {
+    /**
+     * 奖励条件
+     */
+    condition: FirstPayCondition[];
+    /**
+     * 优惠类型(1固定金额2百分比)
+     */
+    discount_type: number;
+    /**
+     * 时长(分) 0表示不限制时间
+     */
+    duration: number;
+    /**
+     * 活动ID
+     */
+    id: number;
+    /**
+     * 活动名称
+     */
+    name: string;
+    /**
+     * 可参与次数 -1表示不限制次数
+     */
+    num: number;
+    /**
+     * 支付类型
+     */
+    pay_type: string[];
+}
+
+export interface FirstPayCondition {
+    /**
+     * 参加金额
+     */
+    amount: string;
+    /**
+     * 奖励代币类型1现金2彩金3免费币4重玩币
+     */
+    coin_type: string;
+    /**
+     * 最多获取奖励
+     */
+    max_reward: string;
+    /**
+     * 充值奖励 1固定额度奖励2比百分奖励(放大100倍)
+     */
+    reward: string;
+    /**
+     * 打码倍率
+     */
+    rollover: string;
+    [property: string]: any;
+}
+
+export interface Pay {
+    /**
+     * 奖励条件
+     */
+    condition: PayCondition[];
+    /**
+     * 优惠类型(1固定金额2百分比)
+     */
+    discount_type: number;
+    /**
+     * 截止时间
+     */
+    end_time: number;
+    /**
+     * 活动ID
+     */
+    id: number;
+    /**
+     * 活动名称
+     */
+    name: string;
+    /**
+     * 可参与次数 -1表示不限制次数
+     */
+    num: number;
+    /**
+     * 支付类型
+     */
+    pay_type: string[];
+    /**
+     * 开始时间
+     */
+    start_time: number;
+}
+
+export interface PayCondition {
+    /**
+     * 参加金额
+     */
+    amount: string;
+    /**
+     * 奖励代币类型1现金2彩金3免费币4重玩币
+     */
+    coin_type: string;
+    /**
+     * 最多获取奖励
+     */
+    max_reward: string;
+    /**
+     * 充值奖励 1固定额度奖励2比百分奖励(放大100倍)
+     */
+    reward: string;
+    /**
+     * 打码倍率
+     */
+    rollover: string;
+}
 
-export const receiveRedPacketApi = (data:RedPacketParams) => {
-  return server.request<any>({
-      url: "/v1/api/user/receive_red_packet",
-      data,
-      method: "POST",
-  });
+export const getPaysApi = async () => {
+    return server
+        .post<PayDataType>({
+            url: "/v1/api/front/activity/pay",
+        })
+        .then((res) => {
+            if (res.code === 200) {
+                return res.data;
+            }
+        });
 };

+ 33 - 2
src/app/[locale]/(TabBar)/[[...share]]/@actionWidget/Service.tsx

@@ -1,7 +1,8 @@
 "use client";
 import { ServiceTypes } from "@/api/customservice";
-import { lredPacketApi, redPacketApi } from "@/api/promo";
+import { getPaysApi, lredPacketApi, PayDataType, redPacketApi } from "@/api/promo";
 import RedPacketModal, { RedPacketModalProps } from "@/components/Box/RedPacketModal";
+import UserRecharge, { ModalRefProps } from "@/components/Box/UserRecharge";
 import { Link } from "@/i18n";
 import { useGlobalNoticeStore } from "@/stores/useGlobalNoticeStore";
 import { useSocialStore } from "@/stores/useSocials";
@@ -17,13 +18,14 @@ interface Props {
 }
 const ServiceWidget: FC<Props> = (props) => {
     const token = getToken();
-    // const [packets, setPackets] = useState<any[]>([]);
     const { services, socials } = props;
     const defaultService = services.find((item) => item.is_suspend === 1);
 
     const newServices = services.filter((item) => item.is_suspend !== 1);
     const setSocials = useSocialStore((state) => state.setSocials);
     const RedPacketModalRef = useRef<RedPacketModalProps>(null);
+
+    const userRechargeRef = useRef<ModalRefProps>(null);
     useEffect(() => {
         // 数据存储,侧边栏使用
         setSocials(socials);
@@ -61,11 +63,39 @@ const ServiceWidget: FC<Props> = (props) => {
         pollingWhenHidden: false,
     });
 
+    // 首充活动
+
+    const getPayInfo = async () => {
+        if (token) {
+            return getPaysApi();
+        }
+        return Promise.resolve({});
+    };
+    const { data: paysInfo } = useRequest<PayDataType, any>(getPayInfo, {
+        pollingErrorRetryCount: 1,
+        pollingWhenHidden: false,
+    });
+    console.log(`🚀🚀🚀🚀🚀-> in Service.tsx on 69`, paysInfo);
+
     return (
         <>
             <div
                 className={`absolute bottom-[0.84rem] right-[0.12rem] z-50 flex w-[100px] flex-col items-center justify-center`}
             >
+                {/*首充*/}
+                {paysInfo?.first_pay?.map((item, index) => {
+                    return (
+                        <div key={index} className={`mb-[0.0694rem] cursor-pointer`}>
+                            <img
+                                className={"h-[0.3889rem] w-[0.3889rem]"}
+                                src="/hby/red-icon.png"
+                                onClick={() => {
+                                    userRechargeRef.current?.onOpen(paysInfo.first_pay, index);
+                                }}
+                            />
+                        </div>
+                    );
+                })}
                 {/* 红包雨icon */}
                 {packets?.map((item, index) => {
                     return (
@@ -115,6 +145,7 @@ const ServiceWidget: FC<Props> = (props) => {
             </div>
 
             <RedPacketModal ref={RedPacketModalRef} onAfterHandler={run} />
+            <UserRecharge ref={userRechargeRef} />
 
             <div className={`grid grid-cols-${newServices.length >= 5 ? 5 : newServices.length}`}>
                 {newServices.map((service, index) => {

+ 0 - 111
src/app/[locale]/(TabBar)/[[...share]]/@popupWidget/UserRecharge.tsx

@@ -1,111 +0,0 @@
-"use client";
-import { useRouter } from "@/i18n";
-import { getToken } from "@/utils/Cookies";
-import { Mask } from "antd-mobile";
-import { useTranslations } from "next-intl";
-import Image from "next/image";
-import { FC, useState } from "react";
-
-interface Props {}
-
-const UserRecharge: FC<Props> = (props) => {
-    const [visible, setVisible] = useState(false);
-    const token = getToken();
-    const router = useRouter();
-    const t = useTranslations("HomePage");
-
-    const receiveHandler = () => {
-        if (token) {
-            router.push("/deposit");
-        } else {
-            router.push("/login?redirect=deposit");
-        }
-        setVisible(false);
-    };
-    return (
-        <Mask visible={visible} onMaskClick={() => setVisible(false)}>
-            <div className={"h-[100vh] h-[10dvh]"}>
-                <div className={"relative mt-[10vh]"}>
-                    <div
-                        onClick={() => setVisible(false)}
-                        className={
-                            "absolute right-[10%] top-0 h-[0.1736rem] w-[0.1736rem]" +
-                            " rounded-[50%] border-[2px] border-[#dcd8bb] text-[#dcd8bb]" +
-                            " flex items-center justify-center"
-                        }
-                    >
-                        <span className={"iconfont icon-guanbi"}></span>
-                    </div>
-
-                    <div className={"absolute -top-[0.34rem] left-0 -z-10 h-[100%] w-[100%]"}>
-                        <img src={"/recharge/bg.png"} className={"h-[100%] w-[100%]"} />
-                    </div>
-                    <div className={"absolute left-0 top-0 -z-[9] h-[100%] w-[100%]"}>
-                        <img src={"/recharge/bg1.png"} className={"h-[100%] w-[100%]"} />
-                    </div>
-                    <Image
-                        src={"/recharge/content.png"}
-                        alt={"recharge"}
-                        className={"z-2 w-[100%]"}
-                        width={750}
-                        height={694}
-                    />
-                    <div
-                        className={
-                            "absolute bottom-[0.59rem] h-[0.50rem] w-[100%] " +
-                            " flex justify-center"
-                        }
-                    >
-                        <svg viewBox="0 -15 200 50" style={{ width: "100%", height: "100%" }}>
-                            <path d="M0 30 C 50 10, 150 10 200 30" fill="transparent" id="circle" />
-                            <text
-                                style={{
-                                    fill: "#ff3333",
-                                    fontSize: "22px",
-                                    fontWeight: "bold",
-                                    textShadow: "0.1em 0.1em rgba(0,0,0,0.5)",
-                                }}
-                            >
-                                <textPath
-                                    xlinkHref="#circle"
-                                    textAnchor="middle"
-                                    startOffset="50%"
-                                    dy="0"
-                                >
-                                    <tspan>{t("rechargeTitle")}</tspan>
-                                </textPath>
-                            </text>
-                        </svg>
-                    </div>
-                    <div
-                        className={
-                            "absolute bottom-[0px] right-[50%] flex h-[0.45rem] " +
-                            " items-center" +
-                            " mb-[0.13rem] translate-x-1/2 font-bold text-[#fee5c1]"
-                        }
-                    >
-                        {t("rechargeTips", { num: "100%" })}
-                    </div>
-                </div>
-                <div className={"relative flex w-[100%] justify-center"}>
-                    <div
-                        style={{
-                            background: "url(/recharge/button.png)",
-                            backgroundRepeat: "no-repeat",
-                            backgroundSize: "100% 100%",
-                        }}
-                        onClick={receiveHandler}
-                        className={
-                            "flex h-[0.7rem] w-[1.5972rem] items-center justify-center" +
-                            " text-[0.1528rem] font-bold text-[#fff]"
-                        }
-                    >
-                        <span> {t("rechargeButton")}</span>
-                    </div>
-                </div>
-            </div>
-        </Mask>
-    );
-};
-
-export default UserRecharge;

+ 0 - 4
src/app/[locale]/(TabBar)/[[...share]]/@popupWidget/page.tsx

@@ -1,5 +1,4 @@
 import { NoticeRep, PromotionRep } from "@/api/home";
-import UserRecharge from "@/app/[locale]/(TabBar)/[[...share]]/@popupWidget/UserRecharge";
 import Desktop from "@/components/Box/Desktop";
 import { server } from "@/utils/server";
 import HomeMessage from "../_home/HomeMessage";
@@ -42,9 +41,6 @@ const Page = async () => {
             />
             {/*安装弹窗*/}
             <Desktop source={"page"} />
-
-            {/* 新用户充值活动 */}
-            <UserRecharge />
         </>
     );
 };

+ 20 - 19
src/app/[locale]/(TabBar)/deposit/DepositData.tsx

@@ -156,25 +156,26 @@ const DepositData: FC<Props> = (props) => {
                                             <span> {item.amount}</span>
                                         </div>
                                         <div>
-                                            {item.rewards
-                                                .sort((p, n) => p.coin_type - n.coin_type)
-                                                .map((reward, index) => {
-                                                    return (
-                                                        <Fragment key={index}>
-                                                            {reward.ratio > 0 ? (
-                                                                <span className="amountTips">
-                                                                    {t("DepositPage.Oferecer")}{" "}
-                                                                    {reward.ratio}%
-                                                                </span>
-                                                            ) : null}
-                                                            {reward.reward > 0 ? (
-                                                                <span className="amountTips">
-                                                                    + {reward.reward}
-                                                                </span>
-                                                            ) : null}
-                                                        </Fragment>
-                                                    );
-                                                })}
+                                            {item.rewards &&
+                                                item.rewards
+                                                    .sort((p, n) => p.coin_type - n.coin_type)
+                                                    .map((reward, index) => {
+                                                        return (
+                                                            <Fragment key={index}>
+                                                                {reward.ratio > 0 ? (
+                                                                    <span className="amountTips">
+                                                                        {t("DepositPage.Oferecer")}{" "}
+                                                                        {reward.ratio}%
+                                                                    </span>
+                                                                ) : null}
+                                                                {reward.reward > 0 ? (
+                                                                    <span className="amountTips">
+                                                                        + {reward.reward}
+                                                                    </span>
+                                                                ) : null}
+                                                            </Fragment>
+                                                        );
+                                                    })}
                                         </div>
                                     </li>
                                 ))}

+ 35 - 14
src/app/[locale]/(enter)/components/Form/index.tsx

@@ -175,6 +175,21 @@ const FormComponent: FC<Props> = (props) => {
 
         looseHandler(values);
     };
+    const loginHandler = async (values: FormProps) => {
+        const loginResult = await loginApi(values).catch((error) => {
+            Toast.show({
+                content: t(`code.${error.data.code}`),
+            });
+        });
+        if (loginResult?.code === 200) {
+            setCookies("Token", loginResult.data.token as string);
+            const result = await userInfoApi();
+            if (result.code === 200) {
+                setUserInfo(result.data);
+                return result;
+            }
+        }
+    };
     /// 宽松模式
     const looseHandler = async (values: FormProps) => {
         // 请求
@@ -184,9 +199,11 @@ const FormComponent: FC<Props> = (props) => {
         // 注册
         if (type === "register") {
             registerApi(values)
-                .then((res) => {
+                .then(async (res) => {
                     if (res.code === 200) {
-                        router.replace("/login");
+                        loginHandler(values).then(() => {
+                            router.replace("/recharge");
+                        });
                     }
                 })
                 .catch((error) => {
@@ -199,19 +216,23 @@ const FormComponent: FC<Props> = (props) => {
                 });
         } else {
             /// 登录
-            const loginResult = await loginApi(values).catch((error) => {
-                Toast.show({
-                    content: t(`code.${error.data.code}`),
-                });
+
+            loginHandler(values).then(() => {
+                router.replace(`/${searchParams.get("redirect")}` || "/");
             });
-            if (loginResult?.code === 200) {
-                setCookies("Token", loginResult.data.token as string);
-                const result = await userInfoApi();
-                if (result.code === 200) {
-                    setUserInfo(result.data);
-                    router.replace(`/${searchParams.get("redirect")}` || "/");
-                }
-            }
+            // const loginResult = await loginApi(values).catch((error) => {
+            //     Toast.show({
+            //         content: t(`code.${error.data.code}`),
+            //     });
+            // });
+            // if (loginResult?.code === 200) {
+            //     setCookies("Token", loginResult.data.token as string);
+            //     const result = await userInfoApi();
+            //     if (result.code === 200) {
+            //         setUserInfo(result.data);
+            //
+            //     }
+            // }
         }
     };
 

+ 24 - 0
src/app/[locale]/(navbar)/recharge/layout.tsx

@@ -0,0 +1,24 @@
+import HeaderBack from "@/components/HeaderBack";
+import { getTranslations } from "next-intl/server";
+import { ReactNode } from "react";
+export const generateMetadata = async () => {
+    const t = await getTranslations("titles");
+    return {
+        title: t("transactions"),
+    };
+};
+export default async function Layout({
+    children,
+    params: { locale },
+}: {
+    children: ReactNode;
+    params: { locale: string };
+}) {
+    const t = await getTranslations("ProfilePage");
+    return (
+        <>
+            <HeaderBack showBack={false} title={t("transactions")} />
+            <main className={"main-header bg-[#282828]"}>{children}</main>
+        </>
+    );
+}

+ 13 - 0
src/app/[locale]/(navbar)/recharge/page.tsx

@@ -0,0 +1,13 @@
+"use client";
+import { RechargeContent } from "@/components/Box/UserRecharge";
+import { useEffect } from "react";
+
+const Page = () => {
+    useEffect(() => {}, []);
+    return (
+        <div>
+            <RechargeContent onCancel={() => {}} type={"page"} />
+        </div>
+    );
+};
+export default Page;

+ 3 - 1
src/components/Box/Desktop.tsx

@@ -19,6 +19,7 @@ interface Props {
 const Desktop = forwardRef<DesktopRefProps, Props>(function Desktop(props, ref) {
     const prompt = useRef<Event | null>(null);
     const { source = "page" } = props;
+    const elementRef = useRef<HTMLElement | null>(null);
 
     const t = useTranslations("HomePage");
     // const { isHasDesktop, setHasDesktop } = useSystemStore((state) => {
@@ -49,6 +50,7 @@ const Desktop = forwardRef<DesktopRefProps, Props>(function Desktop(props, ref)
     };
 
     useEffect(() => {
+        elementRef.current = document.getElementById("app");
         window.addEventListener("beforeinstallprompt", initDesktop);
         // @ts-ignore
         window.onappinstalled = function (ev) {
@@ -73,7 +75,7 @@ const Desktop = forwardRef<DesktopRefProps, Props>(function Desktop(props, ref)
     return (
         <Popup
             visible={!!isHasDesktop}
-            getContainer={document.getElementById("app")}
+            getContainer={elementRef.current}
             bodyStyle={{ padding: "0.2rem", background: "#fff" }}
         >
             <div className={"flex text-[0.12rem] text-[#8d8d8d]"}>

+ 143 - 0
src/components/Box/UserRecharge.tsx

@@ -0,0 +1,143 @@
+"use client";
+import { useRouter } from "@/i18n";
+import { getToken } from "@/utils/Cookies";
+import { Mask } from "antd-mobile";
+import { useTranslations } from "next-intl";
+import Image from "next/image";
+import { FC, forwardRef, useImperativeHandle, useRef, useState } from "react";
+
+interface Props {}
+
+export interface ModalRefProps {
+    onClose?: () => void;
+    onOpen?: (data: any, index: number) => void;
+}
+
+export interface RechargeContentProps {
+    onCancel: () => void;
+    type?: "page" | "popup";
+}
+export const RechargeContent: FC<RechargeContentProps> = (props) => {
+    const { onCancel, type = "popup" } = props;
+    const t = useTranslations("HomePage");
+    const token = getToken();
+    const router = useRouter();
+    const receiveHandler = () => {
+        if (token) {
+            router.push("/deposit");
+        } else {
+            router.push("/login?redirect=deposit");
+        }
+        onCancel();
+    };
+    return (
+        <div className={""}>
+            <div className={"relative mt-[10vh]"}>
+                {type === "popup" ? (
+                    <div
+                        onClick={onCancel}
+                        className={
+                            "absolute right-[10%] top-0 h-[0.1736rem] w-[0.1736rem]" +
+                            " rounded-[50%] border-[2px] border-[#dcd8bb] text-[#dcd8bb]" +
+                            " flex items-center justify-center"
+                        }
+                    >
+                        <span className={"iconfont icon-guanbi"}></span>
+                    </div>
+                ) : null}
+
+                <div className={"absolute -top-[0.34rem] left-0 -z-10 h-[100%] w-[100%]"}>
+                    <img src={"/recharge/bg.png"} className={"h-[100%] w-[100%]"} />
+                </div>
+                <div className={"absolute left-0 top-0 -z-[9] h-[100%] w-[100%]"}>
+                    <img src={"/recharge/bg1.png"} className={"h-[100%] w-[100%]"} />
+                </div>
+                <Image
+                    src={"/recharge/content.png"}
+                    alt={"recharge"}
+                    className={"z-2 w-[100%]"}
+                    width={750}
+                    height={694}
+                />
+                <div
+                    className={
+                        "absolute bottom-[0.59rem] h-[0.50rem] w-[100%] " + " flex justify-center"
+                    }
+                >
+                    <svg viewBox="0 -15 200 50" style={{ width: "100%", height: "100%" }}>
+                        <path d="M0 30 C 50 10, 150 10 200 30" fill="transparent" id="circle" />
+                        <text
+                            style={{
+                                fill: "#ff3333",
+                                fontSize: "22px",
+                                fontWeight: "bold",
+                                textShadow: "0.1em 0.1em rgba(0,0,0,0.5)",
+                            }}
+                        >
+                            <textPath
+                                xlinkHref="#circle"
+                                textAnchor="middle"
+                                startOffset="50%"
+                                dy="0"
+                            >
+                                <tspan>{t("rechargeTitle")}</tspan>
+                            </textPath>
+                        </text>
+                    </svg>
+                </div>
+                <div
+                    className={
+                        "absolute bottom-[0px] right-[50%] flex h-[0.45rem] " +
+                        " items-center" +
+                        " mb-[0.13rem] translate-x-1/2 font-bold text-[#fee5c1]"
+                    }
+                >
+                    {t("rechargeTips", { num: "100%" })}
+                </div>
+            </div>
+            <div className={"relative flex w-[100%] justify-center"}>
+                <div
+                    style={{
+                        background: "url(/recharge/button.png)",
+                        backgroundRepeat: "no-repeat",
+                        backgroundSize: "100% 100%",
+                    }}
+                    onClick={receiveHandler}
+                    className={
+                        "flex h-[0.7rem] w-[1.5972rem] items-center justify-center" +
+                        " text-[0.1528rem] font-bold text-[#fff]"
+                    }
+                >
+                    <span> {t("rechargeButton")}</span>
+                </div>
+            </div>
+        </div>
+    );
+};
+const UserRecharge = forwardRef<ModalRefProps, Props>(function UserRecharge(props, ref) {
+    const [visible, setVisible] = useState(false);
+
+    const recharges = useRef<any>();
+    const activeIndex = useRef<number>(0);
+
+    useImperativeHandle(ref, () => {
+        return {
+            onClose: () => setVisible(false),
+            onOpen: (source: any, index?: number) => {
+                recharges.current = source;
+                console.log(`🚀🚀🚀🚀🚀-> in UserRecharge.tsx on 36`, source);
+                if (index !== null && index !== undefined) {
+                    activeIndex.current = index;
+                }
+                setVisible(true);
+            },
+        };
+    });
+    return (
+        <Mask visible={visible} onMaskClick={() => setVisible(false)}>
+            <RechargeContent onCancel={() => setVisible(false)} />
+        </Mask>
+    );
+});
+
+export default UserRecharge;