更新登录

Change-Id: I0b2663f4291f573625222995b09a99ac53c2a081
diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx
index 7234c32..f9891d7 100644
--- a/src/pages/Home/index.tsx
+++ b/src/pages/Home/index.tsx
@@ -9,6 +9,7 @@
 import { Typography } from "@mui/material";
 import { useRequest } from '@umijs/max';
 import { getPlanetList, updatePlanet, getUserPlanet, getPlanetInfo, PlanetEntity } from '@/services/planets/api';
+import {generatePassKey} from '../../services/bt/index'
 
 const Welcome: React.FC = () => {
   //  获取用户信息
@@ -251,9 +252,29 @@
         <div>
 
           {/* 第一排:悬浮搜索框 */}
-          <div className={styles.searchBarContainer}>
-            <input type="text" placeholder="Search for everything..." className={styles.searchInput} />
-          </div>
+            <div style={{ display: 'flex', alignItems: 'center' }}>
+            <div className={styles.searchBarContainer}>
+              <input type="text" placeholder="Search for everything..." className={styles.searchInput} />
+            </div>
+            <Button
+              type="primary"
+              style={{ marginLeft: 16 }}
+              onClick={async () => {
+              try {
+                const res = await generatePassKey();
+                if (res && res.code === 0 && res.data && res.data.passkey) {
+                window.alert(`邀请码: ${res.data.passkey}`);
+                } else {
+                window.alert('邀请码生成失败');
+                }
+              } catch (e) {
+                window.alert('邀请码生成失败');
+              }
+              }}
+            >
+              邀请他人
+            </Button>
+            </div>
           <div style={{ display: "flex", marginTop: '40px' }}>
             <div className={styles.leftBox}>
               <div className={styles.textContent}>
@@ -321,7 +342,7 @@
                   种子
                 </div>
                 <Button type="primary" onClick={() => window.location.href = '/torrent-upload'}>新建种子</Button>
-                <Button onClick={() => window.location.href = '/torrent-list'}>我的种子</Button>
+                <Button onClick={() => window.location.href = '/torrent-list-my'}>我的种子</Button>
               </Flex>
             </Card>
 
diff --git a/src/pages/Torrent/torrentAudit.tsx b/src/pages/Torrent/torrentAudit.tsx
index e90af3c..3e6a45b 100644
--- a/src/pages/Torrent/torrentAudit.tsx
+++ b/src/pages/Torrent/torrentAudit.tsx
@@ -2,7 +2,7 @@
 import { useParams,useSearchParams, useNavigate } from 'react-router-dom';
 import { Card, Button, Spin, Tag, message, Input } from 'antd';
 import { ArrowLeftOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons';
-import { getTorrentInfo,auditTorrent,downloadTorrent } from '../../services/bt/index';
+import { getTorrentInfo,auditTorrent,downloadTorrent,getCategories } from '../../services/bt/index';
 
 
 // 状态映射
@@ -17,7 +17,7 @@
 const TorrentAudit: React.FC = () => {
     const { id } = useParams<{ id: string }>();
     const navigate = useNavigate();
-
+    const [categories, setCategories] = useState<any[]>([]);
     const [loading, setLoading] = useState(true);
     const [torrent, setTorrent] = useState<any>(null);
     const [auditLoading, setAuditLoading] = useState(false);
@@ -33,6 +33,7 @@
         getTorrentInfo({ id })
             .then(res => setTorrent(res.data))
             .finally(() => setLoading(false));
+        getCategories().then((res) => setCategories(res.data || []));
     }, [id, navigate]);
 const handleDownload = async () => {
     try {
@@ -68,7 +69,10 @@
             setAuditLoading(false);
         }
     };
-
+const getCategoryName = (catId: number) => {
+    console.log('categories', catId, categories);
+    return categories.find((c) => c.id === catId)?.name || '未知分类';
+};
     return (
         <div style={{ minHeight: '100vh', background: '#f4f8ff', padding: 32 }}>
             <div style={{ maxWidth: 800, margin: '0 auto' }}>
@@ -101,7 +105,7 @@
                         <>
                             <h2>{torrent.title}</h2>
                             <div style={{ marginBottom: 8 }}>
-                                <Tag color="blue">{torrent.categoryName || '未知分类'}</Tag>
+                                <Tag color="blue">{getCategoryName(torrent.category) || '未知分类'}</Tag>
                                 {torrent.tags?.map((tag: string) => (
                                     <Tag key={tag}>{tag}</Tag>
                                 ))}
@@ -132,6 +136,7 @@
                                     borderRadius: 8,
                                     marginBottom: 24,
                                     minHeight: 80,
+                                    color: '#333',
                                 }}
                                 dangerouslySetInnerHTML={{ __html: torrent.description || '' }}
                             />
diff --git a/src/pages/Torrent/torrentDetail.tsx b/src/pages/Torrent/torrentDetail.tsx
index 7e194a9..e27be12 100644
--- a/src/pages/Torrent/torrentDetail.tsx
+++ b/src/pages/Torrent/torrentDetail.tsx
@@ -285,6 +285,17 @@
                                     <div style={{ color: '#cbd5e1', marginBottom: 8 }}>
                                         上传者:{torrent?.owner} | 上传时间:{torrent?.createdAt}
                                     </div>
+                                    <div
+                                style={{
+                                    background: '#f6f8fa',
+                                    padding: 16,
+                                    borderRadius: 8,
+                                    marginBottom: 24,
+                                    minHeight: 80,
+                                    color: '#333',
+                                }}
+                                dangerouslySetInnerHTML={{ __html: torrent.description || '' }}
+                            />
                                     <Button
                                         type="primary"
                                         icon={<DownloadOutlined />}
