feat: 持久化 AI 审查结果,文件级内联展示与页面集成

This commit is contained in:
2026-06-19 23:24:06 +08:00
parent a89d057716
commit 0528eee4de
7 changed files with 518 additions and 23 deletions
+88
View File
@@ -780,6 +780,94 @@ const DiffViewer = {
</td>`;
row.parentNode.insertBefore(suggestionRow, row.nextSibling);
},
// ── Insert file-level suggestion (no line number required) ─────
insertFileSuggestion(filename, severity, content, suggestionId) {
const diffContent = this.container.querySelector('#diff-content');
if (!diffContent) return;
// Find or index the file
const fileEntry = this._ensureFileIndexed(filename);
if (!fileEntry) return;
const wrapper = fileEntry.wrapper;
// Expand the file if collapsed
const fileContent = wrapper.querySelector('.d2h-file-diff');
if (fileContent && fileContent.style.display === 'none') {
fileContent.style.display = 'block';
wrapper.classList.remove('d2h-collapsed');
}
// Find or create the file-level suggestions container
let sugContainer = wrapper.querySelector('.file-suggestions-container');
if (!sugContainer) {
sugContainer = document.createElement('div');
sugContainer.className = 'file-suggestions-container';
// Insert after the file header, before the diff content
const header = wrapper.querySelector('.d2h-file-header');
if (header) {
header.parentNode.insertBefore(sugContainer, header.nextSibling);
} else {
wrapper.prepend(sugContainer);
}
}
const severityStyles = {
critical: 'border-l-4 border-red-500 bg-red-50',
warning: 'border-l-4 border-yellow-500 bg-yellow-50',
info: 'border-l-4 border-green-500 bg-green-50',
};
const severityLabels = {
critical: '🔴 严重',
warning: '🟡 建议',
info: '🟢 提示',
};
const card = document.createElement('div');
card.className = `review-file-suggestion ${severityStyles[severity] || severityStyles.info} p-3 mx-2 my-1 rounded`;
card.setAttribute('data-suggestion-id', suggestionId || '');
card.innerHTML = `
<div class="flex items-center gap-2 mb-1">
<span class="text-xs font-medium">${severityLabels[severity] || severityLabels.info}</span>
</div>
<div class="text-sm text-gray-700 review-content">${typeof renderMarkdown === 'function' ? renderMarkdown(content) : content}</div>
<div class="mt-2 note-editor-placeholder" data-scope="suggestion" data-scope-key="${suggestionId || ''}"></div>`;
sugContainer.appendChild(card);
},
// ── Mark file severity in sidebar ──────────────────────────────
markFileSeverity(filename, severity) {
const treeFiles = this.container.querySelectorAll('.file-tree-file');
const severityColors = {
critical: 'bg-red-500',
warning: 'bg-yellow-500',
info: 'bg-green-500',
};
const severityOrder = { critical: 3, warning: 2, info: 1 };
for (const item of treeFiles) {
const treeName = item.getAttribute('data-filename');
if (treeName && (treeName === filename || treeName.endsWith('/' + filename) || filename.endsWith('/' + treeName))) {
let badge = item.querySelector('.file-tree-severity');
if (!badge) {
badge = document.createElement('span');
badge.className = 'file-tree-severity inline-block w-2 h-2 rounded-full ml-1';
item.querySelector('.file-tree-name').appendChild(badge);
}
// Only upgrade severity, never downgrade
const currentSev = badge.getAttribute('data-severity') || '';
if (!currentSev || (severityOrder[severity] || 0) > (severityOrder[currentSev] || 0)) {
badge.className = `file-tree-severity inline-block w-2 h-2 rounded-full ml-1 ${severityColors[severity] || severityColors.info}`;
badge.setAttribute('data-severity', severity);
}
break;
}
}
}
};