feat: 添加评论功能
This commit is contained in:
@@ -9,6 +9,77 @@ import { generatePopularConcepts } from './concept';
|
||||
// 模拟网络延迟
|
||||
const delay = (ms = 300) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
// ==================== 评论内存存储 ====================
|
||||
// 用于在 Mock 环境下持久化评论数据(按 eventId 分组)
|
||||
const commentsStore = new Map();
|
||||
|
||||
/**
|
||||
* 初始化某个事件的 mock 评论列表
|
||||
* @param {string} eventId - 事件 ID
|
||||
* @returns {Array} 初始的 8 条 mock 评论
|
||||
*/
|
||||
const initializeMockComments = (eventId) => {
|
||||
const comments = [];
|
||||
const users = [
|
||||
{ username: '张三', avatar: null },
|
||||
{ username: '李四', avatar: null },
|
||||
{ username: '王五', avatar: null },
|
||||
{ username: '赵六', avatar: null },
|
||||
{ username: '投资达人', avatar: null },
|
||||
{ username: '价值投资者', avatar: null },
|
||||
{ username: '技术分析师', avatar: null },
|
||||
{ username: '基本面研究员', avatar: null },
|
||||
];
|
||||
|
||||
const commentTemplates = [
|
||||
'这个事件对相关板块影响很大,值得关注后续发展',
|
||||
'相关概念股已经开始异动了,市场反应很快',
|
||||
'感谢分享,这个事件我之前没注意到',
|
||||
'从基本面来看,这个事件会带来实质性利好',
|
||||
'需要观察后续政策落地情况,现在下结论还太早',
|
||||
'相关产业链的龙头企业值得重点关注',
|
||||
'这类事件一般都是短期刺激,长期影响有限',
|
||||
'建议大家理性对待,不要盲目追高',
|
||||
];
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const hoursAgo = Math.floor(Math.random() * 48) + 1; // 1-48 小时前
|
||||
const createdAt = new Date(Date.now() - hoursAgo * 60 * 60 * 1000);
|
||||
const user = users[i % users.length];
|
||||
|
||||
comments.push({
|
||||
id: `comment_${eventId}_${i + 1}`,
|
||||
content: commentTemplates[i % commentTemplates.length],
|
||||
content_type: 'text',
|
||||
author: {
|
||||
id: `user_${i + 1}`,
|
||||
username: user.username,
|
||||
avatar: user.avatar,
|
||||
},
|
||||
created_at: createdAt.toISOString(),
|
||||
likes_count: Math.floor(Math.random() * 20),
|
||||
is_liked: false,
|
||||
});
|
||||
}
|
||||
|
||||
// 按时间升序排序(最旧的在前)
|
||||
comments.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
|
||||
|
||||
return comments;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取或初始化评论列表
|
||||
* @param {string} eventId - 事件 ID
|
||||
* @returns {Array} 评论列表
|
||||
*/
|
||||
const getOrInitComments = (eventId) => {
|
||||
if (!commentsStore.has(eventId)) {
|
||||
commentsStore.set(eventId, initializeMockComments(eventId));
|
||||
}
|
||||
return commentsStore.get(eventId);
|
||||
};
|
||||
|
||||
export const eventHandlers = [
|
||||
// ==================== 事件列表相关 ====================
|
||||
|
||||
@@ -1249,4 +1320,111 @@ export const eventHandlers = [
|
||||
);
|
||||
}
|
||||
}),
|
||||
|
||||
// ==================== 评论相关 ====================
|
||||
|
||||
// 获取事件评论列表
|
||||
http.get('/api/events/:eventId/posts', async ({ params, request }) => {
|
||||
await delay(300);
|
||||
|
||||
const { eventId } = params;
|
||||
const url = new URL(request.url);
|
||||
const sort = url.searchParams.get('sort') || 'latest';
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const perPage = parseInt(url.searchParams.get('per_page') || '20');
|
||||
|
||||
console.log('[Mock] 获取评论列表, eventId:', eventId, 'sort:', sort);
|
||||
|
||||
try {
|
||||
// 从内存存储获取评论列表
|
||||
const allComments = getOrInitComments(eventId);
|
||||
|
||||
// ✅ 创建副本并排序(避免直接修改原数组)
|
||||
let sortedComments = [...allComments];
|
||||
if (sort === 'hot') {
|
||||
sortedComments.sort((a, b) => b.likes_count - a.likes_count);
|
||||
} else {
|
||||
// 默认按时间升序(oldest first)- 最旧评论在前,最新在后
|
||||
sortedComments.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
|
||||
}
|
||||
|
||||
// 分页处理(使用排序后的副本)
|
||||
const startIndex = (page - 1) * perPage;
|
||||
const endIndex = startIndex + perPage;
|
||||
const paginatedComments = sortedComments.slice(startIndex, endIndex);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: paginatedComments,
|
||||
pagination: {
|
||||
page: page,
|
||||
per_page: perPage,
|
||||
total: allComments.length,
|
||||
pages: Math.ceil(allComments.length / perPage),
|
||||
has_prev: page > 1,
|
||||
has_next: endIndex < allComments.length,
|
||||
},
|
||||
message: '获取评论成功',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[Mock] 获取评论列表失败:', error);
|
||||
return HttpResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: '获取评论失败',
|
||||
data: [],
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}),
|
||||
|
||||
// 发表评论
|
||||
http.post('/api/events/:eventId/posts', async ({ params, request }) => {
|
||||
await delay(500);
|
||||
|
||||
const { eventId } = params;
|
||||
const body = await request.json();
|
||||
|
||||
console.log('[Mock] 发表评论, eventId:', eventId, 'content:', body.content);
|
||||
|
||||
try {
|
||||
// 模拟创建新评论
|
||||
const newComment = {
|
||||
id: `comment_${eventId}_${Date.now()}`,
|
||||
content: body.content,
|
||||
content_type: body.content_type || 'text',
|
||||
author: {
|
||||
id: 'current_user',
|
||||
username: '当前用户',
|
||||
avatar: null,
|
||||
},
|
||||
created_at: new Date().toISOString(),
|
||||
likes_count: 0,
|
||||
is_liked: false,
|
||||
};
|
||||
|
||||
// 将新评论添加到内存存储(插入到列表开头)
|
||||
const comments = getOrInitComments(eventId);
|
||||
comments.unshift(newComment);
|
||||
|
||||
console.log('[Mock] 评论已添加到内存存储, 当前评论总数:', comments.length);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: newComment,
|
||||
message: '评论发布成功',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[Mock] 发表评论失败:', error);
|
||||
return HttpResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: '评论发布失败',
|
||||
message: '系统错误,请稍后重试',
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user