瀏覽代碼

fix: message page

Before 11 月之前
父節點
當前提交
b941a936c5

+ 2 - 1
.env.development

@@ -1,3 +1,4 @@
 #NEXT_PUBLIC_BASE_URL=http://192.168.0.66:8800
-NEXT_PUBLIC_BASE_URL=http://192.168.0.84:8800
+#NEXT_PUBLIC_BASE_URL=http://192.168.0.84:8800
+NEXT_PUBLIC_BASE_URL=http://104.251.122.138:8800
 #NEXT_PUBLIC_BASE_URL=http://206.168.191.125:8800

+ 4 - 1
messages/br.json

@@ -117,7 +117,10 @@
     "instant":  "Minhas Apostas Virtuais Instantâneas",
     "transactions": "Transações",
     "message":  "Mensagem",
-    "initial": "Adicionar à Tela inicial"
+    "initial": "Adicionar à Tela inicial",
+
+    "systemMessage": "Plataforma",
+    "personalMessage": "Pessoal"
   },
   "DepositPage": {
     "Montante": "Montante",

+ 48 - 0
src/api/betrecord.ts

@@ -0,0 +1,48 @@
+import { Pagination } from "@/types";
+import { server } from "@/utils/client";
+
+export interface RecordBillsResp {
+    /**
+     * 金额
+     */
+    amount?: number;
+    /**
+     * 下注
+     */
+    bet?: number;
+    /**
+     * 下注后余额
+     */
+    bet_after_amount?: number;
+    /**
+     * 下注前余额
+     */
+    bet_before_amount?: number;
+    /**
+     * 类型,1:充值,2:提现,3:红包雨,4:输返,5:代理佣金,6:提现失败,7:盲盒,8:内部测试
+     */
+    category?: number;
+    /**
+     * 创建时间
+     */
+    created_at?: number;
+    /**
+     * 产品
+     */
+    product?: string;
+    /**
+     * 返奖
+     */
+    reward?: number;
+    /**
+     * 玩家ID
+     */
+    user_id?: number;
+}
+export const betRecordApi = (data: any) => {
+    return server.post<RecordBillsResp[], Pagination>({
+        url: "/v1/api/user/user_bill_list",
+        data: data,
+        method: "POST",
+    });
+};

+ 2 - 6
src/api/home.ts

@@ -1,3 +1,4 @@
+import { Pagination } from "@/types";
 import { server } from "@/utils/client";
 
 export type ActionType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | undefined;
@@ -215,14 +216,9 @@ export type SearchProps = {
     page_size: number;
     use_page: boolean;
 };
-type Page = {
-    page: {
-        is_end: boolean; // 是否最后一页 ture:是 false:否
-    };
-};
 // 获取游戏列表-(跳转 搜索)
 export const searchGameListApi = (props: SearchProps) => {
-    return server.post<GameListRep[], Page>({
+    return server.post<GameListRep[], Pagination>({
         url: "/v1/api/front/game_list_search",
         data: props,
     });

+ 4 - 40
src/api/summary.ts

@@ -1,3 +1,4 @@
+import { Pagination } from "@/types";
 import { server } from "@/utils/client";
 
 /**
@@ -114,46 +115,9 @@ export interface UserLevelToDayResp {
      */
     score_num?: number;
 }
-export interface UserLevelToDayPagination {
-    /**
-     * 分页模式--当前页数
-     */
-    current_page?: number;
-    /**
-     * 升序-降序
-     */
-    is_asc?: boolean;
-    /**
-     * 是否已经没有数据
-     */
-    is_end?: boolean;
-    /**
-     * 下一页的起始位,默认0
-     */
-    next_cursor?: string;
-    /**
-     * 每页大小
-     */
-    page_size?: number;
-    /**
-     * 如果是升序-那就是最大ID,如果是降序那就是最小ID
-     */
-    start_cursor?: string;
-    /**
-     * 总数
-     */
-    total_count?: number;
-    /**
-     * 是否使用分页----默认为下标模式
-     */
-    use_page?: boolean;
-}
-type UserLevelToDayPage = {
-    page: UserLevelToDayPagination;
-};
 
 export const getInfoDayApi = (data: InfoDayRequest) => {
-    return server.post<UserLevelToDayResp[], UserLevelToDayPage>({
+    return server.post<UserLevelToDayResp[], Pagination>({
         url: "/v1/api/user/user_self_info_day",
         data,
     });
@@ -200,7 +164,7 @@ export interface UserTodayInfoList {
     register_new?: number;
 }
 export const getInfoDayList = (data: InfoDayListRequest) => {
-    return server.post<UserTodayInfoList[], { page: UserLevelToDayPagination }>({
+    return server.post<UserTodayInfoList[], Pagination>({
         url: "/v1/api/user/user_self_info_list",
         data,
     });
@@ -224,7 +188,7 @@ export interface UserWithdrawalList {
     withdrawal_time?: number;
 }
 export const getWithdrawalListApi = (data: InfoDayListRequest) => {
-    return server.post<UserWithdrawalList[], { page: UserLevelToDayPagination }>({
+    return server.post<UserWithdrawalList[], Pagination>({
         url: "/v1/api/user/user_commission_withdrawal_list",
         data,
     });

+ 2 - 2
src/app/[locale]/(TabBar)/(ordinary)/profile/component/ItemCom/index.tsx

@@ -23,11 +23,11 @@ const links = [
     },
     { label: "pray", desc: "", icon: "icon-mianfei", color: "#20894d", url: "/" },
     { label: "cashback", desc: "", icon: "icon-qiandai", color: "rgb(255, 147, 35)", url: "/" },
-    { label: "gamblingBets", desc: "", icon: "", url: "/gambling" },
+    { label: "gamblingBets", desc: "", icon: "", url: "/betrecord" },
     { label: "league", desc: "", icon: "", url: "/" },
     { label: "instant", desc: "", icon: "", url: "/" },
     { label: "transactions", desc: "", icon: "", url: "/" },
-    { label: "message", desc: "", icon: "", url: "/" },
+    { label: "message", desc: "", icon: "", url: "/notification" },
     { label: "initial", desc: "", icon: "", url: "/" },
 ];
 

+ 1 - 1
src/app/[locale]/(TabBar)/[[...share]]/_home/HomeSwiper.tsx

@@ -10,7 +10,7 @@ interface Props {
     banners: BannerRep[];
 }
 const HomeSwiper: FC<Props> = (props) => {
-    const { banners } = props;
+    const { banners = [] } = props;
     // 获取分享id
     const pathname = usePathname();
     useEffect(() => {

+ 65 - 0
src/app/[locale]/(navbar)/betrecord/components/list.tsx

@@ -0,0 +1,65 @@
+"use client";
+import { RecordBillsResp } from "@/api/betrecord";
+import Empty from "@/components/Empty";
+import { Pagination, Response } from "@/types";
+import { InfiniteScroll, List } from "antd-mobile";
+import dayjs from "dayjs";
+import { FC, useState } from "react";
+
+interface Props {
+    record: Response<RecordBillsResp[]> & Pagination;
+}
+
+const BetRecord: FC<Props> = (props) => {
+    const {
+        record: { data, page },
+    } = props;
+    const [recordBills, setRecordBills] = useState(data);
+    const loadMore = async () => {
+        console.log(`🎯🎯🎯🎯🎯-> in list.tsx on 8`);
+    };
+    if (recordBills.length === 0) return <Empty text={"Sem apostas"} />;
+
+    return (
+        <>
+            <List
+                style={{
+                    "--border-bottom": "none",
+                    "--border-top": "none",
+                    "--border-inner": "solid 1px #333333",
+                }}
+            >
+                {recordBills.map((_, index) => (
+                    <List.Item key={index}>
+                        <div className={"flex justify-between"}>
+                            <div className={"text-[#999]"}>Mines</div>
+                            <div>
+                                {Math.random() > 0.5 ? (
+                                    <span className={"text-[green]"}>
+                                        + {Math.random().toFixed(1)}
+                                    </span>
+                                ) : (
+                                    <span className={"text-[red]"}>LOST</span>
+                                )}
+                            </div>
+                        </div>
+
+                        <div
+                            className={
+                                "flex justify-between text-[0.10rem] text-[#999]" + " mt-[0.02rem]"
+                            }
+                        >
+                            <div>
+                                Bet: <span>0.4</span>
+                            </div>
+                            <div>{dayjs().format("DD-MM-YY hh:mm")}</div>
+                        </div>
+                    </List.Item>
+                ))}
+            </List>
+            <InfiniteScroll loadMore={loadMore} hasMore={!page.is_end} />
+        </>
+    );
+};
+
+export default BetRecord;

+ 19 - 0
src/app/[locale]/(navbar)/betrecord/layout.tsx

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

+ 27 - 0
src/app/[locale]/(navbar)/betrecord/page.tsx

@@ -0,0 +1,27 @@
+"use server";
+import { RecordBillsResp } from "@/api/betrecord";
+import Box from "@/components/Box";
+import { Pagination } from "@/types";
+import { server } from "@/utils/server";
+import { FC } from "react";
+import List from "./components/list";
+interface Props {}
+
+const getDataList = async () => {
+    return server.request<RecordBillsResp[], Pagination>({
+        url: "/v1/api/user/user_bill_list",
+        method: "POST",
+        data: { current_page: 1, page_size: 30 },
+    });
+};
+
+const BetRecord: FC<Props> = async (props) => {
+    const p = await getDataList();
+    return (
+        <Box>
+            <List record={p}></List>
+        </Box>
+    );
+};
+
+export default BetRecord;

+ 0 - 18
src/app/[locale]/(navbar)/gambling/layout.tsx

@@ -1,18 +0,0 @@
-import HeaderBack from "@/components/HeaderBack";
-import { useTranslations } from "next-intl";
-import { ReactNode } from "react";
-export default async function LocaleLayout({
-    children,
-    params: { locale },
-}: {
-    children: ReactNode;
-    params: { locale: string };
-}) {
-    const t = useTranslations("HeaderCom");
-    return (
-        <>
-            <HeaderBack showBack={true} title={"123"} />
-            <main className={"main-header"}>{children}</main>
-        </>
-    );
-}

+ 0 - 9
src/app/[locale]/(navbar)/gambling/page.tsx

@@ -1,9 +0,0 @@
-import { FC, PropsWithChildren } from "react";
-
-interface Props {}
-
-const Gambling: FC<PropsWithChildren<Props>> = (props) => {
-    return <div>hello React</div>;
-};
-
-export default Gambling;

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

@@ -0,0 +1,63 @@
+"use client";
+import { Badge, Tabs } from "antd-mobile";
+import { useTranslations } from "next-intl";
+import { FC, PropsWithChildren } from "react";
+import SystemMessage from "./SystemMessage";
+
+interface Props {}
+
+const Message: FC<PropsWithChildren<Props>> = (props) => {
+    const t = useTranslations("ProfilePage");
+    return (
+        <div className={"z-1000 sticky top-0"}>
+            <Tabs
+                style={{
+                    "--active-line-color": "#fb8910",
+                    "--active-title-color": "#fb8910",
+                    "--active-line-height": "3px",
+                    // @ts-ignore
+                    "--adm-color-border": "none",
+                }}
+            >
+                <Tabs.Tab
+                    title={
+                        <Badge
+                            content="1"
+                            style={{
+                                "--right": "-10px",
+                                "--top": "8px",
+                                "--adm-color-text-light-solid": "#000",
+                            }}
+                            color={"#f0dc00"}
+                        >
+                            {t("systemMessage")}
+                        </Badge>
+                    }
+                    key="fruits"
+                >
+                    <SystemMessage />
+                </Tabs.Tab>
+                <Tabs.Tab
+                    title={
+                        <Badge
+                            content="1"
+                            style={{
+                                "--right": "-10px",
+                                "--top": "8px",
+                                "--adm-color-text-light-solid": "#000",
+                            }}
+                            color={"#f0dc00"}
+                        >
+                            {t("personalMessage")}
+                        </Badge>
+                    }
+                    key="vegetables"
+                >
+                    <SystemMessage />
+                </Tabs.Tab>
+            </Tabs>
+        </div>
+    );
+};
+
+export default Message;

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

@@ -0,0 +1,18 @@
+import { FC, PropsWithChildren } from "react";
+
+interface Props {}
+
+const SystemMessage: FC<PropsWithChildren<Props>> = (props) => {
+    console.log(`🎯🎯🎯🎯🎯-> in SystemMessage.tsx on 6`);
+    return (
+        <div>
+            {Array(100)
+                .fill(0)
+                .map((item, index) => {
+                    return <div key={index}>{index}</div>;
+                })}
+        </div>
+    );
+};
+
+export default SystemMessage;

+ 19 - 0
src/app/[locale]/(navbar)/notification/layout.tsx

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

+ 15 - 0
src/app/[locale]/(navbar)/notification/page.tsx

@@ -0,0 +1,15 @@
+import { FC } from "react";
+import HeaderTabs from "./components/HeaderTabs";
+
+interface Props {}
+
+const Notification: FC<Props> = (props) => {
+    return (
+        <div className={"static top-0 overflow-visible border-3"}>
+            head
+            <HeaderTabs />
+        </div>
+    );
+};
+
+export default Notification;

+ 23 - 0
src/components/Empty/index.tsx

@@ -0,0 +1,23 @@
+import clsx from "clsx";
+import React, { FC } from "react";
+
+interface Props {
+    style?: React.CSSProperties;
+    className?: string;
+    render?: () => React.ReactNode;
+    text?: string;
+}
+
+const Empty: FC<Props> = (props) => {
+    const { render, text = "no data", className } = props;
+    const cls = clsx(
+        "iconfont icon-meiyoushuju flex h-[2.0833rem] flex-col items-center justify-center text-[0.4167rem] text-[#999]",
+        className
+    );
+    return (
+        <div className={cls}>
+            {render ? render() : <span className={"text-[0.12rem]"}>{text}</span>}
+        </div>
+    );
+};
+export default Empty;

+ 41 - 0
src/types/index.ts

@@ -9,3 +9,44 @@ export type LocalPropsWithChildren<T = unknown> = {
         local: string;
     };
 } & PropsWithChildren<T>;
+export interface Pagination {
+    page: {
+        /**
+         * 分页模式--当前页数
+         */
+        current_page: number;
+        /**
+         * 升序-降序
+         */
+        is_asc: boolean;
+        /**
+         * 是否已经没有数据
+         */
+        is_end: boolean;
+        /**
+         * 下一页的起始位,默认0
+         */
+        next_cursor: string;
+        /**
+         * 每页大小
+         */
+        page_size: number;
+        /**
+         * 如果是升序-那就是最大ID,如果是降序那就是最小ID
+         */
+        start_cursor: string;
+        /**
+         * 总数
+         */
+        total_count: number;
+        /**
+         * 是否使用分页----默认为下标模式
+         */
+        use_page: boolean;
+    };
+}
+export interface Response<T> {
+    code: number;
+    msg: string;
+    data: T;
+}

+ 5 - 3
src/utils/server/index.ts

@@ -12,7 +12,9 @@ const requestInterceptor = (options: ServerOptions) => {
     }
     return options;
 };
-const responseInterceptor = <T = any>(response: Result<T>): Promise<Result<T>> => {
+const responseInterceptor = <T = any, R = unknown>(
+    response: Result<T> & R
+): Promise<Result<T> & R> => {
     return new Promise((resolve, reject) => {
         const { code, msg } = response;
         switch (code) {
@@ -35,7 +37,7 @@ class Server {
         this.BASE_URL = process.env.NEXT_PUBLIC_BASE_URL as string;
     }
 
-    async request<T>(options: ServerOptions): Promise<Result<T>> {
+    async request<T, R = unknown>(options: ServerOptions): Promise<Result<T> & R> {
         options = requestInterceptor(options);
         const { method = "GET", url, headers = {}, data = {}, body, ...other } = options;
         const params = JSON.stringify(data);
@@ -50,7 +52,7 @@ class Server {
                 body: params,
                 ...other,
             }).then((res) => res.json());
-            return responseInterceptor<T>(response);
+            return responseInterceptor<T, R>(response);
         } catch (error) {
             return Promise.reject(error);
         }