Browse Source

feat: 修改

year 3 days ago
parent
commit
e59f6ae840
37 changed files with 389 additions and 37 deletions
  1. BIN
      public/wheel/RotaryCenter.webp
  2. BIN
      public/wheel/Turntableoutsidethebox.webp
  3. BIN
      public/wheel/peishi1_bg.webp
  4. BIN
      public/wheel/peishi3_bg.webp
  5. BIN
      public/wheel/peishi4_bg.webp
  6. BIN
      public/wheel/peishi5_bg.webp
  7. BIN
      public/wheel/peishi6_bg.webp
  8. BIN
      public/wheel/spinLeft.webp
  9. BIN
      public/wheel/spinbt.webp
  10. BIN
      public/wheel/waipan_bg.webp
  11. BIN
      public/wheel/word.webp
  12. BIN
      public/wheel/zhizhen_bg.webp
  13. BIN
      public_original/wheel/RotaryCenter.webp
  14. BIN
      public_original/wheel/Turntableoutsidethebox.webp
  15. BIN
      public_original/wheel/peishi1_bg.webp
  16. BIN
      public_original/wheel/peishi3_bg.webp
  17. BIN
      public_original/wheel/peishi4_bg.webp
  18. BIN
      public_original/wheel/peishi5_bg.webp
  19. BIN
      public_original/wheel/peishi6_bg.webp
  20. BIN
      public_original/wheel/spinLeft.webp
  21. BIN
      public_original/wheel/spinbt.webp
  22. BIN
      public_original/wheel/waipan_bg.webp
  23. BIN
      public_original/wheel/word.webp
  24. BIN
      public_original/wheel/zhizhen_bg.webp
  25. 61 24
      src/app/[locale]/providers.tsx
  26. 15 0
      src/app/globals.scss
  27. 0 0
      src/components/HomeWheel/index.module.scss
  28. 135 0
      src/components/HomeWheel/index.tsx
  29. 0 0
      src/components/ImageModal/index.module.scss
  30. 14 0
      src/components/ImageModal/index.tsx
  31. 1 1
      src/components/Wheel/index.tsx
  32. 15 0
      src/feedback/Help/index.module.scss
  33. 38 0
      src/feedback/Help/index.tsx
  34. 74 0
      src/feedback/auto.tsx
  35. 20 9
      src/feedback/dialog/component.tsx
  36. 13 1
      src/feedback/dialog/index.tsx
  37. 3 2
      src/feedback/index.tsx

BIN
public/wheel/RotaryCenter.webp


BIN
public/wheel/Turntableoutsidethebox.webp


BIN
public/wheel/peishi1_bg.webp


BIN
public/wheel/peishi3_bg.webp


BIN
public/wheel/peishi4_bg.webp


BIN
public/wheel/peishi5_bg.webp


BIN
public/wheel/peishi6_bg.webp


BIN
public/wheel/spinLeft.webp


BIN
public/wheel/spinbt.webp


BIN
public/wheel/waipan_bg.webp


BIN
public/wheel/word.webp


BIN
public/wheel/zhizhen_bg.webp


BIN
public_original/wheel/RotaryCenter.webp


BIN
public_original/wheel/Turntableoutsidethebox.webp


BIN
public_original/wheel/peishi1_bg.webp


BIN
public_original/wheel/peishi3_bg.webp


BIN
public_original/wheel/peishi4_bg.webp


BIN
public_original/wheel/peishi5_bg.webp


BIN
public_original/wheel/peishi6_bg.webp


BIN
public_original/wheel/spinLeft.webp


BIN
public_original/wheel/spinbt.webp


BIN
public_original/wheel/waipan_bg.webp


BIN
public_original/wheel/word.webp


BIN
public_original/wheel/zhizhen_bg.webp


+ 61 - 24
src/app/[locale]/providers.tsx

