/** * 文档集对话框组件 * 功能:添加文档集的对话框 */ export function getDocsetDialogContent(): string { return `

添加文档集

支持 .md/.txt/.v/.sv/.pdf,单个文件最大 10 MB,文档集最大 50 MB,最多 1000 个文件
确认删除
修改名称
`; } export function getDocsetDialogStyles(): string { return ` .docset-dialog { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10000; } .docset-dialog.active { display: flex; align-items: center; justify-content: center; } .docset-dialog-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); } .docset-dialog-content { position: relative; width: 90%; max-width: 500px; background: var(--vscode-editor-background); border: 1px solid var(--vscode-panel-border); border-radius: 8px; display: flex; flex-direction: column; max-height: 80vh; } .docset-dialog-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--vscode-panel-border); } .docset-dialog-header h3 { margin: 0; font-size: 16px; font-weight: 600; } .docset-dialog-header button { width: 32px; height: 32px; background: transparent; border: none; font-size: 24px; cursor: pointer; color: var(--vscode-foreground); border-radius: 4px; } .docset-dialog-header button:hover { background: var(--vscode-toolbar-hoverBackground); } .docset-dialog-body { padding: 20px; overflow-y: auto; } .docset-form-group { margin-bottom: 20px; } .docset-form-group label { display: block; margin-bottom: 8px; font-size: 13px; font-weight: 500; } .docset-hint { font-size: 11px; font-weight: 400; color: var(--vscode-descriptionForeground); margin-bottom: 8px; } .docset-form-group input { width: 100%; padding: 8px 12px; background: var(--vscode-input-background); border: 1px solid var(--vscode-input-border); border-radius: 4px; color: var(--vscode-input-foreground); font-size: 13px; box-sizing: border-box; } .docset-add-file-btn { display: flex; align-items: center; gap: 4px; padding: 6px 12px; background: transparent; color: var(--vscode-textLink-foreground); border: 1px solid var(--vscode-textLink-foreground); border-radius: 4px; cursor: pointer; font-size: 12px; } .docset-add-file-btn:hover { background: var(--vscode-toolbar-hoverBackground); } .docset-add-file-btn svg { width: 14px; height: 14px; } .docset-dialog-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 16px 20px; border-top: 1px solid var(--vscode-panel-border); } .docset-dialog-footer button { padding: 6px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 13px; } .docset-btn-cancel { background: var(--vscode-button-secondaryBackground); color: var(--vscode-button-secondaryForeground); } .docset-btn-cancel:hover { background: var(--vscode-button-secondaryHoverBackground); } .docset-btn-confirm { background: var(--vscode-button-background); color: var(--vscode-button-foreground); } .docset-btn-confirm:hover { background: var(--vscode-button-hoverBackground); } .docset-delete-btn, .docset-change-btn { position: relative; background: transparent; border: none; cursor: pointer; padding: 4px; color: var(--vscode-foreground); opacity: 0.6; } .docset-delete-btn:hover, .docset-change-btn:hover { opacity: 1; } .docset-delete-btn:hover::after, .docset-change-btn:hover::after { content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); background: var(--vscode-editorHoverWidget-background); color: var(--vscode-editorHoverWidget-foreground); border: 1px solid var(--vscode-editorHoverWidget-border); padding: 4px 8px; border-radius: 3px; font-size: 12px; white-space: nowrap; margin-bottom: 4px; z-index: 1000; } .delete-confirm-dialog { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.4); z-index: 10000; align-items: center; justify-content: center; } .delete-confirm-dialog.active { display: flex; } .delete-confirm-content { background: var(--vscode-editor-background); border: 1px solid var(--vscode-panel-border); border-radius: 6px; padding: 20px; min-width: 300px; max-width: 400px; } .delete-confirm-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; } .delete-confirm-message { font-size: 13px; color: var(--vscode-descriptionForeground); margin-bottom: 16px; } .delete-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; } .delete-confirm-actions button { padding: 6px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 13px; } .rename-dialog { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.4); z-index: 10000; align-items: center; justify-content: center; } .rename-dialog.active { display: flex; } .rename-content { background: var(--vscode-editor-background); border: 1px solid var(--vscode-panel-border); border-radius: 6px; padding: 20px; min-width: 300px; max-width: 400px; } .rename-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; } .rename-input { width: 100%; padding: 8px 12px; background: var(--vscode-input-background); border: 1px solid var(--vscode-input-border); border-radius: 4px; color: var(--vscode-input-foreground); font-size: 13px; box-sizing: border-box; margin-bottom: 16px; } .rename-actions { display: flex; justify-content: flex-end; gap: 8px; } .rename-actions button { padding: 6px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 13px; } `; } export function getDocsetDialogScript(): string { return ` let docsetFiles = []; function openAddDocumentSetDialog() { const dialog = document.getElementById('docsetDialog'); if (dialog) { dialog.classList.add('active'); docsetFiles = []; document.getElementById('docsetName').value = ''; document.getElementById('addFileBtn').style.display = 'flex'; document.getElementById('docsetFilesDisplay').style.display = 'none'; } } function closeDocsetDialog() { const dialog = document.getElementById('docsetDialog'); if (dialog) { dialog.classList.remove('active'); } } function addFileToDocset() { vscode.postMessage({ command: 'selectFilesForDocset' }); } function formatFileSize(bytes) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; } function updateDocsetDisplay() { if (docsetFiles.length === 0) { document.getElementById('addFileBtn').style.display = 'flex'; document.getElementById('docsetFilesDisplay').style.display = 'none'; return; } document.getElementById('addFileBtn').style.display = 'none'; document.getElementById('docsetFilesDisplay').style.display = 'block'; const listEl = document.getElementById('docsetFilesList'); const summaryEl = document.getElementById('docsetFilesSummary'); listEl.innerHTML = docsetFiles.map((file, index) => \`
\${file.name || file.absolutePath}
\`).join(''); const totalSize = docsetFiles.reduce((sum, f) => sum + (f.size || 0), 0); summaryEl.textContent = \`已选择 \${docsetFiles.length} 个文件,总大小 \${formatFileSize(totalSize)}\`; } function removeDocsetFile(index) { docsetFiles.splice(index, 1); updateDocsetDisplay(); } function confirmDocset() { const name = document.getElementById('docsetName').value.trim(); if (!name) { alert('请输入文档集名称'); return; } if (docsetFiles.length === 0) { alert('请添加至少一个文件'); return; } vscode.postMessage({ command: 'saveDocumentSet', name: name, documents: docsetFiles }); closeDocsetDialog(); } function renderDocumentSets(documentSets) { const listEl = document.getElementById('contextDocsList'); if (!listEl) return; if (!documentSets || documentSets.length === 0) { listEl.innerHTML = '

暂无文档集

'; return; } listEl.innerHTML = documentSets.map(ds => \`
\${ds.name}
更新于 \${new Date(ds.updatedAt).toLocaleString('zh-CN')}
\`).join(''); } let deleteTargetId = null; let renameTargetId = null; let renameOriginalName = null; window.showDeleteConfirm = function(id, name) { deleteTargetId = id; document.getElementById('deleteConfirmMessage').textContent = \`确定要删除文档集 "\${name}" 吗?此操作不可恢复。\`; document.getElementById('deleteConfirmDialog').classList.add('active'); }; window.changeDocsetName = function(id, name) { renameTargetId = id; renameOriginalName = name; document.getElementById('renameInput').value = name; document.getElementById('renameDialog').classList.add('active'); setTimeout(() => document.getElementById('renameInput').focus(), 100); }; window.closeDeleteConfirm = function() { document.getElementById('deleteConfirmDialog').classList.remove('active'); deleteTargetId = null; }; window.closeRenameDialog = function() { document.getElementById('renameDialog').classList.remove('active'); renameTargetId = null; renameOriginalName = null; }; window.confirmDelete = function() { if (deleteTargetId) { vscode.postMessage({ command: 'deleteDocumentSet', id: deleteTargetId }); closeDeleteConfirm(); } }; window.confirmRename = function() { const newName = document.getElementById('renameInput').value.trim(); if (!newName) { alert('请输入名称'); return; } if (newName !== renameOriginalName) { vscode.postMessage({ command: 'changeDocumentSetName', id: renameTargetId, newName: newName }); } closeRenameDialog(); }; window.addEventListener('message', event => { const message = event.data; if (message.command === 'filesSelectedForDocset') { if (message.errors && message.errors.length > 0) { alert('部分文件添加失败:\\n' + message.errors.join('\\n')); } const MAX_FILE_SIZE = 10 * 1024 * 1024; const MAX_TOTAL_SIZE = 50 * 1024 * 1024; const MAX_FILE_COUNT = 1000; const vaildFiles = []; const errors = []; for (const file of message.files) { if (file.size > MAX_FILE_SIZE) { errors.push(\`\${file.name || file.absolutePath} 超过单个文件大小限制(\${formatFileSize(MAX_FILE_SIZE)})\`); } else { vaildFiles.push(file); } } const newFiles = [...docsetFiles, ...vaildFiles]; const totalSize = newFiles.reduce((sum, f) => sum + (f.size || 0), 0); if (newFiles.length > MAX_FILE_COUNT) { errors.push(\`文档数量超过限制(最多1000个),当前数量(\${newFiles.length} 个)\`); return; } if (totalSize > MAX_TOTAL_SIZE) { errors.push(\`文档集总大小超过 50MB 限制,当前大小为(\${formatFileSize(MAX_TOTAL_SIZE)})\`); return; } if(errors.length > 0) { alert('以下文件被跳过:\\n' + errors.join('\\n')); } docsetFiles = newFiles; updateDocsetDisplay(); } else if (message.command === 'documentSetSaved') { renderDocumentSets(message.documentSets); } }); `; }