add reward manage

Change-Id: Ic0a25e1fb6442bbda2285b2cc9c736f8a9ed9713
diff --git a/src/app/user/manage/resources/page.tsx b/src/app/user/manage/resources/page.tsx
index 6c18cf0..e3b7301 100644
--- a/src/app/user/manage/resources/page.tsx
+++ b/src/app/user/manage/resources/page.tsx
@@ -126,8 +126,6 @@
             });
             console.log("用户" + 22301010 + "要删除" + deleteData.resourceId + "号资源");
             console.log(deleteData);
-            console.log(response);
-            console.log(response.status)
 
             if (response.status === 204) {
                 console.log("用户成功删除资源");
diff --git "a/src/app/user/manage/rewards/data/\133rewardId\135/page.tsx" "b/src/app/user/manage/rewards/data/\133rewardId\135/page.tsx"
deleted file mode 100644
index c48b626..0000000
--- "a/src/app/user/manage/rewards/data/\133rewardId\135/page.tsx"
+++ /dev/null
@@ -1,12 +0,0 @@
-'use client';
-import React from 'react';
-
-const EmptyPage: React.FC = () => {
-  return (
-    <div className="p-d-flex p-jc-center p-ai-center" style={{ height: '100vh' }}>
-      {"一个空页面"}
-    </div>
-  );
-};
-
-export default EmptyPage;
diff --git a/src/app/user/manage/rewards/page.tsx b/src/app/user/manage/rewards/page.tsx
deleted file mode 100644
index c48b626..0000000
--- a/src/app/user/manage/rewards/page.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-'use client';
-import React from 'react';
-
-const EmptyPage: React.FC = () => {
-  return (
-    <div className="p-d-flex p-jc-center p-ai-center" style={{ height: '100vh' }}>
-      {"一个空页面"}
-    </div>
-  );
-};
-
-export default EmptyPage;
diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx
index 7a1b631..1172aeb 100644
--- a/src/app/user/page.tsx
+++ b/src/app/user/page.tsx
@@ -23,13 +23,16 @@
 import { Toast } from 'primereact/toast';
 // 页面跳转
 import { useRouter } from "next/navigation";
+// 类型转换
+import {toNumber} from "lodash";
+// 分页
+import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
 
 // 接口传输
 import axios from "axios";
 
 // 样式
 import './user.scss';
-import {toNumber} from "lodash";
 
 // 用户信息
 interface UserInfo {
@@ -76,6 +79,42 @@
     records: Resource[];
 }
 
+// 帖子
+interface Thread {
+    threadId: number;
+    userId:  number;
+    threadPicture:   string;
+    title: string;
+    likes:  number;
+    createAt:  string;
+}
+
+// 发布帖子列表
+interface ThreadList {
+    records: Thread[];
+    total: number;
+    pages: number;
+    current: number;
+    size: number;
+}
+
+// 悬赏
+interface Reward {
+    rewardId: number;
+    userId: number;
+    rewardPicture: string;
+    rewardName: string;
+    createAt: string;
+    rewardDescription: string;
+    price: number;
+}
+
+// 我的悬赏列表
+interface RewardList {
+    rewardList: Reward[];
+    total: number; // 总记录数
+}
+
 // 资源标签
 interface GameplayOption {
     name: string;
@@ -112,8 +151,32 @@
     const toast = useRef<Toast>(null);
     // 资源标签
     const [selectedGameplay, setSelectedGameplay] = useState<GameplayOption[]>([]);
-    // 判断用户是否上传资源封面
-    const [isUploadPicture, setIsUploadPicture] = useState<boolean>(false);
+    // 资源封面路径
+    const [resourcePictureUrl, setResourcePictureUrl] = useState<string>('');
+    // 主页发布帖子列表
+    const [homePageThread, setHomePageThread] = useState<ThreadList>();
+    // 我的帖子列表
+    const [threadList, setThreadList] = useState<Thread[]>([]);
+    // 我的悬赏列表
+    const [rewardList, setRewardList] = useState<Reward[]>([]);
+    // 控制Tab切换
+    const [activeIndex, setActiveIndex] = useState(0);
+    // 帖子分页
+    const [threadFirst, setThreadFirst] = useState(0);
+    const [threadRows, setThreadRows] = useState(6);
+    const [totalThreads, setTotalThreads] = useState<number>(0);
+    const onThreadPageChange = (event: PaginatorPageChangeEvent) => {
+        setThreadFirst(event.first);
+        setThreadRows(event.rows);
+    };
+    // 悬赏分页
+    const [rewardFirst, setRewardFirst] = useState(0);
+    const [rewardRows, setRewardRows] = useState(5);
+    const [totalRewards, setTotalRewards] = useState<number>(0);
+    const onRewardPageChange = (event: PaginatorPageChangeEvent) => {
+        setRewardFirst(event.first);
+        setRewardRows(event.rows);
+    };
 
     useEffect(() => {
         fetchUserInfo();
@@ -175,15 +238,71 @@
             });
             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: '获取发布资源失败' });
         }
     };
 
