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

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:
# db:
# host: 192.168.125.128
# password: MySQL@5678
# host: 192.168.59.129
# password: Forely123!
# redis:
# host: 192.168.125.128
# host: 192.168.59.129
# port: 6379
# password: Redis@9012
# password: Forely123!
# rabbitmq:
# host: 192.168.125.128
# host: 192.168.59.129
# port: 5672
# username: rabbit_admin
# password: Rabbit@3456
# username: admin
# password: Forely123!
# minio:
# endpoint: http://192.168.125.128:9000
# accessKey: minio_admin
# secretKey: Minio@1234
# endpoint: http://192.168.59.129:9000
# accessKey: forely
# 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: [], // 评论列表
userInfo: null, // 用户信息
isLike: false, // 是否点赞
lastVal: 0, // 用于滚动分页的时间戳
lastVal: Date.now(), // 用于滚动分页的时间戳
offset: 0, // 偏移量
size: 5, // 每页评论数
detailLoading: false, // 加载状态
@ -104,14 +104,12 @@ export const usePostDetailStore = defineStore("postDetail", {
commentObj.repliesLoading = false;
}
},
async fetchPostDetail(postId) {
this.detailLoading = true;
try {
// 获取帖子详情
const RequestPostDetailData = {
id: postId,
};
const postRes = await request.get('/post/detail/', RequestPostDetailData);
const postRes = await request.get('/post/detail', { params: { id: postId } });
if (postRes.code === 200 && postRes.data) {
const {
id,

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

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

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

Loading…
Cancel
Save