0.2.1 onlyoffice修复
This commit is contained in:
@@ -1,9 +1,35 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const url = new URL(request.url);
|
||||
const documentId = url.searchParams.get("documentId") ?? "";
|
||||
|
||||
if (!documentId) {
|
||||
return NextResponse.json({ error: "缺少 documentId" }, { status: 400 });
|
||||
}
|
||||
|
||||
const client = getConvexHttpClient();
|
||||
const result = await client.query(api.documents.getContent, {
|
||||
userId: auth.userId,
|
||||
id: documentId,
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
return NextResponse.json({ error: "页面不存在" }, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json({ content: result.content ?? null });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
@@ -37,4 +63,3 @@ export async function GET(request: Request) {
|
||||
|
||||
return NextResponse.json({ content: document.content ?? null });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import type { Json } from "@/types/supabase";
|
||||
@@ -158,6 +162,142 @@ function replaceAssetRefsInContent(content: Json | null, assetMap: Map<string, {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const client = getConvexHttpClient();
|
||||
|
||||
const payload = (await request.json()) as CopyTreePayload;
|
||||
if (!payload?.items?.length) {
|
||||
return NextResponse.json({ error: "缺少 items" }, { status: 400 });
|
||||
}
|
||||
|
||||
const normalizedItems = payload.items.filter((it) => it?.documentId);
|
||||
if (normalizedItems.length === 0) {
|
||||
return NextResponse.json({ error: "items 为空" }, { status: 400 });
|
||||
}
|
||||
|
||||
const targetParentId = payload.targetParentId ?? null;
|
||||
let workspaceId: string | null = null;
|
||||
|
||||
if (targetParentId) {
|
||||
const targetDoc = await client.query(api.documents.getMeta, { userId: auth.userId, id: targetParentId });
|
||||
if (!targetDoc) {
|
||||
return NextResponse.json({ error: "目标页面不存在或无权限" }, { status: 404 });
|
||||
}
|
||||
workspaceId = targetDoc.workspace_id;
|
||||
}
|
||||
|
||||
const sourceIds = Array.from(new Set(normalizedItems.map((it) => it.documentId)));
|
||||
const firstMeta = await client.query(api.documents.getMeta, { userId: auth.userId, id: sourceIds[0] });
|
||||
if (!firstMeta) {
|
||||
return NextResponse.json({ error: "源页面不存在或无权限" }, { status: 404 });
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
workspaceId = firstMeta.workspace_id;
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return NextResponse.json({ error: "缺少目标工作空间" }, { status: 400 });
|
||||
}
|
||||
|
||||
const wid = workspaceId;
|
||||
|
||||
const allDocs = await client.query(api.documents.listAllForCopy, {
|
||||
userId: auth.userId,
|
||||
workspaceId: wid,
|
||||
});
|
||||
|
||||
const sourceById = new Map<string, DocRow>();
|
||||
(allDocs as unknown as DocRow[]).forEach((d) => sourceById.set(d.id, d));
|
||||
|
||||
const missing = sourceIds.find((id) => !sourceById.has(id));
|
||||
if (missing) {
|
||||
return NextResponse.json({ error: "源页面不存在或无权限" }, { status: 404 });
|
||||
}
|
||||
|
||||
const childrenByParent = new Map<string | null, DocRow[]>();
|
||||
(allDocs as unknown as DocRow[]).forEach((doc) => {
|
||||
const list = childrenByParent.get(doc.parent_id) ?? [];
|
||||
list.push(doc);
|
||||
childrenByParent.set(doc.parent_id, list);
|
||||
});
|
||||
|
||||
const existingTitleSetByParent = new Map<string | null, Set<string>>();
|
||||
const seedTitleSet = (parent: string | null) => {
|
||||
if (existingTitleSetByParent.has(parent)) return;
|
||||
const titles = new Set<string>();
|
||||
(childrenByParent.get(parent) ?? []).forEach((d) => titles.add(normalizeTitle(d.title)));
|
||||
existingTitleSetByParent.set(parent, titles);
|
||||
};
|
||||
seedTitleSet(targetParentId);
|
||||
|
||||
const newIdByOldId = new Map<string, string>();
|
||||
const copyQueue: Array<{ old: DocRow; newParentId: string | null; parentKey: string | null }> = [];
|
||||
|
||||
const enqueueTree = (root: DocRow, newParent: string | null, recursive: boolean) => {
|
||||
const visit = (node: DocRow, parentNewId: string | null, parentKey: string | null) => {
|
||||
const newId =
|
||||
typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
||||
newIdByOldId.set(node.id, newId);
|
||||
copyQueue.push({ old: node, newParentId: parentNewId, parentKey });
|
||||
if (!recursive) return;
|
||||
const children = getChildrenSorted(childrenByParent, node.id);
|
||||
children.forEach((child) => visit(child, newId, newId));
|
||||
};
|
||||
visit(root, newParent, newParent);
|
||||
};
|
||||
|
||||
normalizedItems.forEach((item) => {
|
||||
const doc = sourceById.get(item.documentId) ?? null;
|
||||
if (doc) {
|
||||
enqueueTree(doc, targetParentId, Boolean(item.recursive));
|
||||
}
|
||||
});
|
||||
|
||||
if (copyQueue.length === 0) {
|
||||
return NextResponse.json({ error: "没有可复制的页面" }, { status: 400 });
|
||||
}
|
||||
|
||||
const insertedDocs: Array<{ oldId: string; newId: string }> = [];
|
||||
|
||||
for (const item of copyQueue) {
|
||||
const newId = newIdByOldId.get(item.old.id)!;
|
||||
const parentId = item.newParentId;
|
||||
|
||||
if (!existingTitleSetByParent.has(parentId)) {
|
||||
seedTitleSet(parentId);
|
||||
}
|
||||
const titleSet = existingTitleSetByParent.get(parentId) ?? new Set<string>();
|
||||
existingTitleSetByParent.set(parentId, titleSet);
|
||||
|
||||
const newTitle = makeUniqueTitle(normalizeTitle(item.old.title), titleSet);
|
||||
titleSet.add(newTitle);
|
||||
|
||||
await client.mutation(api.documents.create, {
|
||||
userId: auth.userId,
|
||||
id: newId,
|
||||
workspaceId: wid,
|
||||
parentId,
|
||||
accessScope: (item.old.access_scope ?? "private") as "private" | "shared" | "public",
|
||||
title: newTitle,
|
||||
content: item.old.content ?? [],
|
||||
});
|
||||
|
||||
await ensureDocumentScaffold(newId, newTitle);
|
||||
await client.mutation(api.mindmaps.copyByDocument, {
|
||||
userId: auth.userId,
|
||||
sourceDocId: item.old.id,
|
||||
targetDocId: newId,
|
||||
});
|
||||
insertedDocs.push({ oldId: item.old.id, newId });
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
items: insertedDocs.map((d) => ({ oldId: d.oldId, newId: d.newId })),
|
||||
});
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { ensureDefaultWorkspace, resolveActiveWorkspaceId } from "@/lib/workspaces";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
function makeId(): string {
|
||||
return typeof crypto.randomUUID === "function"
|
||||
? crypto.randomUUID()
|
||||
: `${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
||||
}
|
||||
|
||||
type CreateChildPayload = {
|
||||
parentId: string | null;
|
||||
@@ -11,6 +21,58 @@ type CreateChildPayload = {
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const client = getConvexHttpClient();
|
||||
|
||||
const { parentId, title, blocks }: CreateChildPayload = await request.json();
|
||||
|
||||
if (typeof parentId === "undefined") {
|
||||
return NextResponse.json({ error: "缺少 parentId" }, { status: 400 });
|
||||
}
|
||||
|
||||
let workspaceId: string;
|
||||
let accessScope: "private" | "shared" | "public" = "private";
|
||||
|
||||
if (parentId) {
|
||||
const parentDoc = await client.query(api.documents.getMeta, { userId: auth.userId, id: parentId });
|
||||
if (!parentDoc) {
|
||||
return NextResponse.json({ error: "父页面不存在" }, { status: 404 });
|
||||
}
|
||||
workspaceId = parentDoc.workspace_id;
|
||||
accessScope = (parentDoc.access_scope ?? "private") as typeof accessScope;
|
||||
} else {
|
||||
const ensured = await client.mutation(api.workspaces.ensureDefaultWorkspace, {
|
||||
userId: auth.userId,
|
||||
fallbackName: auth.name ?? auth.email ?? "我的空间",
|
||||
workspaceIdIfCreate: makeId(),
|
||||
});
|
||||
workspaceId = ensured.activeWorkspaceId;
|
||||
if (!workspaceId) {
|
||||
return NextResponse.json({ error: "缺少目标工作空间" }, { status: 400 });
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedTitle = title && title.trim().length > 0 ? title.trim() : "未命名页面";
|
||||
const contentPayload = Array.isArray(blocks) ? blocks : [];
|
||||
const pageId = makeId();
|
||||
|
||||
const created = await client.mutation(api.documents.create, {
|
||||
userId: auth.userId,
|
||||
id: pageId,
|
||||
workspaceId,
|
||||
parentId: parentId ?? null,
|
||||
title: resolvedTitle,
|
||||
accessScope,
|
||||
content: contentPayload,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
pageId: created.id,
|
||||
title: created.title ?? resolvedTitle,
|
||||
});
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -7,6 +7,10 @@ import { composeContentWithBlocks, extractBlocksFromContent } from "@/lib/docume
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import { getDocumentsBaseDir } from "@/lib/server/local-paths";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
|
||||
const documentsBaseDir = getDocumentsBaseDir();
|
||||
|
||||
@@ -25,6 +29,9 @@ async function ensureDocumentScaffold(id: string, title: string | null) {
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
if (isConvexEnabled()) {
|
||||
return await handleCreateRequestConvex(request);
|
||||
}
|
||||
return await handleCreateRequest(request);
|
||||
} catch (error) {
|
||||
console.error("创建页面失败", error);
|
||||
@@ -33,6 +40,83 @@ export async function POST(request: Request) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleCreateRequestConvex(request: Request) {
|
||||
const auth = requireAuthContext();
|
||||
const client = getConvexHttpClient();
|
||||
|
||||
const { parentId }: { parentId?: string | null } = await request.json();
|
||||
|
||||
const workspaceBootstrap = await client.mutation(api.workspaces.ensureDefaultWorkspace, {
|
||||
userId: auth.userId,
|
||||
fallbackName: auth.email ?? auth.name ?? "我的空间",
|
||||
workspaceIdIfCreate: randomUUID(),
|
||||
});
|
||||
|
||||
let workspaceId: string | null = null;
|
||||
let parentContent: Json | null = null;
|
||||
let accessScope: "private" | "shared" | "public" = "private";
|
||||
|
||||
if (parentId) {
|
||||
const parentDoc = await client.query(api.documents.getMeta, {
|
||||
userId: auth.userId,
|
||||
id: parentId,
|
||||
});
|
||||
|
||||
if (!parentDoc) {
|
||||
return NextResponse.json({ error: "父页面不存在或无权限" }, { status: 404 });
|
||||
}
|
||||
|
||||
workspaceId = parentDoc.workspace_id;
|
||||
accessScope = (parentDoc.access_scope ?? "private") as typeof accessScope;
|
||||
const parentContentRes = await client.query(api.documents.getContent, { userId: auth.userId, id: parentId });
|
||||
parentContent = (parentContentRes?.content as Json | null) ?? null;
|
||||
} else {
|
||||
workspaceId = workspaceBootstrap.activeWorkspaceId || null;
|
||||
}
|
||||
|
||||
if (!workspaceId) {
|
||||
return NextResponse.json({ error: "缺少目标工作空间" }, { status: 400 });
|
||||
}
|
||||
|
||||
const id = randomUUID();
|
||||
const data = await client.mutation(api.documents.create, {
|
||||
userId: auth.userId,
|
||||
id,
|
||||
workspaceId,
|
||||
parentId: parentId ?? null,
|
||||
title: "无标题",
|
||||
accessScope,
|
||||
content: [],
|
||||
});
|
||||
|
||||
// 为文件树创建本地目录和 index.md
|
||||
if (data?.id) {
|
||||
await ensureDocumentScaffold(data.id, data.title ?? "无标题");
|
||||
}
|
||||
|
||||
if (parentId && data) {
|
||||
const existingBlocks = extractBlocksFromContent(parentContent);
|
||||
const pageReferenceBlock = {
|
||||
id: randomUUID(),
|
||||
type: "pageReference",
|
||||
props: {
|
||||
pageId: data.id,
|
||||
title: data.title ?? "无标题",
|
||||
},
|
||||
};
|
||||
const nextBlocks = [...existingBlocks, pageReferenceBlock as Json];
|
||||
const payload = composeContentWithBlocks(parentContent, nextBlocks);
|
||||
|
||||
await client.mutation(api.documents.updateContent, {
|
||||
userId: auth.userId,
|
||||
id: parentId,
|
||||
content: payload,
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json(data);
|
||||
}
|
||||
|
||||
async function handleCreateRequest(request: Request) {
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId } = await request.json();
|
||||
if (!documentId) {
|
||||
return NextResponse.json({ error: "缺少 documentId" }, { status: 400 });
|
||||
}
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.softDelete, { userId: auth.userId, id: documentId });
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import { getDocumentsBaseDir } from "@/lib/server/local-paths";
|
||||
@@ -43,6 +47,50 @@ async function copyMindmapIfExists(sourceId: string, targetId: string) {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const client = getConvexHttpClient();
|
||||
|
||||
const { documentId }: DuplicatePayload = await request.json();
|
||||
if (!documentId) {
|
||||
return NextResponse.json({ error: "缺少 documentId" }, { status: 400 });
|
||||
}
|
||||
|
||||
const sourceDoc = await client.query(api.documents.getMeta, { userId: auth.userId, id: documentId });
|
||||
if (!sourceDoc) {
|
||||
return NextResponse.json({ error: "页面不存在或无权访问" }, { status: 404 });
|
||||
}
|
||||
|
||||
const fallbackTitle =
|
||||
sourceDoc.title?.trim() && sourceDoc.title.trim().length > 0 ? sourceDoc.title.trim() : "无标题";
|
||||
const duplicatedTitle = `${fallbackTitle} 副本`;
|
||||
|
||||
const newId = typeof crypto.randomUUID === "function"
|
||||
? crypto.randomUUID()
|
||||
: `${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
||||
|
||||
const duplicated = await client.mutation(api.documents.duplicate, {
|
||||
userId: auth.userId,
|
||||
sourceId: documentId,
|
||||
newId,
|
||||
title: duplicatedTitle,
|
||||
});
|
||||
|
||||
await ensureDocumentScaffold(duplicated.id, duplicated.title ?? duplicatedTitle);
|
||||
await client.mutation(api.mindmaps.copyByDocument, {
|
||||
userId: auth.userId,
|
||||
sourceDocId: documentId,
|
||||
targetDocId: duplicated.id,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
id: duplicated.id,
|
||||
title: duplicated.title ?? duplicatedTitle,
|
||||
parent_id: duplicated.parent_id ?? null,
|
||||
sort_order: duplicated.sort_order ?? null,
|
||||
});
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -3,6 +3,9 @@ import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import type { Json } from "@/types/supabase";
|
||||
import { composeContentWithBlocks, extractBlocksFromContent } from "@/lib/document-content";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { getAuthedConvexClient } from "@/lib/convex/route";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
interface EmbedPayload {
|
||||
sourceId: string;
|
||||
@@ -10,6 +13,49 @@ interface EmbedPayload {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const { auth, client } = getAuthedConvexClient();
|
||||
|
||||
const { sourceId, targetId }: EmbedPayload = await request.json();
|
||||
|
||||
if (!sourceId || !targetId) {
|
||||
return NextResponse.json({ error: "缺少参数" }, { status: 400 });
|
||||
}
|
||||
|
||||
const sourceDoc = await client.query(api.documents.getMeta, { userId: auth.userId, id: sourceId });
|
||||
if (!sourceDoc) {
|
||||
return NextResponse.json({ error: "原始页面不存在或无权限" }, { status: 404 });
|
||||
}
|
||||
|
||||
const targetContent = await client.query(api.documents.getContent, { userId: auth.userId, id: targetId });
|
||||
if (!targetContent) {
|
||||
return NextResponse.json({ error: "目标页面不存在或无权限" }, { status: 404 });
|
||||
}
|
||||
|
||||
const currentBlocks = extractBlocksFromContent(targetContent.content);
|
||||
const nextBlocks: Json[] = [
|
||||
...currentBlocks,
|
||||
{
|
||||
id: randomUUID(),
|
||||
type: "pageReference",
|
||||
props: {
|
||||
pageId: sourceDoc.id,
|
||||
title: sourceDoc.title ?? "无标题",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const payload: Json = composeContentWithBlocks(targetContent.content, nextBlocks);
|
||||
|
||||
await client.mutation(api.documents.updateContent, {
|
||||
userId: auth.userId,
|
||||
id: targetId,
|
||||
content: payload,
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
@@ -8,6 +12,17 @@ interface EmptyTrashPayload {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { workspaceId }: EmptyTrashPayload = await request.json();
|
||||
if (!workspaceId) {
|
||||
return NextResponse.json({ error: "缺少 workspaceId" }, { status: 400 });
|
||||
}
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.emptyTrashByWorkspace, { userId: auth.userId, workspaceId });
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
interface MovePayload {
|
||||
documentId: string;
|
||||
@@ -8,6 +12,20 @@ interface MovePayload {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId, parentId = null, position }: MovePayload = await request.json();
|
||||
const sortOrder = Number.isFinite(position) ? Math.floor(position) : 0;
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.move, {
|
||||
userId: auth.userId,
|
||||
id: documentId,
|
||||
parentId,
|
||||
sortOrder,
|
||||
});
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import type { PageOptionsState } from "@/types/page-options";
|
||||
import type { Database } from "@/types/supabase";
|
||||
|
||||
@@ -19,6 +23,31 @@ const COLUMN_MAP: Record<keyof PageOptionsState, keyof Database["public"]["Table
|
||||
};
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId, options }: OptionsPayload = await request.json();
|
||||
if (!documentId || !options) {
|
||||
return NextResponse.json({ error: "缺少参数" }, { status: 400 });
|
||||
}
|
||||
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.updateOptions, {
|
||||
userId: auth.userId,
|
||||
id: documentId,
|
||||
options: {
|
||||
wideLayout: options.wideLayout,
|
||||
smallText: options.smallText,
|
||||
showHeadingNumbers: options.showHeadingNumbers,
|
||||
showToc: options.showToc,
|
||||
showStructure: options.showStructure,
|
||||
protectEditing: options.protectEditing,
|
||||
showWordCount: options.showWordCount,
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId } = await request.json();
|
||||
if (!documentId) {
|
||||
return NextResponse.json({ error: "缺少 documentId" }, { status: 400 });
|
||||
}
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.purge, { userId: auth.userId, id: documentId });
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId } = await request.json();
|
||||
if (!documentId) {
|
||||
return NextResponse.json({ error: "缺少 documentId" }, { status: 400 });
|
||||
}
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.restore, { userId: auth.userId, id: documentId });
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
|
||||
interface SavePayload {
|
||||
documentId: string;
|
||||
@@ -7,6 +11,18 @@ interface SavePayload {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId, content }: SavePayload = await request.json();
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.updateContent, {
|
||||
userId: auth.userId,
|
||||
id: documentId,
|
||||
content,
|
||||
});
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import type { DocumentStats } from "@/types/page-options";
|
||||
|
||||
interface StatsPayload {
|
||||
@@ -8,6 +12,25 @@ interface StatsPayload {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId, stats }: StatsPayload = await request.json();
|
||||
if (!documentId || !stats) {
|
||||
return NextResponse.json({ error: "缺少参数" }, { status: 400 });
|
||||
}
|
||||
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.updateStats, {
|
||||
userId: auth.userId,
|
||||
id: documentId,
|
||||
wordCount: stats.wordCount,
|
||||
characterCount: stats.characterCount,
|
||||
blockCount: stats.blockCount,
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { createSupabaseRouteClient } from "@/lib/supabase/server";
|
||||
import { isConvexEnabled } from "@/lib/convex/enabled";
|
||||
import { getConvexHttpClient } from "@/lib/convex/server";
|
||||
import { api } from "@/lib/convex/api";
|
||||
import { requireAuthContext } from "@/lib/auth/authContext";
|
||||
|
||||
interface RenamePayload {
|
||||
documentId: string;
|
||||
@@ -7,6 +11,18 @@ interface RenamePayload {
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
if (isConvexEnabled()) {
|
||||
const auth = requireAuthContext();
|
||||
const { documentId, title }: RenamePayload = await request.json();
|
||||
const client = getConvexHttpClient();
|
||||
await client.mutation(api.documents.updateTitle, {
|
||||
userId: auth.userId,
|
||||
id: documentId,
|
||||
title,
|
||||
});
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
|
||||
const supabase = await createSupabaseRouteClient();
|
||||
const {
|
||||
data: { session },
|
||||
|
||||
Reference in New Issue
Block a user