2026-05-26 01:58:00 +08:00
|
|
|
export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => {
|
|
|
|
|
const {
|
|
|
|
|
copyWorkspaceSourceParams,
|
|
|
|
|
currentDocumentId,
|
|
|
|
|
currentRootUri,
|
2026-05-28 22:01:44 +08:00
|
|
|
currentSourceKind,
|
2026-05-26 01:58:00 +08:00
|
|
|
fileTreeIconKindForFileName,
|
|
|
|
|
getNavigationInFlight,
|
|
|
|
|
isCodeAttachmentFileName,
|
|
|
|
|
isNonOfficeAttachmentName,
|
2026-05-28 22:01:44 +08:00
|
|
|
isPdfAttachmentFileName,
|
2026-05-26 01:58:00 +08:00
|
|
|
openCodeEditorAttachment,
|
|
|
|
|
resolveWorkspaceId,
|
|
|
|
|
setNavigationInFlight,
|
|
|
|
|
shouldOpenLocalResourceInNewWindow,
|
|
|
|
|
uploadedFileSize,
|
|
|
|
|
} = dependencies;
|
2026-05-28 22:01:44 +08:00
|
|
|
const currentSourceKindFn = typeof currentSourceKind === 'function' ? currentSourceKind : function() { return ''; };
|
2026-05-26 01:58:00 +08:00
|
|
|
|
|
|
|
|
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) {
|
2026-05-28 22:01:44 +08:00
|
|
|
if (shouldUseOfficePreview(input.fileType, input.mode)) {
|
|
|
|
|
return buildOfficePreviewOpenUrl(input);
|
|
|
|
|
}
|
2026-05-26 01:58:00 +08:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-28 22:01:44 +08:00
|
|
|
function shouldUseOfficePreview(fileType, mode) {
|
|
|
|
|
var normalizedMode = String(mode || 'view').trim().toLowerCase();
|
|
|
|
|
if (normalizedMode === 'edit') return false;
|
|
|
|
|
var ext = String(fileType || '').trim().toLowerCase();
|
|
|
|
|
return ['docx', 'xlsx', 'xls', 'csv', 'pptx'].indexOf(ext) >= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildOfficePreviewOpenUrl(input) {
|
|
|
|
|
var _rto_ = window.__mnoteResourceOpenRuntime;
|
|
|
|
|
if (_rto_ && typeof _rto_.buildOfficePreviewOpenUrl === 'function') {
|
|
|
|
|
return _rto_.buildOfficePreviewOpenUrl(input);
|
|
|
|
|
}
|
|
|
|
|
var target = new URL('/office-preview', window.location.origin);
|
|
|
|
|
var workspacePath = input && input.workspacePath && typeof input.workspacePath === 'object' ? input.workspacePath : {};
|
|
|
|
|
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);
|
|
|
|
|
var workspaceId = String(input.workspaceId || workspacePath.workspaceId || '').trim();
|
|
|
|
|
var sourceKind = String(input.sourceKind || workspacePath.sourceKind || currentSourceKindFn() || '').trim();
|
|
|
|
|
var rootUri = String(input.rootUri || workspacePath.rootUri || currentRootUri() || '').trim();
|
|
|
|
|
if (workspaceId) target.searchParams.set('workspaceId', workspaceId);
|
|
|
|
|
if (sourceKind) target.searchParams.set('sourceKind', sourceKind);
|
|
|
|
|
if (rootUri) target.searchParams.set('rootUri', rootUri);
|
|
|
|
|
return target.toString();
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 01:58:00 +08:00
|
|
|
function buildOnlyOfficeOpenPath(input) {
|
|
|
|
|
var _rto_ = window.__mnoteResourceOpenRuntime;
|
|
|
|
|
if (_rto_ && typeof _rto_.buildOnlyOfficeOpenPath === 'function') {
|
|
|
|
|
return _rto_.buildOnlyOfficeOpenPath(input);
|
|
|
|
|
}
|
2026-05-28 22:01:44 +08:00
|
|
|
if (shouldUseOfficePreview(input.fileType, input.mode)) {
|
|
|
|
|
return buildOfficePreviewOpenUrl(input);
|
|
|
|
|
}
|
2026-05-26 01:58:00 +08:00
|
|
|
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: '',
|
2026-05-28 22:01:44 +08:00
|
|
|
mode: mode || 'view',
|
|
|
|
|
workspaceId: resolveWorkspaceId(document.body) || '',
|
|
|
|
|
sourceKind: currentSourceKindFn() || 'local_folder',
|
|
|
|
|
rootUri: currentRootUri() || ''
|
2026-05-26 01:58:00 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function openLocalOfficeFileInActiveTab(detail, mode) {
|
|
|
|
|
var localFilePath = localFilePathFromAssetId(detail.assetId);
|
2026-05-28 22:01:44 +08:00
|
|
|
var workspacePath = workspacePathFromDetail(detail);
|
|
|
|
|
if (!localFilePath && workspacePath) localFilePath = String(workspacePath.relativePath || workspacePath.localRelativePath || '').trim();
|
2026-05-26 01:58:00 +08:00
|
|
|
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,
|
2026-05-28 22:01:44 +08:00
|
|
|
workspacePath: workspacePath,
|
2026-05-26 01:58:00 +08:00
|
|
|
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) : '';
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-28 22:01:44 +08:00
|
|
|
function workspacePathFromDetail(detail) {
|
|
|
|
|
var workspacePath = detail && detail.workspacePath && typeof detail.workspacePath === 'object' ? detail.workspacePath : null;
|
|
|
|
|
return workspacePath && workspacePath.schema === 'mnote.workspace_path.v1' ? workspacePath : null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function workspacePathObjectIdentity(workspacePath) {
|
|
|
|
|
var objectIdentity = workspacePath && workspacePath.objectIdentity && typeof workspacePath.objectIdentity === 'object'
|
|
|
|
|
? workspacePath.objectIdentity
|
|
|
|
|
: null;
|
|
|
|
|
return objectIdentity || {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resourceObjectIdentityFromWorkspacePath(input) {
|
|
|
|
|
input = input || {};
|
|
|
|
|
var workspacePath = input.workspacePath && typeof input.workspacePath === 'object' ? input.workspacePath : null;
|
|
|
|
|
var structuredIdentity = workspacePathObjectIdentity(workspacePath);
|
|
|
|
|
var objectKind = String(input.objectKind || workspacePath && (workspacePath.objectKind || workspacePath.resourceKind) || structuredIdentity.objectKind || '').trim();
|
|
|
|
|
var documentId = String(input.documentId || workspacePath && workspacePath.documentId || structuredIdentity.documentId || currentDocumentId() || '').trim();
|
|
|
|
|
var assetId = String(input.assetId || workspacePath && workspacePath.assetId || structuredIdentity.assetId || '').trim();
|
|
|
|
|
var relativePath = String(input.path || workspacePath && (workspacePath.relativePath || workspacePath.localRelativePath) || '').trim();
|
|
|
|
|
var rootUri = String(input.rootUri || workspacePath && workspacePath.rootUri || currentRootUri() || '').trim();
|
|
|
|
|
var fallback = String(input.fallback || '').trim();
|
|
|
|
|
if (objectKind === 'mindmap' && assetId) return 'resource:mindmap:' + documentId + ':' + assetId;
|
|
|
|
|
if ((objectKind === 'only_office' || objectKind === 'office') && assetId) return 'resource:onlyoffice:' + documentId + ':' + assetId;
|
|
|
|
|
if (objectKind === 'pdf' && assetId) return 'resource:pdf:' + documentId + ':' + assetId;
|
|
|
|
|
if (relativePath && rootUri) return 'resource:file:' + rootUri + ':' + relativePath;
|
|
|
|
|
if (assetId && documentId) return 'resource:' + (objectKind || 'attachment') + ':' + documentId + ':' + assetId;
|
|
|
|
|
return fallback || assetId || '';
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 01:58:00 +08:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-28 22:01:44 +08:00
|
|
|
function buildPdfPreviewOpenUrl(fileUrl, fileName) {
|
|
|
|
|
var _rto_ = window.__mnoteResourceOpenRuntime;
|
|
|
|
|
if (_rto_ && typeof _rto_.buildPdfPreviewOpenUrl === 'function') {
|
|
|
|
|
return _rto_.buildPdfPreviewOpenUrl(fileUrl, fileName);
|
|
|
|
|
}
|
|
|
|
|
var rawUrl = String(fileUrl || '').trim();
|
|
|
|
|
if (!rawUrl) return '';
|
|
|
|
|
var url = new URL('/pdf-preview', window.location.origin);
|
|
|
|
|
url.searchParams.set('fileUrl', rawUrl);
|
|
|
|
|
if (fileName) url.searchParams.set('fileName', fileName);
|
|
|
|
|
return url.toString();
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-26 01:58:00 +08:00
|
|
|
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();
|
2026-05-28 22:01:44 +08:00
|
|
|
var workspacePath = input && input.workspacePath && typeof input.workspacePath === 'object' ? input.workspacePath : null;
|
|
|
|
|
var objectIdentity = resourceObjectIdentityFromWorkspacePath({
|
|
|
|
|
workspacePath: workspacePath,
|
|
|
|
|
objectKind: kind,
|
|
|
|
|
documentId: input && input.documentId,
|
|
|
|
|
assetId: input && input.assetId,
|
|
|
|
|
path: relativePath,
|
|
|
|
|
rootUri: rootUri
|
|
|
|
|
});
|
2026-05-26 01:58:00 +08:00
|
|
|
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(),
|
2026-05-28 22:01:44 +08:00
|
|
|
workspacePath: workspacePath,
|
2026-05-26 01:58:00 +08:00
|
|
|
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') {
|
2026-05-28 22:01:44 +08:00
|
|
|
var sideWorkspacePath = workspacePathFromDetail(detail);
|
2026-05-26 01:58:00 +08:00
|
|
|
var sideLocalFilePath = localFilePathFromAssetId(assetId);
|
2026-05-28 22:01:44 +08:00
|
|
|
if (!sideLocalFilePath && sideWorkspacePath) sideLocalFilePath = String(sideWorkspacePath.relativePath || sideWorkspacePath.localRelativePath || '').trim();
|
2026-05-26 01:58:00 +08:00
|
|
|
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';
|
2026-05-28 22:01:44 +08:00
|
|
|
if (!sideOfficeUrl && isPdfAttachmentFileName(sideFileName)) sideHref = buildPdfPreviewOpenUrl(sideHref, sideFileName);
|
2026-05-26 01:58:00 +08:00
|
|
|
void window.__mnoteDocumentPaneRuntime.openResourceAsSideTarget({
|
2026-05-28 22:01:44 +08:00
|
|
|
objectIdentity: resourceObjectIdentityFromWorkspacePath({
|
|
|
|
|
workspacePath: sideWorkspacePath,
|
|
|
|
|
objectKind: sideKind,
|
|
|
|
|
documentId: detail.documentId,
|
|
|
|
|
assetId: assetId,
|
|
|
|
|
path: sideLocalFilePath,
|
|
|
|
|
rootUri: sideRootUri,
|
|
|
|
|
fallback: String(detail.objectIdentity || detail.assetId || '')
|
|
|
|
|
}),
|
2026-05-26 01:58:00 +08:00
|
|
|
assetId: assetId,
|
|
|
|
|
title: sideFileName,
|
|
|
|
|
fileName: sideFileName,
|
|
|
|
|
kind: sideKind,
|
|
|
|
|
path: sideLocalFilePath,
|
|
|
|
|
rootUri: sideRootUri,
|
|
|
|
|
href: sideHref,
|
|
|
|
|
officeUrl: sideOfficeUrl,
|
|
|
|
|
documentId: String(detail.documentId || currentDocumentId() || ''),
|
2026-05-28 22:01:44 +08:00
|
|
|
workspaceId: String(detail.workspaceId || resolveWorkspaceId(document.body) || ''),
|
|
|
|
|
workspacePath: sideWorkspacePath
|
2026-05-26 01:58:00 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-05-28 22:01:44 +08:00
|
|
|
var detailWorkspacePath = workspacePathFromDetail(detail);
|
2026-05-26 01:58:00 +08:00
|
|
|
var localFilePath = localFilePathFromAssetId(assetId);
|
2026-05-28 22:01:44 +08:00
|
|
|
if (!localFilePath && detailWorkspacePath) localFilePath = String(detailWorkspacePath.relativePath || detailWorkspacePath.localRelativePath || '').trim();
|
2026-05-26 01:58:00 +08:00
|
|
|
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({
|
2026-05-28 22:01:44 +08:00
|
|
|
objectIdentity: resourceObjectIdentityFromWorkspacePath({
|
|
|
|
|
workspacePath: detailWorkspacePath,
|
|
|
|
|
objectKind: 'mindmap',
|
|
|
|
|
documentId: detail && detail.documentId,
|
|
|
|
|
assetId: assetId,
|
|
|
|
|
path: localFilePath
|
|
|
|
|
}),
|
2026-05-26 01:58:00 +08:00
|
|
|
assetId: assetId,
|
|
|
|
|
mindmapId: assetId,
|
|
|
|
|
title: String(detail && detail.title || localFileName || '思维导图').trim(),
|
|
|
|
|
fileName: localFileName,
|
|
|
|
|
kind: 'mindmap',
|
|
|
|
|
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
|
2026-05-28 22:01:44 +08:00
|
|
|
workspaceId: String(detail.workspaceId || '').trim(),
|
|
|
|
|
workspacePath: detailWorkspacePath
|
2026-05-26 01:58:00 +08:00
|
|
|
});
|
|
|
|
|
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(),
|
2026-05-28 22:01:44 +08:00
|
|
|
officeUrl: localOfficeUrl,
|
|
|
|
|
workspacePath: detailWorkspacePath
|
2026-05-26 01:58:00 +08:00
|
|
|
})) return;
|
|
|
|
|
window.open(localOfficeUrl, '_blank', 'noopener,noreferrer');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var localFileUrl = buildLocalFileOpenUrl(localFilePath, false);
|
|
|
|
|
if (localFileUrl) {
|
2026-05-28 22:01:44 +08:00
|
|
|
var localOpenUrl = isPdfAttachmentFileName(localFileName) ? buildPdfPreviewOpenUrl(localFileUrl, localFileName) : localFileUrl;
|
2026-05-26 01:58:00 +08:00
|
|
|
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(),
|
2026-05-28 22:01:44 +08:00
|
|
|
href: localOpenUrl,
|
|
|
|
|
workspacePath: detailWorkspacePath
|
2026-05-26 01:58:00 +08:00
|
|
|
})) return;
|
2026-05-28 22:01:44 +08:00
|
|
|
window.open(localOpenUrl, '_blank', 'noopener,noreferrer');
|
2026-05-26 01:58:00 +08:00
|
|
|
}
|
|
|
|
|
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({
|
2026-05-28 22:01:44 +08:00
|
|
|
objectIdentity: resourceObjectIdentityFromWorkspacePath({
|
|
|
|
|
workspacePath: detailWorkspacePath,
|
|
|
|
|
objectKind: 'mindmap',
|
|
|
|
|
documentId: documentId,
|
|
|
|
|
assetId: assetId
|
|
|
|
|
}),
|
2026-05-26 01:58:00 +08:00
|
|
|
assetId: assetId,
|
|
|
|
|
mindmapId: assetId,
|
|
|
|
|
title: String(detail.title || '思维导图').trim(),
|
|
|
|
|
fileName: String(detail.title || '思维导图').trim(),
|
|
|
|
|
kind: 'mindmap',
|
|
|
|
|
documentId: documentId,
|
2026-05-28 22:01:44 +08:00
|
|
|
workspaceId: String(detail.workspaceId || '').trim(),
|
|
|
|
|
workspacePath: detailWorkspacePath
|
2026-05-26 01:58:00 +08:00
|
|
|
});
|
|
|
|
|
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({
|
2026-05-28 22:01:44 +08:00
|
|
|
objectIdentity: resourceObjectIdentityFromWorkspacePath({
|
|
|
|
|
workspacePath: detailWorkspacePath,
|
|
|
|
|
objectKind: 'only_office',
|
|
|
|
|
documentId: String(asset.document_id || detail.documentId || '').trim(),
|
|
|
|
|
assetId: assetId
|
|
|
|
|
}),
|
2026-05-26 01:58:00 +08:00
|
|
|
assetId: assetId,
|
|
|
|
|
title: fileName,
|
|
|
|
|
fileName: fileName,
|
|
|
|
|
kind: 'office',
|
|
|
|
|
officeUrl: officeUrl,
|
|
|
|
|
documentId: String(asset.document_id || detail.documentId || '').trim(),
|
2026-05-28 22:01:44 +08:00
|
|
|
workspaceId: String(detail.workspaceId || '').trim(),
|
|
|
|
|
workspacePath: detailWorkspacePath
|
2026-05-26 01:58:00 +08:00
|
|
|
});
|
|
|
|
|
if (didOpen) return;
|
|
|
|
|
}
|
|
|
|
|
window.open(officeUrl, '_blank', 'noopener,noreferrer');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-05-28 22:01:44 +08:00
|
|
|
if (isPdfAttachmentFileName(fileName)) {
|
|
|
|
|
var pdfPreviewUrl = buildPdfPreviewOpenUrl(fileUrl, fileName);
|
|
|
|
|
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
|
|
|
|
|
var didOpenPdf = await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
|
|
|
|
|
objectIdentity: resourceObjectIdentityFromWorkspacePath({
|
|
|
|
|
workspacePath: detailWorkspacePath,
|
|
|
|
|
objectKind: 'pdf',
|
|
|
|
|
documentId: String(asset.document_id || detail.documentId || '').trim(),
|
|
|
|
|
assetId: assetId
|
|
|
|
|
}),
|
|
|
|
|
assetId: assetId,
|
|
|
|
|
title: fileName,
|
|
|
|
|
fileName: fileName,
|
|
|
|
|
kind: 'pdf',
|
|
|
|
|
href: pdfPreviewUrl,
|
|
|
|
|
documentId: String(asset.document_id || detail.documentId || '').trim(),
|
|
|
|
|
workspaceId: String(detail.workspaceId || '').trim(),
|
|
|
|
|
workspacePath: detailWorkspacePath
|
|
|
|
|
});
|
|
|
|
|
if (didOpenPdf) return;
|
|
|
|
|
}
|
|
|
|
|
window.open(pdfPreviewUrl || fileUrl, '_blank', 'noopener,noreferrer');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-05-26 01:58:00 +08:00
|
|
|
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,
|
2026-05-28 22:01:44 +08:00
|
|
|
buildOfficePreviewOpenUrl,
|
2026-05-26 01:58:00 +08:00
|
|
|
buildOnlyOfficeOpenPath,
|
|
|
|
|
buildOnlyOfficeOpenUrl,
|
2026-05-28 22:01:44 +08:00
|
|
|
buildPdfPreviewOpenUrl,
|
2026-05-26 01:58:00 +08:00
|
|
|
fetchCurrentOnlyOfficeUserId,
|
|
|
|
|
inferOnlyOfficeFileType,
|
|
|
|
|
isMindmapAssetDetail,
|
|
|
|
|
localFilePathFromAssetId,
|
|
|
|
|
navigateToMindmapObject,
|
|
|
|
|
openConvexAssetFromFileTree,
|
|
|
|
|
openLocalOfficeFileInActiveTab,
|
|
|
|
|
openLocalResourceInActiveTab,
|
|
|
|
|
readFileTreeObjectIdentity,
|
2026-05-28 22:01:44 +08:00
|
|
|
resourceObjectIdentityFromWorkspacePath,
|
|
|
|
|
workspacePathFromDetail,
|
2026-05-26 01:58:00 +08:00
|
|
|
};
|
|
|
|
|
};
|