实现用户主页帖子的展示和帖子页的展示,但首页的帖子未能展示

main
Hacker-00001 4 weeks ago
parent b006059b41
commit 60ed9daa67

@ -1,36 +1,36 @@
##本地开发环境 ###本地开发环境
lj:
db:
host: 192.168.59.129
password: Forely123!
redis:
host: 192.168.59.129
port: 6379
password: Forely123!
rabbitmq:
host: 192.168.59.129
port: 5672
username: admin
password: Forely123!
minio:
endpoint: http://192.168.59.129:9000
accessKey: forely
secretKey: Forely123!
#lj: #lj:
# db: # db:
# host: 192.168.125.128 # host: 192.168.59.129
# password: MySQL@5678 # password: Forely123!
# redis: # redis:
# host: 192.168.125.128 # host: 192.168.59.129
# port: 6379 # port: 6379
# password: Redis@9012 # password: Forely123!
# rabbitmq: # rabbitmq:
# host: 192.168.125.128 # host: 192.168.59.129
# port: 5672 # port: 5672
# username: rabbit_admin # username: admin
# password: Rabbit@3456 # password: Forely123!
# minio: # minio:
# endpoint: http://192.168.125.128:9000 # endpoint: http://192.168.59.129:9000
# accessKey: minio_admin # accessKey: forely
# secretKey: Minio@1234 # secretKey: Forely123!
lj:
db:
host: 192.168.125.128
password: MySQL@5678
redis:
host: 192.168.125.128
port: 6379
password: Redis@9012
rabbitmq:
host: 192.168.125.128
port: 5672
username: rabbit_admin
password: Rabbit@3456
minio:
endpoint: http://192.168.125.128:9000
accessKey: minio_admin
secretKey: Minio@1234