@@ -6,15 +6,16 @@ import ptBR from "antd-mobile/es/locales/pt-BR";
 import { ThemeProviderProps } from "next-themes/dist/types";
 import { ReactNode, useEffect, useState } from "react";
 
+import { usePathname } from "@/i18n/routing";
 import { server } from "@/utils/client";
 import { useDebounceEffect, useRequest } from "ahooks";
 import clsx from "clsx";
 import { initializeApp } from "firebase/app";
 import { getMessaging, getToken, onMessage } from "firebase/messaging";
-import { usePathname, useSearchParams } from "next/navigation";
+import { useSearchParams } from "next/navigation";
 import Script from "next/script";
 
-import { setupFontSize } from "@/utils";
+import { commonMask, setupFontSize } from "@/utils";
 import { Local } from "@/utils/storage";
 import { motion } from "framer-motion";
 
@@ -23,18 +24,30 @@ import { useActivityStore } from "@/stores/useActivityStore";
 import { useGlobalNoticeStore } from "@/stores/useGlobalNoticeStore";
 import { getToken as getUserToken } from "@/utils/Cookies";
 
-import Agent, { AgentSuffix } from "@/components/Agent";
+import { PromotionRep } from "@/api/home";
 import feedback from "@/feedback";
+import doAutoDialog from "@/feedback/auto";
 import { PollingState, usePollingStore } from "@/stores/usePollingStore";
 import { useSuspensionStore } from "@/stores/useSuspensionStore";
 import { useUserInfoStore } from "@/stores/useUserInfoStore";
 import { useVipStore } from "@/stores/useVipStore";
 import { useWalletStore } from "@/stores/useWalletStore";
-
 export interface ProvidersProps {
     children: ReactNode;
     themeProps?: Omit<ThemeProviderProps, "children">;
 }
+
+const getPromotions = async () => {
+    return server
+        .request<PromotionRep[], { summery: { showType: 1 | 2 } }>({
+            url: "/v1/api/front/pop_list",
+            method: "POST",
+        })
+        .then((res) => {
+            if (res.code === 200) return res;
+        });
+};
+
 // 初始化 fireBase
 const initFirebase = () => {
     // 是否是https
@@ -352,31 +365,55 @@ export default function SidebarLayout({ children, themeProps }: ProvidersProps)
         isCollapse: state.isCollapse,
         setCollapse: state.setCollapse,
     }));
+    const [popData, setPopData] = useState<PromotionRep[]>([]);
     const pathname = usePathname();
-
     useEffect(() => {
-        const local = pathname.split("/")[1];
-        doShowProxyCheck();
+        if (feedback.hasShowDialog()) {
+            feedback.hideDialog();
+        }
+        if (pathname !== "/") {
+            setPopData([]);
+            return;
+        }
+        getData();
     }, [pathname]);