diff --git a/src/pages/Torrent/torrentListMy.tsx b/src/pages/Torrent/torrentListMy.tsx
new file mode 100644
index 0000000..2f336ac
--- /dev/null
+++ b/src/pages/Torrent/torrentListMy.tsx
@@ -0,0 +1,505 @@
+import React, { useEffect, useState } from "react";
+import { styled } from "@mui/material/styles";
+import axios from "axios";
+import {
+    Box,
+    Button,
+    Card,
+    CardContent,
+    Chip,
+    CircularProgress,
+    Container,
+    MenuItem,
+    Pagination,
+    Select,
+    Typography,
+    TextField,
+    InputAdornment,
+    IconButton,
+} from "@mui/material";
+import { getCategories, getMyTorrentList,searchTorrents } from "../../services/bt/index";
+
+// 优化后的星空背景
+const StarBg = styled("div")({
+    minHeight: "100vh",
+    width: "auto",
+    background: "radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%)",
+    overflow: "auto",
+    position: "relative",
+    top: 0,
+    left: 0,
+    "&:before, &:after": {
+        content: '""',
+        position: "absolute",
+        top: 0,
+        left: 0,
+        width: "100%",
+        height: "100%",
+        pointerEvents: "none",
+    },
+    "&:before": {
+        background: `
+            radial-gradient(1px 1px at 20% 30%, rgba(255,255,255,0.8), rgba(255,255,255,0)),
+            radial-gradient(1px 1px at 40% 70%, rgba(255,255,255,0.8), rgba(255,255,255,0)),
+            radial-gradient(1.5px 1.5px at 60% 20%, rgba(255,255,255,0.9), rgba(255,255,255,0)),
+            radial-gradient(1.5px 1.5px at 80% 90%, rgba(255,255,255,0.9), rgba(255,255,255,0))
+        `,
+        backgroundRepeat: "repeat",
+        backgroundSize: "200px 200px",
+        animation: "twinkle 10s infinite ease-in-out",
+    },
+    "&:after": {
+        background: `
+            radial-gradient(1px 1px at 70% 40%, rgba(255,255,255,0.7), rgba(255,255,255,0)),
+            radial-gradient(1.2px 1.2px at 10% 80%, rgba(255,255,255,0.7), rgba(255,255,255,0)),
+            radial-gradient(1.5px 1.5px at 30% 60%, rgba(255,255,255,0.8), rgba(255,255,255,0))
+        `,
+        backgroundRepeat: "repeat",
+        backgroundSize: "300px 300px",
+        animation: "twinkle 15s infinite 5s ease-in-out",
+    },
+    "@keyframes twinkle": {
+        "0%, 100%": { opacity: 0.3 },
+        "50%": { opacity: 0.8 },
+    }
+});
+
+// 分类标签栏
+const CategoryBar = styled(Box)({
+    display: "flex",
+    gap: 12,
+    alignItems: "center",
+    marginBottom: 24,
+    flexWrap: "wrap",
+});
+
+// 种子卡片
+const TorrentCard = styled(Card)({
+    background: "rgba(30, 41, 59, 0.85)",
+    color: "#fff",
+    borderRadius: 16,
+    boxShadow: "0 4px 24px 0 rgba(0,0,0,0.4)",
+    border: "1px solid #334155",
+    transition: "transform 0.2s",
+    "&:hover": {
+        transform: "scale(1.025)",
+        boxShadow: "0 8px 32px 0 #0ea5e9",
+    },
+});
+
+const sortOptions = [
+    { label: "最新", value: { sortField: "create_time", sortDirection: "desc" } },
+    { label: "下载量", value: { sortField: "completions", sortDirection: "desc" } },
+    { label: "推荐", value: { sortField: "seeders", sortDirection: "desc" } },
+];
+
+const statusMap: Record<number, string> = {
+    0: '审核中',
+    1: '已发布',
+    2: '审核不通过',
+    3: '已上架修改重审中',
+    10: '已下架',
+};
+
+const PAGE_SIZE = 20;
+
+const TorrentListPage: React.FC = () => {
+    const [categories, setCategories] = useState<
+        { id: number; name: string; remark?: string | null; type?: number | null }[]
+    >([]);
+    const [selectedCat, setSelectedCat] = useState<number | null>(null);
+    const [sort, setSort] = useState(sortOptions[0].value);
+    const [torrents, setTorrents] = useState<any[]>([]);
+    const [loading, setLoading] = useState(false);
+    const [page, setPage] = useState(1);
+    const [total, setTotal] = useState(0);
+
+    // 搜索相关
+    const [searchKeyword, setSearchKeyword] = useState("");
+    const [searching, setSearching] = useState(false);
+    const [isSearchMode, setIsSearchMode] = useState(false);
+
+    // 获取分类
+    useEffect(() => {
+        getCategories().then((res) => {
+            setCategories(res.data || []);
+        });
+    }, []);
+
+    // 获取种子列表
+    useEffect(() => {
+        if (isSearchMode) return;
+        setLoading(true);
+        getMyTorrentList()
+            .then((res) => {
+                setTorrents(res.datarow || []);
+                setTotal(res.data.page?.size || 0);
+            })
+            .finally(() => setLoading(false));
+    }, [selectedCat, sort, page, isSearchMode]);
+
+    // 搜索
+    const handleSearch = async () => {
+        if (!searchKeyword.trim()) {
+            setIsSearchMode(false);
+            setPage(1);
+            return;
+        }
+        setSearching(true);
+        setIsSearchMode(true);
+        try {
+            const res = await searchTorrents({
+                titleKeyword: searchKeyword.trim(),
+                category: selectedCat !== null ? selectedCat : undefined,
+                sortField: sort.sortField,
+                sortDirection: sort.sortDirection,
+                pageNum: page,
+                pageSize: PAGE_SIZE,
+            });
+            setTorrents((res.records || []).map((r: any) => ({
+                ...r.torrent,
+                ownerInfo: r.ownerInfo,
+            })));
+            setTotal(res.total || 0);
+        } finally {
+            setSearching(false);
+        }
+    };
+
+    // 搜索模式下翻页
+    useEffect(() => {
+        if (!isSearchMode) return;
+        handleSearch();
+        // eslint-disable-next-line
+    }, [page, sort, selectedCat]);
+
+    // 切换分类/排序时退出搜索模式
+    useEffect(() => {
+        setIsSearchMode(false);
+        setSearchKeyword("");
+        setPage(1);
+    }, [selectedCat, sort]);
+
+    return (
+        <StarBg>
+            <Container maxWidth="lg" sx={{ pt: 6, pb: 6, position: "relative" }}>
+                <Typography
+                    variant="h3"
+                    sx={{
+                        color: "#fff",
+                        fontWeight: 700,
+                        mb: 3,
+                        letterSpacing: 2,
+                        textShadow: "0 2px 16px #0ea5e9",
+                    }}
+                >
+                    我的种子
+                </Typography>
+                搜索框
+                <Box
+                    sx={{
+                        mb: 4,
+                        display: "flex",
+                        alignItems: "center",
+                        gap: 2,
+                        background: "rgba(30,41,59,0.7)",
+                        borderRadius: 3,
+                        px: 2,
+                        py: 1.5,
+                        boxShadow: "0 2px 12px 0 #0ea5e950",
+                        border: "1px solid #334155",
+                        maxWidth: 700,
+                        mx: { xs: "auto", md: 0 },
+                    }}
+                >
+                    <TextField
+                        variant="outlined"
+                        size="small"
+                        placeholder="🔍 搜索种子标题"
+                        value={searchKeyword}
+                        onChange={(e) => setSearchKeyword(e.target.value)}
+                        onKeyDown={(e) => {
+                            if (e.key === "Enter") {
+                                setPage(1);
+                                handleSearch();
+                            }
+                        }}
+                        sx={{
+                            background: "rgba(17,24,39,0.95)",
+                            borderRadius: 2,
+                            input: {
+                                color: "#fff",
+                                fontSize: 17,
+                                fontWeight: 500,
+                                letterSpacing: 1,
+                                px: 1,
+                            },
+                            width: 320,
+                            ".MuiOutlinedInput-notchedOutline": { border: 0 },
+                            boxShadow: "0 1px 4px 0 #0ea5e930",
+                        }}
+                        InputProps={{
+                            endAdornment: (
+                                <InputAdornment position="end">
+                                    <IconButton
+                                        onClick={() => {
+                                            setPage(1);
+                                            handleSearch();
+                                        }}
+                                        edge="end"
+                                        sx={{
+                                            color: "#0ea5e9",
+                                            bgcolor: "#1e293b",
+                                            borderRadius: 2,
+                                            "&:hover": { bgcolor: "#0ea5e9", color: "#fff" },
+                                            transition: "all 0.2s",
+                                        }}
+                                    >
+                                        <svg width="22" height="22" fill="none" viewBox="0 0 24 24">
+                                            <circle cx="11" cy="11" r="7" stroke="currentColor" strokeWidth="2"/>
+                                            <path stroke="currentColor" strokeWidth="2" strokeLinecap="round" d="M20 20l-3.5-3.5"/>
+                                        </svg>
+                                    </IconButton>
+                                </InputAdornment>
+                            ),
+                        }}
+                    />
+                    {isSearchMode && (
+                        <Button
+                            variant="outlined"
+                            color="secondary"
+                            onClick={() => {
+                                setIsSearchMode(false);
+                                setSearchKeyword("");
+                                setPage(1);
+                            }}
+                            sx={{
+                                ml: 1,
+                                color: "#fff",
+                                borderColor: "#64748b",
+                                borderRadius: 2,
+                                fontWeight: 600,
+                                letterSpacing: 1,
+                                px: 2,
+                                py: 0.5,
+                                background: "rgba(51,65,85,0.7)",
+                                "&:hover": {
+                                    borderColor: "#0ea5e9",
+                                    background: "#0ea5e9",
+                                    color: "#fff",
+                                },
+                                transition: "all 0.2s",
+                            }}
+                        >
+                            清除搜索
+                        </Button>
+                    )}
+                    <Box sx={{ flex: 1 }} />
+                    <Button
+                        variant="contained"
+                        color="primary"
+                        onClick={() => window.open("/torrent-upload", "_self")}
+                        sx={{
+                            borderRadius: 2,
+                            fontWeight: 700,
+                            letterSpacing: 1,
+                            px: 3,
+                            py: 1,
+                            boxShadow: "0 2px 8px 0 #0ea5e950",
+                            background: "#0ea5e9",
+                            color: "#fff",
+                            "&:hover": {
+                                background: "#38bdf8",
+                            },
+                            transition: "all 0.2s",
+                        }}
+                    >
+                        分享资源
+                    </Button>
+                </Box>
+                <CategoryBar>
+                    <Chip
+                        label="全部"
+                        color={selectedCat === null ? "primary" : "default"}
+                        onClick={() => {
+                            setSelectedCat(null);
+                            setPage(1);
+                        }}
+                        sx={{
+                            fontWeight: 600,
+                            fontSize: 16,
+                            color: selectedCat === null ? undefined : "#fff",
+                        }}
+                    />
+                    {categories.map((cat) => (
+                        <Chip
+                            key={cat.id}
+                            label={cat.name}
+                            color={selectedCat === cat.id ? "primary" : "default"}
+                            onClick={() => {
+                                setSelectedCat(cat.id);
+                                setPage(1);
+                            }}
+                            sx={{
+                                fontWeight: 600,
+                                fontSize: 16,
+                                color: selectedCat === cat.id ? undefined : "#fff",
+                            }}
+                        />
+                    ))}
+                    <Box sx={{ flex: 1 }} />
+                    <Select
+                        size="small"
+                        value={JSON.stringify(sort)}
+                        onChange={(e) => {
+                            setSort(JSON.parse(e.target.value));
+                            setPage(1);
+                        }}
+                        sx={{
+                            color: "#fff",
+                            background: "#1e293b",
+                            borderRadius: 2,
+                            ".MuiOutlinedInput-notchedOutline": { border: 0 },
+                            minWidth: 120,
+                        }}
+                    >
+                        {sortOptions.map((opt) => (
+                            <MenuItem key={opt.label} value={JSON.stringify(opt.value)}>
+                                {opt.label}
+                            </MenuItem>
+                        ))}
+                    </Select>
+                </CategoryBar>
+                {(loading || searching) ? (
+                    <Box sx={{ display: "flex", justifyContent: "center", mt: 8 }}>
+                        <CircularProgress color="info" />
+                    </Box>
+                ) : (
+                    <>
+                        <Box
+                            sx={{
+                                display: "flex",
+                                flexWrap: "wrap",
+                                gap: 3,
+                                justifyContent: { xs: "center", md: "flex-start" },
+                            }}
+                        >
+                            {torrents.map((torrent) => (
+                                <Box
+                                    key={torrent.id}
+                                    sx={{
+                                        flex: "1 1 320px",
+                                        maxWidth: { xs: "100%", sm: "48%", md: "32%" },
+                                        minWidth: 300,
+                                        mb: 3,
+                                        display: "flex",
+                                        cursor: "pointer",
+                                    }}
+                                    onClick={() => window.open(`/torrent-detail/${torrent.id}`, "_self")}
+                                >
+                                    <TorrentCard sx={{ width: "100%" }}>
+                                        <CardContent>
+                                            <Typography
+                                                variant="h6"
+                                                sx={{
+                                                    color: "#38bdf8",
+                                                    fontWeight: 700,
+                                                    mb: 1,
+                                                    textOverflow: "ellipsis",
+                                                    overflow: "hidden",
+                                                    whiteSpace: "nowrap",
+                                                }}
+                                                title={torrent.title}
+                                            >
+                                                {torrent.title}
+                                            </Typography>
+                                            <Box
+                                                sx={{
+                                                    display: "flex",
+                                                    gap: 1,
+                                                    alignItems: "center",
+                                                    mb: 1,
+                                                    flexWrap: "wrap",
+                                                }}
+                                            >
+                                                <Chip
+                                                    size="small"
+                                                    label={
+                                                        categories.find((c) => c.id === torrent.category)?.name ||
+                                                        "未知"
+                                                    }
+                                                    sx={{
+                                                        background: "#0ea5e9",
+                                                        color: "#fff",
+                                                        fontWeight: 600,
+                                                    }}
+                                                />
+                                                {torrent.free === "1" && (
+                                                    <Chip
+                                                        size="small"
+                                                        label="促销"
+                                                        sx={{
+                                                            background: "#fbbf24",
+                                                            color: "#1e293b",
+                                                            fontWeight: 600,
+                                                        }}
+                                                    />
+                                                )}
+                                                {/* 状态标签 */}
+                                                {typeof torrent.status !== "undefined" && (
+                                                    <Chip
+                                                        size="small"
+                                                        label={statusMap[torrent.status] || "未知状态"}
+                                                        sx={{
+                                                            background: "#64748b",
+                                                            color: "#fff",
+                                                            fontWeight: 600,
+                                                        }}
+                                                    />
+                                                )}
+                                            </Box>
+                                            <Typography variant="body2" sx={{ color: "#cbd5e1", mb: 1 }}>
+                                                上传时间:{torrent.createTime}
+                                            </Typography>
+                                            <Box sx={{ display: "flex", gap: 2, mt: 1 }}>
+                                                <Typography variant="body2" sx={{ color: "#38bdf8" }}>
+                                                    做种:{torrent.seeders}
+                                                </Typography>
+                                                <Typography variant="body2" sx={{ color: "#f472b6" }}>
+                                                    下载量:{torrent.completions}
+                                                </Typography>
+                                                <Typography variant="body2" sx={{ color: "#fbbf24" }}>
+                                                    下载中:{torrent.leechers}
+                                                </Typography>
+                                            </Box>
+                                        </CardContent>
+                                    </TorrentCard>
+                                </Box>
+                            ))}
+                        </Box>
+                        <Box sx={{ display: "flex", justifyContent: "center", mt: 4 }}>
+                            <Pagination
+                                count={Math.ceil(total / PAGE_SIZE)}
+                                page={page}
+                                onChange={(_, v) => setPage(v)}
+                                color="primary"
+                                sx={{
+                                    ".MuiPaginationItem-root": {
+                                        color: "#fff",
+                                        background: "#1e293b",
+                                        border: "1px solid #334155",
+                                    },
+                                    ".Mui-selected": {
+                                        background: "#0ea5e9 !important",
+                                    },
+                                }}
+                            />
+                        </Box>
+                    </>
+                )}
+            </Container>
+        </StarBg>
+    );
+};
+
+export default TorrentListPage;
\ No newline at end of file
diff --git a/src/pages/User/Login/index.less b/src/pages/User/Login/index.less
new file mode 100644
index 0000000..cfd2f08
--- /dev/null
+++ b/src/pages/User/Login/index.less
@@ -0,0 +1,3 @@
+.ant-pro-form-login-container{
+    overflow: hidden;
+}
\ No newline at end of file
diff --git a/src/pages/User/Login/index.tsx b/src/pages/User/Login/index.tsx
index e29032e..b8a44ff 100644
--- a/src/pages/User/Login/index.tsx
+++ b/src/pages/User/Login/index.tsx
@@ -22,6 +22,8 @@
 import React, { useEffect, useState } from 'react';
 import { flushSync } from 'react-dom';
 import { clearSessionToken, setSessionToken } from '@/access';
