add resource detail and user part interface

Change-Id: I83541b5dc80bde465878cdccdbc77431b56dbff6
diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx
new file mode 100644
index 0000000..0af92a4
--- /dev/null
+++ b/src/app/user/page.tsx
@@ -0,0 +1,356 @@
+'use client';
+
+import React, { useEffect, useState, useRef } from 'react';
+import { TabView, TabPanel } from 'primereact/tabview';
+import { Avatar } from 'primereact/avatar';
+import { Button } from 'primereact/button';
+import { Card } from 'primereact/card';
+import {Image} from "primereact/image";
+// 浮动按钮
+import { SpeedDial } from 'primereact/speeddial';
+// 评分图标
+import { Fire } from '@icon-park/react';
+// 消息提醒
+import { Toast } from 'primereact/toast';
+// 页面跳转
+import { useRouter } from "next/navigation";
+// import Link from 'next/link';
+
+// 接口传输
+import axios from "axios";
+
+// 样式
+import './user.scss';
+
+
+
+// 用户信息
+interface UserInfo {
+    userId: number;
+    username: string;
+    password: string;
+    avatar: string;
+    followerCount: number;// 粉丝数
+    subscriberCount: number;// 关注数
+    signature:  string;// 个性签名
+    uploadAmount: number;
+    purchaseAmount: number;
+    credits: number;
+}
+
+// 用户数据
+interface UserData {
+    subscriberCount:  number; // 关注数
+    uploadAmount:  number; // 上传量(资源个数)
+    beDownloadedAmount:  number; // 上传资源被下载量
+    seedPercentageList: number[]; // 上传资源类型百分比列表,按材质包、模组、整合包、地图的顺序返回
+}
+
+// 用户发布的资源
+interface Resource {
+    resourceId: number;
+    resourceName: string;
+    resourcePicture:  string;
+    resourceSummary:  string; // 资源简介(一句话)
+    resourceDetail: string; // 资源介绍
+    uploadTime: string; // 上传时间
+    lastUpdateTime:  string; // 最近更新时间
+    price:  number;
+    downloads:  number;
+    likes:   number;
+    collections: number;
+    comments: number;
+    seeds:  number; // 种子数
+    classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
+}
+
+// 用户发布的资源列表
+interface ResourceList {
+    records: Resource[];
+}
+
+export default function UserPage() {
+    // 路由
+    const router = useRouter();
+    // 发布资源列表
+    const [resourceList, setResourceList] = useState<Resource[]>([]);
+    // 用户信息
+    const [userInfo, setUserInfo] = useState<UserInfo>();
+    // 用户数据
+    const [userData, setUserData] = useState<UserData>();
+    // 消息提醒
+    const toast = useRef<Toast>(null);
+
+
+    useEffect(() => {
+        fetchUserInfo();
+        fetchUserData();
+        fetchResourceList();
+    }, []);
+
+    // 获取用户信息
+    const fetchUserInfo = async () => {
+        try {
+            const response = await axios.get<UserInfo>(process.env.PUBLIC_URL + `/user/info`, {
+                params: { userId: 22301010 }
+            });
+            console.log('获取用户信息:', response.data);
+            setUserInfo(response.data);
+        } catch (err) {
+            console.error('获取用户信息失败', err);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取用户信息失败' });
+        }
+    };
+
+    // 获取用户数据
+    const fetchUserData = async () => {
+        try {
+            const response = await axios.get<UserData>(process.env.PUBLIC_URL + `/user/data`, {
+                params: { userId: 22301010 }
+            });
+            console.log('获取用户数据:', response.data);
+            setUserData(response.data);
+        } catch (err) {
+            console.error('获取用户数据失败', err);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取用户数据失败' });
+        }
+    };
+
+    // 格式化数字显示 (3000 -> 3k)
+    const formatCount = (count?: number): string => {
+        if (count == null) return "0"; // 同时处理 undefined/null
+
+        const absCount = Math.abs(count); // 处理负数
+
+        const format = (num: number, suffix: string) => {
+            const fixed = num.toFixed(1);
+            return fixed.endsWith('.0')
+                ? `${Math.floor(num)}${suffix}`
+                : `${fixed}${suffix}`;
+        };
+
+        if (absCount >= 1e6) return format(count / 1e6, "m");
+        if (absCount >= 1e3) return format(count / 1e3, "k");
+        return count.toString();
+    };
+
+    // 获取发布资源
+    const fetchResourceList = async () => {
+        try {
+            const response = await axios.get<ResourceList>(process.env.PUBLIC_URL +`/user/upload`, {
+                params: { userId: 22301010, pageNumber: 1, rows: 3 }
+            });
+            console.log('获取发布资源列表:', response.data.records);
+            setResourceList(response.data.records);
+
+            // const imgUrl = `${process.env.NEXT_PUBLIC_NGINX_URL}/${resourceList[0].resourcePicture}`;
+            // console.log("Image URL:", imgUrl);
+        } catch (err) {
+            console.error('获取发布资源失败', err);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取发布资源失败' });
+        }
+    };
+
+    // 浮动按钮的子模块
+    const actions = [
+        {
+            template: () => (
+                <Button  label="管理资源" onClick={() => router.push(`/user/manage/resources/`)}/>
+            )
+        },
+        {
+            template: () => (
+                <Button  label="已购资源" onClick={() => router.push(`/user/purchased-resources/`)}/>
+            )
+        },
+        {
+            template: () => (
+                <Button  label="发布资源" onClick={() => router.push(`/user/manage/resources/`)}/>
+            )
+        },
+        {
+            template: () => (
+                <Button  label="编辑悬赏" onClick={() => router.push(`/user/manage/resources/`)}/>
+            )
+        }
+    ];
+
+
+
+
+    return (
+        <div className="user-container">
+
+            {/*个人信息*/}
+            <div className="user-profile-card">
+                <Avatar
+                    image={`${process.env.NEXT_PUBLIC_NGINX_URL}/users/${userInfo?.avatar}`}
+                    className="user-avatar"
+                    shape="circle"
+                />
+                <div className="user-info">
+                    <div className="user-detail-info">
+                        <div className="name-container">
+                            <h2 className="name">{userInfo?.username}</h2>
+                            <span className="signature">{userInfo?.signature}</span>
+                        </div>
+
+                        <div className="stats-container">
+                            <div className="stats">
+                                <span className="stats-label">粉丝:</span>
+                                <span className="stats-value">{userInfo?.followerCount}</span>
+                            </div>
+                            <div className="stats">
+                                <span className="stats-label">累计上传量:</span>
+                                <span className="stats-value">{formatCount(userData?.uploadAmount)}</span>
+                            </div>
+                            <div className="stats">
+                                <span className="stats-label">关注:</span>
+                                <span className="stats-value">{userInfo?.subscriberCount}</span>
+                            </div>
+                            <div className="stats">
+                                <span className="stats-label">累计被下载量:</span>
+                                <span className="stats-value">{formatCount(userData?.beDownloadedAmount)}</span>
+                            </div>
+                        </div>
+                    </div>
+
+                    <Button label="关注" className="action-button"/>
+                </div>
+            </div>
+
+            {/*个人内容*/}
+            <TabView>
+                <TabPanel header="主页">
+                    {/*推荐资源*/}
+                    <div className="homepage-item">
+                        <div className="section-header">
+                            <h1>推荐资源</h1>
+                            <Button
+                                label="显示更多"
+                                link
+                                onClick={() => router.push('/resource/recommend/模组')}
+                            />
+                        </div>
+                        <div className="resource-grid">
+                            {/*{mods.map((mod) => (*/}
+                            {/*    <Card key={mod.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${mod.resourceId}`)}>*/}
+                            {/*        <Image*/}
+                            {/*            src={process.env.NEXT_PUBLIC_NGINX_URL + mod.resourcePicture}*/}
+                            {/*            alt={mod.resourceName}*/}
+                            {/*            width="368"*/}
+                            {/*            height="200"*/}
+                            {/*        />*/}
+                            {/*        <div className="card-content">*/}
+                            {/*            <h3>{mod.resourceName}</h3>*/}
+                            {/*            <div className="view-count">*/}
+                            {/*                <Fire theme="outline" size="16" fill="#FF8D1A" />*/}
+                            {/*                <span>{mod.likes}</span>*/}
+                            {/*            </div>*/}
+                            {/*        </div>*/}
+                            {/*    </Card>*/}
+                            {/*))}*/}
+                        </div>
+                    </div>
+
+                    {/*发布资源*/}
+                    <div className="homepage-item">
+                        <div className="section-header">
+                            <h1>发布资源</h1>
+                            <Button
+                                label="显示更多"
+                                link
+                                onClick={() => router.push('/user/manage/resources/')}
+                            />
+                        </div>
+                        <div className="resource-grid">
+                            {resourceList.map((resourceList) => (
+                                <Card key={resourceList.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}>
+                                    <Image
+                                        src={process.env.NEXT_PUBLIC_NGINX_URL + resourceList.resourcePicture}
+                                        alt={resourceList.resourceName}
+                                        width="368"
+                                        height="200"
+                                    />
+                                    <div className="card-content">
+                                        <h3>{resourceList.resourceName}</h3>
+                                        <div className="view-count">
+                                            <Fire theme="outline" size="16" fill="#FF8D1A" />
+                                            <span>{resourceList.likes}</span>
+                                        </div>
+                                    </div>
+                                </Card>
+                            ))}
+                        </div>
+                    </div>
+
+                    {/*发布帖子*/}
+                    <div className="homepage-item">
+                        <div className="section-header">
+                            <h1>发布帖子</h1>
+                            <Button
+                                label="显示更多"
+                                link
+                                onClick={() => router.push('/resource/recommend/模组')}
+                            />
+                        </div>
+                        <div className="resource-grid">
+
+                            {/*{mods.map((mod) => (*/}
+                            {/*    <Card key={mod.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${mod.resourceId}`)}>*/}
+                            {/*        <Image*/}
+                            {/*            src={process.env.NEXT_PUBLIC_NGINX_URL + mod.resourcePicture}*/}
+                            {/*            alt={mod.resourceName}*/}
+                            {/*            width="368"*/}
+                            {/*            height="200"*/}
+                            {/*        />*/}
+                            {/*        <div className="card-content">*/}
+                            {/*            <h3>{mod.resourceName}</h3>*/}
+                            {/*            <div className="view-count">*/}
+                            {/*                <Fire theme="outline" size="16" fill="#FF8D1A" />*/}
+                            {/*                <span>{mod.likes}</span>*/}
+                            {/*            </div>*/}
+                            {/*        </div>*/}
+                            {/*    </Card>*/}
+                            {/*))}*/}
+                        </div>
+                    </div>
+                </TabPanel>
+
+                <TabPanel header="发布">
+
+                </TabPanel>
+
+                <TabPanel header="帖子">
+
+                </TabPanel>
+
+                <TabPanel header="收藏">
+
+                </TabPanel>
+
+                <TabPanel header="数据">
+
+                </TabPanel>
+
+                <TabPanel header="悬赏">
+
+                </TabPanel>
+            </TabView>
+
+            {/*浮动按钮*/}
+            <div className="card">
+                <SpeedDial
+                    model={actions}
+                    direction="up"
+                    style={{ position: 'fixed', bottom: '2rem', right: '2rem' }}
+                    showIcon="pi pi-plus"
+                    hideIcon="pi pi-times"
+                    buttonClassName="custom-speeddial-button"
+                />
+            </div>
+
+        </div>
+    );
+};
+
diff --git a/src/app/user/user.scss b/src/app/user/user.scss
new file mode 100644
index 0000000..0d044bc
--- /dev/null
+++ b/src/app/user/user.scss
@@ -0,0 +1,172 @@
+//全局容器样式
+.user-container {
+  max-width: 1200px;
+  margin: 0 auto;
+  padding: 0 2rem;
+
+  .p-tabview-title {
+    font-size: 20px;
+  }
+}
+
+//个人信息样式
+.user-profile-card {
+  display: flex;
+
+  .user-avatar {
+    height: 200px;
+    width: 200px;
+    margin: 30px;
+  }
+  .user-info {
+    width: 796px;
+    position: relative;
+    margin-top: 22px;
+
+    .user-detail-info {
+      display: flex;
+      justify-content: space-between;
+
+      .name-container {
+        width: 750px;
+        margin-left: 1rem;
+        .name {
+          font-size: 43px;
+          margin-bottom: 3px;
+        }
+
+        .signature {
+          margin-top: 0;
+          font-size: 20px;
+        }
+      }
+
+      .stats-container {
+        display: flex;
+        flex-wrap: wrap; // 允许换行
+        margin-top: 60px;
+
+        .stats {
+          width: 50%;
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          margin-bottom: 16px;
+
+          // 左上角:粉丝
+          &:nth-child(1) {
+            justify-content: flex-start; // 左对齐
+          }
+
+          // 右上角:累计上传量
+          &:nth-child(2) {
+            justify-content: flex-end; // 右对齐
+          }
+
+          // 左下角:关注
+          &:nth-child(3) {
+            justify-content: flex-start; // 左对齐
+          }
+
+          // 右下角:累计被下载量
+          &:nth-child(4) {
+            justify-content: flex-end; // 右对齐
+          }
+
+          .stats-label {
+            font-size: 18px;
+            color: #666;
+            margin-right: 4px;
+            white-space: nowrap;
+          }
+
+          .stats-value {
+            font-size: 20px;
+            font-weight: bold;
+            color: #333;
+          }
+        }
+      }
+    }
+
+    .action-button {
+      align-self: flex-end; // 底部对齐
+      margin-top: auto; // 自动上边距将其推到底部
+      // 固定位置:
+      position: absolute;
+      right: 0;
+      bottom: 10px;
+    }
+  }
+}
+
+
+//每一模块的首部样式
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 20px;
+}
+
+//每个模块中的资源样式
+.resource-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+  gap: 1rem;
+
+  .resource-card {
+    transition: transform 0.2s ease;
+    cursor: pointer;
+    box-shadow: none !important;
+
+    .p-image {
+      img {
+        border-radius: 0.5rem 0.5rem 0 0;
+        object-fit: cover;
+      }
+    }
+
+    .p-card-body {
+      padding: 0;
+    }
+
+    .p-card-content {
+      padding: 0;
+    }
+
+    &:hover {
+      transform: translateY(-4px);
+    }
+
+    .card-content {
+      display: flex;
+      flex-direction: column;
+      position: relative;
+      margin-left: 16px;
+      margin-right: 16px;
+      margin-bottom: 16px;
+
+      h3 {
+        margin: 1rem 0;
+        font-size: 1rem;
+        line-height: 1.5;
+        color: #2d3748;
+      }
+
+      .view-count {
+        position: absolute;
+        bottom: 0rem;
+        right: 0rem;
+        display: flex;
+        align-items: center;
+        gap: 0.5rem;
+        color: #718096;
+        font-size: 0.9rem;
+      }
+    }
+  }
+}
+
+
+