export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => { const { copyWorkspaceSourceParams, currentDocumentId, currentRootUri, fileTreeIconKindForFileName, getNavigationInFlight, isCodeAttachmentFileName, isNonOfficeAttachmentName, openCodeEditorAttachment, resolveWorkspaceId, setNavigationInFlight, shouldOpenLocalResourceInNewWindow, uploadedFileSize, } = dependencies; function inferOnlyOfficeFileType(fileName, mimeType) { var name = String(fileName || '').trim().toLowerCase(); var mt = String(mimeType || '').trim().toLowerCase(); var ext = name.indexOf('.') >= 0 ? name.split('.').pop() : ''; if (['doc', 'docx', 'odt', 'rtf'].indexOf(ext) >= 0) return ext; if (['ppt', 'pptx', 'odp'].indexOf(ext) >= 0) return ext; if (['xls', 'xlsx', 'ods', 'csv'].indexOf(ext) >= 0) return ext; if (isNonOfficeAttachmentName(name, ext)) return ''; if (mt.indexOf('wordprocessingml') >= 0) return 'docx'; if (mt.indexOf('presentationml') >= 0) return 'pptx'; if (mt.indexOf('spreadsheetml') >= 0) return 'xlsx'; return ''; } function buildOnlyOfficeOpenUrl(input) { var target = new URL('/onlyoffice', window.location.origin); var fileUrl = String(input.fileUrl || '').trim(); if (fileUrl) { try { fileUrl = new URL(fileUrl, window.location.origin).toString(); } catch (_error) {} } target.searchParams.set('fileUrl', fileUrl); target.searchParams.set('fileName', input.fileName || '未命名资源'); target.searchParams.set('fileType', input.fileType || 'docx'); if (input.assetId) target.searchParams.set('assetId', input.assetId); if (input.documentId) target.searchParams.set('documentId', input.documentId); if (input.userId) target.searchParams.set('userId', input.userId); target.searchParams.set('mode', input.mode || 'view'); return target.toString(); } function buildOnlyOfficeOpenPath(input) { var _rto_ = window.__mnoteResourceOpenRuntime; if (_rto_ && typeof _rto_.buildOnlyOfficeOpenPath === 'function') { return _rto_.buildOnlyOfficeOpenPath(input); } var params = new URLSearchParams(); params.set('fileUrl', input.fileUrl || ''); params.set('fileName', input.fileName || '未命名资源'); params.set('fileType', input.fileType || 'docx'); if (input.assetId) params.set('assetId', input.assetId); if (input.documentId) params.set('documentId', input.documentId); if (input.userId) params.set('userId', input.userId); params.set('mode', input.mode || 'view'); if (input.documentId && input.assetId) { return '/office/' + encodeURIComponent(input.documentId) + '/' + encodeURIComponent(input.assetId) + '?' + params.toString(); } return '/onlyoffice?' + params.toString(); } function buildLocalOnlyOfficeOpenUrl(relativePath, fileName, documentId, assetId, mode) { var fileType = inferOnlyOfficeFileType(fileName || relativePath || '', ''); if (!fileType) return ''; var fileUrl = buildLocalFileOpenUrl(relativePath, false); if (!fileUrl) return ''; return buildOnlyOfficeOpenUrl({ fileUrl: fileUrl, fileName: fileName || relativePath || '未命名资源', fileType: fileType, assetId: assetId || ('local-file:' + relativePath), documentId: documentId || currentDocumentId() || '', userId: '', mode: mode || 'view' }); } async function openLocalOfficeFileInActiveTab(detail, mode) { var localFilePath = localFilePathFromAssetId(detail.assetId); if (!localFilePath) return false; var localFileName = localFilePath.split('/').pop() || localFilePath; var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail.documentId || currentDocumentId() || '').trim(), detail.assetId, mode || 'view'); if (!localOfficeUrl) return false; var opened = await openLocalResourceInActiveTab({ path: localFilePath, title: detail.fileName || localFileName, kind: 'office', assetId: detail.assetId, documentId: detail.documentId || currentDocumentId() || '', workspaceId: detail.workspaceId || resolveWorkspaceId(document.body) || '', href: buildLocalFileOpenUrl(localFilePath, false), officeUrl: localOfficeUrl, paneRole: detail.paneRole || 'primary' }); if (!opened) window.open(localOfficeUrl, '_blank', 'noopener,noreferrer'); return true; } function buildMindmapOpenPath(documentId, assetId) { var doc = String(documentId || '').trim(); var map = String(assetId || '').trim(); if (!doc || !map) return ''; var targetUrl = new URL('/mindmap/' + encodeURIComponent(doc) + '/' + encodeURIComponent(map), window.location.origin); copyWorkspaceSourceParams(targetUrl); return targetUrl.pathname + targetUrl.search; } function navigateToMindmapObject(documentId, assetId, workspaceId) { var mindmapPath = buildMindmapOpenPath(documentId, assetId); if (!mindmapPath) return false; var targetUrl = new URL(mindmapPath, window.location.origin); var url = targetUrl.pathname + targetUrl.search; if (getNavigationInFlight() === url) return true; if (typeof window.__mnoteDocumentPaneRuntime?.openPrimaryMindmap === 'function') { setNavigationInFlight(url); document.documentElement.setAttribute('data-mnote-navigation-pending', 'true'); document.documentElement.setAttribute('data-mnote-navigation-target', assetId); window.__mnoteDocumentPaneRuntime.openPrimaryMindmap({ documentId: documentId, mindmapId: assetId, workspaceId: workspaceId || '', url: targetUrl }).then(function(){ if (getNavigationInFlight() === url) setNavigationInFlight(''); document.documentElement.removeAttribute('data-mnote-navigation-pending'); }).catch(function(error){ console.warn('mnote mindmap pane 内导航失败,将回退整页导航', error); if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') { window.__mnoteTreeLiveEventSource.close(); } window.location.assign(url); }); return true; } setNavigationInFlight(url); document.documentElement.setAttribute('data-mnote-navigation-pending', 'true'); document.documentElement.setAttribute('data-mnote-navigation-target', assetId); if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') { window.__mnoteTreeLiveEventSource.close(); } window.location.assign(url); return true; } function isMindmapAssetDetail(detail) { var assetId = String(detail && detail.assetId || '').trim(); var assetType = String(detail && detail.assetType || '').trim(); if (assetType === 'mindmap') return true; var fileName = assetId.indexOf('/') >= 0 ? assetId.split('/').pop() : assetId; return assetId.indexOf('mindmap_') === 0 || assetId.indexOf('mindmap-') === 0 || /\.mindmap\.json$/i.test(fileName) || (/^思维导图/i.test(fileName) && /\.json$/i.test(fileName)); } function localFilePathFromAssetId(assetId) { var _rto_ = window.__mnoteResourceOpenRuntime; if (_rto_ && typeof _rto_.localFilePathFromAssetId === 'function') { return _rto_.localFilePathFromAssetId(assetId); } var value = String(assetId || '').trim(); return value.indexOf('local-file:') === 0 ? value.slice('local-file:'.length) : value.indexOf('local:asset:') === 0 ? value.slice('local:asset:'.length) : ''; } function buildLocalFileOpenUrl(relativePath, download) { var _rto_ = window.__mnoteResourceOpenRuntime; if (_rto_ && typeof _rto_.buildLocalFileOpenUrl === 'function') { return _rto_.buildLocalFileOpenUrl(relativePath, download); } var rootUri = currentRootUri(); if (!rootUri || !relativePath) return ''; var url = new URL('/api/local-folder/files/open', window.location.origin); url.searchParams.set('rootUri', rootUri); url.searchParams.set('path', relativePath); if (download) url.searchParams.set('download', 'true'); return url.toString(); } async function openLocalResourceInActiveTab(input) { if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab !== 'function') return false; var relativePath = String(input && input.path || '').trim(); var rootUri = String(input && input.rootUri || currentRootUri() || '').trim(); if (!relativePath || !rootUri) return false; var title = String(input && input.title || '').trim() || relativePath.split('/').pop() || relativePath; var kind = String(input && input.kind || fileTreeIconKindForFileName(title) || '').trim(); var objectIdentity = 'resource:file:' + rootUri + ':' + relativePath; return await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({ objectIdentity: objectIdentity, assetId: String(input && input.assetId || '').trim() || 'local-file:' + relativePath, title: title, fileName: title, kind: kind, rootUri: rootUri, path: relativePath, href: String(input && input.href || buildLocalFileOpenUrl(relativePath, false) || '').trim(), officeUrl: String(input && input.officeUrl || '').trim(), documentId: String(input && input.documentId || currentDocumentId() || '').trim(), workspaceId: String(input && input.workspaceId || resolveWorkspaceId(document.body) || '').trim(), paneRole: String(input && input.paneRole || 'primary').trim() || 'primary' }); } function readFileTreeObjectIdentity(row) { if (!row) return null; var raw = row.getAttribute('data-object-identity') || ''; if (!raw) return null; try { var parsed = JSON.parse(raw); return parsed && typeof parsed === 'object' ? parsed : null; } catch (_error) { return null; } } async function fetchCurrentOnlyOfficeUserId() { try { var response = await fetch('/api/auth/whoami', { method: 'GET', credentials: 'include', cache: 'no-store' }); var payload = await response.json().catch(function() { return null; }); return String(payload && payload.userId || '').trim(); } catch (_error) { return ''; } } async function openConvexAssetFromFileTree(detail) { var assetId = String(detail && detail.assetId || '').trim(); if (!assetId) return; var openTarget = String(detail && detail.openTarget || '').trim().toLowerCase(); var forceNewWindow = openTarget === 'new-window'; var forceEditMode = openTarget === 'edit-mode'; if (openTarget === 'side') { if (typeof window.__mnoteDocumentPaneRuntime?.openResourceAsSideTarget === 'function') { var sideLocalFilePath = localFilePathFromAssetId(assetId); var sideRootUri = String(detail.rootUri || currentRootUri() || '').trim(); var sideFileName = String(detail.title || detail.fileName || (sideLocalFilePath ? sideLocalFilePath.split('/').pop() : '') || assetId || '').trim(); var sideKind = String(detail.iconKind || detail.assetType || fileTreeIconKindForFileName(sideFileName) || 'file').trim(); var sideHref = sideLocalFilePath ? buildLocalFileOpenUrl(sideLocalFilePath, false) : ''; var sideOfficeUrl = sideLocalFilePath ? buildLocalOnlyOfficeOpenUrl(sideLocalFilePath, sideFileName, String(detail.documentId || currentDocumentId() || '').trim(), assetId, 'view') : ''; if (sideOfficeUrl) sideKind = 'office'; void window.__mnoteDocumentPaneRuntime.openResourceAsSideTarget({ objectIdentity: sideLocalFilePath && sideRootUri ? 'resource:file:' + sideRootUri + ':' + sideLocalFilePath : String(detail.objectIdentity || detail.assetId || ''), assetId: assetId, title: sideFileName, fileName: sideFileName, kind: sideKind, path: sideLocalFilePath, rootUri: sideRootUri, href: sideHref, officeUrl: sideOfficeUrl, documentId: String(detail.documentId || currentDocumentId() || ''), workspaceId: String(detail.workspaceId || resolveWorkspaceId(document.body) || '') }); } return; } var localFilePath = localFilePathFromAssetId(assetId); if (localFilePath) { var localFileName = localFilePath.split('/').pop() || localFilePath; if (isMindmapAssetDetail(detail) || String(detail && detail.assetType || '').trim() === 'mindmap') { if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') { document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab'); document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId); void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({ objectIdentity: 'resource:mindmap:' + String(detail && detail.documentId || currentDocumentId() || '').trim() + ':' + assetId, assetId: assetId, mindmapId: assetId, title: String(detail && detail.title || localFileName || '思维导图').trim(), fileName: localFileName, kind: 'mindmap', documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(), workspaceId: String(detail.workspaceId || '').trim() }); return; } document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell'); document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId); navigateToMindmapObject(String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, String(detail.workspaceId || '').trim()); return; } var requestedOfficeMode = forceNewWindow || forceEditMode ? 'edit' : 'view'; var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, requestedOfficeMode); if (localOfficeUrl) { if (!forceNewWindow && await openLocalResourceInActiveTab({ path: localFilePath, title: localFileName, kind: 'office', assetId: assetId, documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(), workspaceId: String(detail.workspaceId || '').trim(), officeUrl: localOfficeUrl })) return; window.open(localOfficeUrl, '_blank', 'noopener,noreferrer'); return; } var localFileUrl = buildLocalFileOpenUrl(localFilePath, false); if (localFileUrl) { var shouldOpenInNewWindow = forceNewWindow || shouldOpenLocalResourceInNewWindow(localFileName); if (!shouldOpenInNewWindow && await openLocalResourceInActiveTab({ path: localFilePath, title: localFileName, kind: fileTreeIconKindForFileName(localFileName), assetId: assetId, documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(), workspaceId: String(detail.workspaceId || '').trim(), href: localFileUrl })) return; window.open(localFileUrl, '_blank', 'noopener,noreferrer'); } return; } var documentId = String(detail && detail.documentId || '').trim(); if (isMindmapAssetDetail(detail) && documentId) { if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') { document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab'); document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId); void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({ objectIdentity: 'resource:mindmap:' + documentId + ':' + assetId, assetId: assetId, mindmapId: assetId, title: String(detail.title || '思维导图').trim(), fileName: String(detail.title || '思维导图').trim(), kind: 'mindmap', documentId: documentId, workspaceId: String(detail.workspaceId || '').trim() }); return; } document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-object-shell'); document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId); navigateToMindmapObject(documentId, assetId, String(detail.workspaceId || '').trim()); return; } try { var response = await fetch('/api/media/sign?assetId=' + encodeURIComponent(assetId), { method: 'GET', credentials: 'include' }); var payload = await response.json().catch(function() { return null; }); if (!response.ok) { throw new Error(payload && payload.error ? payload.error : '生成签名链接失败'); } var asset = payload && payload.asset && typeof payload.asset === 'object' ? payload.asset : {}; var fileUrl = String(payload && payload.signedUrl || asset.file_url || asset.signed_url || '').trim(); if (!fileUrl) throw new Error('附件链接不可用'); var fileName = String(asset.file_name || detail.fileName || '未命名资源').trim() || '未命名资源'; var fileType = inferOnlyOfficeFileType(fileName, asset.mime_type); if (fileType) { var userId = await fetchCurrentOnlyOfficeUserId(); var officeUrl = buildOnlyOfficeOpenUrl({ fileUrl: fileUrl, fileName: fileName, fileType: fileType, assetId: assetId, documentId: String(asset.document_id || detail.documentId || '').trim(), userId: userId, mode: forceEditMode ? 'edit' : 'view' }); if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') { var didOpen = await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({ objectIdentity: 'resource:onlyoffice:' + String(asset.document_id || detail.documentId || '').trim() + ':' + assetId, assetId: assetId, title: fileName, fileName: fileName, kind: 'office', officeUrl: officeUrl, documentId: String(asset.document_id || detail.documentId || '').trim(), workspaceId: String(detail.workspaceId || '').trim() }); if (didOpen) return; } window.open(officeUrl, '_blank', 'noopener,noreferrer'); return; } if (isCodeAttachmentFileName(fileName) && String(asset.document_id || detail.documentId || '').trim() === currentDocumentId()) { await openCodeEditorAttachment({ href: fileUrl, fileUrl: fileUrl, fileName: fileName, assetId: assetId, documentId: String(asset.document_id || detail.documentId || '').trim(), fileSize: uploadedFileSize(asset) }); return; } window.open(fileUrl, '_blank', 'noopener,noreferrer'); } catch (error) { window.alert(error && error.message ? error.message : '打开附件失败'); } } window.addEventListener('tree.asset.open', function(event) { void openConvexAssetFromFileTree(event.detail || {}); }); return { buildLocalFileOpenUrl, buildLocalOnlyOfficeOpenUrl, buildMindmapOpenPath, buildOnlyOfficeOpenPath, buildOnlyOfficeOpenUrl, fetchCurrentOnlyOfficeUserId, inferOnlyOfficeFileType, isMindmapAssetDetail, localFilePathFromAssetId, navigateToMindmapObject, openConvexAssetFromFileTree, openLocalOfficeFileInActiveTab, openLocalResourceInActiveTab, readFileTreeObjectIdentity, }; };