V10.613 高可見頁面繁中化
All checks were successful
CD Pipeline / deploy (push) Successful in 1m14s

This commit is contained in:
OoO
2026-06-16 09:54:27 +08:00
parent 56ebba045b
commit 239b773288
10 changed files with 118 additions and 58 deletions

View File

@@ -1,6 +1,6 @@
{% extends "ewoooc_base.html" %}
{% block title %}AI Code Review - EwoooC{% endblock %}
{% block title %}AI 程式碼審查 - EwoooC{% endblock %}
{% block extra_css %}
<style>
@@ -276,9 +276,9 @@
<!-- Top Bar -->
<div class="topbar">
<span>🔍</span>
<h1>AI Code Review</h1>
<span class="badge">EwoooC · Post-Deploy Pipeline</span>
<div id="liveDot" class="live-dot idle" title="Pipeline 狀態"></div>
<h1>AI 程式碼審查</h1>
<span class="badge">EwoooC · 部署後檢查流程</span>
<div id="liveDot" class="live-dot idle" title="流程狀態"></div>
</div>
<div class="layout">
@@ -288,16 +288,16 @@
<!-- Pipeline Steps -->
<div class="card">
<div class="card-header">🤖 Pipeline 進度
<div class="card-header">🤖 流程進度
<span id="pipelineId" style="font-size:11px;color:var(--muted);margin-left:auto;font-family:monospace"></span>
</div>
<div class="card-body">
<div class="pipeline" id="stepsContainer">
<div class="step" id="step-1"><div class="step-num">1</div><div class="step-info"><div class="step-name">讀取變更檔案</div><div class="step-agent">system</div></div></div>
<div class="step" id="step-1"><div class="step-num">1</div><div class="step-info"><div class="step-name">讀取變更檔案</div><div class="step-agent">系統</div></div></div>
<div class="step" id="step-2"><div class="step-num">2</div><div class="step-info"><div class="step-name">Hermes 程式碼掃描</div><div class="step-agent">Hermes · hermes3:latest</div></div></div>
<div class="step" id="step-3"><div class="step-num">3</div><div class="step-info"><div class="step-name">OpenClaw 架構評估</div><div class="step-agent">OpenClaw · Gemini 2.5</div></div></div>
<div class="step" id="step-3"><div class="step-num">3</div><div class="step-info"><div class="step-name">OpenClaw 架構評估</div><div class="step-agent">OpenClaw · Ollama 優先</div></div></div>
<div class="step" id="step-4"><div class="step-num">4</div><div class="step-info"><div class="step-name">Elephant Alpha 決策</div><div class="step-agent">Elephant Alpha · 100B</div></div></div>
<div class="step" id="step-5"><div class="step-num">5</div><div class="step-info"><div class="step-name">NemoTron 行動派遣</div><div class="step-agent">NemoTron · Dispatcher</div></div></div>
<div class="step" id="step-5"><div class="step-num">5</div><div class="step-info"><div class="step-name">NemoTron 行動派遣</div><div class="step-agent">NemoTron · 派遣器</div></div></div>
</div>
</div>
</div>
@@ -307,10 +307,10 @@
<div class="card-header">📊 問題嚴重度分佈</div>
<div class="card-body">
<div class="sev-grid">
<div class="sev-cell sev-critical"><div class="num" id="cnt-critical"></div><div class="lbl">🔴 CRITICAL</div></div>
<div class="sev-cell sev-high"><div class="num" id="cnt-high"></div><div class="lbl">🟠 HIGH</div></div>
<div class="sev-cell sev-medium"><div class="num" id="cnt-medium"></div><div class="lbl">🟡 MEDIUM</div></div>
<div class="sev-cell sev-low"><div class="num" id="cnt-low"></div><div class="lbl">🟢 LOW</div></div>
<div class="sev-cell sev-critical"><div class="num" id="cnt-critical"></div><div class="lbl">🔴 最高</div></div>
<div class="sev-cell sev-high"><div class="num" id="cnt-high"></div><div class="lbl">🟠 </div></div>
<div class="sev-cell sev-medium"><div class="num" id="cnt-medium"></div><div class="lbl">🟡 </div></div>
<div class="sev-cell sev-low"><div class="num" id="cnt-low"></div><div class="lbl">🟢 </div></div>
</div>
</div>
</div>
@@ -354,7 +354,7 @@
</div>
<div class="card-body" style="padding:0">
<div id="findingsTable">
<div class="empty"><div class="icon">🔍</div><div>等待 Code Review 完成...</div></div>
<div class="empty"><div class="icon">🔍</div><div>等待程式碼審查完成...</div></div>
</div>
</div>
</div>
@@ -392,6 +392,9 @@
{% block extra_js %}
<script>
const SEV_ORDER = { CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3 };
const SEV_LABEL = { CRITICAL: '最高', HIGH: '高', MEDIUM: '中', LOW: '低' };
const PRIORITY_LABEL = { critical: '最高', high: '高', medium: '中', low: '低' };
const DEPLOY_TYPE_LABEL = { sync: '同步部署', rebuild: '重建部署', manual: '手動觸發' };
let _polling = null;
let _lastPipelineId = null;
@@ -452,7 +455,7 @@ function renderFindings(findings) {
<thead><tr><th>嚴重度</th><th>類型</th><th>檔案 / 位置</th><th>問題說明</th><th>修復建議</th></tr></thead>
<tbody>${sorted.map(f => `
<tr>
<td><span class="badge-sev badge-${f.severity}">${f.severity}</span></td>
<td><span class="badge-sev badge-${f.severity}">${SEV_LABEL[f.severity] || f.severity || '?'}</span></td>
<td><span class="badge-type">${f.type||'?'}</span></td>
<td><code>${(f.file||'').split('/').pop()}</code><br><span style="font-size:11px;color:var(--muted)">${f.line_hint||''}</span></td>
<td>${escHtml(f.description||'')}</td>
@@ -474,11 +477,12 @@ function renderEA(ea, autoFix) {
}
const priColors = { critical: 'var(--red)', high: 'var(--orange)', medium: 'var(--yellow)', low: 'var(--green)' };
const col = priColors[ea.priority] || 'var(--blue)';
const priorityLabel = PRIORITY_LABEL[ea.priority] || ea.priority || '待確認';
const fixFiles = (ea.fix_files||[]).map(f=>`<code>${f}</code>`).join(' ');
document.getElementById('eaDecision').innerHTML = `
<div class="ea-box ${ea.priority}">
<div style="display:flex;align-items:center;gap:10px">
<div class="ea-priority" style="color:${col}">${ea.priority.toUpperCase()}</div>
<div class="ea-priority" style="color:${col}">${priorityLabel}</div>
<div>${autoFix ? '🔧 <b>自動修復已觸發AiderHeal</b>' : (ea.human_review_needed ? '👁 <b>需人工審查</b>' : '✅ <b>無需修復</b>')}</div>
</div>
<div class="ea-reasoning">${escHtml(ea.reasoning||'')}</div>
@@ -493,9 +497,9 @@ function renderCommitInfo(state) {
const files = (state.changed_files||[]).slice(0,5).map(f=>`<code>${f.split('/').pop()}</code>`).join(' ');
const more = (state.changed_files||[]).length > 5 ? `<span style="color:var(--muted)">+${state.changed_files.length-5}</span>` : '';
el.innerHTML = `
<div><b>Commit</b> <code>${state.commit_sha.slice(0,8)}</code></div>
<div><b>Branch</b> <code>${state.branch||'?'}</code></div>
<div><b>模式</b> ${state.deploy_type||'sync'}</div>
<div><b>提交</b> <code>${state.commit_sha.slice(0,8)}</code></div>
<div><b>分支</b> <code>${state.branch||'?'}</code></div>
<div><b>模式</b> ${DEPLOY_TYPE_LABEL[state.deploy_type] || state.deploy_type || '同步部署'}</div>
<div><b>變更</b> ${files} ${more}</div>`;
}
@@ -508,9 +512,9 @@ function renderStatusBar(state) {
el.style.display = 'block';
el.className = state.status;
const msgs = {
running: `⟳ <b>Pipeline 執行中</b> — Step ${state.current_step}/5`,
completed: `✅ <b>Code Review 完成</b> — ${state.message||''}`,
error: `❌ <b>Pipeline 失敗</b> — ${escHtml(state.message||'')}`,
running: `⟳ <b>流程執行中</b> — ${state.current_step}/5`,
completed: `✅ <b>程式碼審查完成</b> — ${state.message||''}`,
error: `❌ <b>流程失敗</b> — ${escHtml(state.message||'')}`,
skipped: `⏭ <b>已略過</b> — ${escHtml(state.message||'')}`,
};
el.innerHTML = msgs[state.status] || '';
@@ -554,15 +558,15 @@ function loadHistoryItem(idx) {
const files = (h.changed_files||[]).slice(0,5).map(f=>`<code>${f.split('/').pop()}</code>`).join(' ');
const more = (h.changed_files||[]).length > 5 ? `<span style="color:var(--muted)">+${h.changed_files.length-5}</span>` : '';
document.getElementById('commitInfo').innerHTML = `
<div><b>Commit</b> <code>${h.commit_sha}</code></div>
<div><b>Branch</b> <code>${h.branch||'?'}</code></div>
<div><b>提交</b> <code>${h.commit_sha}</code></div>
<div><b>分支</b> <code>${h.branch||'?'}</code></div>
<div><b>時間</b> ${h.created_at.slice(0,16).replace('T',' ')}</div>
<div><b>變更</b> ${files} ${more}</div>`;
document.getElementById('pipelineId').textContent = (h.pipeline_id||'').slice(-14);
const sBar = document.getElementById('statusBar');
sBar.style.display = 'block';
sBar.className = 'completed';
sBar.innerHTML = `✅ <b>歷史記錄</b> — Commit ${h.commit_sha}${h.auto_fix ? ' 🔧 已自動修復' : ''}`;
sBar.innerHTML = `✅ <b>歷史記錄</b> — 提交 ${h.commit_sha}${h.auto_fix ? ' 🔧 已自動修復' : ''}`;
renderFindings(h.findings || []);
renderOpenClaw(h.openclaw_report || '');
renderEA(h.ea_decision || {}, h.auto_fix || false);