massive fix
Change-Id: I5972893fc44707bddab7d0014b981ac3097238d6
diff --git "a/src/app/community/community-detail/\133communityId\135/page.tsx" "b/src/app/community/community-detail/\133communityId\135/page.tsx"
index e366843..33011eb 100644
--- "a/src/app/community/community-detail/\133communityId\135/page.tsx"
+++ "b/src/app/community/community-detail/\133communityId\135/page.tsx"
@@ -142,12 +142,13 @@
const handleSubmit = async () => {
try {
const currentDate = new Date().toISOString();
+ console.log(formData);
const postData = {
userId, // 记得用户登录状态获取
threadPicture: formData.threadPicture,
title: formData.title,
content: formData.content,
- createdAt: currentDate,
+ createAt: currentDate.slice(0, 10),
communityId: communityId // 从URL参数获取的社区ID
};
// 发送POST请求
@@ -213,7 +214,7 @@
{threads.map((thread) => (
<Card key={thread.threadId} className="resource-card" onClick={() => router.push(`/community/thread-detail/${thread.threadId}`)}>
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + thread.threadPicture}
+ src={ thread.threadPicture}
alt={thread.title}
width="368"
height="200"
@@ -285,8 +286,9 @@
try {
const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
- const fileUrl = res.data.url;
+ const fileUrl = res.data;
console.log(fileUrl);
+ setFormData(prev => ({ ...prev, threadPicture: fileUrl }))
toast.current?.show({ severity: 'success', summary: '上传成功' });
} catch (error) {
console.log(error);
diff --git a/src/app/community/page.tsx b/src/app/community/page.tsx
index 81c8a6b..b24242a 100644
--- a/src/app/community/page.tsx
+++ b/src/app/community/page.tsx
@@ -106,7 +106,7 @@
width="24"
height="24"
/></div>
- <Image src={process.env.NEXT_PUBLIC_NGINX_URL + item.communityPicture} alt={item.communityName} height="200" className="w-full h-48 object-cover" />
+ <Image src={item.communityPicture} alt={item.communityName} height="200" className="w-full h-48 object-cover" />
</div>
}
>
@@ -165,7 +165,7 @@
<div className="all-communities-list">
{communities.map((community) => (
<Card key={community.communityId} className="all-communities-card" onClick={() => router.push(`/community/community-detail/${community.communityId}`)}>
- <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + community.communityPicture} className="community-avatar" width="250" height="140" />
+ <Image alt="avatar" src={ community.communityPicture} className="community-avatar" width="250" height="140" />
<div className="community-header">
<div className="community-content">
<h3>{community.communityName}</h3>
diff --git "a/src/app/community/resource-community-list/\133category\135/page.tsx" "b/src/app/community/resource-community-list/\133category\135/page.tsx"
index 16f6bd6..cb3e3b0 100644
--- "a/src/app/community/resource-community-list/\133category\135/page.tsx"
+++ "b/src/app/community/resource-community-list/\133category\135/page.tsx"
@@ -111,7 +111,7 @@
<div className="resource-communities-list">
{communities.map((community) => (
<Card key={community.communityId} className="resource-communities-list-card" onClick={() => router.push(`/community/community-detail/${community.communityId}`)}>
- <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + community.communityPicture} className="community-avatar" width="250" height="140" />
+ <Image alt="avatar" src={ community.communityPicture} className="community-avatar" width="250" height="140" />
<div className="community-header">
<div className="community-content">
<h3>{community.communityName}</h3>
diff --git "a/src/app/community/thread-detail/\133threadId\135/page.tsx" "b/src/app/community/thread-detail/\133threadId\135/page.tsx"
index 0f3e5b2..097c35a 100644
--- "a/src/app/community/thread-detail/\133threadId\135/page.tsx"
+++ "b/src/app/community/thread-detail/\133threadId\135/page.tsx"
@@ -59,9 +59,9 @@
// 新评论接口
interface NewComment {
userId: number;
- threadId: number;
- resourceId: number;
- replyId: number;
+ threadId: number | null;
+ resourceId: number | null;
+ replyId: number | null;
content: string;
createdAt: string;
}
@@ -139,7 +139,7 @@
try {
const response = await axios.post(
process.env.PUBLIC_URL + `/thread/like`, {
- params: { threadId, userId }
+ threadId, userId
}
);
fetchThreadInfo(); // 刷新帖子信息
@@ -194,7 +194,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 + `/comment`, {
params: { threadId, pageNumber, rows }
}
);
@@ -225,10 +225,10 @@
const newComment: NewComment = {
userId,
threadId: threadInfo.threadId,
- resourceId: 0,
+ resourceId: null,
replyId: commentId,
content: commentValue,
- createdAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+ createdAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
};
const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -255,10 +255,10 @@
const newComment: NewComment = {
userId,
threadId: threadInfo.threadId,
- resourceId: 0,
- replyId: 0, // 直接评论,不是回复
+ resourceId: null,
+ replyId: null, // 直接评论,不是回复
content: commentValue,
- createdAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+ createdAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
};
const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -310,7 +310,7 @@
{/* 帖子头部 */}
<div className="thread-header">
<div className="user-info">
- <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+ <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
<div className="user-meta">
<h3>{userInfo.username}</h3>
<span>{userInfo.signature}</span>
@@ -324,7 +324,7 @@
<h1>{threadInfo.title}</h1>
<div className="content-body">
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + threadInfo.threadPicture}
+ src={ threadInfo.threadPicture}
alt={threadInfo.title}
width="800"
height="400"
@@ -347,7 +347,7 @@
<h2>评论 ({totalComments})</h2>
</div>
<div className="comments-input">
- <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+ <Avatar image={ "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>
@@ -356,7 +356,7 @@
<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'}
+ image={comment.userId ? "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
size="normal"
shape="circle"
/>
@@ -391,7 +391,7 @@
</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" />
+ <Avatar image={ "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>
diff --git a/src/app/hook/useLocalStorage.ts b/src/app/hook/useLocalStorage.ts
index 2b28b01..7628f37 100644
--- a/src/app/hook/useLocalStorage.ts
+++ b/src/app/hook/useLocalStorage.ts
@@ -1,19 +1,51 @@
import { useEffect, useState } from 'react';
-export const useLocalStorage = <T>(key: string): T | null => {
- const [value, setValue] = useState<T | null>(null);
+// export const useLocalStorage = <T>(key: string): T | null => {
+// const [value, setValue] = useState<T | null>(null);
- useEffect(() => {
- if (typeof window !== 'undefined') {
+// useEffect(() => {
+// if (typeof window !== 'undefined') {
+// const item = localStorage.getItem(key);
+// if (item) {
+// try {
+// setValue(JSON.parse(item));
+// console.log(JSON.parse(item));
+// } catch (e) {
+// console.error(`解析 localStorage ${key} 失败`, e);
+// }
+// }
+// }
+// }, [key]);
+
+// return value;
+// };
+
+export const useLocalStorage = <T>(key: string): T | null => {
+ const isClient = typeof window !== 'undefined';
+ const [value, setValue] = useState<T | null>(() => {
+ if (isClient) {
const item = localStorage.getItem(key);
if (item) {
try {
- setValue(JSON.parse(item));
+ return JSON.parse(item);
} catch (e) {
console.error(`解析 localStorage ${key} 失败`, e);
}
}
}
+ return null;
+ });
+
+ useEffect(() => {
+ if (!isClient) return;
+ 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/page.tsx b/src/app/page.tsx
index 5076a0a..f3555da 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -233,7 +233,7 @@
className="custom-carousel"
itemTemplate={(hotResource) => (
<div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
- <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" />
+ <Image alt="slide" src={hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" />
</div>
)}
/>
@@ -288,7 +288,7 @@
{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}
+ src={mod.resourcePicture}
alt={mod.resourceName}
width="368"
height="200"
@@ -318,7 +318,7 @@
{maps.map((map) => (
<Card key={map.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${map.resourceId}`)}>
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + map.resourcePicture}
+ src={map.resourcePicture}
alt={map.resourceName}
width="368"
height="200"
@@ -348,7 +348,7 @@
{textures.map((texture) => (
<Card key={texture.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${texture.resourceId}`)}>
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + texture.resourcePicture}
+ src={texture.resourcePicture}
alt={texture.resourceName}
width="368"
height="200"
@@ -378,7 +378,7 @@
{modpacks.map((modpack) => (
<Card key={modpack.resourceId} className="resource-card" onClick={() => router.push(`/resource/${modpack.resourceId}`)}>
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + modpack.resourcePicture}
+ src={modpack.resourcePicture}
alt={modpack.resourceName}
width="368"
height="200"
diff --git a/src/app/resource/classification/page.tsx b/src/app/resource/classification/page.tsx
index f147ed2..ce9d43e 100644
--- a/src/app/resource/classification/page.tsx
+++ b/src/app/resource/classification/page.tsx
@@ -88,8 +88,8 @@
pageNumber,
rows,
classify: selectedClassify,
- gameplayList: selectedGameplay.join(','),
- versionList: selectedVersions.join(','),
+ gameplayList: selectedGameplay.join(',') ,
+ gameVersionList: selectedVersions.join(','),
searchValue
}
});
@@ -115,7 +115,7 @@
<div className="all-resources-list">
{hotResources.map((hotResource) => (
<Card key={hotResource.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
- <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
+ <Image alt="avatar" src={ "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
<div className="resource-header">
<div className="resource-content">
<h3>{hotResource.resourceName}</h3>
diff --git a/src/app/resource/hot-resource/page.tsx b/src/app/resource/hot-resource/page.tsx
index 4990638..57f1b26 100644
--- a/src/app/resource/hot-resource/page.tsx
+++ b/src/app/resource/hot-resource/page.tsx
@@ -216,7 +216,7 @@
className="custom-carousel"
itemTemplate={(hotResource) => (
<div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
- <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="480" height="350" />
+ <Image alt="slide" src={ hotResource.resourcePicture} className="carousel-avatar" width="480" height="350" />
<h3>{hotResource.resourceName}</h3>
</div>
)}
@@ -238,7 +238,7 @@
<div className="all-resources-list">
{hotResources.map((hotResource) => (
<Card key={hotResource.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
- <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
+ <Image alt="avatar" src={ "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
<div className="resource-header">
<div className="resource-content">
<h3>{hotResource.resourceName}</h3>
diff --git "a/src/app/resource/resource-detail/\133resourceId\135/page.tsx" "b/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
index 5e0a634..22abfdb 100644
--- "a/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
+++ "b/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
@@ -61,7 +61,6 @@
likes: number; // 点赞数
collections: number; // 收藏数
comments: number; // 评论数
- seeds: number; // 种子数
classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
hot: number; // 资源热度
gameplayList: string[]; // 资源标签
@@ -70,7 +69,7 @@
isLike: boolean; // 是否被点赞
isPurchase: boolean; // 是否被购买
isUpload: boolean; // 是否是该用户上传的
- userId: number; // 资源上传者的id
+ uploaderId: number; // 资源上传者的id
}
// 评论信息
@@ -99,10 +98,10 @@
// 新评论接口
interface NewComment {
userId: number;
- threadId: number;
- resourceId: number;
- rewardId: number;
- replyId: number;
+ threadId: number | null;
+ resourceId: number | null;
+ rewardId: number | null;
+ replyId: number | null;
content: string;
createAt: string;
}
@@ -131,7 +130,7 @@
const userId: number = user?.Id ?? -1;
// 获取URL参数
const params = useParams<{ resourceId: string }>();
- const resourceId = decodeURIComponent(params.resourceId); // 防止中文路径乱码
+ const resourceId = Number(decodeURIComponent(params.resourceId)); // 防止中文路径乱码
// 页面跳转
const router = useRouter();
@@ -198,7 +197,7 @@
setCollectionCount(response.data.collections);
}
- setResourceAuthorId(response.data.userId);
+ setResourceAuthorId(response.data.uploaderId);
} catch (err) {
console.error('获取资源信息失败', err);
toast.current?.show({ severity: 'error', summary: 'error', detail: "获取资源信息失败" });
@@ -246,9 +245,9 @@
}
useEffect(() => {
- if (!resource?.userId || !subscriberList?.userList) return;
+ if (!resource?.uploaderId || !subscriberList?.userList) return;
- const authorId = resource.userId;
+ const authorId = resource.uploaderId;
// 设置 isSubscribed 状态
const subscribed = subscriberList.userList.some(user => user.userId === authorId);
setIsSubscribed(subscribed);
@@ -257,7 +256,7 @@
// 若浏览用户与资源作者是同一人,则不显示关注按钮。若不是同一人,则显示按钮
const handleSubscribe = () => {
// 资源作者 ID
- const authorId = resource?.userId;
+ const authorId = resource?.uploaderId;
// 当前登录用户 ID
const currentUserId = userId;
@@ -340,7 +339,7 @@
// 判断该资源是否已被购买, 返回不同的购买按钮
const isPurchase = () => {
// 作者本人查看资源,不显示购买按钮
- if (resource?.userId == userId) {
+ if (resource?.uploaderId == userId) {
return;
}
@@ -405,7 +404,7 @@
if (newCollectionState) {
// 收藏操作
await axios.post(process.env.PUBLIC_URL + `/resource/collection`, {
- params: { resourceId: resourceId, userId }
+ resourceId: resourceId, userId
});
console.log('收藏资源');
} else {
@@ -442,7 +441,7 @@
if (newLikeState) {
// 点赞操作
await axios.post(process.env.PUBLIC_URL + `/resource/like`, {
- params: { resourceId: resourceId, userId }
+ resourceId: resourceId, userId
});
console.log('点赞资源');
} else {
@@ -488,7 +487,7 @@
useEffect(() => {
if (!resource) return;
// 发帖人
- axios.get(process.env.PUBLIC_URL + `/user/info?userId=${resource?.userId}`)
+ axios.get(process.env.PUBLIC_URL + `/user/info?userId=${resource?.uploaderId}`)
.then(res => setUserInfo(res.data))
.catch(console.error);
}, [resource]);
@@ -515,7 +514,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 + `/comment`, {
params: { id: resourceId, pageNumber, rows, type: 'resource' }
}
);
@@ -547,12 +546,12 @@
try {
const newComment: NewComment = {
userId,
- rewardId: 0,
- threadId: 0,
+ rewardId: null,
+ threadId: null,
resourceId: resource.resourceId,
replyId: commentId,
content: commentValue,
- createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+ createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
};
const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -578,12 +577,12 @@
try {
const newComment: NewComment = {
userId,
- rewardId: 0,
- threadId: 0,
+ rewardId: null,
+ threadId: null,
resourceId: resource.resourceId,
- replyId: 0, // 直接评论,不是回复
+ replyId: null, // 直接评论,不是回复
content: commentValue,
- createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+ createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
};
const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -763,7 +762,7 @@
<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" />
+ <Avatar image={ "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>
@@ -772,7 +771,7 @@
<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'}
+ image={comment.userId ? "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
size="normal"
shape="circle"
/>
@@ -807,7 +806,7 @@
</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" />
+ <Avatar image={ "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>
diff --git a/src/app/reward/page.tsx b/src/app/reward/page.tsx
index b53d93c..99d00ec 100644
--- a/src/app/reward/page.tsx
+++ b/src/app/reward/page.tsx
@@ -166,7 +166,7 @@
<div className="rewards-list">
{rewards.map((reward) => (
<Card key={reward.rewardId} className="rewards-list-card" onClick={() => router.push(`/reward/reward-detail/${reward.rewardId}`)}>
- <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "rewards/" + reward.rewardPicture} className="reward-avatar" width="250" height="140" />
+ <Image alt="avatar" src={ "rewards/" + reward.rewardPicture} className="reward-avatar" width="250" height="140" />
<div className="reward-header">
<div className="reward-content">
<h3>{reward.rewardName}</h3>
@@ -185,7 +185,7 @@
<div className="rewards-list">
{rewards.map((reward) => (
<Card key={reward.rewardId} className="rewards-list-card" onClick={() => router.push(`/reward/reward-detail/${reward.rewardId}`)}>
- <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + reward.rewardPicture} className="reward-avatar" width="250" height="140" />
+ <Image alt="avatar" src={ reward.rewardPicture} className="reward-avatar" width="250" height="140" />
<div className="reward-header">
<div className="reward-content">
<h3>{reward.rewardName}</h3>
diff --git "a/src/app/reward/reward-detail/\133rewardId\135/page.tsx" "b/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
index 0ba1a04..6c7b5bd 100644
--- "a/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
+++ "b/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
@@ -61,10 +61,10 @@
// 新评论接口
interface NewComment {
userId: number;
- threadId: number;
- resourceId: number;
- rewardId: number;
- replyId: number;
+ threadId: number | null;
+ resourceId: number | null;
+ rewardId: number | null;
+ replyId: number | null;
content: string;
createAt: string;
}
@@ -150,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 + `/comment`, {
params: { id: rewardId, pageNumber, rows, type: 'reward' }
}
);
@@ -182,11 +182,11 @@
const newComment: NewComment = {
userId,
rewardId: rewardInfo.rewardId,
- threadId: 0,
- resourceId: 0,
+ threadId: null,
+ resourceId: null,
replyId: commentId,
content: commentValue,
- createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+ createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
};
const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -213,11 +213,11 @@
const newComment: NewComment = {
userId,
rewardId: rewardInfo.rewardId,
- threadId: 0,
- resourceId: 0,
- replyId: 0, // 直接评论,不是回复
+ threadId: null,
+ resourceId: null,
+ replyId: null, // 直接评论,不是回复
content: commentValue,
- createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+ createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
};
const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -276,7 +276,7 @@
<div className="reward-content">
<div className="reward-info-container">
<div className="user-info">
- <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+ <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
<div className="user-meta">
<h3>{userInfo.username}</h3>
<span>{userInfo.signature}</span>
@@ -293,7 +293,7 @@
{/* 右侧图片+价格+按钮 */}
<div className="reward-media">
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + "rewards/" + rewardInfo.rewardPicture}
+ src={ "rewards/" + rewardInfo.rewardPicture}
alt={rewardInfo.rewardName}
width="500"
height="400"
@@ -310,7 +310,7 @@
<h2>评论 ({totalComments})</h2>
</div>
<div className="comments-input">
- <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+ <Avatar image={ "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>
@@ -319,7 +319,7 @@
<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'}
+ image={comment.userId ? "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
size="normal"
shape="circle"
/>
@@ -354,7 +354,7 @@
</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" />
+ <Avatar image={ "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>
diff --git a/src/app/search/page.tsx b/src/app/search/page.tsx
index 5f6642b..65d2465 100644
--- a/src/app/search/page.tsx
+++ b/src/app/search/page.tsx
@@ -81,7 +81,7 @@
<Card key={item.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${item.resourceId}`)}>
{/* 左侧图片 */}
<Image
- src={process.env.NEXT_PUBLIC_NGINX_URL + item.resourcePicture}
+ src={ item.resourcePicture}
alt={item.resourceName}
width="250" height="140"
preview
diff --git a/src/app/user/component/userAvatar.tsx b/src/app/user/component/userAvatar.tsx
index ba164de..abc1b66 100644
--- a/src/app/user/component/userAvatar.tsx
+++ b/src/app/user/component/userAvatar.tsx
@@ -1,111 +1,159 @@
-'use client';
+"use client";
-import { useRef, useState } from 'react';
-import { Avatar } from 'primereact/avatar';
-import { Button } from 'primereact/button';
+import { useRef, useState } from "react";
+import { Avatar } from "primereact/avatar";
+import { Button } from "primereact/button";
// 弹窗
-import { Dialog } from 'primereact/dialog';
+import { Dialog } from "primereact/dialog";
// 头像下拉框
-import { OverlayPanel } from 'primereact/overlaypanel';
+import { OverlayPanel } from "primereact/overlaypanel";
// 输入框
import { FloatLabel } from "primereact/floatlabel";
-import { InputText } from 'primereact/inputtext';
+import { InputText } from "primereact/inputtext";
// 页面跳转
-import Link from 'next/link';
+import Link from "next/link";
// 文件上传
-import { FileUpload } from 'primereact/fileupload';
+import { FileUpload } from "primereact/fileupload";
// 通知
-import { Toast } from 'primereact/toast';
+import { Toast } from "primereact/toast";
// 接口传输
-import axios from 'axios';
-import { useLocalStorage } from '../../hook/useLocalStorage';
+import axios from "axios";
+import { useLocalStorage } from "../../hook/useLocalStorage";
// 样式
-import './user-avatar.scss';
+import "./user-avatar.scss";
+
interface User {
- Id: number;
+ Id: number;
+ Avatar: string,
}
+
// 用户下拉框
export default function UserAvatar() {
- const user = useLocalStorage<User>('user');
- const userId: number = user?.Id ?? -1;
+ const user = useLocalStorage<User>("user");
+ const userId: number = user?.Id ?? -1;
+ // 功能选项
+ const op = useRef<OverlayPanel>(null);
+ let hoverTimeout: NodeJS.Timeout;
+ // 通知
+ const toast = useRef<Toast>(null);
+ // 控制三个弹窗可见性
+ const [showEditSignature, setShowEditSignature] = useState(false);
+ const [showEditAvatar, setShowEditAvatar] = useState(false);
+ const [showEditPassword, setShowEditPassword] = useState(false);
+ // 头像URL
+ const [avatarUrl, setAvatar] = useState<string>("");
+ // 签名
+ const [signValue, setSignValue] = useState<string>("");
+ // 新密码
+ const [passwardValue, setPasswardValue] = useState<string>("");
+ const [newPasswardValue, setNewPasswardValue] = useState<string>("");
+ // 老密码
+ const [oldPasswardValue, setOldPasswardValue] = useState<string>("");
- // 功能选项
- const op = useRef<OverlayPanel>(null);
- let hoverTimeout: NodeJS.Timeout;
- // 通知
- const toast = useRef<Toast>(null);
- // 控制三个弹窗可见性
- const [showEditSignature, setShowEditSignature] = useState(false);
- const [showEditAvatar, setShowEditAvatar] = useState(false);
- const [showEditPassword, setShowEditPassword] = useState(false);
- // 头像URL
- const [avatarUrl, setAvatar] = useState<string>('');
- // 签名
- const [signValue, setSignValue] = useState<string>('');
- // 新密码
- const [passwardValue, setPasswardValue] = useState<string>('');
- const [newPasswardValue, setNewPasswardValue] = useState<string>('');
- // 老密码
- const [oldPasswardValue, setOldPasswardValue] = useState<string>('');
+ const handleMouseEnter = (event: React.MouseEvent) => {
+ clearTimeout(hoverTimeout);
+ op.current?.show(event, event.currentTarget);
+ };
+ const handleMouseLeave = () => {
+ hoverTimeout = setTimeout(() => {
+ op.current?.hide();
+ }, 300);
+ };
- const handleMouseEnter = (event: React.MouseEvent) => {
- clearTimeout(hoverTimeout);
- op.current?.show(event, event.currentTarget);
- };
-
- const handleMouseLeave = () => {
- hoverTimeout = setTimeout(() => {
- op.current?.hide();
- }, 300);
- };
-
-
- // 修改密码接口
- const editPassward = async () => {
- try {
- await axios.put(process.env.PUBLIC_URL + `/user/password`, {
- params: { userId, password: oldPasswardValue, newPassword: passwardValue }
- });
- toast.current?.show({ severity: 'success', summary: 'success', detail: '修改密码成功' });
- setShowEditPassword(false);
- } catch (err) {
- console.error('修改密码失败', err);
- toast.current?.show({ severity: 'error', summary: 'error', detail: '修改密码失败' });
- }
+ // 修改密码接口
+ const editPassward = async () => {
+ try {
+ await axios.put(process.env.PUBLIC_URL + `/user/password`, {
+ body: {
+ userId,
+ password: oldPasswardValue,
+ newPassword: passwardValue,
+ },
+ });
+ toast.current?.show({
+ severity: "success",
+ summary: "success",
+ detail: "修改密码成功",
+ });
+ setShowEditPassword(false);
+ } catch (err) {
+ console.error("修改密码失败", err);
+ toast.current?.show({
+ severity: "error",
+ summary: "error",
+ detail: "修改密码失败",
+ });
}
- // 修改签名接口
- const editSign = async () => {
- try {
- await axios.put(process.env.PUBLIC_URL + `/user/signature`, {
- params: { userId, signature: signValue }
- });
- toast.current?.show({ severity: 'success', summary: 'success', detail: '修改签名成功' });
- setShowEditSignature(false);
- } catch (err) {
- console.error('修改签名失败', err);
- toast.current?.show({ severity: 'error', summary: 'error', detail: '修改签名失败' });
- }
- }
+ };
- // 修改头像接口
- const editAvatar = async () => {
- try {
- await axios.put(process.env.PUBLIC_URL + `/user/avatar`, {
- params: { userId, avatar: avatarUrl }
- });
- toast.current?.show({ severity: 'success', summary: 'success', detail: '修改头像成功' });
- setShowEditAvatar(false);
- } catch (err) {
- console.error('修改头像失败', err);
- toast.current?.show({ severity: 'error', summary: 'error', detail: '修改头像失败' });
- }
+ // 修改签名接口
+ const editSign = async () => {
+ try {
+ await axios.put(process.env.PUBLIC_URL + `/user/signature`, {
+ params: { userId, signature: signValue },
+ });
+ toast.current?.show({
+ severity: "success",
+ summary: "success",
+ detail: "修改签名成功",
+ });
+ setShowEditSignature(false);
+ } catch (err) {
+ console.error("修改签名失败", err);
+ toast.current?.show({
+ severity: "error",
+ summary: "error",
+ detail: "修改签名失败",
+ });
}
- return (
+ };
+
+ // 修改头像接口
+ const editAvatar = async () => {
+ try {
+ await axios.put(process.env.PUBLIC_URL + `/user/avatar`, {
+ userId,
+ avatar: avatarUrl,
+ });
+ toast.current?.show({
+ severity: "success",
+ summary: "success",
+ detail: "修改头像成功",
+ });
+ setAvatar(avatarUrl);
+ setShowEditAvatar(false);
+ localStorage.setItem("user", JSON.stringify({...user, Avatar: avatarUrl}))
+ } catch (err) {
+ console.error("修改头像失败", err);
+ toast.current?.show({
+ severity: "error",
+ summary: "error",
+ detail: "修改头像失败",
+ });
+ }
+ };
+ return (
+ <div
+ onMouseEnter={handleMouseEnter}
+ onMouseLeave={handleMouseLeave}
+ className="user-avatar-wrapper"
+ >
+ <Toast ref={toast}></Toast>
+ <Link href="/user" className="no-underline">
+ <Avatar
+ image={useLocalStorage<User>("user")?.Avatar}
+ size="large"
+ shape="circle"
+ className="user-avatar-link"
+ />
+ </Link>
+
+ <OverlayPanel ref={op} dismissable={false}>
<div
- onMouseEnter={handleMouseEnter}
- onMouseLeave={handleMouseLeave}
- className="user-avatar-wrapper"
+ onMouseEnter={() => clearTimeout(hoverTimeout)}
+ onMouseLeave={handleMouseLeave}
+ className="user-overlay-panel"
>
<Toast ref={toast}></Toast>
<Link href="/user" className="no-underline">
@@ -199,7 +247,7 @@
try {
const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
- const fileUrl = res.data.url;
+ const fileUrl = res.data;
console.log(fileUrl);
setAvatar(fileUrl);
toast.current?.show({ severity: 'success', summary: '上传成功' });
@@ -283,6 +331,179 @@
</div>
</Dialog>
</div>
- );
+ </OverlayPanel>
+ {/* 修改签名弹窗 */}
+ <Dialog
+ header="修改签名"
+ visible={showEditSignature}
+ style={{ width: "30vw" }}
+ onHide={() => {
+ setSignValue("");
+ setShowEditSignature(false);
+ }}
+ modal
+ >
+ <div className="dialog-container">
+ <div className="dialog-input-group">
+ <FloatLabel>
+ <InputText
+ id="username"
+ value={signValue}
+ onChange={(e) => setSignValue(e.target.value)}
+ />
+ <label htmlFor="username">个性签名</label>
+ </FloatLabel>
+ </div>
+ <div className="dialog-button-group">
+ <Button
+ label="确定"
+ className="p-button-sm"
+ onClick={() => editSign()}
+ />
+ <Button
+ label="取消"
+ className="p-button-secondary p-button-sm"
+ onClick={() => {
+ setSignValue("");
+ setShowEditSignature(false);
+ }}
+ />
+ </div>
+ </div>
+ </Dialog>
+
+ {/* 修改头像弹窗 */}
+ <Dialog
+ header="修改头像"
+ visible={showEditAvatar}
+ style={{ display: "flex", flexDirection: "column", width: "30vw" }}
+ onHide={() => {
+ setAvatar("");
+ setShowEditAvatar(false);
+ }}
+ modal
+ >
+ <div className="dialog-container">
+ <FileUpload
+ mode="advanced"
+ name="file"
+ 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;
+ console.log(fileUrl);
+ setAvatar(fileUrl);
+ toast.current?.show({
+ severity: "success",
+ summary: "上传成功",
+ });
+ } catch (error) {
+ console.log(error);
+ toast.current?.show({ severity: "error", summary: "上传失败" });
+ }
+ }}
+ auto
+ accept="image/*"
+ chooseLabel="上传头像"
+ />
+
+ <div className="dialog-button-group">
+ <Button
+ label="确定"
+ className="p-button-sm"
+ onClick={() => editAvatar()}
+ />
+ <Button
+ label="取消"
+ className="p-button-secondary p-button-sm"
+ onClick={() => setShowEditAvatar(false)}
+ />
+ </div>
+ </div>
+ </Dialog>
+
+ {/* 修改密码弹窗 */}
+ <Dialog
+ header="修改密码"
+ visible={showEditPassword}
+ style={{ width: "30vw" }}
+ onHide={() => {
+ setOldPasswardValue("");
+ setPasswardValue("");
+ setNewPasswardValue("");
+ setShowEditPassword(false);
+ }}
+ modal
+ >
+ <div className="dialog-container">
+ <div className="dialog-input-group">
+ <FloatLabel>
+ <InputText
+ id="username"
+ value={oldPasswardValue}
+ onChange={(e) => setOldPasswardValue(e.target.value)}
+ />
+ <label htmlFor="username">输入旧密码</label>
+ </FloatLabel>
+ </div>
+ <div className="dialog-input-group">
+ <FloatLabel>
+ <InputText
+ id="username"
+ value={passwardValue}
+ onChange={(e) => setPasswardValue(e.target.value)}
+ />
+ <label htmlFor="username">更新密码</label>
+ </FloatLabel>
+ </div>
+ <div className="dialog-input-group">
+ <FloatLabel>
+ <InputText
+ id="username"
+ value={newPasswardValue}
+ onChange={(e) => setNewPasswardValue(e.target.value)}
+ />
+ <label htmlFor="username">确认密码</label>
+ </FloatLabel>
+ </div>
+ <div className="dialog-button-group">
+ <Button
+ label="确定"
+ className="p-button-sm"
+ onClick={() => {
+ if (passwardValue !== newPasswardValue) {
+ toast.current?.show({
+ severity: "warn",
+ summary: "两次密码不一致",
+ detail: "请确保新密码和确认密码一致",
+ });
+ return;
+ } else {
+ editPassward();
+ }
+ }}
+ />
+ <Button
+ label="取消"
+ className="p-button-secondary p-button-sm"
+ onClick={() => {
+ setOldPasswardValue("");
+ setPasswardValue("");
+ setNewPasswardValue("");
+ setShowEditPassword(false);
+ }}
+ />
+ </div>
+ </div>
+ </Dialog>
+ </div>
+ );
}
diff --git a/src/app/user/manage/resources/page.tsx b/src/app/user/manage/resources/page.tsx
index 4d0d03f..0bfa184 100644
--- a/src/app/user/manage/resources/page.tsx
+++ b/src/app/user/manage/resources/page.tsx
@@ -195,7 +195,7 @@
<Card key={resourceList.resourceId} className="resources-list-card"
onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}>
<Image alt="avatar"
- src={process.env.NEXT_PUBLIC_NGINX_URL + "resource/" + resourceList.resourcePicture}
+ src={ "resource/" + resourceList.resourcePicture}
className="resource-avatar" width="250" height="140" />
<div className="resource-header">
<div className="resource-content">
diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx
index d534cd5..986f6ec 100644
--- a/src/app/user/page.tsx
+++ b/src/app/user/page.tsx
@@ -508,7 +508,7 @@
{/*个人信息*/}
<div className="user-profile-card">
<Avatar
- image={`${process.env.NEXT_PUBLIC_NGINX_URL}/users/${userInfo?.avatar}`}
+ image={userInfo?.avatar}
className="user-avatar"
shape="circle"
/>
@@ -560,7 +560,7 @@
{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}
+ src={ resourceList.resourcePicture}
alt={resourceList.resourceName}
width="368"
height="200"
@@ -591,7 +591,7 @@
{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}
+ src={ homePageThread.threadPicture}
alt={homePageThread.title}
width="368"
height="200"
@@ -619,7 +619,7 @@
{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}
+ src={ threadList.threadPicture}
alt={threadList.title}
width="368"
height="200"
@@ -663,7 +663,7 @@
<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}
+ src={ "rewards/" + rewardItem.rewardPicture}
className="resource-avatar" width="250" height="140"/>
<div className="resource-header">
<div className="resource-content">