feat: 完成社区首页功能迭代,新增首页聚合与工作台组件

本次提交实现了完整的社区首页功能:
1. 新增首页聚合接口与服务,包含社区统计、热门帖、活跃用户与板块数据
2. 实现帖子推荐排序、SSR缓存与点赞态同步逻辑
3. 重构导航与布局系统,新增工作台侧边栏与移动端适配
4. 优化主题色与UI样式,统一设计系统风格
5. 修复登录注册页自动跳转与组件状态同步问题
This commit is contained in:
2026-09-12 23:36:18 +08:00
parent 055688a6cf
commit bee06fa962
24 changed files with 1446 additions and 359 deletions

View File

@@ -39,9 +39,37 @@ export interface Board {
name: string;
description: string;
icon: string;
color_index?: number;
sort_order: number;
}
// 首页聚合接口
export interface OverviewStats {
posts: number;
users: number;
comments: number;
today_posts: number;
}
export interface ActiveUser {
id: number;
username: string;
nickname: string;
avatar: string;
activity_count: number;
}
export interface BoardWithCount extends Board {
post_count: number;
}
export interface OverviewResponse {
stats: OverviewStats;
hot: PostListItem[];
active_users: ActiveUser[];
boards: BoardWithCount[];
}
export interface PostListItem {
id: number;
board_id: number;
@@ -222,16 +250,25 @@ export async function fetchPosts(
boardId?: number,
sort = "latest",
keyword = "",
recommended = false,
cookieHeader?: string
): Promise<PostsResponse> {
const params = new URLSearchParams({ page: String(page), size: String(size), sort });
if (boardId) params.set("board_id", String(boardId));
if (keyword) params.set("keyword", keyword);
if (recommended) params.set("recommended", "true");
const res = await fetch(`${API_BASE}/api/posts?${params}`, ssrInit(cookieHeaders(cookieHeader)));
if (!res.ok) throw new Error("获取帖子失败");
return res.json();
}
// SSR 首页聚合数据;失败时抛错,由首页调用方 try/catch 降级为无侧栏模块
export async function fetchOverview(cookieHeader?: string): Promise<OverviewResponse> {
const res = await fetch(`${API_BASE}/api/overview`, ssrInit(cookieHeaders(cookieHeader)));
if (!res.ok) throw new Error("获取社区概览失败");
return res.json();
}
export async function fetchBoards(): Promise<{ boards: Board[] }> {
const res = await fetch(`${API_BASE}/api/boards`, ssrInit());
if (!res.ok) throw new Error("获取板块失败");

View File

@@ -0,0 +1,6 @@
import { cache } from "react";
import { fetchMe } from "./api";
// 同一 SSR 请求内去重:layout 与页面可能同时需要当前用户,
// 相同 Cookie 头参数下只产生一次 /api/me 调用。
export const getMeCached = cache((cookieHeader?: string) => fetchMe(cookieHeader));