Selaa lähdekoodia

feat: 增加输钱返水页面

Before 7 kuukautta sitten
vanhempi
commit
878bd126e3

+ 2 - 2
.env.development

@@ -1,7 +1,7 @@
 # 环境
 #baseurl
-NEXT_PUBLIC_BASE_URL=http://192.168.0.84:8800
-#NEXT_PUBLIC_BASE_URL=http://192.168.0.67:8800
+#NEXT_PUBLIC_BASE_URL=http://192.168.0.84:8800
+NEXT_PUBLIC_BASE_URL=http://192.168.0.67:8800
 #share link
 NEXT_PUBLIC_SHARE_URL=http://192.168.0.84:3000
 

BIN
public/doings/activity.png


BIN
public/img/cashback-details.jpg


BIN
public/wheels/group.png


+ 29 - 0
src/api/cashback.ts

@@ -1,3 +1,5 @@
+import { server } from "@/utils/client";
+
 export interface CashbackTypes {
     /**
      * 返现金额
@@ -67,3 +69,30 @@ export interface Rule {
      */
     level: number;
 }
+
+/**
+ * 获取输返活动信息
+ *   POST /v1/api/front/activity_lose_back
+ *   接口ID:239540305
+ *   接口地址:https://app.apifox.com/link/project/4790544/apis/api-239540305
+ */
+
+export interface ActivityType {
+    /**
+     * VIP等级
+     */
+    level: number;
+    /**
+     * 最大补偿金额
+     */
+    max_value: number;
+    /**
+     * 补偿比例
+     */
+    ratio: number;
+}
+export const getActivityLoseApi = () => {
+    return server.post<ActivityType>({
+        url: "/v1/api/front/activity_lose_back",
+    });
+};

+ 4 - 0
src/api/user.ts

