0.2 在线版本打通
This commit is contained in:
@@ -37,7 +37,7 @@ import type { SidebarInitialData, SidebarSectionId } from "@/components/sidebar/
|
||||
import { useSidebarData } from "@/hooks/use-sidebar-data";
|
||||
import { PrivateTree } from "@/components/sidebar/private-tree";
|
||||
import { buildSidebarSectionsFromTree, flattenDocumentTree } from "@/lib/sidebar-tree";
|
||||
import { supabaseBrowser } from "@/lib/supabase/client";
|
||||
import { getSupabaseBrowserClient } from "@/lib/supabase/client";
|
||||
import { useSearchPaletteStore } from "@/store/search-palette";
|
||||
import { useEditorBridgeStore } from "@/store/editor-bridge";
|
||||
import { FileTree } from "@/components/sidebar/file-tree";
|
||||
@@ -57,6 +57,7 @@ import {
|
||||
import type { MediaAsset } from "@/types/media";
|
||||
import { AssetContextMenu } from "@/components/sidebar/asset-context-menu";
|
||||
import { ASSETS_CHANGED_EVENT, DOCUMENTS_CHANGED_EVENT, emitAssetsChanged, emitDocumentsChanged } from "@/lib/events";
|
||||
import { getMnoteRuntimeConfig } from "@/lib/runtime-config";
|
||||
|
||||
const TOP_BUTTONS = [
|
||||
{ id: "search", icon: SearchIcon, label: "搜索" },
|
||||
@@ -78,6 +79,21 @@ const SECTION_ICONS: Record<Exclude<SidebarSectionId, "private">, React.ReactNod
|
||||
|
||||
const normalizeStoragePath = (storagePath: string): string => storagePath.replaceAll("\\", "/");
|
||||
|
||||
const officeFileTypeFromAsset = (fileName: string | null, mimeType: string | null) => {
|
||||
const name = (fileName ?? "").trim().toLowerCase();
|
||||
const mt = (mimeType ?? "").trim().toLowerCase();
|
||||
const ext = name.includes(".") ? name.split(".").pop() : null;
|
||||
if (ext && ["doc", "docx", "odt", "rtf"].includes(ext)) return ext;
|
||||
if (ext && ["ppt", "pptx", "odp"].includes(ext)) return ext;
|
||||
if (ext && ["xls", "xlsx", "ods", "csv"].includes(ext)) return ext;
|
||||
if (ext && ["pdf"].includes(ext)) return ext;
|
||||
if (mt.includes("wordprocessingml")) return "docx";
|
||||
if (mt.includes("presentationml")) return "pptx";
|
||||
if (mt.includes("spreadsheetml")) return "xlsx";
|
||||
if (mt.includes("pdf")) return "pdf";
|
||||
return null;
|
||||
};
|
||||
|
||||
const extractMindmapIdFromStoragePath = (
|
||||
storagePath: string | null | undefined,
|
||||
): string | null => {
|
||||
@@ -112,6 +128,7 @@ interface ContextMenuState {
|
||||
export function Sidebar({ initialData }: SidebarProps) {
|
||||
const { open, setOpen, width, setWidth, collapsedSections, toggleSection, setSectionCollapsed, trashConfirm, setTrashConfirm } =
|
||||
useSidebarStore();
|
||||
const supabaseBrowser = useMemo(() => getSupabaseBrowserClient(), []);
|
||||
const sectionsTrayOpen = useSidebarStore((state) => state.sectionsTrayOpen);
|
||||
const toggleSectionsTray = useSidebarStore((state) => state.toggleSectionsTray);
|
||||
const setSectionsTrayOpen = useSidebarStore((state) => state.setSectionsTrayOpen);
|
||||
@@ -530,6 +547,36 @@ export function Sidebar({ initialData }: SidebarProps) {
|
||||
setOpen(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const officeFileType = officeFileTypeFromAsset(asset.file_name ?? null, asset.mime_type ?? null);
|
||||
if (officeFileType) {
|
||||
const officeBase = getMnoteRuntimeConfig().onlyofficeBaseUrl;
|
||||
if (!officeBase) {
|
||||
window.alert("缺少 ONLYOFFICE 地址,请在 .env.local 配置 NEXT_PUBLIC_ONLYOFFICE_BASE_URL");
|
||||
return;
|
||||
}
|
||||
void (async () => {
|
||||
try {
|
||||
const res = await fetch(`/api/media/sign?assetId=${encodeURIComponent(asset.id)}`);
|
||||
if (!res.ok) {
|
||||
const payload = await res.json().catch(() => null);
|
||||
throw new Error(payload?.error ?? "生成签名链接失败");
|
||||
}
|
||||
const { signedUrl } = (await res.json()) as { signedUrl: string };
|
||||
const target = new URL("/onlyoffice", window.location.origin);
|
||||
target.searchParams.set("fileUrl", signedUrl);
|
||||
target.searchParams.set("fileName", asset.file_name ?? `未命名.${officeFileType}`);
|
||||
target.searchParams.set("fileType", officeFileType);
|
||||
target.searchParams.set("assetId", asset.id);
|
||||
window.open(target.toString(), "_blank", "noopener,noreferrer");
|
||||
setOpen(false);
|
||||
} catch (error) {
|
||||
window.alert((error as Error).message);
|
||||
}
|
||||
})();
|
||||
return;
|
||||
}
|
||||
|
||||
const url = asset.signed_url ?? asset.file_url;
|
||||
if (!url) {
|
||||
window.alert("暂无可用的文件链接");
|
||||
|
||||
Reference in New Issue
Block a user