+    useEffect(() => {
+        fetchHomePageThread();
+    }, []);
+
+    // 获取主页部分的发布帖子
+    const fetchHomePageThread = async () => {
+        try {
+            const response = await axios.get<ThreadList>(process.env.PUBLIC_URL + `/user/thread`, {
+                params: { userId: 22301010,  pageNumber: 1, rows: 3 }
+            })
+            console.log('获取主页发布帖子:', response.data);
+            setHomePageThread(response.data);
+
+        } catch (err) {
+            console.error('获取主页发布帖子失败', err);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取主页发布帖子失败' });
+        }
+    }
+
+    useEffect(() => {
+        fetchThreadList();
+    }, [threadFirst, threadRows]);
+
+    // 获取用户发布的所有帖子
+    const fetchThreadList = async () => {
+        try {
+            const pageNumber = threadFirst / threadRows + 1;
+            const response = await axios.get<ThreadList>(process.env.PUBLIC_URL + `/user/thread`, {
+                params: { userId: 22301010,  pageNumber: pageNumber, rows: threadRows }
+            })
+            console.log('获取我的帖子:', response.data);
+            setThreadList(response.data.records);
+            setTotalThreads(response.data.total)
+        }catch (err) {
+            console.error('获取我的帖子失败', err);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取我的帖子失败' });
+        }
+    }
+
+    useEffect(() => {
+        fetchRewardList();
+    }, [rewardFirst, rewardRows]);
+
+    // 获取用户发布的所有悬赏
+    const fetchRewardList = async () => {
+        try {
+            const pageNumber = rewardFirst / rewardRows + 1;
+            const response = await axios.get<RewardList>(process.env.PUBLIC_URL + `/user/reward`, {
+                params: { userId: 22301010,  pageNumber: pageNumber, rows: rewardRows }
+            })
+            console.log('获取我的悬赏:', response.data);
+            setRewardList(response.data.rewardList);
+            setTotalRewards(response.data.total)
+        }catch (err) {
+            console.error('获取我的悬赏失败', err);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取我的悬赏失败' });
+        }
+    }
+
     // 浮动按钮的子模块
     const actions = [
         {
@@ -227,11 +346,68 @@
     });
     const [ingredient, setIngredient] = useState<string>('');
 