@ -8,7 +8,7 @@ export const usePostDetailStore = defineStore("postDetail", {
comments: [], // 评论列表 comments: [], // 评论列表
userInfo: null, // 用户信息 userInfo: null, // 用户信息
isLike: false, // 是否点赞 isLike: false, // 是否点赞
lastVal: 0, // 用于滚动分页的时间戳 lastVal: Date.now(), // 用于滚动分页的时间戳
offset: 0, // 偏移量 offset: 0, // 偏移量
size: 5, // 每页评论数 size: 5, // 每页评论数
detailLoading: false, // 加载状态 detailLoading: false, // 加载状态
@ -104,14 +104,12 @@ export const usePostDetailStore = defineStore("postDetail", {
commentObj.repliesLoading = false; commentObj.repliesLoading = false;
} }
}, },
async fetchPostDetail(postId) { async fetchPostDetail(postId) {
this.detailLoading = true; this.detailLoading = true;
try { try {
// 获取帖子详情 // 获取帖子详情
const RequestPostDetailData = { const postRes = await request.get('/post/detail', { params: { id: postId } });
id: postId,
};
const postRes = await request.get('/post/detail/', RequestPostDetailData);
if (postRes.code === 200 && postRes.data) { if (postRes.code === 200 && postRes.data) {
const { const {
id, id,

@ -1,11 +1,11 @@
<template> <template>
<div class="post-detail-container"> <div class="post-detail-container">
<!-- 作者信息栏可保留或移除 --> <!-- 作者信息栏 -->
<div class="author-info"> <div class="author-info" v-if="author && author.userName">
<img :src="author.userAvatar" alt="头像" class="author-avatar" /> <img :src="author.userAvatar || require('@/assets/default-avatar/boy_1.png')" alt="头像" class="author-avatar" />
<div class="author-details"> <div class="author-details">
<h3 class="author-name">{{ author.userName }}</h3> <h3 class="author-name">{{ author.userName || '匿名用户' }}</h3>
<p class="author-stats">粉丝数{{ author.followers }}</p> <p class="author-stats">粉丝数{{ author.followers ?? 0 }}</p>
<button @click="toggleFollow" class="follow-button"> <button @click="toggleFollow" class="follow-button">
{{ isFollowing ? '取消关注' : '关注' }} {{ isFollowing ? '取消关注' : '关注' }}
</button> </button>
@ -14,9 +14,9 @@
<!-- 帖子内容 --> <!-- 帖子内容 -->
<div class="post-content"> <div class="post-content">
<img :src="author.userAvatar" alt="作者头像" class="post-author-avatar" /> <img :src="author?.userAvatar || require('@/assets/default-avatar/boy_1.png')" alt="作者头像" class="post-author-avatar" />
<h1 class="post-title">{{ postDetailStore.post?.title }}</h1> <h1 class="post-title">{{ postDetailStore.post?.title || '' }}</h1>
<p class="post-body">{{ postDetailStore.post?.content }}</p> <p class="post-body">{{ postDetailStore.post?.content || '' }}</p>
<div class="post-stats"> <div class="post-stats">
<span> 热度 {{ postDetailStore.post?.likeCount ?? 0 }}</span> <span> 热度 {{ postDetailStore.post?.likeCount ?? 0 }}</span>
<span> 点赞 {{ postDetailStore.post?.favoriteCount ?? 0 }}</span> <span> 点赞 {{ postDetailStore.post?.favoriteCount ?? 0 }}</span>
@ -34,25 +34,25 @@
<li v-for="comment in postDetailStore.comments" :key="comment.id" class="comment-item"> <li v-for="comment in postDetailStore.comments" :key="comment.id" class="comment-item">
<img :src="comment.userAvatar || require('@/assets/default-avatar/boy_1.png')" alt="评论者头像" class="comment-avatar" /> <img :src="comment.userAvatar || require('@/assets/default-avatar/boy_1.png')" alt="评论者头像" class="comment-avatar" />
<div class="comment-content"> <div class="comment-content">
<p class="comment-name">{{ comment.userName }}</p> <p class="comment-name">{{ comment.userName || '匿名用户' }}</p>
<p class="comment-text">{{ comment.content }}</p> <p class="comment-text">{{ comment.content || '' }}</p>
<div class="comment-meta"> <div class="comment-meta">
<span class="comment-time">{{ comment.createTime ? formatTime(comment.createTime) : '' }}</span> <span class="comment-time">{{ comment.createTime ? formatTime(comment.createTime) : '' }}</span>
<span class="comment-likes"> {{ comment.likeCount ?? 0 }}</span> <span class="comment-likes"> {{ comment.likeCount ?? 0 }}</span>
<span v-if="comment.replyCount > 0"> <span v-if="comment.replyCount > 0">
<button @click="loadReplies(comment)"> <button @click="loadReplies(comment)">
{{ comment.replies.length > 0 ? '收起回复' : '展开回复' }} ({{ comment.replyCount }}) {{ comment.replies && comment.replies.length > 0 ? '收起回复' : '展开回复' }} ({{ comment.replyCount }})
</button> </button>
</span> </span>
<button class="reply-btn" @click="startReply(comment)"></button> <button class="reply-btn" @click="startReply(comment)"></button>
</div> </div>
<!-- 子评论列表 --> <!-- 子评论列表 -->
<ul v-if="comment.replies.length > 0" class="replies-list"> <ul v-if="comment.replies && comment.replies.length > 0" class="replies-list">
<li v-for="reply in comment.replies" :key="reply.id" class="comment-item reply-item"> <li v-for="reply in comment.replies" :key="reply.id" class="comment-item reply-item">
<img :src="reply.userAvatar" alt="评论者头像" class="comment-avatar" /> <img :src="reply.userAvatar || require('@/assets/default-avatar/boy_1.png')" alt="评论者头像" class="comment-avatar" />
<div class="comment-content"> <div class="comment-content">
<p class="comment-name">{{ reply.userName }}</p> <p class="comment-name">{{ reply.userName || '匿名用户' }}</p>
<p class="comment-text">{{ reply.content }}</p> <p class="comment-text">{{ reply.content || '' }}</p>
<div class="comment-meta"> <div class="comment-meta">
<span class="comment-time">{{ reply.createTime ? formatTime(reply.createTime) : '' }}</span> <span class="comment-time">{{ reply.createTime ? formatTime(reply.createTime) : '' }}</span>
<span class="comment-likes"> {{ reply.likeCount ?? 0 }}</span> <span class="comment-likes"> {{ reply.likeCount ?? 0 }}</span>
@ -71,7 +71,7 @@
<!-- 发送评论 --> <!-- 发送评论 -->
<div class="comment-box"> <div class="comment-box">
<div v-if="replyingComment" class="replying-tip"> <div v-if="replyingComment" class="replying-tip">
正在回复 @{{ replyingComment.userName }} 正在回复 @{{ replyingComment.userName || '匿名用户' }}
<button class="cancel-reply-btn" @click="cancelReply"></button> <button class="cancel-reply-btn" @click="cancelReply"></button>
</div> </div>
<textarea <textarea
@ -85,57 +85,55 @@
</template> </template>
<script setup lang="js" name="PostDetail"> <script setup lang="js" name="PostDetail">
import { ref, onMounted , onUnmounted} from 'vue'; import { ref, computed, onMounted , onUnmounted, watch } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { usePostDetailStore } from '@/stores/postdetail.js'; import { usePostDetailStore } from '@/stores/postdetail.js';
import { useUserStore } from '@/stores/user.js'; import { useUserStore } from '@/stores/user.js';
const route = useRoute(); const route = useRoute();
const postDetailStore = usePostDetailStore(); const postDetailStore = usePostDetailStore();
const userStore = useUserStore(); // const userStore = useUserStore();
const newComment = ref(''); const newComment = ref('');
const replyingComment = ref(null); // null const replyingComment = ref(null);
// author undefined
const author = computed(() => postDetailStore.post?.author || {});
//
const author = postDetailStore.post?.author ;
const isFollowing = ref(false); const isFollowing = ref(false);
const toggleFollow = () => { const toggleFollow = () => {
isFollowing.value = !isFollowing.value; isFollowing.value = !isFollowing.value;
}; };
//
function startReply(comment) { function startReply(comment) {
replyingComment.value = comment; replyingComment.value = comment;
} }
//
function cancelReply() { function cancelReply() {
replyingComment.value = null; replyingComment.value = null;
} }
//
function formatTime(timeStr) { function formatTime(timeStr) {
const date = new Date(timeStr); const date = new Date(timeStr);
return `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`; return `${date.getFullYear()}${date.getMonth() + 1}${date.getDate()}${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
} }
// // postDetailStore.post postId
function handleScroll() { function handleScroll() {
const el = document.documentElement; const el = document.documentElement;
if ( if (
el.scrollTop + window.innerHeight >= el.scrollHeight - 100 && el.scrollTop + window.innerHeight >= el.scrollHeight - 100 &&
!postDetailStore.commentsLoading && !postDetailStore.commentsLoading &&
!postDetailStore.commentsFinished !postDetailStore.commentsFinished &&
postDetailStore.post &&
(postDetailStore.post.id || postDetailStore.post.postId)
) { ) {
postDetailStore.fetchComments(); postDetailStore.fetchComments();
} }
} }
//
function loadReplies(comment) { function loadReplies(comment) {
if (!comment.repliesLoading && !comment.repliesFinished) { if (!comment.repliesLoading && !comment.repliesFinished) {
postDetailStore.fetchReplies(comment.id, comment); postDetailStore.fetchReplies(comment.id, comment);
} }
} }
//
const sendComment = () => { const sendComment = () => {
if (!userStore.isLoggedIn) { if (!userStore.isLoggedIn) {
alert('请先登录后再评论'); alert('请先登录后再评论');
@ -150,8 +148,8 @@ const sendComment = () => {
createTime: new Date().toISOString(), createTime: new Date().toISOString(),
likeCount: 0, likeCount: 0,
replyCount: 0, replyCount: 0,
postId: postDetailStore.post.id, postId: postDetailStore.post?.id || postDetailStore.post?.postId,
parentCommentId: replyingComment.value ? replyingComment.value.id : null, // parentCommentId parentCommentId: replyingComment.value ? replyingComment.value.id : null,
topId: null, topId: null,
isLike: false, isLike: false,
} }
@ -160,6 +158,17 @@ const sendComment = () => {
} }
}; };
// postDetailStore.post
watch(
() => postDetailStore.post,
(val) => {
if (val && (val.id || val.postId)) {
postDetailStore.fetchComments();
}
},
{ immediate: true }
);
onMounted(() => { onMounted(() => {
postDetailStore.fetchPostDetail(route.params.id); postDetailStore.fetchPostDetail(route.params.id);
window.addEventListener('scroll', handleScroll); window.addEventListener('scroll', handleScroll);

@ -143,8 +143,9 @@ export default {
const res = await request.post('/post', postData) const res = await request.post('/post', postData)
if (res.code === 200) { if (res.code === 200) {
showResult('success', '帖子发布成功') showResult('success', '帖子发布成功')
console.log(res.data);
setTimeout(() => { setTimeout(() => {
router.push(`/post/${res.data}`) router.push(`/`)
}, 1200) }, 1200)
} else { } else {
showResult('error', res.msg || '发布失败') showResult('error', res.msg || '发布失败')

@ -168,6 +168,7 @@ import { useUserStore } from '@/stores/user.js';
import request from '@/utils/request'; import request from '@/utils/request';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const userStore = useUserStore(); const userStore = useUserStore();
@ -177,13 +178,14 @@ const userInfo = ref({});
const userId = computed(() => route.params.userId || userStore.userInfo.userid); const userId = computed(() => route.params.userId || userStore.userInfo.userid);
const isCurrentUser = computed(() => String(userId.value) === String(userStore.userInfo.userid)); const isCurrentUser = computed(() => String(userId.value) === String(userStore.userInfo.userid));
// //
const userPosts = ref([]); const userPosts = ref([]);
const loading = ref(false); const loading = ref(false);
const finished = ref(false); const finished = ref(false);
const error = ref(null); const error = ref(null);
const pageParams = reactive({ const pageParams = reactive({
lastVal: 0, lastVal: Date.now(),
offset: 0, offset: 0,
size: 10 size: 10
}); });
@ -276,7 +278,6 @@ const loadUserInfo = async () => {
// //
const loadUserPosts = async () => { const loadUserPosts = async () => {
if (loading.value || finished.value) return; if (loading.value || finished.value) return;
loading.value = true; loading.value = true;
try { try {
const response = await request.get('/post/user', { const response = await request.get('/post/user', {
@ -285,9 +286,9 @@ const loadUserPosts = async () => {
...pageParams ...pageParams
} }
}); });
console.log('加载用户帖子响应:', response.data.records);
if (response && response.code === 200) { if (response && response.code === 200) {
const newPosts = response.data.list || []; const newPosts = response.data.records || [];
userPosts.value = [...userPosts.value, ...newPosts]; userPosts.value = [...userPosts.value, ...newPosts];
if (newPosts.length < pageParams.size) { if (newPosts.length < pageParams.size) {
@ -409,6 +410,7 @@ const viewUser = (id) => {
// //
const goToPostDetail = (postId) => { const goToPostDetail = (postId) => {
console.log('跳转到帖子详情:', postId);
router.push({ router.push({
name: 'PostDetail', name: 'PostDetail',
params: { id: postId } params: { id: postId }

Loading…
Cancel
Save