@@ -235,6 +235,10 @@ export interface Wallet {
      * 用户名
      */
     user_name: string;
+
+    gift_packet: {
+        amount: number;
+    };
 }
 // 前台用户获取金额信息
 export const getUserMoneyApi = () => {

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

@@ -0,0 +1,57 @@
+"use client";
+import { useWalletStore } from "@/stores/useWalletStore";
+import { Mask } from "antd-mobile";
+import { useEffect, useState } from "react";
+
+const ActivityMask = () => {
+    const [visible, setVisible] = useState<boolean>(false);
+
+    const wallet = useWalletStore((state) => state.wallet);
+    useEffect(() => {
+        if (wallet.gift_packet.amount > 0) {
+            setVisible(true);
+        }
+    }, [wallet.gift_packet.amount]);
+
+    return (
+        <Mask visible={visible} destroyOnClose={true} getContainer={null}>
+            {/*<div*/}
+            {/*    className={"absolute right-[0.2083rem] top-[20%] z-50"}*/}
+            {/*    onClick={() => setVisible(false)}*/}
+            {/*>*/}
+            {/*    <span className={"iconfont icon-guanbi"}></span>*/}
+            {/*</div>*/}
+            <div className={"absolute top-[20%] z-50"}>
+                <div className={"h-[4.2rem] w-[100%]"}>
+                    <div
+                        className={"iconfont icon-guanbi absolute right-[30px]"}
+                        onClick={() => setVisible(false)}
+                    ></div>
+                    <img src={"/doings/activity.png"} className={"h-[4.1667rem] object-contain"} />
+
+                    <div
+                        className={
+                            "absolute -left-[8%] top-[28%] h-[2.0833rem] w-[56%]" +
+                            " translate-x-1/2" +
+                            " p-[0.0694rem] text-[#000]"
+                        }
+                    >
+                        <div className={"text-center font-bold"}>Um presente</div>
+                        <div className={"mt-[0.0294rem] text-center"}>
+                            <span>Não tive sorte hoje,</span>
+                            <span>Continue com o bom trabalho</span>
+                        </div>
+                        <div className={"mt-[0.4167rem] flex items-center justify-center"}>
+                            <span className={"mr-[0.0694rem]"}>presente: </span>
+                            <span className={"text-[0.2083rem] font-bold"}>
+                                {wallet.gift_packet.amount}
+                            </span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </Mask>
+    );
+};
+
+export default ActivityMask;

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

@@ -4,6 +4,7 @@ import WheelModal from "@/components/Box/WheelModal";
 import { server } from "@/utils/server";
 import HomeMessage from "../_home/HomeMessage";
 import HomePromotion from "../_home/HomePromotion";
+import ActivityMask from "./ActivityMask";
 const getPromotions = async () => {
     return server
         .request<PromotionRep[], { summery: { showType: 1 | 2 } }>({
@@ -45,6 +46,9 @@ const Page = async () => {
 
             {/*  轮盘弹窗 */}
             <WheelModal />
+
+            {/*  */}
+            <ActivityMask />
         </>
     );
 };

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

@@ -210,9 +210,9 @@ const FormComponent: FC<Props> = (props) => {
                 channel_code: localStorage.getItem("channel_code") ?? undefined,
 
                 //  轮盘邀请
-                turntable_id: sessionStorage.getItem("turntable_id") ?? undefined,
-                turntable_user_id: sessionStorage.getItem("turntable_user_id") ?? undefined,
-                turntable_time: sessionStorage.getItem("turntable_time") ?? undefined,
+                turntable_id: Number(sessionStorage.getItem("turntable_id")) ?? undefined,
+                turntable_user_id: Number(sessionStorage.getItem("turntable_user_id")) ?? undefined,
+                turntable_time: Number(sessionStorage.getItem("turntable_time")) ?? undefined,
             };
             registerApi(newValues)
                 .then(async (res) => {

+ 77 - 0
src/app/[locale]/(navbar)/cashbackDetails/DetailsTable.tsx

@@ -0,0 +1,77 @@
+"use client";
+import Box from "@/components/Box";
+import Table, { TableHeaderItem } from "@/components/Table";
+import { useTranslations } from "next-intl";
+import { JSX } from "react";
+
+interface Props {
+    data: Datum[];
+}
+export interface Datum {
+    /**
+     * VIP等级
+     */
+    level: number;
+    /**
+     * 最大补偿金额
+     */
+    max_value: number;
+    /**
+     * 补偿比例
+     */
+    ratio: number;
+}
+const DetailsTable = (props: Props) => {
+    const { data } = props;
+    const t = useTranslations("cashback");
+    const columns: TableHeaderItem[] = [
+        {
+            title: <div className={"text-center text-primary-color"}>VIP</div>,
+            dataIndex: "level",
+            align: "center",
+            width: "20%",
+            render: (item: Datum) => (
+                <div className={"text-[0.13rem] font-bold text-[#2b2b2b]"}>{item.level}</div>
+            ),
+        },
+        {
+            title: <div className={"text-center text-primary-color"}>APOSTA</div>,
+            dataIndex: "aposta",
+            align: "center",
+            width: "40%",
+            render: (item: Datum) => (
+                <div className={"text-[0.13rem] font-bold text-[#2b2b2b]"}>
+                    {item.max_value} + BRL
+                </div>
+            ),
+        },
+        {
+            title: (
+                <div className={"text-center text-primary-color"}>CASHBACK</div>
+            ) as JSX.Element,
+            dataIndex: "cashback",
+            align: "center",
+            render: (item: Datum) => (
+                <div className={"text-[0.13rem] font-bold text-[#2b2b2b]"}>{item.ratio}%</div>
+            ),
+        },
+    ];
+    const loadMore = async () => {
+        return Promise.resolve();
+    };
+    return (
+        <Box className={"mt-[20px] rounded-[10px] bg-[#ededed]"}>
+            <div className={"mb-[10px]"}> {t("cashbackStatus")}</div>
+            <Table
+                columns={columns}
+                dataSource={data}
+                loadMore={loadMore}
+                hasMore={false}
+                isLoadMore={false}
+                isBackground={true}
+            />
+        </Box>
+    );
+};
+
+export default DetailsTable;

+ 32 - 0
src/app/[locale]/(navbar)/cashbackDetails/layout.tsx

@@ -0,0 +1,32 @@
+import Box from "@/components/Box";
+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("cashback"),
+    };
+};
+export default async function Layout({
+    children,
+    params: { locale },
+}: {
+    children: ReactNode;
+    params: { locale: string };
+    cashbackInfo: ReactNode;
+    // cashbackTable: ReactNode;
+}) {
+    const t = await getTranslations("cashback");
+    return (
+        <>
+            <HeaderBack showBack={true} title={t("cashbackTitle")} />
+            <main className={"main-header bg-[#1f2225] text-[#000]"}>
+                <Box>
+                    {/*{cashbackTable}*/}
+                    {children}
+                </Box>
+            </main>
+        </>
+    );
+}

+ 22 - 0
src/app/[locale]/(navbar)/cashbackDetails/page.tsx

@@ -0,0 +1,22 @@
+import { server } from "@/utils/server";
+import DetailsTable, { Datum } from "./DetailsTable";
+
+const getTableData = () => {
+    return server.request<Datum[]>({
+        url: "/v1/api/front/activity_lose_back",
+        method: "post",
+    });
+};
+
+const Page = async () => {
+    const result = await getTableData();
+    return (
+        <div>
+            <img src={"/img/cashback-details.jpg"} />
+
+            <DetailsTable data={result.data} />
+        </div>
+    );
+};
+
+export default Page;

+ 133 - 60
src/app/[locale]/(wheel)/cashWheel/CashWheelClient.tsx

@@ -7,19 +7,20 @@ import { Link } from "@/i18n/routing";
 import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { copyText, timeFormat } from "@/utils/methods";
 import { useCountDown } from "ahooks";
-import { Mask, Popup, Toast } from "antd-mobile";
+import { Popup, Toast } from "antd-mobile";
 import clsx from "clsx";
 import { useTranslations } from "next-intl";
 import Image from "next/image";
-import { createContext, FC, useContext, useEffect, useState } from "react";
+import { createContext, FC, Fragment, useContext, useEffect, useState } from "react";
 import LotteryWheel from "./LotteryWheel";
 import styles from "./style.module.scss";
 interface Props {
     // wheel: WheelsType;
     allHistory: any[];
+    selfHistory: any[];
+    phones: any[];
 }
-interface ContextType extends WheelsType {
-    allHistory: any[];
+interface ContextType extends WheelsType, Props {
     handler: () => void;
 }
 const WheelContext = createContext<Partial<ContextType>>({});
@@ -115,6 +116,57 @@ const LeftListClient = () => {
         </>
     );
 };
+
+const RightListClient = () => {
+    const wheel = useContext(WheelContext);
+    return (
+        <div className={"h-[100%] overflow-scroll p-[10px]"}>
+            <div
+                className={
+                    "grid grid-cols-[1.3889rem_1fr_0.6944rem] gap-y-[0.1389rem] text-[0.0972rem]" +
+                    " text-[#8795b1]"
+                }
+            >
+                {wheel.selfHistory &&
+                    wheel.selfHistory.map((n, index) => {
+                        return (
+                            <Fragment key={index}>
+                                <div className={"flex"}>
+                                    <span
+                                        className={"mr-[0.0694rem] text-[0.12rem] text-[#6ddf39]"}
+                                    >
+                                        +100.00
+                                    </span>
+                                    <div
+                                        className={
+                                            "h-[0.16rem] w-[0.16rem] rounded-[50%] bg-[#6ddf39] text-center" +
+                                            " text-[0.07rem] leading-[0.16rem] text-[#fff]"
+                                        }
+                                    >
+                                        R$
+                                    </div>
+                                </div>
+                                <div className={"flex flex-1"}>
+                                    {" "}
+                                    {timeFormat(Date.now(), "br", undefined, true)}
+                                </div>
+                                <div className={"flex justify-end text-[#f0ae18]"}>
+                                    <Image
+                                        className={"mr-[0.0694rem] object-contain"}
+                                        src={"/wheels/group.png"}
+                                        alt={"group"}
+                                        width={20}
+                                        height={8}
+                                    />
+                                    <span>+12</span>
+                                </div>
+                            </Fragment>
+                        );
+                    })}
+            </div>
+        </div>
+    );
+};
 const Report = () => {
     const [activeTab, setActiveTab] = useState<Dtltype>("left");
 
@@ -152,7 +204,7 @@ const Report = () => {
                 <div className={styles.vanTabsContent}>
                     <div className={styles.vantabpane}>
                         <div className={styles.tabContent}>
-                            {activeTab === "left" ? <LeftListClient /> : null}
+                            {activeTab === "left" ? <LeftListClient /> : <RightListClient />}
                         </div>
                     </div>
                 </div>
@@ -311,7 +363,9 @@ const DrawMain = () => {
         <div className={"relative"}>
             <WheelWallet />
 
-            <WheelClient isRotate={true} wheel={wheel} onRotateEnd={wheel.handler!} />
+            <div className={"pt-[0.1389rem]"}>
+                <WheelClient isRotate={true} wheel={wheel} onRotateEnd={wheel.handler!} />
+            </div>
         </div>
     );
 };
@@ -351,11 +405,21 @@ const CountdownClient = () => {
         </div>
     );
 };
+const phones = Array(9)
+    .fill(0)
+    .map((_, i) => {
+        const num = `557894567${Math.floor(Math.random() * 1000)
+            .toString()
+            .padStart(4, "0")}`;
+        return num;
+    });
 const ShareClient = () => {
     const [visible, setVisible] = useState(false);
     const wheel = useContext(WheelContext);
     const user = useUserInfoStore((state) => state.userInfo);
 
+    const [currentPhoneIndex, setCurrentPhoneIndex] = useState(0);
+
     const shareUrl = `${process.env.NEXT_PUBLIC_SHARE_URL}/br/sharecwbr?turntable=${wheel.activities && wheel.activities[0].id}&user=${user.id}&time=${wheel.activate?.end_time}`;
     const url = encodeURIComponent(`${shareUrl}`);
     const text = encodeURIComponent(`Receba 100 BRL de graça,Pix SAQUE RÁPIDO`);
@@ -392,6 +456,11 @@ const ShareClient = () => {
         copyText(text);
         Toast.show({ icon: "success", content: t("SummaryPage.copySuc"), maskClickable: false });
     };
+    const handler = () => {
+        const current = phones[currentPhoneIndex];
+        window.open(`https://wa.me/${current}`);
+        setCurrentPhoneIndex((value) => (value += 1));
+    };
 
     return (
         <>
@@ -431,7 +500,7 @@ const ShareClient = () => {
                     setVisible(false);
                 }}
                 showCloseButton
-                bodyStyle={{ height: "2.9rem", background: "#fff" }}
+                bodyStyle={{ background: "#fff" }}
             >
                 <div className={"p-[0.1389rem] text-[#555555]"}>
                     <h1>1.Convide amlgos para ajudar com saques</h1>
@@ -479,48 +548,64 @@ const ShareClient = () => {
                     <div className={"mt-[0.0694rem]"}>
                         <h1>2.Enviar convite para jogador aleatório ajudar</h1>
 
-                        <div
-                            className={
-                                "grid grid-cols-2 gap-[0.1389rem] text-[0.12rem] text-[#fff]" +
-                                " mt-[0.0694rem]"
-                            }
-                        >
-                            <Link
-                                href={"#"}
-                                className={
-                                    "flex items-center rounded-[0.0694rem] bg-[#10cb8c]" +
-                                    " p-[0.0694rem] text-[#fff]"
-                                }
-                            >
-                                <div className={"flex-1"}>
-                                    <p>Enviar Mensagem </p>
-                                    <p>no WhatsAPP</p>
-                                </div>
-                                <Image
-                                    src={"/summary/WhatsApp-nobg.png"}
-                                    alt={"whatsApp"}
-                                    width={40}
-                                    height={40}
-                                />
-                            </Link>
-                            <Link
-                                href={"sms:10086?body=message_body"}
+                        <div className={"mt-[0.0694rem] bg-[#000] p-[10px]"}>
+                            <div className={"grid grid-cols-3 gap-[5px] text-[0.0833rem]"}>
+                                {phones.map((phone, index) => {
+                                    return (
+                                        <span
+                                            style={{
+                                                color: index < currentPhoneIndex ? "#fff" : "#ccc",
+                                            }}
+                                            key={index}
+                                        >
+                                            {phone}
+                                        </span>
+                                    );
+                                })}
+                            </div>
+
+                            <div
                                 className={
-                                    "flex items-center rounded-[10px] bg-[#35b2fe]" +
-                                    " p-[0.0694rem] text-[#fff]"
+                                    "grid grid-cols-2 gap-[0.1389rem] text-[0.12rem] text-[#fff]"
                                 }
                             >
-                                <div className={"flex-1"}>
-                                    <p>Enviar Mensagem </p>
-                                    <p>SMS</p>
+                                <div
+                                    onClick={handler}
+                                    className={
+                                        "flex items-center rounded-[0.0694rem] bg-[#10cb8c]" +
+                                        " p-[0.0694rem] text-[#fff]"
+                                    }
+                                >
+                                    <div className={"flex-1"}>
+                                        <p>Enviar Mensagem </p>
+                                        <p>no WhatsAPP</p>
+                                    </div>
+                                    <Image
+                                        src={"/summary/WhatsApp-nobg.png"}
+                                        alt={"whatsApp"}
+                                        width={40}
+                                        height={40}
+                                    />
                                 </div>
-                                <Image
-                                    src={"/summary/SMS.png"}
-                                    alt={"whatsApp"}
-                                    width={40}
-                                    height={40}
-                                />
-                            </Link>
+                                <Link
+                                    href={`sms:${phones.join(";")}?body=message_body`}
+                                    className={
+                                        "flex items-center rounded-[10px] bg-[#35b2fe]" +
+                                        " p-[0.0694rem] text-[#fff]"
+                                    }
+                                >
+                                    <div className={"flex-1"}>
+                                        <p>Enviar Mensagem </p>
+                                        <p>SMS</p>
+                                    </div>
+                                    <Image
+                                        src={"/summary/SMS.png"}
+                                        alt={"whatsApp"}
+                                        width={40}
+                                        height={40}
+                                    />
+                                </Link>
+                            </div>
                         </div>
                     </div>
                 </div>
@@ -529,20 +614,6 @@ const ShareClient = () => {
     );
 };
 
-const ReceiveClient = () => {
-    const wheel = useContext(WheelContext);
-    console.log(`🚀🚀🚀🚀🚀-> in CashWheelClient.tsx on 664`, wheel);
-    const receiveHandler = () => {
-        console.log(`🚀🚀🚀🚀🚀-> in CashWheelClient.tsx on 666`);
-    };
-    return (
-        <Mask visible={false}>
-            <div className={"absolute top-1/2 flex w-[100%] items-center justify-center"}>
-                <Image src={"/wheels/receive-button.png"} alt={"receive"} height={0} width={160} />
-            </div>
-        </Mask>
-    );
-};
 const CashWheelClient: FC<Props> = (props) => {
     const getWheelData = async () => {
         return getWheelApi().then((res) => {
@@ -558,6 +629,8 @@ const CashWheelClient: FC<Props> = (props) => {
     const [values, setValues] = useState<Partial<ContextType>>({
         num: 100,
         allHistory: props.allHistory || [],
+        selfHistory: props.selfHistory || [],
+        phones: props.phones || [],
         handler: getWheelData,
     });
     useEffect(() => {
@@ -571,7 +644,7 @@ const CashWheelClient: FC<Props> = (props) => {
                 {/*倒计时*/}
                 <CountdownClient />
                 {/*分享*/}
-                <ShareClient />
+                {values.activate && values.activate?.end_time > 0 ? <ShareClient /> : null}
                 <div className={styles.cashWheelClient}>
                     {/*<CashMainCom />*/}
                     {/*<DrawContent />*/}

+ 22 - 2
src/app/[locale]/(wheel)/cashWheel/page.tsx

@@ -7,10 +7,30 @@ const getAllHistoryApi = () => {
         method: "POST",
     });
 };
+const getSelfHistoryApi = () => {
+    return server.request<any[]>({
+        url: "/v1/api/user/turntable/self_receive",
+        method: "POST",
+    });
+};
+const getPhoneNumbersApi = () => {
+    return server.request<any[]>({
+        url: "/v1/api/user/turntable/phone_number",
+        method: "POST",
+    });
+};
+
 const CashWheel = async () => {
     const historyResult = await getAllHistoryApi();
-    // 将数据传递给客户端组件
-    return <CashWheelClient allHistory={historyResult.data} />;
+    const selfHistoryResult = await getSelfHistoryApi();
+    const phonesResult = await getPhoneNumbersApi();
+    return (
+        <CashWheelClient
+            allHistory={historyResult.data}
+            selfHistory={selfHistoryResult.data}
+            phones={phonesResult.data}
+        />
+    );
 };
 
 export default CashWheel;

+ 0 - 1
src/middleware.ts

@@ -22,7 +22,6 @@ const whiteRouters = ["/"];
 function authMiddleware(next: Function) {
     return async (request: NextRequest, res: NextResponse) => {
         const url = request.nextUrl;
-        console.log(`🚀🚀🚀🚀🚀-> in middleware.ts on 24`, url);
         return next(request, res);
     };
 }

+ 3 - 0
src/stores/useWalletStore.ts

@@ -39,6 +39,9 @@ const initialState: State = {
         total_red_packet: 0,
         total_score_rollover: 0,
         user_name: "",
+        gift_packet: {
+            amount: 0,
+        },
     },
     score: undefined,
 };