+    // 删除悬赏弹窗
+    const [deleteVisible, setDeleteVisible] = useState(false);
+    // 要删除悬赏的id
+    const [deleteRewardId, setDeleteResourceId] =  useState<number>(0);
+    // 处理删除悬赏接口
+    const handleDeleteSubmit = async () => {
+        try {
+            // 发送DELETE请求
+            const response = await axios.delete(process.env.PUBLIC_URL + `/reward`, {
+                params: {rewardId: deleteRewardId},
+            });
+            console.log("用户" + 22301010 + "要删除" + deleteRewardId + "号悬赏");
 
-    // 图片上传消息通知
-    const onUpload = () => {
-        setIsUploadPicture(true);
-        toast.current?.show({ severity: 'info', summary: 'Success', detail: 'File Uploaded' });
+            if (response.status === 204) {
+                console.log("用户成功删除悬赏");
+                toast.current?.show({severity: 'success', summary: 'Success', detail: '删除悬赏成功'});
+                setDeleteVisible(false);
+                // 重新拉取资源列表
+                fetchRewardList();
+            }
+        } catch (error) {
+            console.error('资源删除失败:', error);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '密码错误,资源删除失败' });
+        }
+    };
+
+
+    // 编辑悬赏弹窗
+    const [editVisible, setEditVisible] = useState(false);
+    // 悬赏封面路径
+    const [rewardPictureUrl, setRewardPictureUrl] = useState<string>('');
+    const [editRewardFormData, setEditRewardFormData] = useState({
+        rewardId: 0,
+        rewardName: '',
+        price: '',
+        rewardDescription: '',
+    });
+
+    // 处理编辑资源接口
+    const handleEditSubmit = async () => {
+        try {
+            const postData = {
+                rewardId: editRewardFormData.rewardId,
+                rewardName: editRewardFormData.rewardName,
+                rewardPicture: rewardPictureUrl,
+                price: toNumber(editRewardFormData.price),
+                rewardDescription: editRewardFormData.rewardDescription,
+            };
+            // 发送POST请求
+            const response = await axios.put(process.env.PUBLIC_URL + '/reward/info', postData);
+            console.log("编辑悬赏的信息:", postData);
+
+            if (response.status === 200) {
+                toast.current?.show({ severity: 'success', summary: 'Success', detail: '悬赏编辑成功' });
+                // 编辑成功
+                setEditVisible(false);
+                fetchRewardList();
+            }
+        } catch (error) {
+            console.error('悬赏编辑失败:', error);
+            toast.current?.show({ severity: 'error', summary: 'error', detail: '悬赏编辑失败' });
+        }
     };
 
     // 上传资源接口
@@ -261,7 +437,7 @@
                 toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源标签' });
                 return;
             }
-            if (!isUploadPicture) {
+            if (resourcePictureUrl === '') {
                 toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源封面' });
                 return;
             }
@@ -270,7 +446,7 @@
             const postData = {
                 resource: {
                     resourceName: resourceFormData.resource.resourceName,
-                    resourcePicture: resourceFormData.resource.resourcePicture,
+                    resourcePicture: resourcePictureUrl,
                     resourceSummary: resourceFormData.resource.resourceSummary,
                     resourceDetail: resourceFormData.resource.resourceDetail,
                     uploadTime: currentDate,
@@ -310,8 +486,8 @@
                 setIngredient("");
                 // 重置资源标签
                 setSelectedGameplay([]);
-                // 重置上传封面状态
-                setIsUploadPicture(false);
+                // 重置资源封面
+                setResourcePictureUrl('');
                 // 可以刷新资源列表
                 // fetchResourceList();
             }
@@ -321,9 +497,6 @@
         }
     };
 
-
-
-
     return (
         <div className="user-container">
             <Toast ref={toast}></Toast>
@@ -366,39 +539,8 @@
             </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>
-
+            <TabView activeIndex={activeIndex} onTabChange={(e) => setActiveIndex(e.index)}>
+                <TabPanel header="主页" >
                     {/*发布资源*/}
                     <div className="homepage-item">
                         <div className="section-header">
@@ -437,38 +579,69 @@
                             <Button
                                 label="显示更多"
                                 link
-                                onClick={() => router.push('/resource/recommend/模组')}
+                                onClick={() => setActiveIndex(1)}
                             />
                         </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>*/}
