瀏覽代碼

Merge remote-tracking branch 'origin/v1.5' into feature-Before

ansoni 3 周之前
父節點
當前提交
bf1bc33d05

+ 2 - 2
src/app/[locale]/(doings)/rank/detail/games.tsx

@@ -89,7 +89,7 @@ const Games = React.forwardRef<ModalProps, Props>(({ data }, ref) => {
                     </FormItem>
                 </Form>
                 <div className="flex min-h-[0px] flex-1">
-                    <div className="mr-[.1rem] h-[100%] w-[.9rem] overflow-auto">
+                    <div className="mr-[.1rem] h-[100%] w-[.8rem] overflow-auto">
                         {!!data?.game_list?.length &&
                             data?.game_list.map((item, idx) => {
                                 return (
@@ -97,7 +97,7 @@ const Games = React.forwardRef<ModalProps, Props>(({ data }, ref) => {
                                         className={clsx(styles.providerItem, {
                                             [styles.active]: idx === actPro,
                                         })}
-                                        key={item.provider_icon}
+                                        key={`${item.provider_icon}_${item.provider}_${idx}`}
                                         onClick={() => {
                                             setSearchStr("");
                                             setActPro(idx);

+ 80 - 50
src/app/[locale]/(doings)/rank/detail/history.tsx

@@ -3,6 +3,7 @@ import { getRankDetail, Rank, RankDetail, RankRequestParams, RankReward } from "
 import Empty from "@/components/Empty";
 import TipsModal from "@/components/TipsModal";
 import Vip from "@/components/Vip";
+import { InfiniteScroll } from "antd-mobile";
 import clsx from "clsx";
 import React from "react";
 import styles from "./page.module.scss";
@@ -14,13 +15,16 @@ export type ModalProps = {
 
 interface Props {
     areaId: number;
+    type: 0 | -1;
 }
 
-const History = React.forwardRef<ModalProps, Props>(({ areaId }, ref) => {
+const History = React.forwardRef<ModalProps, Props>(({ areaId, type }, ref) => {
     const [rankList, setRankList] = React.useState<Rank[]>([]);
+    const [noMore, setNoMore] = React.useState<boolean>(false);
     const [data, setData] = React.useState<RankDetail>({} as RankDetail);
+    const [visible, setVisible] = React.useState<boolean>(false);
     const pageInfo = React.useRef({
-        page: 1,
+        page: 0,
     });
 
     const getNumber = (num: number) => {
@@ -32,24 +36,37 @@ const History = React.forwardRef<ModalProps, Props>(({ areaId }, ref) => {
 
     React.useImperativeHandle(ref, () => {
         return {
-            onClose: () => tipModals.current?.onClose(),
-            onOpen: () => tipModals.current?.onOpen(),
+            // onClose: () => tipModals.current?.onClose(),
+            // onOpen: () => tipModals.current?.onOpen(),
+            onClose: () => setVisible(false),
+            onOpen: () => setVisible(true),
         };
     });
 
     React.useEffect(() => {
-        getData();
-    }, [areaId]);
+        pageInfo.current.page = 0;
+        setNoMore(false);
+        setRankList([]);
+        // getData();
+        // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, [visible]);
 
     const getData = async () => {
+        if (noMore) return;
         const params: RankRequestParams = {
             area_id: areaId,
-            type: -1,
+            type: type,
             page: pageInfo.current?.page || 1,
         };
         const res = await getRankDetail(params);
         if (res?.code === 200) {
-            setRankList(res?.data?.list || []);
+            if (res?.data?.list && res?.data?.list?.length < 10) {
+                setNoMore(true);
+            }
+            setData(res.data);
+            setRankList((value) => {
+                return [...(value || []), ...(res?.data?.list || [])];
+            });
         }
     };
 
@@ -60,57 +77,70 @@ const History = React.forwardRef<ModalProps, Props>(({ areaId }, ref) => {
             position="bottom"
             className={styles.tipModal}
             ref={tipModals}
+            visible={visible}
+            onChange={(visible) => setVisible(visible)}
             title={
                 <div className="p-[.1rem] text-left">
                     <span className="text-[#fff]">Conjunto de prémios:</span>
-                    <span className={styles.moneyText}>R${data.total}</span>
+                    <span className={styles.moneyText}>R${data.total || 0}</span>
                 </div>
             }
         >
-            <div className="bg-[#1f2830] p-[.1rem]">
-                {!!data?.list?.length &&
-                    data.list.map((item) => {
-                        let curReward: RankReward = {} as RankReward;
-                        if (item?.reward?.length) {
-                            curReward = item?.reward[0];
-                        }
-                        return (
-                            <div className={clsx(styles.normalItem)} key={item.rank}>
-                                <div className="mr-[.1rem] w-[.5rem] text-center text-[.2rem] font-bold text-[#11de68]">
-                                    {getNumber(1)}
-                                </div>
-                                <div className={clsx(styles.normalHeader, "mr-[.2rem]")}>
-                                    <img
-                                        src="https://img1.baidu.com/it/u=1699323843,2372946297&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=983"
-                                        alt=""
-                                        className={styles.headerImage}
-                                    />
-                                    <Vip
-                                        style={{
-                                            position: "absolute",
-                                            bottom: "-0.1rem",
-                                        }}
-                                        level={item?.vipLevel}
-                                        vipIconClassName="relative z-[3]"
-                                        vipIconStyle={{ width: ".3rem" }}
-                                    ></Vip>
-                                </div>
-                                <div className="flex-1">
-                                    <div>{item?.nickName}</div>
-                                    <div className={styles.usedPoint}>{item?.score}</div>
-                                </div>
-                                <div className="flex flex-col items-end">
-                                    <div className={styles.moneyText}>
-                                        R${curReward?.amount || 0}
+            <div className="h-[60vh] overflow-auto bg-[#1f2830] p-[.1rem]">
+                {!!rankList?.length && (
+                    <>
+                        {rankList.map((item) => {
+                            let curReward: RankReward = {} as RankReward;
+                            if (item?.reward?.length) {
+                                curReward = item?.reward[0];
+                            }
+                            return (
+                                <div className={clsx(styles.normalItem)} key={item.rank}>
+                                    <div className="mr-[.1rem] w-[.5rem] text-center text-[.2rem] font-bold text-[#11de68]">
+                                        {getNumber(item.rank)}
                                     </div>
-                                    <div className={styles.percentBox}>
-                                        {curReward?.ratio || 0}%
+                                    <div className={clsx(styles.normalHeader, "mr-[.2rem]")}>
+                                        <img
+                                            src="https://img1.baidu.com/it/u=1699323843,2372946297&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=983"
+                                            alt=""
+                                            className={styles.headerImage}
+                                        />
+                                        <Vip
+                                            style={{
+                                                position: "absolute",
+                                                bottom: "-0.1rem",
+                                            }}
+                                            level={item?.vipLevel}
+                                            vipIconClassName="relative z-[3]"
+                                            vipIconStyle={{ width: ".3rem" }}
+                                        ></Vip>
+                                    </div>
+                                    <div className="flex-1">
+                                        <div className="text-[.12rem]">{item?.nickName}</div>
+                                        <div className={styles.usedPoint}>{item?.score}</div>
+                                    </div>
+                                    <div className="flex flex-col items-end">
+                                        <div className={styles.moneyText}>
+                                            R${curReward?.amount || 0}
+                                        </div>
+                                        <div className={styles.percentBox}>
+                                            {curReward?.ratio || 0}%
+                                        </div>
                                     </div>
                                 </div>
-                            </div>
-                        );
-                    })}
-                {!data?.list?.length && (
+                            );
+                        })}
+                    </>
+                )}
+                <InfiniteScroll
+                    loadMore={async () => {
+                        pageInfo.current.page++;
+                        await getData();
+                    }}
+                    hasMore={!noMore}
+                ></InfiniteScroll>
+
+                {!rankList.length && (
                     <div className="flex h-[100%] items-center justify-center">
                         <Empty></Empty>
                     </div>

+ 14 - 5
src/app/[locale]/(doings)/rank/detail/middle.tsx

@@ -44,6 +44,15 @@ const MiddleContainer: React.FC<Props> = ({ data, rankList = [], gamesInfo }) =>
                     targetId = item.id;
                 }
             }
+            const stickyBox: any = document.querySelector("#stickyBox");
+            if (stickyBox) {
+                const stickyRect = stickyBox.getBoundingClientRect();
+                if (stickyRect.top < 60) {
+                    stickyBox.style.background = "rgba(0,0,0,.7)";
+                } else {
+                    stickyBox.style.background = "rgba(255,255,255,0)";
+                }
+            }
         });
         if (actIdRef.current !== targetId) {
         }
@@ -96,7 +105,7 @@ const MiddleContainer: React.FC<Props> = ({ data, rankList = [], gamesInfo }) =>
 
     return (
         <>
-            <div className={clsx(styles.gideBox, "py-[.1rem]")}>
+            <div className={clsx(styles.gideBox, "py-[.1rem]")} id="stickyBox">
                 {hrefCfg.map((item) => {
                     return (
                         <div
@@ -205,8 +214,8 @@ const MiddleContainer: React.FC<Props> = ({ data, rankList = [], gamesInfo }) =>
                                 key={item.rank}
                             >
                                 <div className="mr-[.1rem] w-[.6rem] text-center text-[.2rem] font-bold text-[#11de68]">
-                                    {/* {item.rank} */}
-                                    {idx + 4}
+                                    {item.rank}
+                                    {/* {idx + 4} */}
                                 </div>
                                 <div className={clsx(styles.normalHeader, "mr-[.2rem]")}>
                                     <img
@@ -225,7 +234,7 @@ const MiddleContainer: React.FC<Props> = ({ data, rankList = [], gamesInfo }) =>
                                     ></Vip>
                                 </div>
                                 <div className="flex-1">
-                                    <div>{item?.nickName}</div>
+                                    <div className="text-[.12rem]">{item?.nickName}</div>
                                     <div className={styles.usedPoint}>{item.score}</div>
                                 </div>
                                 <div className="flex flex-col items-end">
@@ -259,7 +268,7 @@ const MiddleContainer: React.FC<Props> = ({ data, rankList = [], gamesInfo }) =>
                                 ></Vip>
                             </div>
                             <div className="flex-1">
-                                <div>{data.self_rank.nickName}</div>
+                                <div className="text-[.12rem]">{data.self_rank.nickName}</div>
                                 <div className={styles.usedPoint}>{data.self_rank.score}</div>
                             </div>
                             <div className="flex flex-col items-end">

+ 4 - 1
src/app/[locale]/(doings)/rank/detail/page.module.scss

@@ -379,6 +379,9 @@
         border-top: none;
         border-bottom: none;
     }
+    :global(.title) {
+        margin-bottom: 0 !important;
+    }
     .card {
         height: auto !important;
         aspect-ratio: 169/234;
@@ -389,7 +392,7 @@
     .gamesContainer {
         display: grid;
         grid-template-columns: repeat(3, 1fr);
-        grid-gap: 0.1rem;
+        grid-gap: 10px;
     }
 }
 

+ 13 - 5
src/app/[locale]/(doings)/rank/detail/page.tsx

@@ -30,6 +30,7 @@ const Page = () => {
     const [loading, setLoading] = React.useState<boolean>(false);
     const [initLoading, setInitLoading] = React.useState<boolean>(false);
     const [noMore, setNoMore] = React.useState<boolean>(false);
+    const [modalType, setModalType] = React.useState<0 | -1>(0);
 
     const pageInfo = React.useRef({
         page: 1,
@@ -54,6 +55,7 @@ const Page = () => {
         setRankList([]);
         setData({} as any);
         getData();
+        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [areaId]);
 
     const getData = async () => {
@@ -111,10 +113,13 @@ const Page = () => {
     };
 
     return (
-        <div className="h-[100%] overflow-auto" id="outContainer">
+        <div className="relative h-[100%] overflow-auto" id="outContainer">
             <div
-                onClick={() => historyRef.current?.onOpen()}
-                className="fixed right-[0px] top-[350px] z-[5] rounded-[.08rem_0_0_.08rem] bg-[rgba(255,255,255,.2)] px-[.1rem] py-[.04rem]"
+                onClick={() => {
+                    setModalType(-1);
+                    historyRef.current?.onOpen();
+                }}
+                className="absolute right-[0px] top-[300px] z-[5] rounded-[.08rem_0_0_.08rem] bg-[rgba(255,255,255,.2)] px-[.1rem] py-[.04rem]"
             >
                 <i className="iconfont icon-tubiaozhizuomoban- mr-[.06rem]"></i>
                 <span>Histórico</span>
@@ -137,7 +142,10 @@ const Page = () => {
                                     styles.normalItem,
                                     "justify-center py-[.1rem!important]"
                                 )}
-                                onClick={loadMore}
+                                onClick={() => {
+                                    setModalType(0);
+                                    historyRef.current?.onOpen();
+                                }}
                             >
                                 Mesa cheia &gt;
                             </div>
@@ -217,7 +225,7 @@ const Page = () => {
                     cancelamento do prémio ou do lucro
                 </div>
             </div>
-            <History ref={historyRef} areaId={areaId}></History>
+            <History ref={historyRef} areaId={areaId} type={modalType}></History>
             <Games data={data} ref={gamesRef}></Games>
         </div>
     );

+ 37 - 23
src/app/[locale]/(navbar)/gameList2/Right.tsx

@@ -2,8 +2,8 @@ import { GameListRep, searchGameListApi } from "@/api/home";
 import Card from "@/components/Card/Card";
 import Empty from "@/components/Empty";
 import { GameListTypeEnum } from "@/enums";
-import { debounce } from "@/utils/methods";
-import { InfiniteScroll } from "antd-mobile";
+import { useDebounceEffect } from "ahooks";
+import { InfiniteScroll, Loading } from "antd-mobile";
 import React from "react";
 import styles from "./page.module.scss";
 
@@ -13,7 +13,7 @@ interface Props {
 
 const Left: React.FC<Props> = ({ actInfo }) => {
     const [data, setData] = React.useState<GameListRep[]>([]);
-    const [loading, setLoading] = React.useState<boolean>(false);
+    const [loading, setLoading] = React.useState<boolean>(true);
     const [hasMore, setHasMore] = React.useState(true);
     const [isInit, setIsInit] = React.useState(true);
     const PageRef = React.useRef({
@@ -21,14 +21,21 @@ const Left: React.FC<Props> = ({ actInfo }) => {
         page_size: 15,
     });
 
+    useDebounceEffect(() => {
+        toInitFn();
+    }, [actInfo]);
+
     React.useEffect(() => {
         setData([]);
-        setHasMore(true);
-        setLoading(false);
         setIsInit(true);
-        PageRef.current.current_page = 0;
+        setLoading(true);
     }, [actInfo]);
 
+    const toInitFn = () => {
+        PageRef.current.current_page = 0;
+        setHasMore(true);
+    };
+
     const getData = async () => {
         if (!actInfo?.id) return;
         try {
@@ -55,29 +62,36 @@ const Left: React.FC<Props> = ({ actInfo }) => {
             setLoading(false);
         }
     };
-    const loadMore = debounce(async () => {
-        if (!hasMore || loading || !actInfo?.id) return;
+    const loadMore = async () => {
+        if (!hasMore || (loading && !isInit) || !actInfo?.id) return;
         PageRef.current.current_page += 1;
         getData();
-    }, 500) as () => Promise<void>;
+    };
 
     return (
         <div className={styles.right}>
-            <div className={styles.rightBox}>
-                {data.map((item) => {
-                    return (
-                        <Card
-                            key={`${actInfo?.type}_${actInfo?.id}_${item.id}`}
-                            item={item}
-                            className={styles.gameCard}
-                            isShowFavorite={true}
-                            isShowOnline={true}
-                        ></Card>
-                    );
-                })}
-            </div>
+            {loading && isInit && (
+                <div className="flex h-[100%] items-center justify-center">
+                    <Loading></Loading>
+                </div>
+            )}
             {(isInit || data.length > 0) && (
-                <InfiniteScroll loadMore={loadMore} hasMore={hasMore}></InfiniteScroll>
+                <>
+                    <div className={styles.rightBox}>
+                        {data.map((item) => {
+                            return (
+                                <Card
+                                    key={`${actInfo?.type}_${actInfo?.id}_${item.id}`}
+                                    item={item}
+                                    className={styles.gameCard}
+                                    isShowFavorite={true}
+                                    isShowOnline={true}
+                                ></Card>
+                            );
+                        })}
+                    </div>
+                    <InfiniteScroll loadMore={loadMore} hasMore={hasMore}></InfiniteScroll>
+                </>
             )}
 
             {!isInit && !loading && data.length <= 0 && <Empty></Empty>}

+ 1 - 0
src/app/[locale]/(navbar)/gameList2/layout.tsx

@@ -21,6 +21,7 @@ export default async function Layout({
                 showBack={true}
                 title={<div className="flex justify-center">Lista</div>}
                 Right={<Search></Search>}
+                showBonus={false}
             ></HeaderBack>
             <main className={"main-header"}>{children}</main>
         </div>

+ 14 - 0
src/app/[locale]/layout.tsx

@@ -88,6 +88,7 @@ export default async function LocaleLayout({
         notFound();
     }
     const messages = await getMessages();
+
     return (
         <html lang={locale} suppressHydrationWarning>
             <body className={clsx("font-sans", fontSans.variable)}>
@@ -99,6 +100,19 @@ export default async function LocaleLayout({
                         </Suspense>
                     </Providers>
                 </NextIntlClientProvider>
+                <div
+                    id="globalMask"
+                    style={{
+                        position: "fixed",
+                        zIndex: 100,
+                        background: "rgba(0,0,0,.7)",
+                        display: "none",
+                        left: 0,
+                        top: 0,
+                        right: 0,
+                        bottom: 0,
+                    }}
+                ></div>
             </body>
         </html>
     );

+ 1 - 0
src/app/[locale]/providers.tsx

@@ -39,6 +39,7 @@ const initFirebase = () => {
     if (!window.Notification) {
         return;
     }
+
     //  是否开启通知
     // new Notification("这是标题", {
     //     body: "这是正文",

+ 4 - 1
src/components/Box/index.tsx

@@ -45,7 +45,10 @@ const openWindow = (url: string) => {
     if (isHttpUrl(url)) {
         window.open(url);
     } else {
-        Toast.show("非法地址");
+        Toast.show({
+            icon: "fail",
+            content: "URL is not valid",
+        });
     }
 };
 

+ 1 - 1
src/components/Card/Card.tsx

@@ -181,7 +181,7 @@ const Card: FC<PropsWithChildren<CardProps>> = (props) => {
                         className={"h-[100%] w-[100%]"}
                     />
                     {props.isShowOnline && item?.online_user && (
-                        <div className={styles.cardOnline}>{item?.online_user} On-Line</div>
+                        <div className={styles.cardOnline}>{item?.online_user}</div>
                     )}
                     {props.isShowFavorite && (
                         <div

+ 1 - 1
src/components/Card/style.module.scss

@@ -22,7 +22,7 @@
     position: absolute;
     left: 0.1rem;
     bottom: 0.05rem;
-    font-size: 0.1rem;
+    font-size: 0.12rem;
     color: #fff;
     &::before {
         content: "";

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

@@ -23,6 +23,7 @@ export interface HeaderBackProps {
     className?: string;
     useBg?: Boolean;
     Right?: ReactNode; // 右侧自定义渲染,优先级高于childre
+    showBonus?: boolean;
 }
 
 const HeaderBack: FC<PropsWithChildren<HeaderBackProps>> = ({
@@ -31,6 +32,7 @@ const HeaderBack: FC<PropsWithChildren<HeaderBackProps>> = ({
     children,
     className,
     useBg = false,
+    showBonus = false,
     Right,
 }) => {
     const t = useTranslations("HeaderBack");
@@ -84,10 +86,14 @@ const HeaderBack: FC<PropsWithChildren<HeaderBackProps>> = ({
                 {(title || selfTitle) && <span>{title || selfTitle}</span>}
             </div>
             <div className={styles.content}>{children}</div>
-            {getToken() && (
+            {getToken() && showBonus && (
                 <div>
                     {is_open_no_bonus === 1 && (
-                        <img src="/img/no_bouns.webp" alt="" className="h-[20px]" />
+                        <img
+                            src="/img/no_bouns.webp"
+                            alt=""
+                            className="h-[20px] w-[auto] max-w-[none]"
+                        />
                     )}
                 </div>
             )}

+ 35 - 8
src/components/TipsModal/index.tsx

@@ -1,7 +1,14 @@
 "use client";
 import { Mask } from "antd-mobile";
 import clsx from "clsx";
-import { forwardRef, PropsWithChildren, ReactNode, useImperativeHandle, useState } from "react";
+import {
+    forwardRef,
+    PropsWithChildren,
+    ReactNode,
+    useEffect,
+    useImperativeHandle,
+    useState,
+} from "react";
 
 type Props = {
     title?: string | ReactNode;
@@ -10,25 +17,45 @@ type Props = {
     className?: string; // 自定义样式类名,用于覆盖默认样式,如:bg-[#fff] text-[#000] 等
     visible?: boolean;
     position?: "center" | "bottom";
+    onChange?: (visible: boolean) => void;
 };
 export type ModalProps = {
     onClose: () => void;
     onOpen: () => void;
 };
 const TipsModal = forwardRef<ModalProps, PropsWithChildren<Props>>(function TipsModal(props, ref) {
-    const { children, title, onBeforeClose, className, position = "center" } = props;
+    const {
+        children,
+        title,
+        onBeforeClose,
+        className,
+        position = "center",
+        onChange,
+        visible,
+    } = props;
 
-    const [visible, setVisible] = useState(props.visible || false);
+    const [innerVisible, setInnerVisible] = useState<boolean>(visible || false);
     useImperativeHandle(ref, () => {
         return {
-            onClose: () => setVisible(false),
-            onOpen: () => setVisible(true),
+            onClose: () => setInnerVisible(false),
+            onOpen: () => setInnerVisible(true),
         };
     });
+
+    useEffect(() => {
+        if (typeof onChange === "function") {
+            onChange(innerVisible);
+        }
+    }, [innerVisible]);
+
+    useEffect(() => {
+        setInnerVisible(!!visible);
+    }, [visible]);
+
     return (
         <Mask
-            visible={visible}
-            onMaskClick={() => setVisible(false)}
+            visible={innerVisible}
+            onMaskClick={() => setInnerVisible(false)}
             getContainer={props?.getContainer}
         >
             <div
@@ -46,7 +73,7 @@ const TipsModal = forwardRef<ModalProps, PropsWithChildren<Props>>(function Tips
                             className="iconfont icon-guanbi closeIcon"
                             onClick={() => {
                                 onBeforeClose && onBeforeClose();
-                                setVisible(false);
+                                setInnerVisible(false);
                             }}
                         ></span>
                     </div>

+ 21 - 1
src/i18n/routing.ts

@@ -5,7 +5,12 @@ export const locales = modulesFiles.keys().map((modulePath: string) => {
     return modulePath.replace(/^\.\/(.*)\.\w+$/, "$1");
 });
 // 路由
-export const { Link, redirect, usePathname, useRouter } = createNavigation({
+const {
+    Link,
+    redirect,
+    usePathname,
+    useRouter: useBaseRouter,
+} = createNavigation({
     locales,
 });
 
@@ -16,3 +21,18 @@ export const routing = defineRouting({
     defaultLocale: defaultLocale,
     localeCookie: { name: "language" },
 });
+
+const useRouter = () => {
+    const router = useBaseRouter();
+
+    const cfg: any = { ...router };
+    Object.keys(router).forEach((key: any) => {
+        cfg[key] = (...args: any) => {
+            // document.querySelector("#globalMask").style.display = "block";
+            (router as any)[key].apply(null, args);
+        };
+    });
+    return cfg;
+};
+
+export { Link, redirect, usePathname, useRouter };

+ 2 - 2
src/utils/methods/index.ts

@@ -13,7 +13,7 @@ export function debounce<T extends (...args: any[]) => any>(
 ): (...args: Parameters<T>) => ReturnType<T> | undefined {
     let timer: NodeJS.Timeout | null = null;
     let isInvoked = false;
-
+    console.log(1122, timer);
     return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
         const context = this;
 
@@ -22,7 +22,7 @@ export function debounce<T extends (...args: any[]) => any>(
             isInvoked = true;
             return fn.apply(context, args);
         }
-
+        console.log(timer);
         // 清除之前的定时器
         if (timer) {
             clearTimeout(timer);