feat(admin): 独立后台壳、站点分析与聊天监管,公开站拆出主题切换与访问埋点

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-17 04:00:14 +08:00
parent cda5fad2e5
commit 9a55c2f6f2
41 changed files with 5655 additions and 1810 deletions

View File

@@ -129,13 +129,20 @@ function parseCookiePair(setCookie: string): [string, string] | null {
return [pair.slice(0, eq).trim(), pair.slice(eq + 1).trim()];
}
/** 透传 pathname 给根布局,用于 /admin 与公开站 chrome 分叉 */
function withPathname(req: NextRequest, init?: { request?: { headers: Headers } }) {
const headers = new Headers(init?.request?.headers ?? req.headers);
headers.set("x-pathname", req.nextUrl.pathname);
return NextResponse.next({ request: { headers } });
}
export async function middleware(req: NextRequest) {
const refreshToken = req.cookies.get(REFRESH_COOKIE)?.value;
const accessToken = req.cookies.get(TOKEN_COOKIE)?.value;
// 游客、access 仍有效、或服务端地址未配置:直接放行
if (!refreshToken || !isAccessTokenExpired(accessToken) || !API_BASE) {
return NextResponse.next();
return withPathname(req);
}
const csrf = req.cookies.get(CSRF_COOKIE)?.value ?? "";
@@ -154,7 +161,7 @@ export async function middleware(req: NextRequest) {
const headers = new Headers(req.headers);
headers.set("Cookie", [...jar].map(([k, v]) => `${k}=${v}`).join("; "));
const res = NextResponse.next({ request: { headers } });
const res = withPathname(req, { request: { headers } });
// 原样透传,HttpOnly/Path/SameSite/Secure 等属性全部以后端为准
for (const sc of setCookies) res.headers.append("Set-Cookie", sc);
return res;
@@ -162,7 +169,7 @@ export async function middleware(req: NextRequest) {
if (setCookies.length > 0) {
// refresh 已失效:透传后端的清 cookie 指令,避免之后每次请求都白轮转
const res = NextResponse.next();
const res = withPathname(req);
for (const sc of setCookies) res.headers.append("Set-Cookie", sc);
return res;
}
@@ -170,7 +177,7 @@ export async function middleware(req: NextRequest) {
// 后端不可达:降级匿名渲染,客户端 fetchWithRefresh 仍可兜底
}
return NextResponse.next();
return withPathname(req);
}
export const config = {