-                            {/*))}*/}
+                            {homePageThread?.records.map((homePageThread) => (
+                                <Card key={homePageThread.threadId} className="resource-card" onClick={() => router.push(`/community/thread-detail/${homePageThread.threadId}`)}>
+                                    <Image
+                                        src={process.env.NEXT_PUBLIC_NGINX_URL + homePageThread.threadPicture}
+                                        alt={homePageThread.title}
+                                        width="368"
+                                        height="200"
+                                    />
+                                    <div className="card-content">
+                                        <h3>{homePageThread.title}</h3>
+                                        <div className="view-count">
+                                            <Fire theme="outline" size="16" fill="#FF8D1A" />
+                                            <span>{homePageThread.likes}</span>
+                                        </div>
+                                    </div>
+                                </Card>
+                            ))}
                         </div>
                     </div>
                 </TabPanel>
 
-                <TabPanel header="发布">
+                {/*<TabPanel header="发布">*/}
 
-                </TabPanel>
+                {/*</TabPanel>*/}
 
                 <TabPanel header="帖子">
-
+                    {/*我的帖子*/}
+                    <div className="homepage-item">
+                        <div className="section-header">
+                            <h1>我的帖子</h1>
+                        </div>
+                        <div className="resource-grid">
+                            {threadList.map((threadList) => (
+                                <Card key={threadList.threadId} className="resource-card" onClick={() => router.push(`/community/thread-detail/${threadList.threadId}`)}>
+                                    <Image
+                                        src={process.env.NEXT_PUBLIC_NGINX_URL + threadList.threadPicture}
+                                        alt={threadList.title}
+                                        width="368"
+                                        height="200"
+                                    />
+                                    <div className="card-content">
+                                        <h3>{threadList.title}</h3>
+                                        <div className="view-count">
+                                            <Fire theme="outline" size="16" fill="#FF8D1A" />
+                                            <span>{threadList.likes}</span>
+                                        </div>
+                                    </div>
+                                </Card>
+                            ))}
+                        </div>
+                        {totalThreads > 6 && <Paginator
+                            className="Paginator"
+                            first={threadFirst}
+                            rows={threadRows}
+                            totalRecords={totalThreads}
+                            rowsPerPageOptions={[6, 12]}
+                            onPageChange={onThreadPageChange}
+                        />}
+                    </div>
                 </TabPanel>
 
                 <TabPanel header="收藏">
@@ -480,7 +653,57 @@
                 </TabPanel>
 
                 <TabPanel header="悬赏">
+                    <div className="resource-list">
+                        {rewardList.map((rewardItem) => (
+                            <Card key={rewardItem.rewardId} className="resources-list-card"
+                                  onClick={() => router.push(`/reward/reward-detail/${rewardItem.rewardId}`)}>
+                                <Image alt="avatar"
+                                       src={process.env.NEXT_PUBLIC_NGINX_URL + "rewards/" + rewardItem.rewardPicture}
+                                       className="resource-avatar" width="250" height="140"/>
+                                <div className="resource-header">
+                                    <div className="resource-content">
+                                        <h3>{rewardItem.rewardName}</h3>
+                                    </div>
 
+                                    <div className="resource-operation">
+                                        <Button
+                                            label="编辑"
+                                            onClick={(e) => {
+                                                e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
+                                                setEditVisible(true);
+
+                                                setEditRewardFormData({
+                                                    rewardId: rewardItem.rewardId,
+                                                    rewardName: rewardItem.rewardName,
+                                                    price: rewardItem.price.toString(),
+                                                    rewardDescription: rewardItem.rewardDescription,
+                                                });
+                                                console.log("用户编辑悬赏");
+                                            }}
+                                        />
+                                        <Button
+                                            label="删除"
+                                            onClick={(e) => {
+                                                e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
+                                                setDeleteResourceId(rewardItem.rewardId);
+                                                setDeleteVisible(true);
+                                            }}
+                                            style={{backgroundColor: "rgba(255, 87, 51, 1)"}}
+                                        />
+                                    </div>
+                                </div>
+                            </Card>
+                        ))}
+
+                        {totalRewards > 5 && <Paginator
+                            className="Paginator"
+                            first={rewardFirst}
+                            rows={rewardRows}
+                            totalRecords={totalRewards}
+                            rowsPerPageOptions={[5, 10]}
+                            onPageChange={onRewardPageChange}
+                        />}
+                    </div>
                 </TabPanel>
             </TabView>
 
