0.3.1 UI修复

This commit is contained in:
liaibo
2026-01-18 19:01:31 +08:00
parent 90a38b48cf
commit 8a5b915002
86 changed files with 1160 additions and 2867 deletions
@@ -1,8 +1,4 @@
import { NextResponse } from "next/server";
import { createSupabaseRouteClient } from "@/lib/supabase/server";
import { promises as fs } from "fs";
import path from "path";
import { getDocumentsBaseDir, getLegacyMindmapsBaseDir } from "@/lib/server/local-paths";
import { isConvexEnabled } from "@/lib/convex/enabled";
import { getAuthedConvexClient } from "@/lib/convex/route";
import { api } from "@/lib/convex/api";
@@ -12,189 +8,56 @@ const defaultMindmapData = {
children: [],
};
// 新版:与页面文件夹(index.md 所在处)对齐,放在 public/documents/<docId>/mindmap.json
// 旧版遗留:public/mindmaps/<docId>/mindmap.json
const preferredBaseDir = getDocumentsBaseDir();
const legacyBaseDir = getLegacyMindmapsBaseDir();
async function ensureDir(dir: string) {
await fs.mkdir(dir, { recursive: true });
}
async function removeFileSafe(file: string) {
try {
await fs.rm(file, { force: true });
} catch {
// 忽略删除失败(例如文件不存在)
}
}
async function ensureIndexFile(folder: string, title = "无标题") {
const indexFile = path.join(folder, "index.md");
try {
await fs.access(indexFile);
} catch {
await fs.writeFile(indexFile, `# ${title}\n`, "utf8");
}
}
export async function GET(
_req: Request,
{ params }: { params: Promise<{ docId: string }> },
) {
const { docId: id } = await params;
const { docId } = await params;
if (isConvexEnabled()) {
const { auth, client } = await getAuthedConvexClient();
const mindmapId = `legacy-${id}`;
const res = await client.query(api.mindmaps.get, {
userId: auth.userId,
docId: id,
mindmapId,
});
const { client } = await getAuthedConvexClient();
const mindmapId = `legacy-${docId}`;
const res = await client.query(api.mindmaps.get, { docId, mindmapId });
return NextResponse.json({ data: res?.data ?? defaultMindmapData, source: "convex" });
}
const supabase = await createSupabaseRouteClient();
const {
data: { session },
} = await supabase.auth.getSession();
if (!session) {
return NextResponse.json({ error: "未登录" }, { status: 401 });
}
const preferredFolder = path.join(preferredBaseDir, id);
const preferredFile = path.join(preferredFolder, "mindmap.json");
const legacyFolder = path.join(legacyBaseDir, id);
const legacyFile = path.join(legacyFolder, "mindmap.json");
const tryRead = async (file: string) => {
try {
const content = await fs.readFile(file, "utf8");
return JSON.parse(content);
} catch {
return null;
}
};
const localData =
(await tryRead(preferredFile)) ??
(await tryRead(legacyFile));
if (localData) {
return NextResponse.json({ data: localData, source: "local" });
}
// fallback Supabase
const { data, error } = await supabase
.from("documents")
.select("mindmap_data")
.eq("id", id)
.eq("user_id", session.user.id)
.maybeSingle();
if (error) {
return NextResponse.json({ error: error.message }, { status: 400 });
}
const payload = data?.mindmap_data ?? defaultMindmapData;
return NextResponse.json({ data: payload, source: "supabase" });
return NextResponse.json({ error: "当前仅支持 Convex 模式" }, { status: 501 });
}
export async function POST(
request: Request,
{ params }: { params: Promise<{ docId: string }> },
) {
const { docId: id } = await params;
const { docId } = await params;
if (isConvexEnabled()) {
const { auth, client } = await getAuthedConvexClient();
const mindmapId = `legacy-${id}`;
const { data } = await request.json();
const { client } = await getAuthedConvexClient();
const mindmapId = `legacy-${docId}`;
const payload = (await request.json().catch(() => ({}))) as { data?: unknown };
const result = await client.mutation(api.mindmaps.put, {
userId: auth.userId,
docId: id,
docId,
mindmapId,
data: data ?? defaultMindmapData,
data: payload.data ?? defaultMindmapData,
});
return NextResponse.json({ ok: true, ...(result ?? {}) });
return NextResponse.json(result ?? { ok: true });
}
const supabase = await createSupabaseRouteClient();
const {
data: { session },
} = await supabase.auth.getSession();
if (!session) {
return NextResponse.json({ error: "未登录" }, { status: 401 });
}
const { data } = await request.json();
const folder = path.join(preferredBaseDir, id);
const file = path.join(folder, "mindmap.json");
try {
await ensureDir(folder);
await ensureIndexFile(folder);
await fs.writeFile(
file,
JSON.stringify(data ?? defaultMindmapData, null, 2),
"utf8",
);
} catch (error) {
return NextResponse.json({ error: String(error) }, { status: 500 });
}
const { error } = await supabase
.from("documents")
.update({ mindmap_data: data ?? defaultMindmapData })
.eq("id", id)
.eq("user_id", session.user.id);
if (error) {
return NextResponse.json({ error: error.message }, { status: 400 });
}
return NextResponse.json({ ok: true });
return NextResponse.json({ error: "当前仅支持 Convex 模式" }, { status: 501 });
}
export async function DELETE(
_req: Request,
{ params }: { params: Promise<{ docId: string }> },
) {
const { docId: id } = await params;
const { docId } = await params;
if (isConvexEnabled()) {
const { auth, client } = await getAuthedConvexClient();
const mindmapId = `legacy-${id}`;
const result = await client.mutation(api.mindmaps.softDelete, {
userId: auth.userId,
docId: id,
mindmapId,
});
return NextResponse.json({ ok: true, ...(result ?? {}) });
const { client } = await getAuthedConvexClient();
const mindmapId = `legacy-${docId}`;
const result = await client.mutation(api.mindmaps.softDelete, { docId, mindmapId });
return NextResponse.json(result ?? { ok: true });
}
const supabase = await createSupabaseRouteClient();
const {
data: { session },
} = await supabase.auth.getSession();
if (!session) {
return NextResponse.json({ error: "未登录" }, { status: 401 });
}
const preferredFolder = path.join(preferredBaseDir, id);
const preferredFile = path.join(preferredFolder, "mindmap.json");
const legacyFolder = path.join(legacyBaseDir, id);
const legacyFile = path.join(legacyFolder, "mindmap.json");
await Promise.all([removeFileSafe(preferredFile), removeFileSafe(legacyFile)]);
const { error } = await supabase
.from("documents")
.update({ mindmap_data: null })
.eq("id", id)
.eq("user_id", session.user.id);
if (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}
return NextResponse.json({ ok: true });
return NextResponse.json({ error: "当前仅支持 Convex 模式" }, { status: 501 });
}