Add files via upload

This commit is contained in:
公明
2026-03-13 20:08:09 +08:00
committed by GitHub
parent cc555af8dd
commit 8bdab678fa
2 changed files with 112 additions and 15 deletions

View File

@@ -1244,6 +1244,9 @@ function addMessage(role, content, mcpExecutionIds = null, progressId = null, cr
const msgTimeOpts = { hour: '2-digit', minute: '2-digit' };
if (msgTimeLocale === 'zh-CN') msgTimeOpts.hour12 = false;
timeDiv.textContent = messageTime.toLocaleTimeString(msgTimeLocale, msgTimeOpts);
try {
timeDiv.dataset.messageTime = messageTime.toISOString();
} catch (e) { /* ignore */ }
contentWrapper.appendChild(timeDiv);
// 如果有MCP执行ID或进度ID添加查看详情区域统一使用"渗透测试详情"样式)
@@ -1594,10 +1597,19 @@ async function showMCPDetail(executionId) {
const normalizedStatus = (exec.status || 'unknown').toLowerCase();
statusEl.textContent = getStatusText(exec.status);
statusEl.className = `status-chip status-${normalizedStatus}`;
try {
statusEl.dataset.detailStatus = (exec.status || '') + '';
} catch (e) { /* ignore */ }
const detailTimeLocale = (typeof window.__locale === 'string' && window.__locale.startsWith('zh')) ? 'zh-CN' : 'en-US';
document.getElementById('detail-time').textContent = exec.startTime
? new Date(exec.startTime).toLocaleString(detailTimeLocale)
: '—';
const detailTimeEl = document.getElementById('detail-time');
if (detailTimeEl) {
detailTimeEl.textContent = exec.startTime
? new Date(exec.startTime).toLocaleString(detailTimeLocale)
: '—';
try {
detailTimeEl.dataset.detailTimeIso = exec.startTime ? new Date(exec.startTime).toISOString() : '';
} catch (e) { /* ignore */ }
}
// 请求参数
const requestData = {
@@ -5273,9 +5285,60 @@ function closeBatchManageModal() {
allConversationsForBatch = [];
}
// 语言切换时刷新批量管理模态框标题(若当前正在显示);并刷新对话列表时间格式与系统就绪提示
// 语言切换时刷新当前聊天页内的时间与动态文案(消息时间、执行流程时间由 monitor 的 refreshProgressAndTimelineI18n 处理)
function refreshChatPanelI18n() {
const locale = (typeof window.__locale === 'string' && window.__locale.startsWith('zh')) ? 'zh-CN' : 'en-US';
const timeOpts = { hour: '2-digit', minute: '2-digit' };
if (locale === 'zh-CN') timeOpts.hour12 = false;
const t = typeof window.t === 'function' ? window.t : function (k) { return k; };
const messagesEl = document.getElementById('chat-messages');
if (messagesEl) {
messagesEl.querySelectorAll('.message-time[data-message-time]').forEach(function (el) {
try {
const d = new Date(el.dataset.messageTime);
if (!isNaN(d.getTime())) {
el.textContent = d.toLocaleTimeString(locale, timeOpts);
}
} catch (e) { /* ignore */ }
});
messagesEl.querySelectorAll('.mcp-call-label').forEach(function (el) {
el.textContent = '\uD83D\uDCCB ' + t('chat.penetrationTestDetail');
});
messagesEl.querySelectorAll('.process-detail-btn').forEach(function (btn) {
const span = btn.querySelector('span');
if (!span) return;
const assistantEl = btn.closest('.message.assistant');
const messageId = assistantEl && assistantEl.id;
const detailsId = messageId ? 'process-details-' + messageId : '';
const timeline = detailsId ? document.getElementById(detailsId) && document.getElementById(detailsId).querySelector('.progress-timeline') : null;
const expanded = timeline && timeline.classList.contains('expanded');
span.textContent = expanded ? t('tasks.collapseDetail') : t('chat.expandDetail');
});
}
const mcpModal = document.getElementById('mcp-detail-modal');
if (mcpModal && mcpModal.style.display === 'block') {
const detailTimeEl = document.getElementById('detail-time');
if (detailTimeEl && detailTimeEl.dataset.detailTimeIso) {
try {
const d = new Date(detailTimeEl.dataset.detailTimeIso);
if (!isNaN(d.getTime())) {
detailTimeEl.textContent = d.toLocaleString(locale);
}
} catch (e) { /* ignore */ }
}
const statusEl = document.getElementById('detail-status');
if (statusEl && statusEl.dataset.detailStatus !== undefined && typeof getStatusText === 'function') {
statusEl.textContent = getStatusText(statusEl.dataset.detailStatus);
}
}
}
// 语言切换时刷新批量管理模态框标题(若当前正在显示);并刷新对话列表时间格式与系统就绪提示;刷新当前页消息时间与动态文案
document.addEventListener('languagechange', function () {
refreshSystemReadyMessageBubbles();
refreshChatPanelI18n();
const modal = document.getElementById('batch-manage-modal');
if (modal && modal.style.display === 'flex') {
updateBatchManageTitle(allConversationsForBatch.length);

View File

@@ -896,17 +896,28 @@ function addTimelineItem(timeline, type, options) {
item.className = `timeline-item timeline-item-${type}`;
// 记录类型与参数,便于 languagechange 时刷新标题文案
item.dataset.timelineType = type;
if (type === 'iteration' && options.iterationN != null) {
item.dataset.iterationN = String(options.iterationN);
if (type === 'iteration') {
const n = options.iterationN != null ? options.iterationN : (options.data && options.data.iteration != null ? options.data.iteration : 1);
item.dataset.iterationN = String(n);
}
if (type === 'progress' && options.message) {
item.dataset.progressMessage = options.message;
}
if (type === 'tool_calls_detected' && options.data && options.data.count != null) {
item.dataset.toolCallsCount = String(options.data.count);
}
// 保存事件时间 ISO语言切换时可重算时间格式
try {
item.dataset.createdAtIso = eventTime.toISOString();
} catch (e) { /* ignore */ }
if (type === 'tool_call' && options.data) {
const d = options.data;
item.dataset.toolName = (d.toolName != null && d.toolName !== '') ? String(d.toolName) : '';
item.dataset.toolIndex = (d.index != null) ? String(d.index) : '0';
item.dataset.toolTotal = (d.total != null) ? String(d.total) : '0';
}
if (type === 'tool_result' && options.data) {
const d = options.data;
item.dataset.toolName = (d.toolName != null && d.toolName !== '') ? String(d.toolName) : '';
item.dataset.toolSuccess = d.success !== false ? '1' : '0';
}
// 使用传入的createdAt时间如果没有则使用当前时间向后兼容
let eventTime;
if (options.createdAt) {
@@ -925,7 +936,11 @@ function addTimelineItem(timeline, type, options) {
} else {
eventTime = new Date();
}
// 保存事件时间 ISO语言切换时可重算时间格式
try {
item.dataset.createdAtIso = eventTime.toISOString();
} catch (e) { /* ignore */ }
const timeLocale = getCurrentTimeLocale();
const timeOpts = getTimeFormatOptions();
const time = eventTime.toLocaleTimeString(timeLocale, timeOpts);
@@ -948,7 +963,7 @@ function addTimelineItem(timeline, type, options) {
<div class="timeline-item-content">
<div class="tool-details">
<div class="tool-arg-section">
<strong>${escapeHtml(paramsLabel)}</strong>
<strong data-i18n="timeline.params">${escapeHtml(paramsLabel)}</strong>
<pre class="tool-args">${escapeHtml(JSON.stringify(args, null, 2))}</pre>
</div>
</div>
@@ -965,9 +980,9 @@ function addTimelineItem(timeline, type, options) {
content += `
<div class="timeline-item-content">
<div class="tool-result-section ${isError ? 'error' : 'success'}">
<strong>${escapeHtml(execResultLabel)}</strong>
<strong data-i18n="timeline.executionResult">${escapeHtml(execResultLabel)}</strong>
<pre class="tool-result">${escapeHtml(resultStr)}</pre>
${data.executionId ? `<div class="tool-execution-id">${escapeHtml(execIdLabel)} <code>${escapeHtml(data.executionId)}</code></div>` : ''}
${data.executionId ? `<div class="tool-execution-id"><span data-i18n="timeline.executionId">${escapeHtml(execIdLabel)}</span> <code>${escapeHtml(data.executionId)}</code></div>` : ''}
</div>
</div>
`;
@@ -1771,6 +1786,11 @@ function refreshProgressAndTimelineI18n() {
titleEl.textContent = '\uD83D\uDD0D ' + translateProgressMessage(raw);
}
});
// 转换后的详情区顶栏「渗透测试详情」:仅刷新不在 .progress-message 内的 progress 标题
document.querySelectorAll('.progress-container .progress-header .progress-title').forEach(function (titleEl) {
if (titleEl.closest('.progress-message')) return;
titleEl.textContent = '\uD83D\uDCCB ' + _t('chat.penetrationTestDetail');
});
// 时间线项:按类型重算标题,并重绘时间戳
document.querySelectorAll('.timeline-item').forEach(function (item) {
@@ -1786,6 +1806,20 @@ function refreshProgressAndTimelineI18n() {
} else if (type === 'tool_calls_detected' && item.dataset.toolCallsCount != null) {
const count = parseInt(item.dataset.toolCallsCount, 10) || 0;
titleSpan.textContent = '\uD83D\uDD27 ' + _t('chat.toolCallsDetected', { count: count });
} else if (type === 'tool_call' && (item.dataset.toolName !== undefined || item.dataset.toolIndex !== undefined)) {
const name = (item.dataset.toolName != null && item.dataset.toolName !== '') ? item.dataset.toolName : _t('chat.unknownTool');
const index = parseInt(item.dataset.toolIndex, 10) || 0;
const total = parseInt(item.dataset.toolTotal, 10) || 0;
titleSpan.textContent = '\uD83D\uDD27 ' + _t('chat.callTool', { name: name, index: index, total: total });
} else if (type === 'tool_result' && (item.dataset.toolName !== undefined || item.dataset.toolSuccess !== undefined)) {
const name = (item.dataset.toolName != null && item.dataset.toolName !== '') ? item.dataset.toolName : _t('chat.unknownTool');
const success = item.dataset.toolSuccess === '1';
const icon = success ? '\u2705 ' : '\u274C ';
titleSpan.textContent = icon + (success ? _t('chat.toolExecComplete', { name: name }) : _t('chat.toolExecFailed', { name: name }));
} else if (type === 'cancelled') {
titleSpan.textContent = '\u26D4 ' + _t('chat.taskCancelled');
} else if (type === 'progress' && item.dataset.progressMessage !== undefined) {
titleSpan.textContent = typeof window.translateProgressMessage === 'function' ? window.translateProgressMessage(item.dataset.progressMessage) : item.dataset.progressMessage;
}
if (timeSpan && item.dataset.createdAtIso) {
const d = new Date(item.dataset.createdAtIso);