@@ -528,7 +751,6 @@
                             }))}
                             placeholder="请输入资源名称"
                             className="w-full"
-                            required
                         />
                     </div>
                     <div className="form-field">
@@ -548,7 +770,6 @@
                             }))}
                             placeholder="请输入资源简介(一句话)"
                             className="w-full"
-                            required
                         />
                     </div>
                     <div className="form-field">
@@ -568,7 +789,6 @@
                             rows={5}
                             placeholder="请输入资源介绍"
                             className="w-full"
-                            required
                         />
                     </div>
                     <div className="form-field">
@@ -711,19 +931,166 @@
                             <label>封面图片</label>
                         </div>
                         <FileUpload
-                            mode="basic"
+                            mode="advanced"
                             name="resource-image"
-                            url={process.env.PUBLIC_URL +"/file"} // 与后端交互的URL
+                            customUpload
+                            uploadHandler={async (e) => {
+                                const formData = new FormData();
+                                formData.append("file", e.files[0]);
+
+                                try {
+                                    const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
+
+                                    const fileUrl = res.data.url;
+                                    console.log(fileUrl);
+                                    setResourcePictureUrl(fileUrl);
+                                    toast.current?.show({ severity: 'success', summary: '上传成功' });
+                                } catch (error) {
+                                    console.log(error);
+                                    toast.current?.show({ severity: 'error', summary: '上传失败' });
+                                }
+                            }}
+                            auto
                             accept="image/*"
-                            maxFileSize={10000000000}
-                            chooseLabel="选择资源封面"
-                            className="w-full"
-                            onUpload={onUpload}
+                            chooseLabel="上传资源封面"
+
+                            // accept="image/*"
+                            // maxFileSize={10000000000}
+                            // chooseLabel="选择资源封面"
+                            // className="w-full"
+                            // onUpload={onUpload}
                         />
                     </div>
                 </div>
             </Dialog>
 