+import './index.less';
+import { registerUser } from '@/services/bt/index';
 
 const ActionIcons = () => {
   const langClassName = useEmotionCss(({ token }) => {
@@ -96,7 +98,7 @@
       display: 'flex',
       flexDirection: 'column',
       height: '100vh',
-      overflow: 'auto',
+      overflow: 'hidden',
       backgroundImage:
         "url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
       backgroundSize: '100% 100%',
@@ -159,6 +161,7 @@
       message.error(defaultLoginFailureMessage);
     }
   };
+
   const { code } = userLoginState;
   const loginType = type;
 
@@ -171,7 +174,8 @@
       className={containerClassName}
       style={{
         backgroundImage:
-          "url('https://images.unsplash.com/photo-1462331940025-496dfbfc7564?auto=format&fit=crop&w=1500&q=80')",
+          "linear-gradient(120deg, #232526 0%, #414345 100%), url('https://images.unsplash.com/photo-1462331940025-496dfbfc7564?auto=format&fit=crop&w=1500&q=80')",
+        backgroundBlendMode: 'overlay',
         backgroundSize: 'cover',
         backgroundPosition: 'center',
         minHeight: '100vh',
@@ -199,7 +203,6 @@
           background: 'radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%)',
         }}
       >
-        {/* 可以集成粒子库如 tsParticles 或者简单用 CSS 动画 */}
         <svg width="100%" height="100%">
           {[...Array(60)].map((_, i) => (
             <circle
@@ -225,303 +228,403 @@
           zIndex: 1,
         }}
       >
-        <LoginForm
-          contentStyle={{
-            minWidth: 320,
-            maxWidth: 400,
-            background: 'rgba(25, 34, 54, 0.92)',
-            borderRadius: 16,
+        <div
+          style={{
+            background: 'rgba(30, 34, 54, 0.96)',
+            borderRadius: 20,
             boxShadow: '0 8px 32px 0 rgba(31, 38, 135, 0.37)',
-            border: '1px solid rgba(255,255,255,0.18)',
-            padding: '32px 32px 24px 32px',
+            border: '1px solid rgba(255,255,255,0.12)',
+            padding: '36px 24px 28px 24px',
+            minWidth: 340,
+            maxWidth: 420,
+            width: '100%',
             color: '#fff',
-          }}
-          // logo={
-          //   <img
-          //     alt="logo"
-          //     src="/planet-logo.svg"
-          //     style={{
-          //       width: 64,
-          //       height: 64,
-          //       filter: 'drop-shadow(0 0 8px #fff8) drop-shadow(0 0 16px #6cf)',
-          //       marginBottom: 8,
-          //     }}
-          //   />
-          // }
-          title={
-            <span style={{ color: '#fff', fontWeight: 700, fontSize: 28, letterSpacing: 2 }}>
-              ThunderHub
-            </span>
-          }
-          subTitle={
-            <span style={{ color: '#b3c7f9', fontSize: 16 }}>
-              探索你的专属星球,畅享PT世界  JRX MSY ZYT HXQ LJB
-            </span>
-          }
-          initialValues={{
-            autoLogin: true,
-          }}
-          // actions={[
-          //   <FormattedMessage
-          //     key="loginWith"
-          //     id="pages.login.loginWith"
-          //     defaultMessage="其他登录方式"
-          //   />,
-          //   <ActionIcons key="icons" />,
-          // ]}
-          onFinish={async (values) => {
-            await handleSubmit(values as API.LoginParams);
+            backdropFilter: 'blur(8px)',
+            position: 'relative',
+            transition: 'max-width 0.2s cubic-bezier(.4,2,.6,1)',
+            overflow: 'hidden',
           }}
         >
-          <Tabs
-            activeKey={type}
-            onChange={setType}
-            centered
-            items={[
-              {
-                key: 'account',
-                label: (
-                  <span style={{ color: '#fff' }}>
-                    {intl.formatMessage({
-                      id: 'pages.login.accountLogin.tab',
-                      defaultMessage: '账户密码登录',
-                    })}
-                  </span>
-                ),
-              },
-              {
-                key: 'mobile',
-                label: (
-                  <span style={{ color: '#fff' }}>
-                    {intl.formatMessage({
-                      id: 'pages.login.phoneLogin.tab',
-                      defaultMessage: '手机号登录',
-                    })}
-                  </span>
-                ),
-              },
-            ]}
-            style={{ marginBottom: 24 }}
-          />
-
-          {code !== 200 && loginType === 'account' && (
-            <LoginMessage
-              content={intl.formatMessage({
-                id: 'pages.login.accountLogin.errorMessage',
-                defaultMessage: '账户或密码错误(admin/admin123)',
-              })}
-            />
-          )}
-          {type === 'account' && (
-            <>
-              <ProFormText
-                name="username"
-                initialValue="admin"
-                fieldProps={{
-                  size: 'large',
-                  prefix: <UserOutlined style={{ color: '#6cf' }} />,
-                  style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
-                }}
-                placeholder={intl.formatMessage({
-                  id: 'pages.login.username.placeholder',
-                  defaultMessage: '用户名: admin',
-                })}
-                rules={[
-                  {
-                    required: true,
-                    message: (
-                      <FormattedMessage
-                        id="pages.login.username.required"
-                        defaultMessage="请输入用户名!"
-                      />
-                    ),
-                  },
-                ]}
-              />
-              <ProFormText.Password
-                name="password"
-                initialValue="admin123"
-                fieldProps={{
-                  size: 'large',
-                  prefix: <LockOutlined style={{ color: '#6cf' }} />,
-                  style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
-                }}
-                placeholder={intl.formatMessage({
-                  id: 'pages.login.password.placeholder',
-                  defaultMessage: '密码: admin123',
-                })}
-                rules={[
-                  {
-                    required: true,
-                    message: (
-                      <FormattedMessage
-                        id="pages.login.password.required"
-                        defaultMessage="请输入密码!"
-                      />
-                    ),
-                  },
-                ]}
-              />
-              <Row>
-                <Col flex={3}>
-                  <ProFormText
-                    style={{
-                      float: 'right',
-                      background: 'rgba(255,255,255,0.08)',
-                      color: '#fff',
-                    }}
-                    name="code"
-                    placeholder={intl.formatMessage({
-                      id: 'pages.login.captcha.placeholder',
-                      defaultMessage: '请输入验证',
-                    })}
-                    rules={[
-                      {
-                        required: true,
-                        message: (
-                          <FormattedMessage
-                            id="pages.searchTable.updateForm.ruleName.nameRules"
-                            defaultMessage="请输入验证啊"
-                          />
-                        ),
-                      },
-                    ]}
-                  />
-                </Col>
-                <Col flex={2}>
-                  <Image
-                    src={captchaCode}
-                    alt="验证码"
-                    style={{
-                      display: 'inline-block',
-                      verticalAlign: 'top',
-                      cursor: 'pointer',
-                      paddingLeft: '10px',
-                      width: '100px',
-                      borderRadius: 8,
-                      boxShadow: '0 0 8px #6cf8',
-                      background: '#fff',
-                    }}
-                    preview={false}
-                    onClick={() => getCaptchaCode()}
-                  />
-                </Col>
-              </Row>
-            </>
-          )}
-
-          {code !== 200 && loginType === 'mobile' && (
-            <LoginMessage content="验证码错误" />
-          )}
-          {type === 'mobile' && (
-            <>
-              <ProFormText
-                fieldProps={{
-                  size: 'large',
-                  prefix: <MobileOutlined style={{ color: '#6cf' }} />,
-                  style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
-                }}
-                name="mobile"
-                placeholder={intl.formatMessage({
-                  id: 'pages.login.phoneNumber.placeholder',
-                  defaultMessage: '手机号',
-                })}
-                rules={[
-                  {
-                    required: true,
-                    message: (
-                      <FormattedMessage
-                        id="pages.login.phoneNumber.required"
-                        defaultMessage="请输入手机号!"
-                      />
-                    ),
-                  },
-                  {
-                    pattern: /^1\d{10}$/,
-                    message: (
-                      <FormattedMessage
-                        id="pages.login.phoneNumber.invalid"
-                        defaultMessage="手机号格式错误!"
-                      />
-                    ),
-                  },
-                ]}
-              />
-              <ProFormCaptcha
-                fieldProps={{
-                  size: 'large',
-                  prefix: <LockOutlined style={{ color: '#6cf' }} />,
-                  style: { background: 'rgba(255,255,255,0.08)', color: '#fff' },
-                }}
-                captchaProps={{
-                  size: 'large',
-                }}
-                placeholder={intl.formatMessage({
-                  id: 'pages.login.captcha.placeholder',
-                  defaultMessage: '请输入验证码',
-                })}
-                captchaTextRender={(timing, count) => {
-                  if (timing) {
-                    return `${count} ${intl.formatMessage({
-                      id: 'pages.getCaptchaSecondText',
-                      defaultMessage: '获取验证码',
-                    })}`;
-                  }
-                  return intl.formatMessage({
-                    id: 'pages.login.phoneLogin.getVerificationCode',
-                    defaultMessage: '获取验证码',
-                  });
-                }}
-                name="captcha"
-                rules={[
-                  {
-                    required: true,
-                    message: (
-                      <FormattedMessage
-                        id="pages.login.captcha.required"
-                        defaultMessage="请输入验证码!"
-                      />
-                    ),
-                  },
-                ]}
-                onGetCaptcha={async (phone) => {
-                  const result = await getFakeCaptcha({
-                    phone,
-                  });
-                  if (!result) {
-                    return;
-                  }
-                  message.success('获取验证码成功!验证码为:1234');
-                }}
-              />
-            </>
-          )}
-          <div
-            style={{
-              marginBottom: 24,
-              color: '#b3c7f9',
-            }}
-          >
-            <ProFormCheckbox>
-              <a
-                style={{
-                  float: 'right',
-                  color: '#fff',
-                  fontSize: 14,
-                }}>
-                <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
-              </a>
-            </ProFormCheckbox>
-            <a
+          <div style={{ textAlign: 'center', marginBottom: 24 }}>
+            <img
+              src="/logo.svg"
+              alt="ThunderHub"
               style={{
-                float: 'right',
-                color: '#6cf',
+                width: 54,
+                height: 48,
+                marginBottom: 8,
+                filter: 'drop-shadow(0 0 8px #6cf8)',
+              }}
+            />
+            <div
+              style={{
+                color: '#fff',
+                fontWeight: 700,
+                fontSize: 26,
+                letterSpacing: 2,
+                marginBottom: 4,
+                fontFamily: 'Montserrat, sans-serif',
               }}
             >
-              <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
-            </a>
+              ThunderHub
+            </div>
+            <div style={{ color: '#b3c7f9', fontSize: 14, letterSpacing: 1 }}>
+              探索你的专属星球,畅享PT世界
+              <span style={{ color: '#6cf', marginLeft: 8, fontWeight: 500, fontSize: 12 }}>
+                JRX MSY ZYT HXQ LJB
+              </span>
+            </div>
           </div>
-        </LoginForm>
+          <LoginForm
+            contentStyle={{
+              background: 'transparent',
+              boxShadow: 'none',
+              padding: 0,
+              color: '#fff',
+              width: '100%',
+              overflow: 'hidden',
+            }}
+            initialValues={{
+              autoLogin: true,
+            }}
+            onFinish={async (values) => {
+              if (type === 'account') {
+                await handleSubmit(values as API.LoginParams);
+              } else {
+                try {
+                  const response = await registerUser(
+                  values.username ?? '',
+                  values.password ?? '',
+                  values.inviteCode ?? ''
+                  );
+                  if (response.code === 0) {
+                  message.success('注册成功!');
+                  // 注册成功后自动跳转到登录页或自动登录
+                  setType('account');
+                  } else {
+                    message.error(response.msg || '注册失败,请重试!');
+                    clearSessionToken();
+                    setUserLoginState({ ...response, type });
+                  }
+                } catch (error) {
+                  message.error('注册失败,请重试!');
+                }
+              }
+            }}
+            submitter={false}
+          >
+            <Tabs
+              activeKey={type}
+              onChange={setType}
+              centered
+              items={[
+                {
+                  key: 'account',
+                  label: (
+                    <span style={{ color: '#fff', fontWeight: 500, fontSize: 16 }}>
+                      {intl.formatMessage({
+                        id: 'pages.login.accountLogin.tab',
+                        defaultMessage: '账户密码登录',
+                      })}
+                    </span>
+                  ),
+                },
+                {
+                  key: 'mobile',
+                  label: (
+                    <span style={{ color: '#fff', fontWeight: 500, fontSize: 16 }}>
+                      {intl.formatMessage({
+                        id: 'pages.login.phoneLogin.tab',
+                        defaultMessage: '注册',
+                      })}
+                    </span>
+                  ),
+                },
+              ]}
+              style={{ marginBottom: 24 }}
+              indicatorSize={36}
+            />
+
+            {code !== 200 && loginType === 'account' && (
+              <LoginMessage
+                content={intl.formatMessage({
+                  id: 'pages.login.accountLogin.errorMessage',
+                  defaultMessage: '账户或密码错误',
+                })}
+              />
+            )}
+            {type === 'account' && (
+              <>
+                <ProFormText
+                  name="username"
+                  fieldProps={{
+                    size: 'large',
+                    prefix: <UserOutlined style={{ color: '#6cf' }} />,
+                    style: {
+                      background: 'rgba(255,255,255,0.08)',
+                      color: '#fff',
+                      borderRadius: 8,
+                    },
+                  }}
+                  placeholder={intl.formatMessage({
+                    id: 'pages.login.username.placeholder',
+                  })}
+                  rules={[
+                    {
+                      required: true,
+                      message: (
+                        <FormattedMessage
+                          id="pages.login.username.required"
+                          defaultMessage="请输入用户名!"
+                        />
+                      ),
+                    },
+                  ]}
+                />
+                <ProFormText.Password
+                  name="password"
+                  fieldProps={{
+                    size: 'large',
+                    prefix: <LockOutlined style={{ color: '#6cf' }} />,
+                    style: {
+                      background: 'rgba(255,255,255,0.08)',
+                      color: '#fff',
+                      borderRadius: 8,
+                    },
+                  }}
+                  placeholder={intl.formatMessage({
+                    id: 'pages.login.password.placeholder',
+                  })}
+                  rules={[
+                    {
+                      required: true,
+                      message: (
+                        <FormattedMessage
+                          id="pages.login.password.required"
+                          defaultMessage="请输入密码!"
+                        />
+                      ),
+                    },
+                  ]}
+                />
+                <Row>
+                  <Col flex={3}>
+                    <ProFormText
+                      style={{
+                        float: 'right',
+                        background: 'rgba(255,255,255,0.08)',
+                        color: '#fff',
+                        borderRadius: 8,
+                      }}
+                      name="code"
+                      placeholder={intl.formatMessage({
+                        id: 'pages.login.captcha.placeholder',
+                        defaultMessage: '请输入验证',
+                      })}
+                      rules={[
+                        {
+                          required: true,
+                          message: (
+                            <FormattedMessage
+                              id="pages.searchTable.updateForm.ruleName.nameRules"
+                              defaultMessage="请输入验证啊"
+                            />
+                          ),
+                        },
+                      ]}
+                    />
+                  </Col>
+                  <Col flex={2}>
+                    <Image
+                      src={captchaCode}
+                      alt="验证码"
+                      style={{
+                        display: 'inline-block',
+                        verticalAlign: 'top',
+                        cursor: 'pointer',
+                        paddingLeft: '10px',
+                        width: '90px',
+                        borderRadius: 8,
+                        boxShadow: '0 0 8px #6cf8',
+                        background: '#fff',
+                      }}
+                      preview={false}
+                      onClick={() => getCaptchaCode()}
+                    />
+                  </Col>
+                </Row>
+              </>
+            )}
+
+            {code !== 200 && loginType === 'mobile' && (
+              <LoginMessage content="验证码错误" />
+            )}
+            {type === 'mobile' && (
+                <>
+                <ProFormText
+                  fieldProps={{
+                  size: 'large',
+                  prefix: <LockOutlined style={{ color: '#6cf' }} />, // 换成钥匙图标
+                  style: {
+                    background: 'rgba(255,255,255,0.08)',
+                    color: '#fff',
+                    borderRadius: 8,
+                  },
+                  }}
+                  name="inviteCode"
+                  placeholder={intl.formatMessage({
+                  id: 'pages.login.inviteCode.placeholder',
+                  defaultMessage: '请输入邀请码',
+                  })}
+                  rules={[
+                  {
+                    required: true,
+                    message: (
+                    <FormattedMessage
+                      id="pages.login.inviteCode.required"
+                      defaultMessage="请输入邀请码!"
+                    />
+                    ),
+                  },
+                  ]}
+                />
+                <ProFormText
+                  fieldProps={{
+                  size: 'large',
+                  prefix: <UserOutlined style={{ color: '#6cf' }} />,
+                  style: {
+                    background: 'rgba(255,255,255,0.08)',
+                    color: '#fff',
+                    borderRadius: 8,
+                  },
+                  }}
+                  name="username"
+                  placeholder={intl.formatMessage({
+                  id: 'pages.login.username.placeholder',
+                  defaultMessage: '请输入用户名',
+                  })}
+                  rules={[
+                  {
+                    required: true,
+                    message: (
+                    <FormattedMessage
+                      id="pages.login.username.required"
+                      defaultMessage="请输入用户名!"
+                    />
+                    ),
+                  },
+                  ]}
+                />
+                <ProFormText.Password
+                  fieldProps={{
+                  size: 'large',
+                  prefix: <LockOutlined style={{ color: '#6cf' }} />,
+                  style: {
+                    background: 'rgba(255,255,255,0.08)',
+                    color: '#fff',
+                    borderRadius: 8,
+                  },
+                  }}
+                  name="password"
+                  placeholder={intl.formatMessage({
+                  id: 'pages.login.password.placeholder',
+                  defaultMessage: '请输入密码',
+                  })}
+                  rules={[
+                  {
+                    required: true,
+                    message: (
+                    <FormattedMessage
+                      id="pages.login.password.required"
+                      defaultMessage="请输入密码!"
+                    />
+                    ),
+                  },
+                  ]}
+                />
+                </>
+            )}
+            {type === 'account' && (
+              <div
+                style={{
+                  marginBottom: 24,
+                  color: '#b3c7f9',
+                  display: 'flex',
+                  alignItems: 'center',
+                  justifyContent: 'space-between',
+                  fontSize: 13,
+                }}
+              >
+                <ProFormCheckbox>
+                  <span style={{ color: '#fff' }}>
+                    <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
+                  </span>
+                </ProFormCheckbox>
+                <a
+                  style={{
+                    color: '#6cf',
+                  }}
+                >
+                  <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
+                </a>
+              </div>
+            )}
+            {/* 登录/注册按钮 */}
+            <div style={{ marginTop: 24, display: 'flex', gap: 16 }}>
+              {type === 'account' && (
+                <button
+                  type="submit"
+                  style={{
+                    width: '100%',
+                    background: 'linear-gradient(90deg, #6cf 0%, #3E71FF 100%)',
+                    color: '#fff',
+                    border: 'none',
+                    borderRadius: 8,
+                    padding: '12px 0',
+                    fontSize: 16,
+                    fontWeight: 600,
+                    cursor: 'pointer',
+                    boxShadow: '0 2px 8px #6cf4',
+                    letterSpacing: 2,
+                  }}
+                  onClick={() => {
+                    // 触发表单提交,登录
+                    document.querySelector('form')?.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
+                  }}
+                >
+                  登录
+                </button>
+              )}
+              {type === 'mobile' && (
+                <button
+                  type="button"
+                  style={{
+                    width: '100%',
+                    background: 'linear-gradient(90deg, #6cf 0%, #3E71FF 100%)',
+                    color: '#fff',
+                    border: 'none',
+                    borderRadius: 8,
+                    padding: '12px 0',
+                    fontSize: 16,
+                    fontWeight: 600,
+                    cursor: 'pointer',
+                    boxShadow: '0 2px 8px #6cf4',
+                    letterSpacing: 2,
+                  }}
+                  onClick={async () => {
+                    // 触发表单校验并注册
+                    const form = document.querySelector('form');
+                    if (form) {
+                      form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
+                    }
+                  }}
+                >
+                  注册
+                </button>
+              )}
+            </div>
+          </LoginForm>
+        </div>
       </div>
       <Footer />
     </div>