Ver Fonte

feat: Merge branch 'dev-year0606' into v1.5

year há 1 mês atrás
pai
commit
52efca0019

+ 2 - 1
messages/br.json

@@ -194,7 +194,8 @@
         "bouns6001": "Condições não satisfeitas",
         "bouns6002": "No Bouns está aberto, não é possível receber",
         "success": "Sucesso",
-        "depositeWarn": "Você está no modo sem bônus. Continuar?"
+        "depositeWarn": "Você está no modo sem bônus. Continuar?",
+        "email": "E-mail"
     },
     "DepositPage": {
         "Montante": "Alcance de recarga",

BIN
public/notice/gift.png


BIN
public/notice/gift2.png


+ 20 - 0
src/api/home.ts

@@ -315,6 +315,25 @@ export const getFreeGamesApi = (props: SearchProps) => {
  *   接口ID:240731148
  *   接口地址:https://app.apifox.com/link/project/4790544/apis/api-240731148
  */
+
+export interface EmailAttachItem {
+    coin_type: Number;
+    amount: Number;
+}
+export interface EmailNoticeRep {
+    id: number;
+    title: string;
+    content: string;
+    mail_tips: string;
+    mail_type: number;
+    time_last: number;
+    display_type: number;
+    status: number;
+    attach: EmailAttachItem[];
+    create_at: number;
+    image?: string;
+}
+
 export const getReplayGamesApi = (props: SearchProps) => {
     return server.post<GameListRep[]>({
         url: "/v1/api/front/game_list_again",
@@ -327,6 +346,7 @@ export interface GlobalNoticeRep extends Omit<NoticeRep, "content"> {
     send_time: number;
     send_user_time: number;
 }
+
 export const getGlobalNoticeApi = () => {
     return server.post<NoticeRep[], { summery: { unread: number; promotion_count: number } }>({
         url: "/v1/api/front/notice_list",

+ 14 - 14
src/app/[locale]/(TabBar)/_deposit/DepositData.tsx

@@ -13,7 +13,7 @@ import { useWalletStore } from "@/stores/useWalletStore";
 import "@/styles/deposit.scss";
 import { neReg } from "@/utils";
 import { server } from "@/utils/client";
-import { Button, Dialog, Form, Input, Toast } from "antd-mobile";
+import { Button, Form, Input, Toast } from "antd-mobile";
 import { FormInstance } from "antd-mobile/es/components/form";
 import clsx from "clsx";
 import { useTranslations } from "next-intl";
@@ -115,19 +115,19 @@ const DepositData: FC<Props> = (props) => {
         setCurrentProduct(result);
     };
     const onFinish = async (values: any) => {
-        if (wallet?.is_open_no_bonus) {
-            const confirmRes = await Dialog.confirm({
-                content: <div className="text-[#fff]">{t(`ProfilePage.depositeWarn`)}</div>,
-                confirmText: t("ProfilePage.sure"),
-                cancelText: t("ProfilePage.cancel"),
-                bodyStyle: {
-                    backgroundColor: "#373737",
-                    color: "#fff",
-                },
-                bodyClassName: "customConfirm",
-            });
-            if (!confirmRes) return;
-        }
+        // if (wallet?.is_open_no_bonus) {
+        //     const confirmRes = await Dialog.confirm({
+        //         content: <div className="text-[#fff]">{t(`ProfilePage.depositeWarn`)}</div>,
+        //         confirmText: t("ProfilePage.sure"),
+        //         cancelText: t("ProfilePage.cancel"),
+        //         bodyStyle: {
+        //             backgroundColor: "#373737",
+        //             color: "#fff",
+        //         },
+        //         bodyClassName: "customConfirm",
+        //     });
+        //     if (!confirmRes) return;
+        // }
 
         if (!amount) return Toast.show({ content: t("form.amount") });
         const params = {

+ 30 - 0
src/app/[locale]/(navbar)/emailDetail/layout.tsx

@@ -0,0 +1,30 @@
+import HeaderBack from "@/components/HeaderBack";
+import { getTranslations } from "next-intl/server";
+import { ReactNode } from "react";
+import styles from "./page.module.scss";
+export const generateMetadata = async () => {
+    const t = await getTranslations("titles");
+    return {
+        title: t("message"),
+    };
+};
+export default async function Layout({
+    children,
+    params: { locale },
+}: {
+    children: ReactNode;
+    params: { locale: string };
+}) {
+    const t = await getTranslations("ProfilePage");
+    return (
+        <div className="h-[100%] overflow-auto bg-[#1e252b]">
+            <HeaderBack
+                showBack={true}
+                title={"Regresso"}
+                useBg={false}
+                className={styles.header}
+            />
+            <main className={"main-header bg-[#0b0e10]"}>{children}</main>
+        </div>
+    );
+}

+ 102 - 0
src/app/[locale]/(navbar)/emailDetail/page.module.scss

@@ -0,0 +1,102 @@
+.emailDetail {
+    background-color: #0b0e10;
+    padding: 0.15rem;
+    line-height: 1.2;
+}
+.title {
+    color: #f0f3f5;
+    font-size: 0.18rem;
+    word-wrap: break-word;
+    word-break: break-word;
+}
+.date {
+    color: #5d7284;
+    font-size: 0.11rem;
+    margin-top: 0.06rem;
+}
+.content {
+    margin-top: 0.1rem;
+}
+.img {
+    width: 100%;
+    border-radius: 0.1rem;
+    margin-bottom: 0.1rem;
+}
+.contentText {
+    color: #b2bcc5;
+}
+
+.more {
+    text-align: center;
+    color: #11de68;
+    margin-top: 0.3rem;
+}
+.giftBox {
+    background-color: #1f2830;
+    border-radius: 0.1rem;
+    box-sizing: border-box;
+    padding: 0.15rem;
+    margin-top: 0.2rem;
+    .giftItem {
+        background-color: #2a333b;
+        border-radius: 0.1rem;
+        padding: 0.1rem;
+        display: flex;
+        align-items: center;
+        margin-bottom: 0.1rem;
+        img {
+            width: 0.7rem;
+            margin-right: 0.1rem;
+        }
+    }
+    .giftDesc {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        min-width: 0;
+        :nth-child(1) {
+            word-wrap: break-word;
+            word-break: break-word;
+        }
+        :nth-child(2) {
+            color: #11de68;
+        }
+    }
+}
+
+.btnBox {
+    text-align: center;
+    button {
+        background-image: linear-gradient(to bottom, #befd53, #3bbb0e);
+        border-radius: 0.2rem;
+        height: 0.36rem;
+        width: 1.35rem;
+        position: relative;
+        &::before {
+            content: "";
+            position: absolute;
+            left: 0;
+            right: 0;
+            height: 100%;
+            bottom: -3px;
+            background-image: linear-gradient(to bottom, #007200, #007200);
+            border-radius: 0.2rem;
+            z-index: 0;
+        }
+        &::after {
+            content: "";
+            position: absolute;
+            left: 0;
+            right: 0;
+            height: 100%;
+            bottom: 0;
+            background-image: linear-gradient(to bottom, #befd53, #3bbb0e);
+            border-radius: 0.2rem;
+            z-index: 1;
+        }
+        span {
+            position: relative;
+            z-index: 2;
+        }
+    }
+}

+ 157 - 0
src/app/[locale]/(navbar)/emailDetail/page.tsx

@@ -0,0 +1,157 @@
+"use client";
+import { EmailNoticeRep } from "@/api/home";
+import GlobalNotify from "@/components/ModalPopup/GlobalNotifyModal";
+import { ClaimActiveErrorMap } from "@/enums";
+import { server } from "@/utils/client";
+import { formatAmount } from "@/utils/index";
+import { timeFormat } from "@/utils/methods";
+import { Toast } from "antd-mobile";
+import { useTranslations } from "next-intl";
+import { useSearchParams } from "next/navigation";
+import React from "react";
+import styles from "./page.module.scss";
+
+const getEmailNotices = () => {
+    return server.request<EmailNoticeRep[]>({
+        url: "/v1/api/user/mail/getMailList",
+        method: "POST",
+        data: {},
+    });
+};
+const changeStatus = (params: { ids: number[]; status: 1 | 0 }) => {
+    return server.request<EmailNoticeRep[]>({
+        url: "/v1/api/user/mail/setStatus",
+        method: "POST",
+        data: params,
+    });
+};
+///v1/api/user/mail/setStatus
+const receiveGift = (ids: number[]) => {
+    return server.request<any>({
+        url: "/v1/api/user/mail/claimMailReward",
+        method: "POST",
+        data: { ids },
+    });
+};
+
+const CoinMap = new Map([
+    [1, "Solad"],
+    [2, "GOLD"],
+    [3, "SILVER"],
+]);
+
+const EmailDetail = () => {
+    const t = useTranslations();
+    const searchParams = useSearchParams();
+    const [data, setData] = React.useState<EmailNoticeRep[]>([]);
+    const [amount, setAmount] = React.useState<any>({});
+    const [visible, setVisible] = React.useState<boolean>(false);
+
+    React.useEffect(() => {
+        getData();
+    }, []);
+
+    const curData = React.useMemo(() => {
+        const id = Number(searchParams.get("id"));
+        const res = data?.filter((item) => {
+            return item.id === id;
+        });
+        if (!res?.length) return {} as EmailNoticeRep;
+        return res[0];
+    }, [data, searchParams]);
+
+    const getData = async () => {
+        const id = Number(searchParams.get("id"));
+        changeStatus({
+            ids: [id],
+            status: 1,
+        });
+        const res = await getEmailNotices();
+        if (res?.code === 200) {
+            setData(res.data);
+        }
+    };
+    const doReceive = async () => {
+        Toast.show({ icon: "loading" });
+        try {
+            const res = await receiveGift([curData.id]);
+
+            if (res.code === 200 && res?.data?.code === 0) {
+                const amountObj: any = {};
+                if (res?.data?.reward) {
+                    res?.data?.reward.forEach((item: any) => {
+                        amountObj[`coin_${item.coin_type}`] = formatAmount(item.amount);
+                    });
+                }
+                if (res?.data?.extra_reward) {
+                    res?.data?.extra_reward.forEach((item: any) => {
+                        amountObj[`coin_${item.coin_type}`] = formatAmount(
+                            new BigNumber(amountObj[`coin_${item.coin_type}`] || 0)
+                                .plus(item.amount)
+                                .toString()
+                        );
+                    });
+                }
+                setAmount(amountObj);
+                setVisible(true);
+            } else {
+                throw new Error(ClaimActiveErrorMap.get(res.data.code) || t(`code.400`));
+            }
+        } finally {
+            getData();
+        }
+    };
+
+    return (
+        <div className={styles.emailDetail}>
+            <div className={styles.title}>{curData?.title}</div>
+            <div className={styles.date}>{timeFormat(curData?.create_at)}</div>
+            <div className={styles.content}>
+                {curData?.image && <img src={curData?.image} alt="" className={styles.img} />}
+                {curData?.content && (
+                    <div
+                        className={styles.contentText}
+                        dangerouslySetInnerHTML={{
+                            __html: `${curData?.content}`,
+                        }}
+                    ></div>
+                )}
+            </div>
+            <div className={styles.more}>&lt;Pular texto&gt;</div>
+            {curData.status !== 2 && (
+                <div className={styles.giftBox}>
+                    {!!curData?.attach?.length &&
+                        curData.attach.map((item, idx) => {
+                            return (
+                                <div
+                                    className={styles.giftItem}
+                                    key={`${item.coin_type}_${item.amount}`}
+                                >
+                                    <img src="/notice/gift2.png" alt="" />
+                                    <div className={styles.giftDesc}>
+                                        <div>O nome da recompensa é mostrado aqui</div>
+                                        <div>prêmio R${item.amount.toString()}</div>
+                                    </div>
+                                </div>
+                            );
+                        })}
+
+                    <div className={styles.btnBox}>
+                        <button onClick={doReceive}>
+                            <span>Receber</span>
+                        </button>
+                    </div>
+                </div>
+            )}
+
+            <GlobalNotify
+                amount={amount}
+                visible={visible}
+                onChange={() => setVisible(false)}
+                deraction={5000}
+            ></GlobalNotify>
+        </div>
+    );
+};
+
+export default EmailDetail;

+ 71 - 5
src/app/[locale]/(navbar)/notification/NotificationClient.tsx

@@ -1,14 +1,32 @@
 "use client";
-import { GlobalNoticeRep, updateGlobalNoticeApi, updateUserNoticeApi } from "@/api/home";
+import {
+    EmailNoticeRep,
+    GlobalNoticeRep,
+    updateGlobalNoticeApi,
+    updateUserNoticeApi,
+} from "@/api/home";
 import Tabs from "@/components/Tabs";
+import { useRouter } from "@/i18n/routing";
+import { server } from "@/utils/client";
 import { useTranslations } from "next-intl";
+import { useSearchParams } from "next/navigation";
 import { FC, useState } from "react";
 import actions from "./actions";
+import Email from "./components/Email";
 import { default as Notices } from "./components/Notices";
 
+const getEmailNotices = () => {
+    return server.request<EmailNoticeRep[]>({
+        url: "/v1/api/user/mail/getMailList",
+        method: "POST",
+        data: {},
+    });
+};
+
 interface Props {
     systemNotices: GlobalNoticeRep[];
     userNotices: GlobalNoticeRep[];
+    emailNotices: EmailNoticeRep[];
 }
 const setReadData = (data: GlobalNoticeRep[], key: number) => {
     const newNotices = data.map((item) => {
@@ -21,8 +39,14 @@ const setReadData = (data: GlobalNoticeRep[], key: number) => {
     return newNotices;
 };
 const NotificationClient: FC<Props> = (props) => {
+    const searchParams = useSearchParams();
+    const router = useRouter();
     const [systemNotices, setSystemNotices] = useState(props.systemNotices);
     const [userNotices, setUserNotices] = useState(props.userNotices);
+    const [emailNotices, setEmailNotices] = useState(props.emailNotices || []);
+
+    const [actKey, setActKey] = useState(searchParams.get("type") || "1");
+
     const t = useTranslations("ProfilePage");
     const handler = async (active: string, key: string) => {
         if (key === "system") {
@@ -30,29 +54,71 @@ const NotificationClient: FC<Props> = (props) => {
             if (isRead) return;
             updateGlobalNoticeApi(+active).then((r) => {});
             setSystemNotices(setReadData(systemNotices, +active));
-        } else {
+        }
+        if (key === "user") {
             const isRead = userNotices.find((item) => item.id === +active)?.is_read;
             if (isRead) return;
             setUserNotices(setReadData(userNotices, +active));
             updateUserNoticeApi(+active).then((r) => {});
         }
+        if (key === "email") {
+            const res = await getEmailNotices();
+            setEmailNotices(res?.data || []);
+        }
 
         await actions();
     };
+
     const defaultTabs = [
         {
             id: 1,
-            name: t("systemMessage"),
+            key: "1",
+            name: (
+                <div className="flex items-center text-[.14rem]">
+                    <i className="iconfont icon-laba mr-[.02rem] text-[.14rem]"></i>
+                    <div>{t("systemMessage")}</div>
+                </div>
+            ),
             content: systemNotices.reduce((count, notice) => count + (notice.is_read ? 0 : 1), 0),
             render: <Notices data={systemNotices} type={"system"} handler={handler} />,
         },
         {
             id: 2,
-            name: t("personalMessage"),
+            key: "2",
+            name: (
+                <div className="flex items-center text-[.14rem]">
+                    <i className="iconfont icon-yonghu mr-[.02rem] text-[.16rem]"></i>
+                    <div>{t("personalMessage")}</div>
+                </div>
+            ),
             content: userNotices.reduce((count, notice) => count + (notice.is_read ? 0 : 1), 0),
             render: <Notices data={userNotices} type={"user"} handler={handler} />,
         },
+        {
+            id: 3,
+            key: "3",
+            name: (
+                <div className="flex items-center text-[.14rem]">
+                    <i className="iconfont icon-duanxinguanli mr-[.02rem] text-[.18rem]"></i>
+                    <div>{t("email")}</div>
+                </div>
+            ),
+            content: emailNotices.reduce(
+                (count, notice) => count + (notice.status === 0 ? 1 : 0),
+                0
+            ),
+            render: <Email data={emailNotices} handler={handler}></Email>,
+        },
     ];
-    return <Tabs items={defaultTabs} />;
+    return (
+        <Tabs
+            items={defaultTabs}
+            activeKey={actKey}
+            onChanage={(key) => {
+                setActKey(key as string);
+                router.replace(`/notification?type=${key}`);
+            }}
+        />
+    );
 };
 export default NotificationClient;

+ 174 - 0
src/app/[locale]/(navbar)/notification/components/Email.tsx

@@ -0,0 +1,174 @@
+"use client";
+import { EmailNoticeRep } from "@/api/home";
+import Empty from "@/components/Empty";
+import GlobalNotify from "@/components/ModalPopup/GlobalNotifyModal";
+import { ClaimActiveErrorMap } from "@/enums";
+import { useRouter } from "@/i18n/routing";
+import { server } from "@/utils/client";
+import { formatAmount } from "@/utils/index";
+import { timeFormat } from "@/utils/methods";
+import { Toast } from "antd-mobile";
+import { useTranslations } from "next-intl";
+import React from "react";
+import styles from "./style.module.scss";
+
+interface Props {
+    data: EmailNoticeRep[];
+    handler?: (active: string, key: string) => void;
+}
+
+enum Status {
+    DELETE = -1,
+    UNREAD = 0,
+    READ = 1,
+    RECEIVED = 2,
+}
+
+const changeStatus = (params: { ids: number[]; status: 1 | -1 }) => {
+    return server.request<EmailNoticeRep[]>({
+        url: "/v1/api/user/mail/setStatus",
+        method: "POST",
+        data: params,
+    });
+};
+const receiveGift = (ids: number[]) => {
+    return server.request<any>({
+        url: "/v1/api/user/mail/claimMailReward",
+        method: "POST",
+        data: { ids },
+    });
+};
+
+const Email: React.FC<Props> = ({ data, handler }) => {
+    const t = useTranslations();
+    const router = useRouter();
+    const [amount, setAmount] = React.useState<any>({});
+    const [visible, setVisible] = React.useState<boolean>(false);
+
+    const goDetail = (item: EmailNoticeRep) => {
+        router.push(`/emailDetail?id=${item.id}`);
+    };
+    const doRefresh = () => {
+        if (typeof handler === "function") {
+            handler("refresh", "email");
+        }
+    };
+
+    const doDeleteRead = async () => {
+        const needSetArr: number[] = [];
+        data.filter((item) => {
+            if (item.status === Status.READ && !item?.attach?.length) {
+                needSetArr.push(item.id);
+            }
+            if (item.status === Status.RECEIVED) {
+                needSetArr.push(item.id);
+            }
+        });
+
+        if (!needSetArr?.length) return;
+        try {
+            Toast.show({ icon: "loading" });
+            await changeStatus({
+                ids: needSetArr,
+                status: -1,
+            });
+            Toast.show({ icon: "success" });
+        } finally {
+            doRefresh();
+        }
+    };
+
+    const doAllReceive = async () => {
+        const needSetArr: number[] = [];
+        data.filter((item) => {
+            if (item.status !== Status.RECEIVED && item?.attach?.length) {
+                needSetArr.push(item.id);
+            }
+        });
+
+        if (!needSetArr?.length) return;
+        try {
+            Toast.show({ icon: "loading" });
+            const res = await receiveGift(needSetArr);
+            if (res.code === 200 && res?.data?.code === 0) {
+                const amountObj: any = {};
+                if (res?.data?.reward) {
+                    res?.data?.reward.forEach((item: any) => {
+                        amountObj[`coin_${item.coin_type}`] = formatAmount(item.amount);
+                    });
+                }
+                if (res?.data?.extra_reward) {
+                    res?.data?.extra_reward.forEach((item: any) => {
+                        amountObj[`coin_${item.coin_type}`] = formatAmount(
+                            new BigNumber(amountObj[`coin_${item.coin_type}`] || 0)
+                                .plus(item.amount)
+                                .toString()
+                        );
+                    });
+                }
+                setAmount(amountObj);
+                setVisible(true);
+            } else {
+                throw new Error(ClaimActiveErrorMap.get(res.data.code) || t(`code.400`));
+            }
+        } finally {
+            doRefresh();
+        }
+    };
+
+    return (
+        <div className={styles.emailBox}>
+            <div className={styles.content}>
+                {!!data.length &&
+                    data.map((item) => {
+                        return (
+                            <div
+                                key={item.id}
+                                className={styles.emailItem}
+                                onClick={() => goDetail(item)}
+                            >
+                                <div className={styles.title}>
+                                    <div className="text-[#c6d4e1]">{item.title}</div>
+                                    <div className="mt-[.04rem] text-[.1rem] text-[#5d7284]">
+                                        {timeFormat(item.create_at)}
+                                    </div>
+                                </div>
+                                {item?.attach?.length && item.status !== Status.RECEIVED && (
+                                    <img className={styles.gift} src="/notice/gift.png" alt="" />
+                                )}
+                                {item.status === Status.UNREAD && (
+                                    <div className={styles.doGet}>Nova!!</div>
+                                )}
+                            </div>
+                        );
+                    })}
+
+                {!data?.length && (
+                    <div className="flex h-[100%] items-center justify-center">
+                        <Empty></Empty>
+                    </div>
+                )}
+            </div>
+
+            <div className={styles.footer}>
+                <div className="px-[.12rem] pb-[.12rem] text-[.1rem] text-[#697885]">
+                    Os e-mails nāo podem ser recebidos apos expirar.
+                    <br />
+                    Os e-mails recebidos sao limpos após expirar.
+                </div>
+                <div className={styles.btns}>
+                    <button onClick={doDeleteRead}>Excluir leitura</button>
+                    <button onClick={doAllReceive}>Uma peça para pegar</button>
+                </div>
+            </div>
+            <GlobalNotify
+                amount={amount}
+                visible={visible}
+                onChange={() => setVisible(false)}
+                deraction={5000}
+            ></GlobalNotify>
+        </div>
+    );
+};
+
+export default Email;

+ 26 - 22
src/app/[locale]/(navbar)/notification/components/Notices.tsx

@@ -42,15 +42,15 @@ const SystemMessage = (props: Props) => {
                                         }}
                                     ></div>
                                 )}
-                                <span className={"iconfont icon-zhankai text-[#04e8fc]"} />
+                                <span className={"iconfont icon-zhankai text-[#4d789e]"} />
                             </div>
                         }
                         title={
                             <section>
                                 <header className={"flex items-center"}>
-                                    <h6 className={""}>{notice.content?.title}</h6>
+                                    <h6 className={"text-[#c6d4e1]"}>{notice.content?.title}</h6>
                                 </header>
-                                <p className={"text-[12px] text-[#caceff]"}>
+                                <p className={"text-[12px] text-[#5d7284]"}>
                                     {notice.send_time
                                         ? timeFormat(notice.send_time!, locale)
                                         : timeFormat(notice.send_user_time!, locale)}
@@ -59,27 +59,31 @@ const SystemMessage = (props: Props) => {
                         }
                     >
                         <div>
-                            <p className={"text-[16px] text-[#c1c6d2]"}>{notice.content?.text}</p>
+                            <p className={"break-all text-[16px] text-[#c1c6d2]"}>
+                                {notice.content?.text}
+                            </p>
 
-                            <img src={notice.content?.image} alt="" />
-                            <div
-                                className={`-mb-[12px] mt-[0.0694rem] flex h-[0.2778rem] items-center justify-center border-t-[0.0rem] border-[#caceff] text-[#c1c6d2]`}
-                            >
-                                <Box
-                                    action={notice.action_type}
-                                    actionData={notice.action_params}
-                                    className={"flex items-center"}
+                            {notice.content?.image && <img src={notice.content?.image} alt="" />}
+                            {notice.content?.word && (
+                                <div
+                                    className={`-mb-[12px] mt-[0.0694rem] flex h-[0.2778rem] items-center justify-center border-t-[0.0rem] border-[#caceff] text-[#c1c6d2]`}
                                 >
-                                    <p className={"text-[0.1111rem] text-[#caceff]"}>
-                                        {notice.content?.word}{" "}
-                                    </p>
-                                    <span
-                                        className={
-                                            "iconfont icon-xiangyou2 ml-[5px] text-[0.08rem] text-[#caceff]"
-                                        }
-                                    ></span>
-                                </Box>
-                            </div>
+                                    <Box
+                                        action={notice.action_type}
+                                        actionData={notice.action_params}
+                                        className={"flex items-center"}
+                                    >
+                                        <p className={"text-[0.1111rem] text-[#caceff]"}>
+                                            {notice.content?.word}{" "}
+                                        </p>
+                                        <span
+                                            className={
+                                                "iconfont icon-xiangyou2 ml-[5px] text-[0.08rem] text-[#5d7284]"
+                                            }
+                                        ></span>
+                                    </Box>
+                                </div>
+                            )}
                         </div>
                     </Collapse.Panel>
                 ))}

+ 64 - 2
src/app/[locale]/(navbar)/notification/components/style.module.scss

@@ -1,9 +1,11 @@
 .messageCollapse {
+    padding: 0 0.12rem 0.12rem;
     :global(.adm-list-body-inner) {
         // background: #32343a;
-        box-shadow: 0 0 15px #34a7bb inset;
-        border: 1px solid #46e3ff;
+        // box-shadow: 0 0 15px #34a7bb inset;
+        // border: 1px solid #46e3ff;
         border-radius: 0.1rem;
+        background-color: #1f2830;
     }
     :global(a.adm-list-item:active:not(.adm-list-item-disabled)) {
         // background-color: #32343a;
@@ -13,3 +15,63 @@
         margin-bottom: 10px;
     }
 }
+
+.emailBox {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: stretch;
+    .content {
+        flex: 1;
+        min-height: 0;
+        overflow: auto;
+        padding: 0 0.12rem 0.12rem;
+    }
+    .footer {
+        .btns {
+            display: flex;
+            background-color: #161b1f;
+            justify-content: space-between;
+            box-sizing: border-box;
+            padding: 0.12rem;
+            button {
+                width: 47%;
+                color: #121c1b;
+                height: 0.38rem;
+                border-radius: 0.19rem;
+                &:nth-child(1) {
+                    background-color: #11de68;
+                }
+                &:nth-child(2) {
+                    background-color: #ecc720;
+                }
+            }
+        }
+    }
+    .emailItem {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        background-color: #1f2830;
+        margin-bottom: 0.12rem;
+        border-radius: 0.1rem;
+        padding: 0.12rem;
+    }
+    .doGet {
+        color: #ebc71f;
+        font-size: 0.14rem;
+    }
+    .title {
+        width: 60%;
+        div:nth-child(1) {
+            width: 100%;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+    }
+
+    .gift {
+        width: 0.24rem;
+    }
+}

+ 8 - 2
src/app/[locale]/(navbar)/notification/layout.tsx

@@ -1,6 +1,7 @@
 import HeaderBack from "@/components/HeaderBack";
 import { getTranslations } from "next-intl/server";
 import { ReactNode } from "react";
+import styles from "./style.module.scss";
 export const generateMetadata = async () => {
     const t = await getTranslations("titles");
     return {
@@ -16,8 +17,13 @@ export default async function Layout({
 }) {
     const t = await getTranslations("ProfilePage");
     return (
-        <div className="h-[100%] overflow-auto bg-[url('/home/bg.jpg')]">
-            <HeaderBack showBack={true} title={t("message")} useBg={true} />
+        <div className="h-[100%] overflow-auto">
+            <HeaderBack
+                showBack={true}
+                title={t("message")}
+                useBg={false}
+                className={styles.header}
+            />
             <main className={"main-header"}>{children}</main>
         </div>
     );

+ 32 - 5
src/app/[locale]/(navbar)/notification/page.tsx

@@ -1,4 +1,4 @@
-import { GlobalNoticeRep } from "@/api/home";
+import { EmailNoticeRep, GlobalNoticeRep } from "@/api/home";
 import NotificationClient from "@/app/[locale]/(navbar)/notification/NotificationClient";
 import { server } from "@/utils/server";
 import clsx from "clsx";
@@ -18,12 +18,39 @@ const getUserNotices = () => {
         data: {},
     });
 };
+const getEmailNotices = () => {
+    return server.request<EmailNoticeRep[]>({
+        url: "/v1/api/user/mail/getMailList",
+        method: "POST",
+        data: {},
+    });
+};
 const Notification = async () => {
-    const systemNotices = await getSystemNotifications();
-    const userNotices = await getUserNotices();
+    const result = await Promise.allSettled([
+        getSystemNotifications(),
+        getUserNotices(),
+        getEmailNotices(),
+    ]);
+
+    let dataArr: [GlobalNoticeRep[], GlobalNoticeRep[], EmailNoticeRep[]] = [
+        [] as GlobalNoticeRep[],
+        [] as GlobalNoticeRep[],
+        [] as EmailNoticeRep[],
+    ];
+    result.forEach((item, idx) => {
+        if (item.status === "fulfilled") {
+            dataArr[idx] = item.value?.data || [];
+        }
+    });
+    const [systemNotices, userNotices, emailNotices] = dataArr;
+
     return (
-        <div className={clsx("overflow-visible", styles.notificationPage)}>
-            <NotificationClient systemNotices={systemNotices.data} userNotices={userNotices.data} />
+        <div className={clsx("h-[100%] overflow-visible pt-[.12rem]", styles.notificationPage)}>
+            <NotificationClient
+                systemNotices={systemNotices}
+                userNotices={userNotices}
+                emailNotices={emailNotices}
+            />
         </div>
     );
 };

+ 46 - 30
src/app/[locale]/(navbar)/notification/style.module.scss

@@ -1,40 +1,56 @@
 .notificationPage {
     :global(.adm-tabs-tab-list) {
-        margin: 0.12rem;
-        // border: 1px solid #e43bff;
-        // border-radius: 0.3rem;
-        // box-shadow: 0 0 15px #7735bd inset;
-        padding-bottom: 0.1rem;
+        margin: 0 0.12rem 0.12rem;
+        background-color: #1f2830;
+        border-radius: 0.1rem;
+        height: 0.4rem;
         position: relative;
-        &:after {
-            content: "";
-            position: absolute;
-            left: 0;
-            top: 0;
-            width: 100%;
-            bottom: 0;
-            border-bottom: 1px solid #fcd6ff;
-            border-radius: 0.3rem;
-            pointer-events: none;
-        }
-        &:before {
-            content: "";
-            position: absolute;
-            left: 0;
-            top: 1px;
-            width: 100%;
-            bottom: 1px;
-            border: 1px solid #e43bff;
-            border-radius: 0.3rem;
-            box-shadow: 0 0 15px #7735bd inset;
-            padding-bottom: 0.1rem;
-            pointer-events: none;
-        }
+    }
+    :global(.adm-tabs) {
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        align-items: stretch;
+    }
+    :global(.adm-tabs-content) {
+        flex: 1;
+        min-height: 0;
+        overflow: auto;
+        padding: 0;
     }
     :global(.adm-tabs-tab) {
         padding-bottom: 0;
     }
+    // :global(.adm-tabs-tab-line) {
+    //     bottom: 0.08rem;
+    // }
     :global(.adm-tabs-tab-line) {
-        bottom: 0.08rem;
+        top: 0;
+        bottom: 0;
+        background: #11de68;
+        height: 100%;
+        border-radius: 0.1rem;
     }
+    :global(.adm-tabs-tab-wrapper) {
+        flex: 1;
+        padding: 0;
+        height: 100%;
+    }
+    :global(.adm-tabs-tab) {
+        padding: 0;
+        margin: 0;
+        width: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 100%;
+        color: #5d7284;
+        font-weight: 700;
+    }
+    :global(.adm-tabs-tab-active) {
+        color: #122f23;
+    }
+}
+.header {
+    background: #1e252b;
 }

+ 2 - 3
src/components/HeaderBack/index.tsx

@@ -1,7 +1,6 @@
 "use client";
 import { usePathname, useRouter } from "@/i18n/routing";
 import { useWalletStore } from "@/stores/useWalletStore";
-import { getToken } from "@/utils/Cookies";
 import clsx from "clsx";
 import { useTranslations } from "next-intl";
 import { FC, PropsWithChildren, ReactNode, useEffect, useState } from "react";
@@ -85,13 +84,13 @@ const HeaderBack: FC<PropsWithChildren<HeaderBackProps>> = ({
                 {(title || selfTitle) && <span>{title || selfTitle}</span>}
             </div>
             <div className={styles.content}>{children}</div>
-            {getToken() && (
+            {/* {getToken() && (
                 <div>
                     {wallet.is_open_no_bonus === 1 && (
                         <img src="/img/no_bouns.png" alt="" className="h-[20px]" />
                     )}
                 </div>
-            )}
+            )} */}
 
             {!Right && (
                 <span className={styles.right} onClick={() => goPage("home")}>

+ 0 - 1
src/components/ModalPopup/WalletDescribeModal/index.tsx

@@ -86,7 +86,6 @@ export const BonusContent = (props: { wallet: Wallet; handleAcquire?: any }) =>
                 <li className="mt-[.06rem]">{t("bonusDesc2")}</li>
                 {/* <li className="mt-[.06rem]">{t("bonusDesc3")}</li> */}
             </ul>
-
             {handleAcquire && (
                 <a
                     className={`carteira-box ${wallet.is_point_transfer ? "active" : ""}`}