+            {/*删除悬赏弹窗*/}
+            <Dialog
+                header="删除悬赏"
+                visible={deleteVisible}
+                onHide={() => setDeleteVisible(false)}
+                className="resource-delete-dialog"
+                modal
+                footer={
+                    <div className="dialog-footer">
+                        <Button label="确认" icon="pi pi-check" onClick={handleDeleteSubmit} autoFocus />
+                        <Button label="取消" icon="pi pi-times" onClick={() => setDeleteVisible(false)} className="p-button-text" />
+                    </div>
+                }
+            >
+                <div className="dialog-form">
+                    <span>
+                        确认是否删除该悬赏?
+                    </span>
+                    {/*<div className="form-field">*/}
+                    {/*    <div className="form-field-header">*/}
+                    {/*        <label htmlFor="name">密码</label>*/}
+                    {/*    </div>*/}
+                    {/*    <Password*/}
+                    {/*        id="passwrod"*/}
+                    {/*        value={deleteResourceFormData.password}*/}
+                    {/*        onChange={(e) => setDeleteResourceFormData(prev => ({*/}
+                    {/*            ...prev,*/}
+                    {/*            password: e.target.value*/}
+                    {/*        }))}*/}
+                    {/*        placeholder="请输入密码"*/}
+                    {/*        className="w-full"*/}
+                    {/*        toggleMask*/}
+                    {/*    />*/}
+                    {/*</div>*/}
+                </div>
+            </Dialog>
+
+            {/*编辑资源弹窗*/}
+            <Dialog
+                header="编辑资源"
+                visible={editVisible}
+                onHide={() => setEditVisible(false)}
+                className="resource-edit-dialog"
+                modal
+                footer={
+                    <div className="dialog-footer">
+                        <Button label="确认" icon="pi pi-check" onClick={handleEditSubmit} autoFocus />
+                        <Button label="取消" icon="pi pi-times" onClick={() => setEditVisible(false)} className="p-button-text" />
+                    </div>
+                }
+            >
+                <div className="dialog-form">
+                    <div className="form-field">
+                        <div className="form-field-header">
+                            <label htmlFor="name">更改标题</label>
+                        </div>
+                        <InputText
+                            id="name"
+                            value={editRewardFormData.rewardName}
+                            onChange={(e) => setEditRewardFormData(prev => ({
+                                ...prev,
+                                rewardName:  e.target.value
+                            }))}
+                            className="w-full"
+                        />
+                    </div>
+                    <div className="form-field">
+                        <div className="form-field-header">
+                            <label htmlFor="summary">更改定价</label>
+                        </div>
+                        <InputText
+                            id="summary"
+                            value={editRewardFormData.price}
+                            onChange={(e) => setEditRewardFormData(prev => ({
+                                ...prev,
+                                price:  e.target.value
+                            }))}
+                            className="w-full"
+                        />
+                    </div>
+                    <div className="form-field">
+                        <div className="form-field-header">
+                            <label htmlFor="detail">更改需求</label>
+                        </div>
+                        <InputTextarea
+                            id="detail"
+                            value={editRewardFormData.rewardDescription}
+                            onChange={(e) => setEditRewardFormData(prev => ({
+                                ...prev,
+                                rewardDescription:  e.target.value
+                            }))}
+                            rows={5}
+                            className="w-full"
+                        />
+                    </div>
+                    <div className="form-field">
+                        <div className="form-field-header">
+                            <span className="form-field-sign">*</span>
+                            <label>封面图片</label>
+                        </div>
+                        <FileUpload
+                            mode="advanced"
+                            name="resource-image"
+                            customUpload
+                            uploadHandler={async (e) => {
+                                const formData = new FormData();
+                                formData.append("file", e.files[0]);
+
+                                try {
+                                    const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
+
+                                    const fileUrl = res.data.url;
+                                    console.log(fileUrl);
+                                    setRewardPictureUrl(fileUrl);
+                                    toast.current?.show({ severity: 'success', summary: '上传成功' });
+                                } catch (error) {
+                                    console.log(error);
+                                    toast.current?.show({ severity: 'error', summary: '上传失败' });
+                                }
+                            }}
+                            auto
+                            accept="image/*"
+                            chooseLabel="选择悬赏封面"
+                        />
+                    </div>
+                </div>
+            </Dialog>
         </div>
     );
 };
diff --git a/src/app/user/user.scss b/src/app/user/user.scss
index a3726b6..d0b10c8 100644
--- a/src/app/user/user.scss
+++ b/src/app/user/user.scss
@@ -103,69 +103,156 @@
 }
 
 
-//每一模块的首部样式
-.section-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-top: 20px;
+.p-tabview-panels {
+  padding-top: 0;
 }
 
