Merge branch 'main' of ssh://gerrit.lilingkun.com:29418/G9Frontend
Change-Id: I7b358167f240a1fd4d49e9ff949972c94914e095
diff --git "a/src/app/community/community-detail/\133communityId\135/page.tsx" "b/src/app/community/community-detail/\133communityId\135/page.tsx"
index 962cc0f..6beb423 100644
--- "a/src/app/community/community-detail/\133communityId\135/page.tsx"
+++ "b/src/app/community/community-detail/\133communityId\135/page.tsx"
@@ -23,9 +23,13 @@
import axios from 'axios';
// 防抖函数
import { debounce } from 'lodash';
+import { useLocalStorage } from '../../../hook/useLocalStorage';
// 样式
import './resource-community.scss';
+interface User {
+ Id: number;
+}
// 帖子列表数据
interface Thread {
threadId: number;
@@ -53,6 +57,8 @@
// 社区详情页面
export default function CommunityDetailPage() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
// 获取URL参数,页面跳转
const params = useParams<{ communityId: string }>()
const communityId = decodeURIComponent(params.communityId); // 防止中文路径乱码
@@ -111,7 +117,7 @@
const option = selectedOption.name // 添加排序参数
const response = await axios.get<ThreadList>(
process.env.PUBLIC_URL + `/community/threads`, {
- params: { userId: 22301145, communityId, pageNumber, rows, option, searchValue }
+ params: { userId, communityId, pageNumber, rows, option, searchValue }
}
);
console.log('获取帖子列表:', response.data.records);
@@ -139,7 +145,7 @@
try {
const currentDate = new Date().toISOString();
const postData = {
- userId: 22301145, // 记得用户登录状态获取
+ userId, // 记得用户登录状态获取
threadPicture: formData.threadPicture,
title: formData.title,
content: formData.content,
diff --git "a/src/app/community/thread-detail/\133threadId\135/page.tsx" "b/src/app/community/thread-detail/\133threadId\135/page.tsx"
index f998f64..0f3e5b2 100644
--- "a/src/app/community/thread-detail/\133threadId\135/page.tsx"
+++ "b/src/app/community/thread-detail/\133threadId\135/page.tsx"
@@ -16,8 +16,12 @@
import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
// 消息提醒
import { Toast } from 'primereact/toast';
+import { useLocalStorage } from '../../../hook/useLocalStorage';
// 样式
import './thread.scss';
+interface User {
+ Id: number;
+}
// 评论信息
@@ -65,6 +69,9 @@
//帖子详情界面
export default function ThreadDetailPage() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
+
// 获取URL参数,页面跳转
const params = useParams<{ threadId: string }>()
const threadId = decodeURIComponent(params.threadId); // 防止中文路径乱码
@@ -104,7 +111,7 @@
const { data } = await axios.get(process.env.PUBLIC_URL + `/thread`, {
params: {
threadId,
- userId: 22301145
+ userId
}
});
setThreadInfo(data);
@@ -132,7 +139,7 @@
try {
const response = await axios.post(
process.env.PUBLIC_URL + `/thread/like`, {
- params: { threadId, userId: 22301145 }
+ params: { threadId, userId }
}
);
fetchThreadInfo(); // 刷新帖子信息
@@ -148,7 +155,7 @@
try {
const response = await axios.delete(
process.env.PUBLIC_URL + `/thread/like`, {
- params: { threadId, userId: 22301145 }
+ params: { threadId, userId }
}
);
fetchThreadInfo(); // 刷新帖子信息
@@ -216,7 +223,7 @@
console.log('发布评论:', commentId);
try {
const newComment: NewComment = {
- userId: 22301145,
+ userId,
threadId: threadInfo.threadId,
resourceId: 0,
replyId: commentId,
@@ -246,7 +253,7 @@
try {
const newComment: NewComment = {
- userId: 22301145,
+ userId,
threadId: threadInfo.threadId,
resourceId: 0,
replyId: 0, // 直接评论,不是回复
@@ -373,7 +380,7 @@
if (el) ops.current[index] = el;
}}>
<Button label="回复" text size="small" onClick={() => setVisibleReply(true)} />
- {comment.userId === 22301145 &&
+ {comment.userId === userId &&
<Button
label="删除"
text
diff --git a/src/app/hook/useLocalStorage.ts b/src/app/hook/useLocalStorage.ts
new file mode 100644
index 0000000..2b28b01
--- /dev/null
+++ b/src/app/hook/useLocalStorage.ts
@@ -0,0 +1,20 @@
+import { useEffect, useState } from 'react';
+
+export const useLocalStorage = <T>(key: string): T | null => {
+ const [value, setValue] = useState<T | null>(null);
+
+ useEffect(() => {
+ if (typeof window !== 'undefined') {
+ const item = localStorage.getItem(key);
+ if (item) {
+ try {
+ setValue(JSON.parse(item));
+ } catch (e) {
+ console.error(`解析 localStorage ${key} 失败`, e);
+ }
+ }
+ }
+ }, [key]);
+
+ return value;
+};
diff --git a/src/app/notification/page.tsx b/src/app/notification/page.tsx
index 9e83252..55f0ec5 100644
--- a/src/app/notification/page.tsx
+++ b/src/app/notification/page.tsx
@@ -11,9 +11,11 @@
import { Paginator, PaginatorPageChangeEvent } from 'primereact/paginator';
import { Card } from 'primereact/card';
import { TabView, TabPanel } from 'primereact/tabview'; // ✅ TabView 导入
-
+import { useLocalStorage } from '../hook/useLocalStorage';
import './notification.scss';
-
+interface User {
+ Id: number;
+}
interface Notification {
notificationId: number;
title: string;
@@ -25,6 +27,8 @@
}
export default function NotificationPage() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
const toast = useRef<Toast>(null);
const [notifications, setNotifications] = useState<Notification[]>([]);
const [selectedNotification, setSelectedNotification] = useState<Notification | null>(null);
@@ -41,7 +45,7 @@
try {
const pageNumber = first / rows + 1;
const res = await axios.get(process.env.PUBLIC_URL + '/notification', {
- params: { pageNumber, rows, userId: 22301145 },
+ params: { pageNumber, rows, userId },
});
const { records, total } = res.data;
setNotifications(records);
diff --git a/src/app/page.tsx b/src/app/page.tsx
index fb42dac..941167b 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -13,9 +13,14 @@
import { Fire } from '@icon-park/react';
// 接口传输
import axios from 'axios';
-
+import { useLocalStorage } from './hook/useLocalStorage';
// 样式
import './main.scss';
+
+interface User {
+ Id: number;
+}
+
// 模组列表数据
interface Mod {
resourceId: number;
@@ -88,6 +93,9 @@
}
// 主页
export default function Home() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
+
// 模组列表
const [mods, setMods] = useState<Mod[]>([]);
// 悬赏列表
@@ -126,7 +134,7 @@
// 获取悬赏列表
const fetchRewards = async () => {
try {
- const response = await axios.get<RewardList>(process.env.PUBLIC_URL +`/reward`, {
+ const response = await axios.get<RewardList>(process.env.PUBLIC_URL + `/reward`, {
params: { pageNumber: 1, rows: 5, searchValue: '', option: '' }
});
console.log('获取悬赏列表:', response.data.records);
@@ -140,7 +148,7 @@
// 获取热门资源幻灯片
const fetchHotResources = async () => {
try {
- const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL +`/resource/hot/slide`);
+ const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL + `/resource/hot/slide`);
console.log('获取热门社区幻灯片:', response.data.records);
setHotResources(response.data.records);
} catch (err) {
@@ -152,7 +160,7 @@
// 获取全站数据
const fetchstats = async () => {
try {
- const response = await axios.get<Stats>(process.env.PUBLIC_URL +`/total/info`);
+ const response = await axios.get<Stats>(process.env.PUBLIC_URL + `/total/info`);
console.log('获取全站数据:', response.data);
setStats(response.data);
} catch (err) {
@@ -165,8 +173,8 @@
// 获取推荐模组、地图、整合包、材质包
const fetchRecommendMods = async () => {
try {
- const response = await axios.get<ModList>(process.env.PUBLIC_URL +`/resource/recommend`, {
- params: { userId: 22301145, pageNumber: 1, rows: 3, type: '模组' }
+ const response = await axios.get<ModList>(process.env.PUBLIC_URL + `/resource/recommend`, {
+ params: { userId, pageNumber: 1, rows: 3, type: '模组' }
});
console.log('获取模组列表:', response.data.records);
setMods(response.data.records);
@@ -177,8 +185,8 @@
};
const fetchRecommendMaps = async () => {
try {
- const response = await axios.get<MapList>(process.env.PUBLIC_URL +`/resource/recommend`, {
- params: { userId: 22301145, pageNumber: 1, rows: 3, type: '地图' }
+ const response = await axios.get<MapList>(process.env.PUBLIC_URL + `/resource/recommend`, {
+ params: { userId, pageNumber: 1, rows: 3, type: '地图' }
});
console.log('获取模组列表:', response.data.records);
setMaps(response.data.records);
@@ -189,8 +197,8 @@
};
const fetchRecommendModpacks = async () => {
try {
- const response = await axios.get<ModpackList>(process.env.PUBLIC_URL +`/resource/recommend`, {
- params: { userId: 22301145, pageNumber: 1, rows: 3, type: '整合包' }
+ const response = await axios.get<ModpackList>(process.env.PUBLIC_URL + `/resource/recommend`, {
+ params: { userId, pageNumber: 1, rows: 3, type: '整合包' }
});
console.log('获取模组列表:', response.data.records);
setModpacks(response.data.records);
@@ -201,8 +209,8 @@
};
const fetchRecommendTextures = async () => {
try {
- const response = await axios.get<TextureList>(process.env.PUBLIC_URL +`/resource/recommend`, {
- params: { userId: 22301145, pageNumber: 1, rows: 3, type: '材质包' }
+ const response = await axios.get<TextureList>(process.env.PUBLIC_URL + `/resource/recommend`, {
+ params: { userId, pageNumber: 1, rows: 3, type: '材质包' }
});
console.log('获取模组列表:', response.data.records);
setTextures(response.data.records);
diff --git a/src/app/resource/classification/page.tsx b/src/app/resource/classification/page.tsx
index 88d6629..32648da 100644
--- a/src/app/resource/classification/page.tsx
+++ b/src/app/resource/classification/page.tsx
@@ -20,11 +20,14 @@
import { Sidebar } from 'primereact/sidebar';
// 防抖函数
import { debounce } from 'lodash';
+import { useLocalStorage } from '../../hook/useLocalStorage';
// 样式
import './classification.scss';
+interface User {
+ Id: number;
+}
// 热门资源数据
-
interface HotResource {
resourceId: number;
resourceName: string;
@@ -41,6 +44,9 @@
}
// 主页
export default function ClassificationResource() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
+
// 热门资源列表
const [hotResources, setHotResources] = useState<HotResource[]>([]);
const [totalHotResource, setTotalHotResource] = useState(0);
@@ -70,7 +76,7 @@
// 获取帖子列表
useEffect(() => {
handleSearch();
- }, [first, rows,searchValue]);
+ }, [first, rows, searchValue]);
const handleSearch = async () => {
try {
@@ -78,7 +84,7 @@
console.log(searchValue + " 当前页: " + pageNumber + "rows: " + rows + "selectedClassify: " + selectedClassify + "selectedGameplay: " + selectedGameplay + "selectedVersions: " + selectedVersions);
const response = await axios.get<HotResourceList>(process.env.PUBLIC_URL + `/resource/search`, {
params: {
- userId: 22301145,
+ userId,
pageNumber,
rows,
classify: selectedClassify,
diff --git "a/src/app/resource/resource-detail/\133resourceId\135/page.tsx" "b/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
index 8d28596..5e0a634 100644
--- "a/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
+++ "b/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
@@ -1,10 +1,10 @@
'use client';
-import React, {useEffect, useRef, useState} from 'react';
-import {Image} from "primereact/image";
-import {Button} from "primereact/button";
-import {Avatar} from "primereact/avatar";
-import {ButtonGroup} from "primereact/buttongroup";
-import {InputText} from "primereact/inputtext";
+import React, { useEffect, useRef, useState } from 'react';
+import { Image } from "primereact/image";
+import { Button } from "primereact/button";
+import { Avatar } from "primereact/avatar";
+import { ButtonGroup } from "primereact/buttongroup";
+import { InputText } from "primereact/inputtext";
import { Dialog } from 'primereact/dialog';
// 引入图标
import 'primeicons/primeicons.css';
@@ -24,22 +24,24 @@
import { Sidebar } from 'primereact/sidebar';
// 分页
import { Paginator, PaginatorPageChangeEvent } from 'primereact/paginator';
-
+import { useLocalStorage } from '../../../hook/useLocalStorage';
// 样式
import './resource-detail.scss';
-
+interface User {
+ Id: number;
+}
// 种子
interface Torrent {
- torrentRecordId: number;
+ torrentRecordId: number;
torrentUrl: string;
- infoHash: string;
- uploadTime: string;
- uploaderUserId: number;
+ infoHash: string;
+ uploadTime: string;
+ uploaderUserId: number;
}
// 资源版本
interface ResourceVersion {
- resourceVersionId: string; // 资源版本id
+ resourceVersionId: string; // 资源版本id
resourceVersionName: string; // 资源版本名称
compatibleVersions: string[]; // 兼容的游戏版本列表
torrentList: Torrent[]; // 种子列表
@@ -47,27 +49,27 @@
// 资源信息
interface Resource {
- resourceId: number;
+ resourceId: number;
resourceName: string; // 资源标题
- resourcePicture: string; // 资源照片网址
+ resourcePicture: string; // 资源照片网址
resourceSummary: string; // 资源简介(一句话)
- resourceDetail: string; // 资源介绍
- uploadTime: string; // 上传时间
+ resourceDetail: string; // 资源介绍
+ uploadTime: string; // 上传时间
lastUpdateTime: string; // 最近更新时间
- price: number;
+ price: number;
downloads: number; // 下载数
- likes: number; // 点赞数
- collections: number; // 收藏数
- comments: number; // 评论数
- seeds: number; // 种子数
- classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
+ likes: number; // 点赞数
+ collections: number; // 收藏数
+ comments: number; // 评论数
+ seeds: number; // 种子数
+ classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
hot: number; // 资源热度
gameplayList: string[]; // 资源标签
- resourceVersionList: ResourceVersion[]; // 资源版本列表
- isCollect: boolean; // 是否被收藏
- isLike: boolean; // 是否被点赞
- isPurchase: boolean; // 是否被购买
- isUpload: boolean; // 是否是该用户上传的
+ resourceVersionList: ResourceVersion[]; // 资源版本列表
+ isCollect: boolean; // 是否被收藏
+ isLike: boolean; // 是否被点赞
+ isPurchase: boolean; // 是否被购买
+ isUpload: boolean; // 是否是该用户上传的
userId: number; // 资源上传者的id
}
@@ -116,7 +118,7 @@
// 关注
interface Subscriber {
userId: number;
- username: string;
+ username: string;
}
// 关注列表
@@ -125,6 +127,8 @@
}
export default function ResourceDetail() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
// 获取URL参数
const params = useParams<{ resourceId: string }>();
const resourceId = decodeURIComponent(params.resourceId); // 防止中文路径乱码
@@ -182,8 +186,8 @@
const fetchResourceInfo = async () => {
try {
// console.log(resourceId);
- const response = await axios.get<Resource>(process.env.PUBLIC_URL +`/resource/info`, {
- params: { resourceId: resourceId, userId: 22301010 }
+ const response = await axios.get<Resource>(process.env.PUBLIC_URL + `/resource/info`, {
+ params: { resourceId: resourceId, userId }
});
console.log('获取资源信息:', response.data);
setResource(response.data);
@@ -211,7 +215,7 @@
try {
// console.log(resourceId);
// console.log(resourceAuthorId);
- const response = await axios.get<ResourceAuthor>(process.env.PUBLIC_URL +`/user/info`, {
+ const response = await axios.get<ResourceAuthor>(process.env.PUBLIC_URL + `/user/info`, {
params: { userId: resourceAuthorId }
});
console.log('获取资源作者信息:', response.data);
@@ -231,7 +235,7 @@
const fetchSubscriber = async () => {
try {
const response = await axios.get<SubscriberList>(process.env.PUBLIC_URL + `/user/subscriber`, {
- params: {userId: 223010100}
+ params: { userId }
});
console.log("关注列表:", response.data);
setSubscriberList(response.data);
@@ -255,177 +259,110 @@
// 资源作者 ID
const authorId = resource?.userId;
// 当前登录用户 ID
- const currentUserId = 223010100;
+ const currentUserId = userId;
// 资源作者与浏览用户是同一人,不显示按钮
- if (!authorId || authorId == currentUserId){
+ if (!authorId || authorId == currentUserId) {
return null;
}
return isSubscribed ? (
- // 如果已关注,显示“取消关注”按钮
- <Button
- label="取消关注"
- onClick={async () => {
- try {
- const response = await axios.delete(
- process.env.PUBLIC_URL + '/user/subscription',
- {
- params: { userId: currentUserId, followerId: authorId }
- }
- );
-
- if (response.status === 200) {
- setIsSubscribed(false); // 🔥立刻更新按钮状态
- toast.current?.show({
- severity: 'success',
- summary: '取消成功',
- detail: '已取消关注该用户',
- });
-
- fetchSubscriber(); // 重新拉取完整关注列表
- }
- } catch (error) {
- console.error('取消关注失败:', error);
- toast.current?.show({
- severity: 'error',
- summary: '错误',
- detail: '取消关注失败',
- });
+ // 如果已关注,显示“取消关注”按钮
+ <Button
+ label="取消关注"
+ onClick={async () => {
+ try {
+ const response = await axios.delete(
+ process.env.PUBLIC_URL + '/user/subscription',
+ {
+ params: { userId: currentUserId, followerId: authorId }
}
- }}
- />
+ );
+
+ if (response.status === 200) {
+ setIsSubscribed(false); // 🔥立刻更新按钮状态
+ toast.current?.show({
+ severity: 'success',
+ summary: '取消成功',
+ detail: '已取消关注该用户',
+ });
+
+ fetchSubscriber(); // 重新拉取完整关注列表
+ }
+ } catch (error) {
+ console.error('取消关注失败:', error);
+ toast.current?.show({
+ severity: 'error',
+ summary: '错误',
+ detail: '取消关注失败',
+ });
+ }
+ }}
+ />
) : (
- // 若未关注,则显示关注按钮
- <Button
- label="关注"
- onClick={async () => {
- try {
- const postData = {
- userId: currentUserId,
- followerId: authorId,
- };
- const response = await axios.post(
- process.env.PUBLIC_URL + '/user/subscription',
- postData
- );
+ // 若未关注,则显示关注按钮
+ <Button
+ label="关注"
+ onClick={async () => {
+ try {
+ const postData = {
+ userId: currentUserId,
+ followerId: authorId,
+ };
+ const response = await axios.post(
+ process.env.PUBLIC_URL + '/user/subscription',
+ postData
+ );
- if (response.status === 200) {
- setIsSubscribed(true); // 🔥立刻更新按钮状态
- toast.current?.show({
- severity: 'success',
- summary: '关注成功',
- detail: '已成功关注该用户',
- });
+ if (response.status === 200) {
+ setIsSubscribed(true); // 🔥立刻更新按钮状态
+ toast.current?.show({
+ severity: 'success',
+ summary: '关注成功',
+ detail: '已成功关注该用户',
+ });
- fetchSubscriber(); // 刷新列表
- }
- } catch (error) {
- console.error('关注失败:', error);
- toast.current?.show({
- severity: 'error',
- summary: '错误',
- detail: '关注失败',
- });
- }
- }}
- />
+ fetchSubscriber(); // 刷新列表
+ }
+ } catch (error) {
+ console.error('关注失败:', error);
+ toast.current?.show({
+ severity: 'error',
+ summary: '错误',
+ detail: '关注失败',
+ });
+ }
+ }}
+ />
);
-
-
- // if (isSubscribed) {
- // return (
- // <Button
- // label="取消关注"
- // onClick={async () => {
- // try {
- // const response = await axios.delete(
- // process.env.PUBLIC_URL + '/user/subscription', {
- // params: {userId: currentUserId, followerId: authorId}
- // }
- // );
- //
- // if (response.status === 200) {
- // toast.current?.show({
- // severity: 'success',
- // summary: '取消成功',
- // detail: '已取消关注该用户',
- // });
- // // 重新拉取关注列表
- // fetchSubscriber();
- // }
- // } catch (error) {
- // console.error('取消关注失败:', error);
- // toast.current?.show({
- // severity: 'error',
- // summary: '错误',
- // detail: '取消关注失败',
- // });
- // }
- // }}
- // />
- // );
- // } else {
- // // 未关注,显示“关注”按钮
- // return (
- // <Button
- // label="关注"
- // onClick={async () => {
- // try {
- // const postData = {
- // userId: currentUserId,
- // followerId: authorId,
- // };
- // const response = await axios.post(
- // process.env.PUBLIC_URL + '/user/subscription',
- // postData
- // );
- //
- // if (response.status === 200) {
- // toast.current?.show({
- // severity: 'success',
- // summary: '关注成功',
- // detail: '已成功关注该用户',
- // });
- // // 重新拉取关注列表
- // fetchSubscriber();
- // }
- // } catch (error) {
- // console.error('关注失败:', error);
- // toast.current?.show({
- // severity: 'error',
- // summary: '错误',
- // detail: '关注失败',
- // });
- // }
- // }}
- // />
- // );
- // }
}
// 判断该资源是否已被购买, 返回不同的购买按钮
const isPurchase = () => {
// 作者本人查看资源,不显示购买按钮
- if (resource?.userId == 223010100) {
- return ;
+ if (resource?.userId == userId) {
+ return;
}
// 该资源已被购买
if (resource?.isPurchase) {
return (
- <Button label="已购买" style={{width:"120px", height:"44px",
- borderRadius:"20px 0 0 20px",}} disabled={true}/>
+ <Button label="已购买" style={{
+ width: "120px", height: "44px",
+ borderRadius: "20px 0 0 20px",
+ }} disabled={true} />
)
} else {
// 该资源未被购买
return (
- <Button
- label="立即购买"
- style={{width:"120px", height:"44px",
- borderRadius:"20px 0 0 20px",}}
- onClick={() => setVisible(true)}
- />
+ <Button
+ label="立即购买"
+ style={{
+ width: "120px", height: "44px",
+ borderRadius: "20px 0 0 20px",
+ }}
+ onClick={() => setVisible(true)}
+ />
)
}
}
@@ -434,7 +371,7 @@
const handlePurchase = async () => {
try {
const postData = {
- userId: 223010100, // 记得用户登录状态获取
+ userId, // 记得用户登录状态获取
resourceId: resource?.resourceId
};
// 发送POST请求
@@ -467,14 +404,14 @@
try {
if (newCollectionState) {
// 收藏操作
- await axios.post(process.env.PUBLIC_URL +`/resource/collection`, {
- params: { resourceId: resourceId, userId: 22301010 }
+ await axios.post(process.env.PUBLIC_URL + `/resource/collection`, {
+ params: { resourceId: resourceId, userId }
});
console.log('收藏资源');
} else {
// 取消收藏操作
- await axios.delete(process.env.PUBLIC_URL +`/resource/collection`, {
- params: { resourceId: resourceId, userId: 22301010 }
+ await axios.delete(process.env.PUBLIC_URL + `/resource/collection`, {
+ params: { resourceId: resourceId, userId }
});
console.log('取消收藏资源');
}
@@ -504,14 +441,14 @@
try {
if (newLikeState) {
// 点赞操作
- await axios.post(process.env.PUBLIC_URL +`/resource/like`, {
- params: { resourceId: resourceId, userId: 22301010 }
+ await axios.post(process.env.PUBLIC_URL + `/resource/like`, {
+ params: { resourceId: resourceId, userId }
});
console.log('点赞资源');
} else {
// 取消点赞操作
- await axios.delete(process.env.PUBLIC_URL +`/resource/like`, {
- params: { resourceId: resourceId, userId: 22301010 }
+ await axios.delete(process.env.PUBLIC_URL + `/resource/like`, {
+ params: { resourceId: resourceId, userId }
});
console.log('取消点赞资源');
}
@@ -538,8 +475,8 @@
const format = (num: number, suffix: string) => {
const fixed = num.toFixed(1);
return fixed.endsWith('.0')
- ? `${Math.floor(num)}${suffix}`
- : `${fixed}${suffix}`;
+ ? `${Math.floor(num)}${suffix}`
+ : `${fixed}${suffix}`;
};
if (absCount >= 1e6) return format(count / 1e6, "m");
@@ -551,9 +488,9 @@
useEffect(() => {
if (!resource) return;
// 发帖人
- axios.get(process.env.PUBLIC_URL +`/user/info?userId=${resource?.userId}`)
- .then(res => setUserInfo(res.data))
- .catch(console.error);
+ axios.get(process.env.PUBLIC_URL + `/user/info?userId=${resource?.userId}`)
+ .then(res => setUserInfo(res.data))
+ .catch(console.error);
}, [resource]);
// 当 resourceId 或分页参数变化时重新拉评论
@@ -578,9 +515,9 @@
const pageNumber = first / rows + 1;
console.log("当前页" + pageNumber + "size" + rows);
const response = await axios.get<CommentList>(
- process.env.PUBLIC_URL +`/comments`, {
- params: { id: resourceId, pageNumber, rows, type: 'resource' }
- }
+ process.env.PUBLIC_URL + `/comments`, {
+ params: { id: resourceId, pageNumber, rows, type: 'resource' }
+ }
);
console.log('获取评论列表:', response.data.records);
setComments(response.data.records);
@@ -589,8 +526,8 @@
response.data.records.forEach(comment => {
if (comment.userId != null && !commentUserInfos.has(comment.userId)) {
axios.get<UserInfo>(
- process.env.PUBLIC_URL +`/user/info`,
- { params: { userId: comment.userId } }
+ process.env.PUBLIC_URL + `/user/info`,
+ { params: { userId: comment.userId } }
).then(res => {
setCommentUserInfos(prev => new Map(prev).set(comment.userId!, res.data));
});
@@ -609,7 +546,7 @@
// console.log(typeof resourceId);
try {
const newComment: NewComment = {
- userId: 22301145,
+ userId,
rewardId: 0,
threadId: 0,
resourceId: resource.resourceId,
@@ -618,7 +555,7 @@
createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
};
- const response = await axios.post(process.env.PUBLIC_URL +'/comment', newComment);
+ const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
if (response.status === 200) {
toast.current?.show({ severity: 'success', summary: 'Success', detail: '回复成功' });
@@ -640,7 +577,7 @@
try {
const newComment: NewComment = {
- userId: 22301145,
+ userId,
rewardId: 0,
threadId: 0,
resourceId: resource.resourceId,
@@ -649,7 +586,7 @@
createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
};
- const response = await axios.post(process.env.PUBLIC_URL +'/comment', newComment);
+ const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
if (response.status === 200) {
toast.current?.show({ severity: 'success', summary: 'Success', detail: '评论成功' });
@@ -671,7 +608,7 @@
try {
// 调用 DELETE 接口,URL 中最后一段是要删除的 commentId
const response = await axios.delete(
- process.env.PUBLIC_URL +`/comment?commentId=${commentId}`
+ process.env.PUBLIC_URL + `/comment?commentId=${commentId}`
);
if (response.status === 200) {
@@ -687,219 +624,219 @@
};
const ReplyHeader = (
- <div className="flex align-items-center gap-1">
- <h3>回复评论</h3>
- </div>
+ <div className="flex align-items-center gap-1">
+ <h3>回复评论</h3>
+ </div>
);
if (!resourceId || !userInfo) return <div>Loading...</div>;
- return(
- <div className="resource-detail-container">
- <Toast ref={toast}></Toast>
- {/*资源标题*/}
- <div className="resource-header">
- {resource?.resourceName}
- </div>
- {/*资源详细信息*/}
- <div className="resource-info">
- <Image
- src={(process.env.NEXT_PUBLIC_NGINX_URL! + resource?.resourcePicture)}
- alt= {resource?.resourceName}
- width="540px"
- height="300px"
- />
- <div className="resource-info-detail">
- {/*资源热度*/}
- <div className="resource-hot">
- <Fire theme="outline" size="50" fill="#f5a623" strokeWidth={3}/>
- <span className="resource-hot-data">{resource?.hot}</span>
- </div>
-
- {/*资源标签*/}
- <div className="resource-label">
- {resource?.gameplayList.map((tag, index) => (
- <Button
- key={index} label={tag}
- className="resource-label-button"
- onClick={() => {
- router.push(`/resource/classification/`)
- }}
- />
- ))}
- </div>
-
- {/*资源浏览量和下载量*/}
- <div className="resource-data">
- <div className="resource-data-container">
- <i className="pi pi-download"/>
- <span className="resource-data-container-number">下载量:{formatCount(resource?.downloads)}</span>
- </div>
- </div>
-
- {/*资源发布时间和更新时间*/}
- <div className="resource-time">
- <div className="resource-time-data">
- 发布时间:{resource?.uploadTime}
- </div>
- <div className="resource-time-data">
- 更新时间:{resource?.lastUpdateTime}
- </div>
- </div>
- </div>
- </div>
- {/*资源总结*/}
- <div className="resource-summary">
- {resource?.resourceSummary}
- </div>
- {/*关注作者、点赞、抽藏、购买资源*/}
- <div className="resource-operation">
- <div className="resource-author">
- <Avatar
- image={`${process.env.NEXT_PUBLIC_NGINX_URL}/users/${resourceAuthor?.avatar}`}
- shape="circle"
- style={{ width: "60px", height: "60px" }}
- />
- <span className="resource-author-name">{resourceAuthor?.username}</span>
-
- {handleSubscribe()}
- </div>
-
- <div className="resource-operation-detail">
- <div className="resource-operation-detail-data">
- <i
- className={isCollected ? "pi pi-star-fill" : "pi pi-star"}
- onClick={handleCollection}
- style={{
- cursor: 'pointer',
- fontSize: '30px',
- color: isCollected ? 'rgba(82, 102, 101, 1)' : 'inherit',
- transition: 'color 0.3s ease'
- }}
- />
- <span>{formatCount(collectionCount)}</span>
- </div>
-
-
-
- <div className="resource-operation-detail-data">
- {isLiked ? <SmilingFace
- theme="filled"
- size="30"
- fill="#526665"
- strokeWidth={5}
- onClick={handleLike}
- style={{ cursor: 'pointer' }}
- />
- : <SmilingFace
- theme="outline"
- size="30"
- fill="#526665"
- strokeWidth={5}
- onClick={handleLike}
- style={{ cursor: 'pointer' }}
- />
- }
- <span>{formatCount(likeCount)}</span>
- </div>
-
- <ButtonGroup >
- {isPurchase()}
- <Button label={"$" + resource?.price} style={{
- height:"44px", background:"rgba(82, 102, 101, 1)",
- borderStyle:"solid", borderWidth:"1px", borderColor:"rgba(82, 102, 101, 1)",
- borderRadius:"0 20px 20px 0", fontSize:"26px",
- }} disabled={true}/>
- </ButtonGroup>
- </div>
- </div>
- {/*资源详情*/}
- <div className="resource-detail">
- <h1 className="resource-detail-title">资源详情</h1>
- <div className="resource-detail-text">
- {resource?.resourceDetail}
- </div>
- </div>
- {/* 评论列表 */}
- <div className="comments-section">
- <div className="comments-header">
- <h2>评论 ({totalComments})</h2>
- <Link href="/community" className="no-underline">进入社区</Link>
- </div>
- <div className="comments-input">
- <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
- <InputText value={commentValue} placeholder="发布你的评论" onChange={(e) => setCommentValue(e.target.value)} />
- <Button label="发布评论" onClick={publishComment} disabled={!commentValue.trim()} />
- </div>
- <div className="comments-list">
- {comments.map((comment, index) => (
- <div key={comment.commentId} className="comment-item">
- <div className="comment-user">
- <Avatar
- image={comment.userId ? process.env.NEXT_PUBLIC_NGINX_URL + "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
- size="normal"
- shape="circle"
- />
- <div className="comment-meta">
- <span className="username">
- {comment.userId ? commentUserInfos.get(comment.userId)?.username : '匿名用户'}
- </span>
- <div className="comment-time">
- <span className="floor">#{first + index + 1}楼</span>
- <span className="time">{comment.createAt}</span>
- </div>
- </div>
- <i className='pi pi-ellipsis-v' onClick={(e) => ops.current[index].toggle(e)} />
- </div>
- <div className="comment-content">
- {<span className="reply-to">{getReplyUserName(comment.replyId)}</span>}
- <p>{comment.content}</p>
- </div>
- <OverlayPanel // 回调 ref:把实例放到 ops.current 对应的位置
- ref={el => {
- if (el) ops.current[index] = el;
- }}>
- <Button label="回复" text size="small" onClick={() => setVisibleReply(true)} />
- {comment.userId === 22301010 &&
- <Button
- label="删除"
- text
- size="small"
- onClick={() => { console.log('Deleting comment:', comment.commentId, 'by user:', comment.userId); deleteComment(comment.commentId) }}
- />
- }
- </OverlayPanel>
- <Sidebar className='reply' header={ReplyHeader} visible={visibleReply} position="bottom" onHide={() => setVisibleReply(false)}>
- <div className="reply-input">
- <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
- <InputText value={replyValue} placeholder="发布你的评论" onChange={(e) => setReplyValue(e.target.value)} />
- <Button label="发布评论" onClick={() => publishReply(comment.commentId)} disabled={!replyValue.trim()} />
- </div>
- </Sidebar>
- </div>
- ))}
- {totalComments > 5 && (<Paginator className="Paginator" first={first} rows={rows} totalRecords={totalComments} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />)}
- </div>
- </div>
-
- {/*用户购买资源弹窗*/}
- <Dialog
- header="购买资源"
- visible={visible}
- onHide={() => setVisible(false)}
- className="purchase-dialog"
- modal
- footer={
- <div className="dialog-footer">
- <Button label="购买" icon="pi pi-check" onClick={handlePurchase} autoFocus />
- <Button label="取消" icon="pi pi-times" onClick={() => setVisible(false)} className="p-button-text" />
- </div>
- }
- >
- <div className="form-text">
- 购买该资源需要{resource?.price}积分,是否购买?
- </div>
- </Dialog>
+ return (
+ <div className="resource-detail-container">
+ <Toast ref={toast}></Toast>
+ {/*资源标题*/}
+ <div className="resource-header">
+ {resource?.resourceName}
</div>
+ {/*资源详细信息*/}
+ <div className="resource-info">
+ <Image
+ src={(process.env.NEXT_PUBLIC_NGINX_URL! + resource?.resourcePicture)}
+ alt={resource?.resourceName}
+ width="540px"
+ height="300px"
+ />
+ <div className="resource-info-detail">
+ {/*资源热度*/}
+ <div className="resource-hot">
+ <Fire theme="outline" size="50" fill="#f5a623" strokeWidth={3} />
+ <span className="resource-hot-data">{resource?.hot}</span>
+ </div>
+
+ {/*资源标签*/}
+ <div className="resource-label">
+ {resource?.gameplayList.map((tag, index) => (
+ <Button
+ key={index} label={tag}
+ className="resource-label-button"
+ onClick={() => {
+ router.push(`/resource/classification/`)
+ }}
+ />
+ ))}
+ </div>
+
+ {/*资源浏览量和下载量*/}
+ <div className="resource-data">
+ <div className="resource-data-container">
+ <i className="pi pi-download" />
+ <span className="resource-data-container-number">下载量:{formatCount(resource?.downloads)}</span>
+ </div>
+ </div>
+
+ {/*资源发布时间和更新时间*/}
+ <div className="resource-time">
+ <div className="resource-time-data">
+ 发布时间:{resource?.uploadTime}
+ </div>
+ <div className="resource-time-data">
+ 更新时间:{resource?.lastUpdateTime}
+ </div>
+ </div>
+ </div>
+ </div>
+ {/*资源总结*/}
+ <div className="resource-summary">
+ {resource?.resourceSummary}
+ </div>
+ {/*关注作者、点赞、抽藏、购买资源*/}
+ <div className="resource-operation">
+ <div className="resource-author">
+ <Avatar
+ image={`${process.env.NEXT_PUBLIC_NGINX_URL}/users/${resourceAuthor?.avatar}`}
+ shape="circle"
+ style={{ width: "60px", height: "60px" }}
+ />
+ <span className="resource-author-name">{resourceAuthor?.username}</span>
+
+ {handleSubscribe()}
+ </div>
+
+ <div className="resource-operation-detail">
+ <div className="resource-operation-detail-data">
+ <i
+ className={isCollected ? "pi pi-star-fill" : "pi pi-star"}
+ onClick={handleCollection}
+ style={{
+ cursor: 'pointer',
+ fontSize: '30px',
+ color: isCollected ? 'rgba(82, 102, 101, 1)' : 'inherit',
+ transition: 'color 0.3s ease'
+ }}
+ />
+ <span>{formatCount(collectionCount)}</span>
+ </div>
+
+
+
+ <div className="resource-operation-detail-data">
+ {isLiked ? <SmilingFace
+ theme="filled"
+ size="30"
+ fill="#526665"
+ strokeWidth={5}
+ onClick={handleLike}
+ style={{ cursor: 'pointer' }}
+ />
+ : <SmilingFace
+ theme="outline"
+ size="30"
+ fill="#526665"
+ strokeWidth={5}
+ onClick={handleLike}
+ style={{ cursor: 'pointer' }}
+ />
+ }
+ <span>{formatCount(likeCount)}</span>
+ </div>
+
+ <ButtonGroup >
+ {isPurchase()}
+ <Button label={"$" + resource?.price} style={{
+ height: "44px", background: "rgba(82, 102, 101, 1)",
+ borderStyle: "solid", borderWidth: "1px", borderColor: "rgba(82, 102, 101, 1)",
+ borderRadius: "0 20px 20px 0", fontSize: "26px",
+ }} disabled={true} />
+ </ButtonGroup>
+ </div>
+ </div>
+ {/*资源详情*/}
+ <div className="resource-detail">
+ <h1 className="resource-detail-title">资源详情</h1>
+ <div className="resource-detail-text">
+ {resource?.resourceDetail}
+ </div>
+ </div>
+ {/* 评论列表 */}
+ <div className="comments-section">
+ <div className="comments-header">
+ <h2>评论 ({totalComments})</h2>
+ <Link href="/community" className="no-underline">进入社区</Link>
+ </div>
+ <div className="comments-input">
+ <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+ <InputText value={commentValue} placeholder="发布你的评论" onChange={(e) => setCommentValue(e.target.value)} />
+ <Button label="发布评论" onClick={publishComment} disabled={!commentValue.trim()} />
+ </div>
+ <div className="comments-list">
+ {comments.map((comment, index) => (
+ <div key={comment.commentId} className="comment-item">
+ <div className="comment-user">
+ <Avatar
+ image={comment.userId ? process.env.NEXT_PUBLIC_NGINX_URL + "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
+ size="normal"
+ shape="circle"
+ />
+ <div className="comment-meta">
+ <span className="username">
+ {comment.userId ? commentUserInfos.get(comment.userId)?.username : '匿名用户'}
+ </span>
+ <div className="comment-time">
+ <span className="floor">#{first + index + 1}楼</span>
+ <span className="time">{comment.createAt}</span>
+ </div>
+ </div>
+ <i className='pi pi-ellipsis-v' onClick={(e) => ops.current[index].toggle(e)} />
+ </div>
+ <div className="comment-content">
+ {<span className="reply-to">{getReplyUserName(comment.replyId)}</span>}
+ <p>{comment.content}</p>
+ </div>
+ <OverlayPanel // 回调 ref:把实例放到 ops.current 对应的位置
+ ref={el => {
+ if (el) ops.current[index] = el;
+ }}>
+ <Button label="回复" text size="small" onClick={() => setVisibleReply(true)} />
+ {comment.userId === userId &&
+ <Button
+ label="删除"
+ text
+ size="small"
+ onClick={() => { console.log('Deleting comment:', comment.commentId, 'by user:', comment.userId); deleteComment(comment.commentId) }}
+ />
+ }
+ </OverlayPanel>
+ <Sidebar className='reply' header={ReplyHeader} visible={visibleReply} position="bottom" onHide={() => setVisibleReply(false)}>
+ <div className="reply-input">
+ <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+ <InputText value={replyValue} placeholder="发布你的评论" onChange={(e) => setReplyValue(e.target.value)} />
+ <Button label="发布评论" onClick={() => publishReply(comment.commentId)} disabled={!replyValue.trim()} />
+ </div>
+ </Sidebar>
+ </div>
+ ))}
+ {totalComments > 5 && (<Paginator className="Paginator" first={first} rows={rows} totalRecords={totalComments} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />)}
+ </div>
+ </div>
+
+ {/*用户购买资源弹窗*/}
+ <Dialog
+ header="购买资源"
+ visible={visible}
+ onHide={() => setVisible(false)}
+ className="purchase-dialog"
+ modal
+ footer={
+ <div className="dialog-footer">
+ <Button label="购买" icon="pi pi-check" onClick={handlePurchase} autoFocus />
+ <Button label="取消" icon="pi pi-times" onClick={() => setVisible(false)} className="p-button-text" />
+ </div>
+ }
+ >
+ <div className="form-text">
+ 购买该资源需要{resource?.price}积分,是否购买?
+ </div>
+ </Dialog>
+ </div>
)
}
diff --git a/src/app/reward/page.tsx b/src/app/reward/page.tsx
index 59abf97..b53d93c 100644
--- a/src/app/reward/page.tsx
+++ b/src/app/reward/page.tsx
@@ -20,9 +20,12 @@
// 防抖函数
import { debounce } from 'lodash';
import { TabView, TabPanel } from 'primereact/tabview';
+import { useLocalStorage } from '../hook/useLocalStorage';
// 样式
import './reward.scss';
-
+interface User {
+ Id: number;
+}
// 悬赏列表数据
interface Reward {
rewardId: number;
@@ -41,6 +44,8 @@
// 社区详情页面
export default function RewardDetailPage() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
// 页面跳转
const router = useRouter();
// 帖子列表数据
@@ -106,7 +111,7 @@
try {
const currentDate = new Date().toISOString();
const postData = {
- userId: 22301145, // 记得用户登录状态获取
+ userId, // 记得用户登录状态获取
rewardPicture: formData.rewardPicture,
rewardName: formData.rewardName,
rewardDescription: formData.rewardDescription,
@@ -248,7 +253,7 @@
<FileUpload
mode="basic"
name="thread-image"
- url={process.env.PUBLIC_URL +"/file"} // 与后端交互的URL
+ url={process.env.PUBLIC_URL + "/file"} // 与后端交互的URL
accept="image/*"
maxFileSize={10000000000}
chooseLabel="选择悬赏封面"
diff --git "a/src/app/reward/reward-detail/\133rewardId\135/page.tsx" "b/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
index fb8f8b1..0ba1a04 100644
--- "a/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
+++ "b/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
@@ -16,9 +16,12 @@
import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
// 消息提醒
import { Toast } from 'primereact/toast';
+import { useLocalStorage } from '../../../hook/useLocalStorage';
// 样式
import './reward-detail.scss';
-
+interface User {
+ Id: number;
+}
// 评论信息
interface Comment {
@@ -69,6 +72,8 @@
//帖子详情界面
export default function RewardDetailPage() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
// 获取URL参数,页面跳转
const params = useParams<{ rewardId: string }>()
const rewardId = decodeURIComponent(params.rewardId); // 防止中文路径乱码
@@ -105,7 +110,7 @@
const fetchRewardInfo = async () => {
try {
- const { data } = await axios.get(process.env.PUBLIC_URL +`/reward/info?rewardId=${rewardId}`);
+ const { data } = await axios.get(process.env.PUBLIC_URL + `/reward/info?rewardId=${rewardId}`);
setRewardInfo(data);
} catch (err) {
console.error(err);
@@ -117,7 +122,7 @@
useEffect(() => {
if (!rewardInfo) return;
// 发帖人
- axios.get(process.env.PUBLIC_URL +`/user/info?userId=${rewardInfo.userId}`)
+ axios.get(process.env.PUBLIC_URL + `/user/info?userId=${rewardInfo.userId}`)
.then(res => setUserInfo(res.data))
.catch(console.error);
}, [rewardInfo]);
@@ -145,7 +150,7 @@
const pageNumber = first / rows + 1;
console.log("当前页" + pageNumber + "size" + rows);
const response = await axios.get<CommentList>(
- process.env.PUBLIC_URL +`/comments`, {
+ process.env.PUBLIC_URL + `/comments`, {
params: { id: rewardId, pageNumber, rows, type: 'reward' }
}
);
@@ -156,7 +161,7 @@
response.data.records.forEach(comment => {
if (comment.userId != null && !commentUserInfos.has(comment.userId)) {
axios.get<UserInfo>(
- process.env.PUBLIC_URL +`/user/info`,
+ process.env.PUBLIC_URL + `/user/info`,
{ params: { userId: comment.userId } }
).then(res => {
setCommentUserInfos(prev => new Map(prev).set(comment.userId!, res.data));
@@ -175,7 +180,7 @@
console.log('发布评论:', commentId);
try {
const newComment: NewComment = {
- userId: 22301145,
+ userId,
rewardId: rewardInfo.rewardId,
threadId: 0,
resourceId: 0,
@@ -184,7 +189,7 @@
createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
};
- const response = await axios.post(process.env.PUBLIC_URL +'/comment', newComment);
+ const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
if (response.status === 200) {
toast.current?.show({ severity: 'success', summary: 'Success', detail: '回复成功' });
@@ -206,7 +211,7 @@
try {
const newComment: NewComment = {
- userId: 22301145,
+ userId,
rewardId: rewardInfo.rewardId,
threadId: 0,
resourceId: 0,
@@ -215,7 +220,7 @@
createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
};
- const response = await axios.post(process.env.PUBLIC_URL +'/comment', newComment);
+ const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
if (response.status === 200) {
toast.current?.show({ severity: 'success', summary: 'Success', detail: '评论成功' });
@@ -237,7 +242,7 @@
try {
// 调用 DELETE 接口,URL 中最后一段是要删除的 commentId
const response = await axios.delete(
- process.env.PUBLIC_URL +`/comment?commentId=${commentId}`
+ process.env.PUBLIC_URL + `/comment?commentId=${commentId}`
);
if (response.status === 200) {
@@ -338,7 +343,7 @@
if (el) ops.current[index] = el;
}}>
<Button label="回复" text size="small" onClick={() => setVisibleReply(true)} />
- {comment.userId === 22301145 &&
+ {comment.userId === userId &&
<Button
label="删除"
text
diff --git a/src/app/user/component/userAvatar.tsx b/src/app/user/component/userAvatar.tsx
index 4ed94d7..a7e4802 100644
--- a/src/app/user/component/userAvatar.tsx
+++ b/src/app/user/component/userAvatar.tsx
@@ -18,11 +18,17 @@
import { Toast } from 'primereact/toast';
// 接口传输
import axios from 'axios';
+import { useLocalStorage } from '../../hook/useLocalStorage';
// 样式
import './user-avatar.scss';
-
+interface User {
+ Id: number;
+}
// 用户下拉框
export default function UserAvatar() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
+
// 功能选项
const op = useRef<OverlayPanel>(null);
let hoverTimeout: NodeJS.Timeout;
@@ -59,7 +65,7 @@
const editPassward = async () => {
try {
await axios.put(process.env.PUBLIC_URL + `/user/password`, {
- params: { userId: 22301145, password: oldPasswardValue, newPassword: passwardValue }
+ params: { userId, password: oldPasswardValue, newPassword: passwardValue }
});
toast.current?.show({ severity: 'success', summary: 'success', detail: '修改密码成功' });
setShowEditPassword(false);
@@ -72,7 +78,7 @@
const editSign = async () => {
try {
await axios.put(process.env.PUBLIC_URL + `/user/signature`, {
- params: { userId: 22301145, signature: signValue }
+ params: { userId, signature: signValue }
});
toast.current?.show({ severity: 'success', summary: 'success', detail: '修改签名成功' });
setShowEditSignature(false);
@@ -86,7 +92,7 @@
const editAvatar = async () => {
try {
await axios.put(process.env.PUBLIC_URL + `/user/avatar`, {
- params: { userId: 22301145, avatar: avatarUrl }
+ params: { userId, avatar: avatarUrl }
});
toast.current?.show({ severity: 'success', summary: 'success', detail: '修改头像成功' });
setShowEditAvatar(false);
diff --git a/src/app/user/manage/resources/page.tsx b/src/app/user/manage/resources/page.tsx
index e3b7301..4d0d03f 100644
--- a/src/app/user/manage/resources/page.tsx
+++ b/src/app/user/manage/resources/page.tsx
@@ -1,30 +1,33 @@
'use client';
-import React, {useEffect, useRef, useState} from 'react';
+import React, { useEffect, useRef, useState } from 'react';
// import {TabView, TabPanel} from "primereact/tabview";
-import {Card} from "primereact/card";
-import {Image} from "primereact/image";
-import {Button} from "primereact/button";
+import { Card } from "primereact/card";
+import { Image } from "primereact/image";
+import { Button } from "primereact/button";
// 弹窗
import { Dialog } from 'primereact/dialog';
-import {InputText} from "primereact/inputtext";
-import {InputTextarea} from "primereact/inputtextarea";
-import {FileUpload} from "primereact/fileupload";
+import { InputText } from "primereact/inputtext";
+import { InputTextarea } from "primereact/inputtextarea";
+import { FileUpload } from "primereact/fileupload";
// 类型转换
-import {toNumber} from "lodash";
+import { toNumber } from "lodash";
// 消息提醒
-import {Toast} from 'primereact/toast';
+import { Toast } from 'primereact/toast';
// 接口传输
import axios from "axios";
// 页面跳转
-import {useRouter} from "next/navigation";
+import { useRouter } from "next/navigation";
// 分页
import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
// 密码
import { Password } from 'primereact/password';
+import { useLocalStorage } from '../../../hook/useLocalStorage';
// 样式
import './resources.scss';
-
+interface User {
+ Id: number;
+}
// 用户发布的资源
interface Resource {
@@ -54,12 +57,15 @@
}
export default function UserManageResources() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
+
// 路由
const router = useRouter();
// 发布资源列表
const [resourceList, setResourceList] = useState<Resource[]>([]);
// 要删除资源的id
- const [deleteResourceId, setDeleteResourceId] = useState<number>(0);
+ const [deleteResourceId, setDeleteResourceId] = useState<number>(0);
// 资源封面路径
const [resourcePictureUrl, setResourcePictureUrl] = useState<string>('');
// 编辑资源的分类
@@ -100,7 +106,7 @@
try {
const pageNumber = first / rows + 1;
const response = await axios.get<ResourceList>(process.env.PUBLIC_URL + `/user/upload`, {
- params: {userId: 22301010, pageNumber: pageNumber, rows: rows}
+ params: { userId, pageNumber: pageNumber, rows: rows }
});
console.log('获取发布资源列表:', response.data.records);
@@ -108,7 +114,7 @@
setTotalResources(response.data.total);
} catch (err) {
console.error('获取发布资源失败', err);
- toast.current?.show({severity: 'error', summary: 'error', detail: '获取发布资源失败'});
+ toast.current?.show({ severity: 'error', summary: 'error', detail: '获取发布资源失败' });
}
};
@@ -117,20 +123,20 @@
try {
const deleteData = {
resourceId: deleteResourceId,
- userId: 223010100,
+ userId,
password: deleteResourceFormData.password,
};
// 发送DELETE请求
const response = await axios.delete(process.env.PUBLIC_URL + `/resource`, {
- params: {resourceId: deleteData.resourceId, userId: deleteData.userId, password: deleteData.password},
+ params: { resourceId: deleteData.resourceId, userId: deleteData.userId, password: deleteData.password },
});
- console.log("用户" + 22301010 + "要删除" + deleteData.resourceId + "号资源");
+ console.log("用户" + userId + "要删除" + deleteData.resourceId + "号资源");
console.log(deleteData);
if (response.status === 204) {
console.log("用户成功删除资源");
// setIsDeleteResource(true);
- toast.current?.show({severity: 'success', summary: 'Success', detail: '删除资源成功'});
+ toast.current?.show({ severity: 'success', summary: 'Success', detail: '删除资源成功' });
setDeleteVisible(false);
// 重置表单
setDeleteResourceFormData({
@@ -140,7 +146,7 @@
fetchResourceList();
} else {
console.log('用户密码错误');
- toast.current?.show({severity: 'error', summary: 'Error', detail: '密码错误,删除资源失败'});
+ toast.current?.show({ severity: 'error', summary: 'Error', detail: '密码错误,删除资源失败' });
}
} catch (error) {
@@ -187,10 +193,10 @@
<div className="resource-list">
{resourceList.map((resourceList) => (
<Card key={resourceList.resourceId} className="resources-list-card"
- onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}>
+ onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}>
<Image alt="avatar"
- src={process.env.NEXT_PUBLIC_NGINX_URL + "resource/" + resourceList.resourcePicture}
- className="resource-avatar" width="250" height="140"/>
+ src={process.env.NEXT_PUBLIC_NGINX_URL + "resource/" + resourceList.resourcePicture}
+ className="resource-avatar" width="250" height="140" />
<div className="resource-header">
<div className="resource-content">
<h3>{resourceList.resourceName}</h3>
@@ -202,7 +208,7 @@
onClick={(e) => {
e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
setEditVisible(true);
-
+
setResourceClassify(resourceList.classify);
setEditResourceFormData({
resourceId: resourceList.resourceId,
@@ -221,7 +227,7 @@
setDeleteResourceId(resourceList.resourceId);
setDeleteVisible(true);
}}
- style={{backgroundColor: "rgba(255, 87, 51, 1)"}}
+ style={{ backgroundColor: "rgba(255, 87, 51, 1)" }}
/>
</div>
</div>
@@ -295,7 +301,7 @@
value={editResourceFormData.resourceName}
onChange={(e) => setEditResourceFormData(prev => ({
...prev,
- resourceName: e.target.value
+ resourceName: e.target.value
}))}
className="w-full"
/>
@@ -309,7 +315,7 @@
value={editResourceFormData.resourceSummary}
onChange={(e) => setEditResourceFormData(prev => ({
...prev,
- resourceSummary: e.target.value
+ resourceSummary: e.target.value
}))}
className="w-full"
/>
@@ -323,7 +329,7 @@
value={editResourceFormData.resourceDetail}
onChange={(e) => setEditResourceFormData(prev => ({
...prev,
- resourceDetail: e.target.value
+ resourceDetail: e.target.value
}))}
rows={5}
className="w-full"
@@ -338,7 +344,7 @@
value={editResourceFormData?.price.toString()}
onChange={(e) => setEditResourceFormData(prev => ({
...prev,
- price: e.target.value
+ price: e.target.value
}))}
className="w-full"
/>
diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx
index 8201bc5..4baef17 100644
--- a/src/app/user/page.tsx
+++ b/src/app/user/page.tsx
@@ -5,12 +5,12 @@
import { Avatar } from 'primereact/avatar';
import { Button } from 'primereact/button';
import { Card } from 'primereact/card';
-import {Image} from "primereact/image";
+import { Image } from "primereact/image";
// 发布资源
import { Dialog } from 'primereact/dialog';
-import {InputText} from "primereact/inputtext";
-import {InputTextarea} from "primereact/inputtextarea";
-import {FileUpload} from "primereact/fileupload";
+import { InputText } from "primereact/inputtext";
+import { InputTextarea } from "primereact/inputtextarea";
+import { FileUpload } from "primereact/fileupload";
// 资源分类
import { RadioButton, RadioButtonChangeEvent } from "primereact/radiobutton";
// 资源标签
@@ -30,10 +30,14 @@
// 接口传输
import axios from "axios";
-
+import { useLocalStorage } from '../hook/useLocalStorage';
// 样式
import './user.scss';
+interface User {
+ Id: number;
+};
+
// 用户信息
interface UserInfo {
userId: number;
@@ -42,7 +46,7 @@
avatar: string;
followerCount: number;// 粉丝数
subscriberCount: number;// 关注数
- signature: string;// 个性签名
+ signature: string;// 个性签名
uploadAmount: number;
purchaseAmount: number;
credits: number;
@@ -50,9 +54,9 @@
// 用户数据
interface UserData {
- subscriberCount: number; // 关注数
- uploadAmount: number; // 上传量(资源个数)
- beDownloadedAmount: number; // 上传资源被下载量
+ subscriberCount: number; // 关注数
+ uploadAmount: number; // 上传量(资源个数)
+ beDownloadedAmount: number; // 上传资源被下载量
seedPercentageList: number[]; // 上传资源类型百分比列表,按材质包、模组、整合包、地图的顺序返回
}
@@ -60,17 +64,17 @@
interface Resource {
resourceId: number;
resourceName: string;
- resourcePicture: string;
- resourceSummary: string; // 资源简介(一句话)
+ resourcePicture: string;
+ resourceSummary: string; // 资源简介(一句话)
resourceDetail: string; // 资源介绍
uploadTime: string; // 上传时间
- lastUpdateTime: string; // 最近更新时间
- price: number;
- downloads: number;
- likes: number;
+ lastUpdateTime: string; // 最近更新时间
+ price: number;
+ downloads: number;
+ likes: number;
collections: number;
comments: number;
- seeds: number; // 种子数
+ seeds: number; // 种子数
classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
}
@@ -139,6 +143,9 @@
];
export default function UserPage() {
+ const user = useLocalStorage<User>('user');
+ const userId: number = user?.Id ?? -1;
+
// 路由
const router = useRouter();
// 发布资源列表
@@ -188,7 +195,7 @@
const fetchUserInfo = async () => {
try {
const response = await axios.get<UserInfo>(process.env.PUBLIC_URL + `/user/info`, {
- params: { userId: 22301010 }
+ params: { userId }
});
console.log('获取用户信息:', response.data);
setUserInfo(response.data);
@@ -202,7 +209,7 @@
const fetchUserData = async () => {
try {
const response = await axios.get<UserData>(process.env.PUBLIC_URL + `/user/data`, {
- params: { userId: 22301010 }
+ params: { userId }
});
console.log('获取用户数据:', response.data);
setUserData(response.data);
@@ -233,8 +240,8 @@
// 获取发布资源
const fetchResourceList = async () => {
try {
- const response = await axios.get<ResourceList>(process.env.PUBLIC_URL +`/user/upload`, {
- params: { userId: 22301010, pageNumber: 1, rows: 3 }
+ const response = await axios.get<ResourceList>(process.env.PUBLIC_URL + `/user/upload`, {
+ params: { userId, pageNumber: 1, rows: 3 }
});
console.log('获取发布资源列表:', response.data.records);
setResourceList(response.data.records);
@@ -307,22 +314,22 @@
const actions = [
{
template: () => (
- <Button label="管理资源" onClick={() => router.push(`/user/manage/resources/`)}/>
+ <Button label="管理资源" onClick={() => router.push(`/user/manage/resources/`)} />
)
},
{
template: () => (
- <Button label="已购资源" onClick={() => router.push(`/user/purchased-resources/`)}/>
+ <Button label="已购资源" onClick={() => router.push(`/user/purchased-resources/`)} />
)
},
{
template: () => (
- <Button label="发布资源" onClick={() => setVisible(true)}/>
+ <Button label="发布资源" onClick={() => setVisible(true)} />
)
},
{
template: () => (
- <Button label="编辑悬赏" onClick={() => router.push(`/user/manage/resources/`)}/>
+ <Button label="编辑悬赏" onClick={() => router.push(`/user/manage/resources/`)} />
)
}
];
@@ -456,7 +463,7 @@
},
gameplayList: resourceFormData.gameplayList,
completeRewardId: null,
- userId: 22301010, // 记得用户登录状态获取
+ userId, // 记得用户登录状态获取
};
// 发送POST请求
const response = await axios.post(process.env.PUBLIC_URL + '/resource', postData);
@@ -534,7 +541,7 @@
</div>
</div>
- <Button label="关注" className="action-button"/>
+ <Button label="关注" className="action-button" />
</div>
</div>