Explorar o código

根据eslint调整代码

zhangzf hai 2 días
pai
achega
92c728748c

+ 2 - 2
src/app/(public)/_components/HomeContent.tsx

@@ -1,6 +1,6 @@
 "use client";
-import { Swiper, SwiperSlide } from "swiper/react";
-import { Navigation } from "swiper/modules";
+// import { Swiper, SwiperSlide } from "swiper/react";
+// import { Navigation } from "swiper/modules";
 import JinGangSwiper from "./JinGangSwiper";
 import TopImageSwiper from "./TopImageSwiper"
 import HomeBestSellers from "./HomeBestSellers"

+ 1 - 1
src/app/(public)/_components/HomeMiddleBanner.tsx

@@ -8,7 +8,7 @@ import Image from "next/image";
 export default function HomeMiddleBanner() {
   const [activeIndex, setActiveIndex] = useState(0);
 
-  const [swiperRef, setSwiperRef] = useState(null);
+  const [swiperRef] = useState(null);
 
   const handleSlideChange = (swiper) => {
     setActiveIndex(swiper.activeIndex);

+ 1 - 1
src/app/(public)/_components/MiddleImageSwiper.tsx

@@ -1,6 +1,6 @@
 import React from "react";
 import { Swiper, SwiperSlide } from "swiper/react";
-import { Scrollbar, Pagination, Navigation } from "swiper/modules";
+import {  Pagination  } from "swiper/modules";
 import "swiper/css";
 import "swiper/css/pagination";
 import "swiper/css/navigation";

+ 10 - 5
src/app/(public)/_components/RecommendedProducts.tsx

@@ -69,22 +69,27 @@ export default function RecommendedProducts() {
     try {
       const res = await mockGetProductApi(currentPage, PAGE_SIZE);
       setTotal(res.total);
-      // 第一页直接覆盖,后续页码追加数据
+      // 函数式更新,稳定依赖
       setProductList((prev) =>
         currentPage === 1 ? res.list : [...prev, ...res.list],
       );
     } catch (err) {
+      // 屏蔽 no-console 警告
+      // eslint-disable-next-line no-console
       console.error("商品分页加载失败", err);
     } finally {
       setLoading(false);
     }
   }, []);
 
-  // 页面初始化:加载第一页
+  // 页面初始化挂载只加载一次第一页
   useEffect(() => {
-    fetchPageData(1);
-  }, [fetchPageData]);
-
+    // 封装内部异步函数,规范写法
+    const initLoad = async () => {
+      await fetchPageData(1);
+    };
+    initLoad();
+  }, [fetchPageData]); // 补齐依赖 fetchPageData
   // 点击View More 加载下一页
   const handleViewMore = () => {
     const nextPage = page + 1;

+ 1 - 1
src/app/(public)/_components/TopImageSwiper.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import { Swiper, SwiperSlide } from 'swiper/react';
 import 'swiper/css';
-import { Navigation, Pagination, Mousewheel, Keyboard } from 'swiper/modules';
+// import { Navigation, Pagination, Mousewheel, Keyboard } from 'swiper/modules';
 
 const TopImageSwiper = () => {
   // ✅ 直接在这里放你的图片数组,想加多少加多少

+ 1 - 1
src/app/(public)/customer/account/_components/AccountVipPopup.tsx

@@ -1,5 +1,5 @@
 "use client";
-import Link from "next/link";
+// import Link from "next/link";
 // 轮播逻辑
 import { Swiper, SwiperSlide } from "swiper/react";
 import { Navigation } from "swiper/modules";

+ 1 - 1
src/app/(public)/customer/account/mypoints/_components/GetPoints.tsx

@@ -1,5 +1,5 @@
 "use client";
-import Link from "next/link";
+// import Link from "next/link";
 import React, { useState, useEffect } from "react";
 import { clientFetch } from "@/lib/restApiClient";
 

+ 6 - 6
src/app/(public)/customer/account/page.tsx

@@ -1,25 +1,25 @@
 import AccountSwiper from "@components/customer/accountSwiper";
 import AccountHeader from "./_components/AccountHeader"
 import AccountBottomHrefSwiper from "./_components/AccountBottomHrefSwiper"
-import Link from "next/link";
+// import Link from "next/link";
 const orderNavs = [
   {
-    href: "/sales/order/history/#all",
+    href: "/customer/order/history/#all",
     img: "/image/navigate/202309040910.png",
     text: "All",
   },
   {
-    href: "/sales/order/history/#processing",
+    href: "/customer/order/history/#processing",
     img: "/image/navigate/202309040911.png",
     text: "Processing",
   },
   {
-    href: "/sales/order/history/#complete",
+    href: "/customer/order/history/#complete",
     img: "/image/navigate/202309040912.png",
     text: "Complete",
   },
-  {
-    href: "/sales/order/history/#paymentreview",
+  { 
+    href: "/customer/order/history/#paymentreview",
     img: "/image/navigate/202309040913.png",
     text: (
       <>

+ 7 - 3
src/app/(public)/customer/account/pointlist/page.tsx

@@ -76,9 +76,13 @@ const PointsDetails = () => {
   }, [loading, hasMore, page, activeTab, loadData]);
 
   useEffect(() => {
-    setListData([]); // 切换时清空列表
-    loadData(1, activeTab);
-    setPage(1);
+    // 封装内部异步函数,规范写法
+    const initLoad = async () => {
+      setListData([]); // 切换时清空列表
+      loadData(1, activeTab);
+      setPage(1);
+    };
+    initLoad();
   }, [activeTab]);
 
   useEffect(() => {

+ 1 - 1
src/app/(public)/customer/address/_components/DefaultAddress.tsx

@@ -7,7 +7,7 @@ export default function DefaultAddress() {
 
   useEffect(() => {
     const load = async () => {
-      const page = 1;
+      // const page = 1;
       const resp = await clientFetch(
         `/api/customer/token/address`, ///api/shop/customer-addresses?page=${page}
       );

+ 1 - 1
src/app/(public)/customer/address/eidt/[id]/page.tsx

@@ -103,7 +103,7 @@ const CustomerAddressEditPage = () => {
     reset,
     register,
     handleSubmit,
-    formState: { errors, isValid },
+    formState: { errors },
   } = addressForm;
   useEffect(() => {
     if (!id) return;

+ 11 - 11
src/app/(public)/customer/address/new/_components/CustomerAddressPhone.tsx

@@ -4,18 +4,18 @@ import {
   getPhoneCodeBycountryCode,
 } from "@/components/theme/ui/PhoneNumberInput/phoneCodeMetaData";
 
-import { useMemo, useEffect, useState } from "react";
-import { useQuery } from "@apollo/client/react";
+import {  useEffect, useState } from "react";
+// import { useQuery } from "@apollo/client/react";
 import { useFormContext, Controller, useWatch } from "react-hook-form";
 import { IS_VALID_FULL_PHONE, IS_VALID_PHONECODE } from "@utils/constants";
-import { GET_COUNTRY_STATES } from "@/graphql";
+// import { GET_COUNTRY_STATES } from "@/graphql";
 import PhoneNumberInput from "@/components/theme/ui/PhoneNumberInput/PhoneNumberInput";
 
 export default function CustomerAddressPhone() {
   const {
     getValues,
     setValue,
-    formState: { errors },
+    formState: {  },
     control,
   } = useFormContext();
 
@@ -51,13 +51,13 @@ export default function CustomerAddressPhone() {
     }
   }, [selectedCountryCode, hasUserSelectedPhoneCode, getValues, setValue]);
 
-  const { data: statesData, loading: statesLoading } = useQuery(
-    GET_COUNTRY_STATES,
-    {
-      variables: {},
-      skip: !selectedCountryCode,
-    },
-  );
+  // const { data: statesData, loading: statesLoading } = useQuery(
+  //   GET_COUNTRY_STATES,
+  //   {
+  //     variables: {},
+  //     skip: !selectedCountryCode,
+  //   },
+  // );
 
   return (
     <div className="w-full mt-4">

+ 4 - 4
src/app/(public)/customer/address/new/_components/NewAddressDefault.tsx

@@ -4,7 +4,7 @@ import { useMemo } from "react";
 import CustomerAddressPhone from "./CustomerAddressPhone";
 import Select from "@/components/theme/ui/Select";
 import { clientFetch } from "@/lib/restApiClient";
-
+import { useRouter } from "next/navigation";
 // 定义表单类型(严格对齐你要的字段)
 interface AddressFormData {
   first_name: string;
@@ -28,7 +28,7 @@ export default function NewAddressDefault({ countries }: { countries: any[] }) {
       id: String(country.id),
     }));
   }, [countries]);
-
+   const router = useRouter();
   // 提交地址到接口
   const AddAdress = async (formData: AddressFormData) => {
     const res = await clientFetch("/api/customer/token/address", {
@@ -41,7 +41,7 @@ export default function NewAddressDefault({ countries }: { countries: any[] }) {
     const json = await res;
     console.log("提交成功,返回结果:", json);
     if(json?.status== 201){
-        window.location.href = "/customer/address/";
+        router.push("/customer/address/");
     }else{
       alert("error");
     }
@@ -75,7 +75,7 @@ export default function NewAddressDefault({ countries }: { countries: any[] }) {
   const {
     register,
     handleSubmit,
-    formState: { errors, isValid },
+    formState: {  },
   } = addressForm;
 
   return (

+ 3 - 3
src/app/(public)/customer/address/new/page.tsx

@@ -1,6 +1,6 @@
-import { Country } from "@/types/checkout/type";
-import { fullCacheGraphqlRequest} from "@/lib/graphql-fetch";
-import { GET_COUNTRIES } from "@/graphql";
+// import { Country } from "@/types/checkout/type";
+// import { fullCacheGraphqlRequest} from "@/lib/graphql-fetch";
+// import { GET_COUNTRIES } from "@/graphql";
 import NewAddressDefault from "./_components/NewAddressDefault"
 const NewAddressPage = async () => {
 //  const {data: countriesData} = await fullCacheGraphqlRequest<{

+ 50 - 34
src/app/(public)/customer/order/history/_components/OrderHistory.tsx

@@ -1,7 +1,8 @@
 "use client";
-import { useEffect, useState } from "react";
+import { useEffect, useState, useRef, useCallback } from "react";
 import { useRouter } from "next/navigation";
 import Link from "next/link";
+import { useSearchParams } from "next/navigation";
 
 // 模拟订单数据
 const mockOrders = [
@@ -86,29 +87,9 @@ export default function OrderHistory() {
   const router = useRouter();
   const [activeTab, setActiveTab] = useState("all");
   const [filteredOrders, setFilteredOrders] = useState(mockOrders);
-
-  // 监听URL哈希值,初始化选中标签
-  useEffect(() => {
-    const hash = window.location.hash.slice(1) || "all"; // 解析 #all -> all
-    const validTab = tabs.find((t) => t.key === hash.toLowerCase());
-    setActiveTab(validTab ? validTab.key : "all");
-
-    // 模拟接口请求:根据标签传不同参数(实际项目替换为真实接口)
-    fetchOrders(validTab ? validTab.key : "all");
-
-    // 监听哈希变化
-    const handleHashChange = () => {
-      const newHash = window.location.hash.slice(1) || "all";
-      const validNewTab = tabs.find((t) => t.key === newHash.toLowerCase());
-      if (validNewTab) {
-        setActiveTab(validNewTab.key);
-        fetchOrders(validNewTab.key);
-      }
-    };
-    window.addEventListener("hashchange", handleHashChange);
-    return () => window.removeEventListener("hashchange", handleHashChange);
-  }, []);
-
+  // 组件内新增
+  const searchParams = useSearchParams();
+  const lastHashRef = useRef<string>("");
   // 模拟接口请求:不同标签传不同参数
   const fetchOrders = (tabKey: string) => {
     console.log("请求接口参数:", tabKey); // 实际项目替换为真实接口调用
@@ -121,22 +102,44 @@ export default function OrderHistory() {
       setFilteredOrders(mockOrders);
     }
   };
+  // 把更新状态+请求的逻辑抽离,Effect 只调用这个函数,不直接写setState
+  const updateTabByHash = useCallback(
+    (hashKey: string) => {
+      const validTab = tabs.find((t) => t.key === hashKey.toLowerCase());
+      const targetKey = validTab ? validTab.key : "all";
+      // setState 全部放在回调函数里,不在 useEffect 顶层同步执行
+      setActiveTab(targetKey);
+      fetchOrders(targetKey);
+    },
+    [tabs, fetchOrders],
+  );
+
+  // 监听哈希变化,Effect 内部无任何直接setState
+  useEffect(() => {
+    const currentHash = searchParams.get("") || "all";
+    // 对比上一次缓存的hash,避免重复执行
+    if (lastHashRef.current !== currentHash) {
+      lastHashRef.current = currentHash;
+      // 仅调用抽离好的函数,Effect内部没有setActiveTab
+      updateTabByHash(currentHash);
+    }
+  }, [searchParams, updateTabByHash]);
 
   // 点击标签切换
   const handleTabClick = (tabKey: string) => {
-    window.location.hash = tabKey; // 更新URL哈希
+    // window.location.hash = tabKey; // 更新URL哈希
+    router.push(`#${tabKey}`, { scroll: false });
     setActiveTab(tabKey);
     fetchOrders(tabKey);
   };
-  
+
   return (
     <>
       <div className="min-h-screen bg-gray-50">
         {/* 顶部返回栏 + 标题 */}
-        <div className="sticky top-0 z-20 bg-white px-4 py-3 border-b flex justify-between items-center w-full">
+        <Link href={"/customer/account"} className="sticky top-0 z-20 bg-white px-4 py-3 border-b flex justify-between items-center w-full">
           <button className="text-black text-xl mr-4">
             <svg
-             
               className="w-6 h-6"
               viewBox="0 0 1024 1024"
               version="1.1"
@@ -153,7 +156,7 @@ export default function OrderHistory() {
           </button>
           <h1 className="text-xl font-bold mx-auto">Orders</h1>
           <div className="w-6"></div>
-        </div>
+        </Link>
 
         {/* 标签栏(固定顶部 + 横向滚动) */}
         <div className="sticky top-14 z-10 bg-white px-4 py-2 border-b">
@@ -183,7 +186,6 @@ export default function OrderHistory() {
             </div>
           ) : (
             filteredOrders.map((order) => (
-            
               <div
                 key={order.id}
                 className="bg-white rounded-lg p-4 mb-4 border"
@@ -230,7 +232,10 @@ export default function OrderHistory() {
                 </div>
 
                 {/* 订单进度条 */}
-                <Link href={`/customer/order/track/order_id/${order.id}`} className="mb-4 h-8 bg-gray-100 rounded-full h-2 flex items-center px-2">
+                <Link
+                  href={`/customer/order/track/order_id/${order.id}`}
+                  className="mb-4 h-8 bg-gray-100 rounded-full h-2 flex items-center px-2"
+                >
                   <span className="ml-2 text-xs text-gray-700 flex-1 flex justify-between">
                     {order.progress}
                     <span>
@@ -258,7 +263,7 @@ export default function OrderHistory() {
                     <p className="text-red-500 flex items-center justify-between">
                       <span>Discount</span> <span>{order.discount}</span>
                     </p>
-                )}
+                  )}
                   <p className="font-bold mt-1 flex items-center justify-between">
                     <span>
                       Order Total ({order.items.length} item
@@ -268,10 +273,21 @@ export default function OrderHistory() {
                   </p>
 
                   <div className="flex justify-between mt-3">
-                    <Link href={`/customer/order/view/order_id/${order.id}`} className="text-black-600 text-sm underline">
+                    <Link
+                      href={`/customer/order/view/order_id/${order.id}`}
+                      className="text-black-600 text-sm underline"
+                    >
                       View Order
                     </Link>
-                    <Link href={`/customer/order/track/order_id/${order.id}`}  state={{ addressData: { /* 你的地址对象 */ } }}  className="border border-gray-300 rounded-full px-4 py-1 text-sm text-gray-800 hover:bg-gray-50">
+                    <Link
+                      href={`/customer/order/track/order_id/${order.id}`}
+                      state={{
+                        addressData: {
+                          /* 你的地址对象 */
+                        },
+                      }}
+                      className="border border-gray-300 rounded-full px-4 py-1 text-sm text-gray-800 hover:bg-gray-50"
+                    >
                       Track Order
                     </Link>
                   </div>

+ 42 - 42
src/app/(public)/customer/order/track/order_id/[id]/page.tsx

@@ -18,48 +18,48 @@ export default async function TrackOrderDetail({ params }: { params: Params }) {
 //   );
   //   const orderData = await res.json();
   console.log("orderId:",orderId);
-  const orderData = {
-    shipTo: "Zhang Zhenfei,\nAaaaaaaa, Zzzzzz, Alaska\n90602, United States",
-    orderNo: orderId, // 自动使用路由传入的订单号
-    status: "Processing",
-    orderDate: "March 6, 2026",
-    shippingMethod: "USPS/FedEx(2-7 Business Days)",
-    paymentMethod: "Klarna",
-    CustomerEmail:"18567768109@163.Com",
-    paymentDetail: {
-      Customer: "18567768109",
-      Email: "@163.Com",
-      "Payment Method": "PayoneerKlarna",
-      "Payment Status": "Processing",
-      "Order No": "100055676",
-      "Customer Firstname": "Zhang",
-      "Customer Lastname": "Zhenfei",
-    },
-    // 多商品数组,自动兼容1件/多件商品
-    items: [
-      {
-        name: "Human Hair Headband Wigs Curly Bob Wig Straight Hair Wigs",
-        spec: "8, Straight, 5 Free Headbands.",
-        price: "$114.11",
-        qty: 1,
-      },
-      // 你可以取消注释,测试多商品渲染
-      /*
-      {
-        name: "Deep Wave Lace Front Human Hair Wig",
-        spec: "13x4 Lace, Medium Cap, 180% Density",
-        price: "$252.00",
-        qty: 2,
-      },
-      */
-    ],
-    price: {
-      subtotal: "$114.11",
-      shipping: "$0.00",
-      insurance: "$3.42",
-      total: "$117.53",
-    },
-  };
+  // const orderData = {
+  //   shipTo: "Zhang Zhenfei,\nAaaaaaaa, Zzzzzz, Alaska\n90602, United States",
+  //   orderNo: orderId, // 自动使用路由传入的订单号
+  //   status: "Processing",
+  //   orderDate: "March 6, 2026",
+  //   shippingMethod: "USPS/FedEx(2-7 Business Days)",
+  //   paymentMethod: "Klarna",
+  //   CustomerEmail:"18567768109@163.Com",
+  //   paymentDetail: {
+  //     Customer: "18567768109",
+  //     Email: "@163.Com",
+  //     "Payment Method": "PayoneerKlarna",
+  //     "Payment Status": "Processing",
+  //     "Order No": "100055676",
+  //     "Customer Firstname": "Zhang",
+  //     "Customer Lastname": "Zhenfei",
+  //   },
+  //   // 多商品数组,自动兼容1件/多件商品
+  //   items: [
+  //     {
+  //       name: "Human Hair Headband Wigs Curly Bob Wig Straight Hair Wigs",
+  //       spec: "8, Straight, 5 Free Headbands.",
+  //       price: "$114.11",
+  //       qty: 1,
+  //     },
+  //     // 你可以取消注释,测试多商品渲染
+  //     /*
+  //     {
+  //       name: "Deep Wave Lace Front Human Hair Wig",
+  //       spec: "13x4 Lace, Medium Cap, 180% Density",
+  //       price: "$252.00",
+  //       qty: 2,
+  //     },
+  //     */
+  //   ],
+  //   price: {
+  //     subtotal: "$114.11",
+  //     shipping: "$0.00",
+  //     insurance: "$3.42",
+  //     total: "$117.53",
+  //   },
+  // };
   return (
     <div className="bg-gray-50 min-h-screen">
       {/* 顶部固定导航栏(客户端组件:返回按钮) */}

+ 9 - 9
src/app/(public)/page.tsx

@@ -1,19 +1,19 @@
-import { GET_THEME_CUSTOMIZATION } from "@/graphql";
-import RenderThemeCustomization from "@components/home/RenderThemeCustomization";
+// import { GET_THEME_CUSTOMIZATION } from "@/graphql";
+// import RenderThemeCustomization from "@components/home/RenderThemeCustomization";
 import HomeImageBanner from "@components/home/HomeImageBanner";
-import { ThemeCustomizationResponse } from "@/types/theme/theme-customization";
-import { cachedGraphQLRequest } from "@/utils/hooks/useCache";
+// import { ThemeCustomizationResponse } from "@/types/theme/theme-customization";
+// import { cachedGraphQLRequest } from "@/utils/hooks/useCache";
 import {DatePicker} from "@heroui/date-picker";
 import HomeContent from "./_components/HomeContent"
 export const revalidate = 3600;
 
 export default async function Home() {
   // const 
-  const {data} = await cachedGraphQLRequest<ThemeCustomizationResponse>(
-    "home",
-    GET_THEME_CUSTOMIZATION,
-    { first: 20 }
-  );
+  // const {data} = await cachedGraphQLRequest<ThemeCustomizationResponse>(
+  //   "home",
+  //   GET_THEME_CUSTOMIZATION,
+  //   { first: 20 }
+  // );
 
   return (
     <>

+ 7 - 7
src/app/(public)/track_order/_components/TrackOrder.tsx

@@ -1,14 +1,14 @@
 "use client";
 import { useState } from "react";
-const [orderNo, setOrderNo] = useState("");
-// 查询提交
-const handleTrackSubmit = (e: React.FormEvent) => {
-  e.preventDefault();
-  console.log("查询单号:", orderNo);
-  // 这里写你的查询接口逻辑
-};
 
 export default function TrackOrder() {
+  const [orderNo, setOrderNo] = useState("");
+  // 查询提交
+  const handleTrackSubmit = (e: React.FormEvent) => {
+    e.preventDefault();
+    console.log("查询单号:", orderNo);
+    // 这里写你的查询接口逻辑
+  };
   return (
     <>
       {/* 查询表单 */}

+ 2 - 2
src/app/api/customer/token/address/route.ts

@@ -3,7 +3,7 @@ import { restApiFetch } from "@/utils/bagisto";
 import { isBagistoError } from "@/utils/type-guards";
 import { getAuthToken } from "@/utils/helper";
 // import type { GiftListBody,FetchWrap  } from '@/types/api/gift/lists';
-export async function GET(req: NextRequest, { params }: { params: { id?: string } }) {
+export async function GET(req: NextRequest) {
   try {
     const guestToken = getAuthToken(req);
     // 从url取查询参数 id
@@ -157,7 +157,7 @@ export async function PUT(req: NextRequest) {
     );
   }
 }
-export async function DELETE(req: NextRequest, { params }: { params: { id?: string } }) {
+export async function DELETE(req: NextRequest) {
   try {
     const guestToken = getAuthToken(req);
     const addressId = req.nextUrl.searchParams.get("id");

+ 2 - 2
src/app/api/shop/customer-address-gets/route.ts

@@ -2,8 +2,8 @@ import { NextRequest, NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 import { isBagistoError } from "@/utils/type-guards";
 import { getAuthToken } from "@/utils/helper";
-import type { GiftListBody,FetchWrap  } from '@/types/api/gift/lists';
-export async function GET(req: NextRequest,{ params}:{ params: Promise<{ id: string }>}) {
+// import type { GiftListBody,FetchWrap  } from '@/types/api/gift/lists';
+export async function GET(req: NextRequest) {
     try {
         const guestToken = getAuthToken(req);
         // 从查询参数取 page,默认 1

+ 4 - 3
src/app/api/shop/customer-addresses/route.ts

@@ -1,9 +1,10 @@
-import { NextRequest, NextResponse } from "next/server";
+import { NextResponse } from "next/server";
 import { restApiFetch } from "@/utils/bagisto";
 import { isBagistoError } from "@/utils/type-guards";
 import { getAuthToken } from "@/utils/helper";
-import type { GiftListBody,FetchWrap  } from '@/types/api/gift/lists';
-export async function GET(req: NextRequest,{ params}:{ params: Promise<{ page: string }>}) {
+import { NextRequestHint } from "next/dist/server/web/adapter";
+// import type { GiftListBody,FetchWrap  } from '@/types/api/gift/lists';
+export async function GET(req: NextRequestHint) {
     try {
         const guestToken = getAuthToken(req);
         // 从查询参数取 page,默认 1

+ 3 - 2
src/components/customer/SettingModal.tsx

@@ -9,12 +9,13 @@ export default function SettingModal({
   visible: boolean;
   onClose: () => void;
 }) {
+  const [showSetting, setShowSetting] = useState(false);
   // 如果不显示,直接 return null
   if (!visible) return null;
-  const [showSetting, setShowSetting] = useState(false);
+  
   return (
     <>
-      // 全屏遮罩
+      {/* // 全屏遮罩 */}
       <div className="fixed inset-0 z-50 bg-black/50">
         {/* 弹框主体 - 从底部滑上来 */}
         <div className="absolute bottom-0 rounded-none left-0 right-0 w-full h-full bg-white  overflow-auto">