-//每个模块中的资源样式
-.resource-grid {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
-  gap: 1rem;
+.homepage-item {
+  //每一模块的首部样式
+  .section-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 20px;
+  }
 
-  .resource-card {
-    transition: transform 0.2s ease;
-    cursor: pointer;
-    box-shadow: none !important;
+  //每个模块中的资源样式
+  .resource-grid {
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+    gap: 1rem;
 
-    .p-image {
-      img {
-        border-radius: 0.5rem 0.5rem 0 0;
-        object-fit: cover;
+    .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;
+        }
+      }
+    }
+  }
+}
+
+
+.resources-list {
+  width: 100%;
+  padding: 1rem;
+
+  &-card {
+    height: 140px;
+    padding: 1.5rem;
+    margin-bottom: 1rem;
+    border-radius: 0.5rem;
+    transition: transform 0.3s ease;
+    box-shadow: none !important; // 取消阴影
+
+    //填充卡片
+    &.p-card.p-component {
+      padding: 0;
     }
 
     .p-card-body {
       padding: 0;
     }
 
+    &:hover {
+      transform: translateY(-3px);
+      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+    }
+
     .p-card-content {
+      height: 140px;
+      display: flex;
+      justify-content: space-between;
       padding: 0;
     }
 
-    &:hover {
-      transform: translateY(-4px);
+    img {
+      border-radius: 0.5rem 0 0 0.5rem;
+      object-fit: cover;
     }
 
-    .card-content {
+
+    .resource-avatar {
+      width: 80px;
+      height: 80px;
+      border-radius: 8px;
+      object-fit: cover;
+    }
+
+    .resource-header {
+      display: flex;
+      flex: 1;
+      max-width: 850px;
+      padding-left: 20px;
+      padding-right: 20px;
+      margin-bottom: 20px;
+    }
+
+    .resource-content {
+      flex: 1;
       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;
+        font-size: 1.5rem;
+        font-weight: bold;
+        color: #2c3e50;
       }
 
-      .view-count {
-        position: absolute;
-        bottom: 0rem;
-        right: 0rem;
-        display: flex;
-        align-items: center;
-        gap: 0.5rem;
-        color: #718096;
-        font-size: 0.9rem;
-      }
+
+    }
+
+    .resource-operation {
+      min-width: 240px;
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-end;
+      align-items: flex-end;
+      gap: 1rem;
     }
   }
 }
@@ -245,5 +332,115 @@
   }
 }
 
+//删除资源弹窗样式
+.resource-delete-dialog {
+  width: 350px !important;
+  max-width: 90vw;
+
+  .dialog-footer {
+    margin-top: 10px;
+    display: flex;
+    justify-content: center;
+  }
+
+  .p-dialog-header {
+    font-size: 1.5rem;
+    font-weight: bold;
+    color: $heading-color;
+    padding-bottom: 0.5rem;
+  }
+
+  .p-dialog-content {
+    padding-top: 0;
+    padding-bottom: 0;
+
+    .dialog-form {
+      display: flex;
+      flex-direction: column;
+      gap: 1.5rem;
+      margin-top: 1rem;
+
+      .form-field {
+        display: flex;
+        flex-direction: column;
+        gap: 0.5rem;
+
+        label {
+          font-weight: 600;
+          color: $heading-color;
+        }
+
+        input,
+        textarea{
+          padding: 0.75rem 1rem;
+          border-radius: 8px;
+          font-size: 1rem;
+          color: #2d3748;
+        }
+
+      }
+    }
+  }
+}
+
+//资源编辑弹窗样式
+.resource-edit-dialog {
+  width: 600px !important;
+  max-width: 90vw;
+
+  .dialog-footer {
+    margin-top: 10px;
+    display: flex;
+    justify-content: center;
+  }
+
+  .p-dialog-header {
+    font-size: 1.5rem;
+    font-weight: bold;
+    color: $heading-color;
+    padding-bottom: 0.5rem;
+  }
+
+  .p-dialog-content {
+    padding-top: 0;
+    padding-bottom: 0;
+
+    .dialog-form {
+      display: flex;
+      flex-direction: column;
+      gap: 1.5rem;
+      margin-top: 1rem;
+
+      .form-field {
+        display: flex;
+        flex-direction: column;
+        gap: 0.5rem;
+
+        label {
+          font-weight: 600;
+          color: $heading-color;
+        }
+
+        input,
+        textarea{
+          padding: 0.75rem 1rem;
+          border-radius: 8px;
+          font-size: 1rem;
+          color: #2d3748;
+        }
+
+        .p-fileupload {
+          .p-button {
+            width: 100%;
+            justify-content: center;
+            border: none;
+            margin-bottom: 1rem;
+          }
+        }
+      }
+    }
+  }
+}
+