-
-    const doShowProxyCheck = async () => {
-        const showProxy = sessionStorage.getItem("ShowProxy");
-        if (!showProxy) {
-            await feedback.showModal({
-                content: <Agent step={1}></Agent>,
-                width: "90%",
-                useDefaultFooter: false,
-                suffix: <AgentSuffix></AgentSuffix>,
-            });
-            await feedback.showModal({
-                content: <Agent step={2}></Agent>,
-                width: "90%",
-                useDefaultFooter: false,
-                suffix: <AgentSuffix></AgentSuffix>,
-            });
-            sessionStorage.setItem("ShowProxy", "1");
+    const getData = async () => {
+        commonMask.show();
+        try {
+            const res = await getPromotions();
+            if (res?.code === 200 && res?.data?.length) {
+                setPopData(res.data);
+                if (!res.data?.length) {
+                    commonMask.hide();
+                }
+            }
+        } catch {
+            commonMask.hide();
         }
     };
+
+    useEffect(() => {
+        doAutoDialog(popData);
+    }, [popData]);
+
+    // const doShowProxyCheck = async () => {
+    //     const showProxy = sessionStorage.getItem("ShowProxy");
+    //     if (!showProxy) {
+    //         await feedback.showModal({
+    //             content: <Agent step={1}></Agent>,
+    //             width: "90%",
+    //             useDefaultFooter: false,
+    //             suffix: <AgentSuffix></AgentSuffix>,
+    //         });
+    //         await feedback.showModal({
+    //             content: <Agent step={2}></Agent>,
+    //             width: "90%",
+    //             useDefaultFooter: false,
+    //             suffix: <AgentSuffix></AgentSuffix>,
+    //         });
+    //         sessionStorage.setItem("ShowProxy", "1");
+    //     }
+    // };
     return (
         <div id={"app"} className="relative h-[100%] overflow-hidden">
             <motion.div

+ 15 - 0
src/app/globals.scss

@@ -384,6 +384,18 @@ input[type="number"] {
     }
 }
 
+@keyframes pulse {
+    0% {
+        transform: rotate(-5deg) scaleZ(1);
+    }
+    50% {
+        transform: rotate(0) scale3d(1.1, 1.1, 1.1);
+    }
+    100% {
+        transform: rotate(-5deg) scaleZ(1);
+    }
+}
+
 .homeTabsContainer {
     .adm-tabs-tab-wrapper {
         padding: 0 !important;
@@ -451,3 +463,6 @@ input[type="number"] {
         pointer-events: none;
     }
 }
+.bg-none {
+    background-color: transparent !important;
+}

+ 0 - 0
src/components/HomeWheel/index.module.scss


+ 135 - 0
src/components/HomeWheel/index.tsx

@@ -0,0 +1,135 @@
+"use client";
+// import { useRouter } from "@/i18n/routing";
+import { Link } from "@/i18n/routing";
+import { getToken } from "@/utils/Cookies";
+import React from "react";
+import Wheel from "../Wheel";
+
+const HomeWheel = (props: any) => {
+    const doStart = () => {
+        if (!getToken()) {
+            return;
+        }
+    };
+    const doEnd = () => {
+        if (typeof props?.doClose === "function") {
+            setTimeout(() => {
+                props.doClose("confirm");
+            }, 1000);
+        }
+    };
+    const centerWrap = React.useCallback(() => {
+        return ({ children }: any) => {
+            if (getToken()) {
+                return <>{children}</>;
+            }
+            return (
+                <Link href="/login" onClick={(evt: any) => evt.stopPropagation()}>
+                    {children}
+                </Link>
+            );
+        };
+    }, []);
+
+    const CenterWrap = centerWrap();
+
+    return (
+        <div className="relative py-[.4rem]">
+            <div className="relative z-[10]">
+                <Wheel
+                    className="px-[30px]"
+                    onStart={doStart}
+                    onEnd={doEnd}
+                    center={
+                        <CenterWrap>
+                            <div
+                                className="flex items-center justify-center"
+                                style={{
+                                    background: "url('/wheel/RotaryCenter.webp')",
+                                    width: "1.1rem",
+                                    height: "1.1rem",
+                                    backgroundSize: "100% 100%",
+                                }}
+                            >
+                                <img
+                                    src="/wheel/word.webp"
+                                    className="w-[80%]"
+                                    alt=""
+                                    style={{
+                                        animation:
+                                            "pulse 2s linear 0s infinite normal none running",
+                                    }}
+                                />
+                            </div>
+                        </CenterWrap>
+                    }
+                    renderBg={
+                        <div
+                            className="absolute left-[50%] top-[50%] -translate-x-1/2 -translate-y-1/2 transform"
+                            style={{ width: "calc(100% - 60px + 38px)", top: `calc(50% - 5px)` }}
+                        >
+                            <img src="/wheel/waipan_bg.webp" alt="" />
+                        </div>
+                    }
+                    arrow={() => (
+                        <div className="relative pt-[.2rem]">
+                            <img
+                                src="/wheel/Turntableoutsidethebox.webp"
+                                className="!w-[.64rem]"
+                                alt=""
+                            />
+                            <img
+                                src="/wheel/zhizhen_bg.webp"
+                                className="absolute left-[50%] top-[.25rem] !h-[auto] !w-[.3rem] -translate-x-[50%] transform"
+                                alt=""
+                            />
+                        </div>
+                    )}
+                ></Wheel>
+            </div>
+            <div className="absolute -bottom-[60px]">
+                <div className="relative flex justify-center">
+                    <img src="/wheel/spinbt.webp" className="relative z-[9] w-[90%]" alt="" />
+                    <img
+                        src="/wheel/peishi6_bg.webp"
+                        className="absolute -bottom-[.1rem] -right-[.1rem] z-[11] w-[.7rem]"
+                        alt=""
+                    />
+                    <img
+                        src="/wheel/peishi4_bg.webp"
+                        alt=""
+                        className="absolute -right-[.1rem] bottom-[.47rem] z-[7] w-[.9rem]"
+                    />
+                    <img
+                        src="/wheel/peishi1_bg.webp"
+                        className="absolute -left-[.1rem] bottom-[.15rem] z-[7] w-[.9rem]"
+                        alt=""
+                    />
+                </div>
+            </div>
+            <div className="absolute -top-[.32rem] flex w-[100%] justify-center">
+                <div className="relativeflex justify-center">
+                    <img src="/wheel/peishi3_bg.webp" className="relative z-[8] w-[2rem]" alt="" />
+                    <img
+                        src="/wheel/spinLeft.webp"
+                        className="absolute -right-[.1rem] -top-[.1rem] z-[7] w-[1.4rem] origin-center"
+                        style={{ transform: "rotateY(180deg)" }}
+                        alt=""
+                    />
+                    <img
+                        src="/wheel/spinLeft.webp"
+                        className="absolute -left-[.1rem] -top-[.1rem] z-[7] w-[1.4rem] origin-center"
+                        alt=""
+                    />
+                    <img
+                        src="/wheel/peishi5_bg.webp"
+                        className="absolute -top-[.3rem] left-[.1rem] w-[.75rem]"
+                        alt=""
+                    />
+                </div>
+            </div>
+        </div>
+    );
+};
+
+export default HomeWheel;

+ 0 - 0
src/components/ImageModal/index.module.scss


+ 14 - 0
src/components/ImageModal/index.tsx

@@ -0,0 +1,14 @@
+export interface ImageDialog {
+    imgUrl: string;
+    showAgain?: boolean;
+}
+
+const ModalImage: React.FC<ImageDialog> = ({ imgUrl }) => {
+    return (
+        <div>
+            <img src={imgUrl} alt="" />
+        </div>
+    );
+};
+
+export default ModalImage;

+ 1 - 1
src/components/Wheel/index.tsx

@@ -13,7 +13,7 @@ interface Props {
     center?: React.ReactNode;
     arrow?: (p: { width: number }) => React.ReactNode;
     onStart?: () => void;
-    onEnd?: () => {};
+    onEnd?: () => void;
     total?: number;
     winNum?: number;
 }

+ 15 - 0
src/feedback/Help/index.module.scss

@@ -0,0 +1,15 @@
+// "flex h-[.26rem] w-[.26rem] items-center justify-center rounded-[4px] bg-[var(--mian-icon-color)]
+.check {
+    width: 0.2rem;
+    height: 0.2rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 4px;
+    background-color: var(--mian-icon-color);
+    margin-right: 0.1rem;
+}
+.iconfont {
+    color: var(--primary7);
+    font-size: 0.16rem !important;
+}

+ 38 - 0
src/feedback/Help/index.tsx

@@ -0,0 +1,38 @@
+import clsx from "clsx";
+import React from "react";
+import styles from "./index.module.scss";
+
+interface FooterCheckProps {
+    text?: string;
+    value?: boolean;
+    onChange?: (p: boolean) => void;
+}
+export const FooterCheck = React.forwardRef<{ getValue: () => boolean }, FooterCheckProps>(
+    ({ value, text, onChange }, ref) => {
+        const [innerValue, setInnerValue] = React.useState(value || false);
+        React.useEffect(() => {
+            if (typeof onChange === "function") {
+                onChange(innerValue);
+            }
+        }, [innerValue]);
+
+        React.useImperativeHandle(ref, () => {
+            return {
+                getValue: () => innerValue,
+            };
+        });
+
+        const changeValue = () => {
+            setInnerValue(!innerValue);
+        };
+
+        return (
+            <div className="mt-[.1rem] flex items-center justify-center" onClick={changeValue}>
+                <div className={styles.check}>
+                    {innerValue && <i className={clsx("iconfont icon-gou", styles.iconfont)}></i>}
+                </div>
+                <span className="text-[#fff]">{text}</span>
+            </div>
+        );
+    }
+);

+ 74 - 0
src/feedback/auto.tsx

@@ -0,0 +1,74 @@
+import { PromotionRep } from "@/api/home";
+import Agent, { AgentSuffix } from "@/components/Agent";
+import HomeWheel from "@/components/HomeWheel";
+import ModalImage, { ImageDialog } from "@/components/ImageModal";
+import { FooterCheck } from "./Help";
+import feedback from "./index";
+
+export const showProxy1 = async () => {
+    await feedback.showModal({
+        content: <Agent step={1}></Agent>,
+        width: "90%",
+        useDefaultFooter: false,
+        suffix: <AgentSuffix></AgentSuffix>,
+    });
+};
+
+export const showProxy2 = async () => {
+    await feedback.showModal({
+        content: <Agent step={2}></Agent>,
+        width: "90%",
+        useDefaultFooter: false,
+        suffix: <AgentSuffix></AgentSuffix>,
+    });
+};
+export const showHomeWheel = async () => {
+    await feedback.showModal({
+        content: HomeWheel,
+        width: "100%",
+        useDefaultFooter: false,
+        className: "bg-none ",
+        showClose: false,
+    });
+};
+
+export const showImage = async ({ imgUrl, showAgain = false }: ImageDialog) => {
+    const res = await feedback.showModal({
+        content: <ModalImage imgUrl={imgUrl}></ModalImage>,
+        width: "90%",
+        useDefaultFooter: false,
+        withData: { isCheck: false },
+        suffix: showAgain ? (
+            (props: any) => {
+                return (
+                    <FooterCheck
+                        text="Não pop-up desta vez"
+                        value={props.withData.props}
+                        onChange={(val) =>
+                            props.onChange({
+                                isCheck: val,
+                            })
+                        }
+                    ></FooterCheck>
+                );
+            }
+        ) : (
+            <></>
+        ),
+    });
+    console.log(res);
+};
+
+// await showHomeWheel();
+
+const doAutoDialog = async (data: PromotionRep[]) => {
+    if (!data?.length) return;
+
+    // await showHomeWheel();
+    await showImage({
+        imgUrl: "https://b0.bdstatic.com/ugc/58Gyj7cB4DAjkflQHsz3fQ2071af621db1db46143e42c595af2aa4.jpg",
+        showAgain: true,
+    });
+};
+
+export default doAutoDialog;

+ 20 - 9
src/feedback/dialog/component.tsx

@@ -9,11 +9,11 @@ interface Props {
     callback?: (p: keyof ModalBoxResType) => void;
     className?: string;
     content?: ((p?: any) => React.ReactNode) | React.ReactNode;
-    suffix?: React.ReactNode;
+    suffix?: ((p?: any) => React.ReactNode) | React.ReactNode;
     footer?: (p?: any) => React.ReactNode;
     useDefaultFooter?: boolean;
     confirmText?: string;
-    clsssName?: string;
+    showClose?: boolean;
     [key: string]: any;
 }
 
@@ -24,11 +24,12 @@ const Components: React.FC<Props> = ({
     footer,
     confirmText = "comfirm",
     useDefaultFooter = true,
-    clsssName,
+    showClose = true,
     callback,
     ...props
 }) => {
     const [animateType, setAnimateType] = React.useState<number>(0);
+    const [innerWithData, setInnerWithData] = React.useState(props.withData || {});
     React.useEffect(() => {
         setTimeout(() => {
             setAnimateType(1);
@@ -44,7 +45,7 @@ const Components: React.FC<Props> = ({
 
     return (
         <div
-            className={clsx(styles.modalBox, clsssName, {
+            className={clsx(styles.modalBox, className, {
                 [styles.showed]: animateType === 1,
             })}
             style={{
@@ -53,7 +54,8 @@ const Components: React.FC<Props> = ({
         >
             <div className={clsx(styles.modalBoxContainer, className)}>
                 {React.isValidElement(content) && content}
-                {typeof content === "function" && content({ ...props, doClose })}
+                {typeof content === "function" &&
+                    content({ ...props, doClose, onChange: (val: any) => setInnerWithData(val) })}
                 {useDefaultFooter && (
                     <div className={styles.footer}>
                         {!footer && (
@@ -70,10 +72,19 @@ const Components: React.FC<Props> = ({
 
                 {!!footer && footer({ ...props, doClose })}
             </div>
-            {suffix}
-            <div className={styles.closeBtn} onClick={() => doClose("cancel")}>
-                <SvgIcon iconClass="icon-a-H7_celan_guanbi_btnpng" size={16}></SvgIcon>
-            </div>
+            {typeof suffix === "function" &&
+                suffix({ ...props, doClose, onChange: (val: any) => setInnerWithData(val) })}
+            {React.isValidElement(suffix) && suffix}
+            {showClose && (
+                <div
+                    className={styles.closeBtn}
+                    onClick={() =>
+                        doClose(props.withData ? { ...innerWithData, cancel: true } : "cancel")
+                    }
+                >
+                    <SvgIcon iconClass="icon-a-H7_celan_guanbi_btnpng" size={16}></SvgIcon>
+                </div>
+            )}
         </div>
     );
 };

+ 13 - 1
src/feedback/dialog/index.tsx

@@ -21,8 +21,11 @@ export interface ModalState {
     titleStyle?: React.CSSProperties;
     contentStyle?: React.CSSProperties;
     useDefaultFooter?: boolean;
-    suffix?: string | React.ReactNode;
+    suffix?: ((p?: any) => React.ReactNode) | React.ReactNode;
     callback?: (p: keyof ModalBoxResType) => void;
+    className?: string;
+    showClose?: boolean;
+    [key: string]: any;
 }
 
 export interface ModalBoxResType {
@@ -46,6 +49,7 @@ export const showModal = (opts: ModalState = {}): Promise<ModalBoxResType> => {
             confirmColor: "#fff",
             width: 500,
             showCancel: true,
+            showClose: true,
         };
         const useProps = {
             ...defaultProps,
@@ -80,3 +84,11 @@ export const showModal = (opts: ModalState = {}): Promise<ModalBoxResType> => {
         }
     });
 };
+
+export const hideDialog = () => {
+    const siblingCom = feedbackStatus.get(moduleName, siblingKey);
+    if (siblingCom) {
+        siblingCom.destroy();
+        feedbackStatus.removeKey(moduleName, siblingKey);
+    }
+};

+ 3 - 2
src/feedback/index.tsx

@@ -1,12 +1,13 @@
 import { FeedbackStatusEnum } from "@/enums";
-import { showModal } from "./dialog";
+import { hideDialog, showModal } from "./dialog";
 import feedbackStatus from "./status";
 
 const feedConfig = {
     showModal: showModal,
-    hasShow: () => {
+    hasShowDialog: () => {
         return feedbackStatus.getStatus() === FeedbackStatusEnum.RUNNING;
     },
+    hideDialog,
 };
 
 export default feedConfig;