fix(portal): 讀不到就說讀不到——總圖不再把「讀不到」畫成「你沒有」(Arcrun#100)
leo 2026-08-12 打開總圖看到:「0 個實體 · 0 條關聯/知識庫還沒有任何關聯—— 上傳文件後 AI 會自動織網」。**而他庫裡有 1854 條三元組。** 那句話會叫他去做一件不需要做的事。 三個獨立的洞疊起來才變成那句謊: ① console-dashboard.ts 打 kbdb-graph-plugin 沒帶認證(同段落打 kbdb 的兩支都有帶) ② 那顆 worker 不在更新的部署清單裡 ⇒ token 一換它就落單 ③ **畫面把 null 畫成 0**——後端已經誠實回 null 了,是前端把它變成謊話 為什麼一直沒被發現:graph plugin 原本身上沒有 token ⇒ 門開著 ⇒ 沒帶也進得去。 2026-08-12 輪替後它有了 token,門關上,401 才浮出來。 📍 repo:matrix/arcrun(cypher-executor/src/routes/、console-ui/public/) 📍 票:Leo/Arcrun#100
This commit is contained in:
@@ -277,9 +277,12 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
} else {
|
||||
rows.push(sysRow('語意嵌入', '狀態讀不到', 'off'));
|
||||
}
|
||||
rows.push(sys.graph && sys.graph.ok
|
||||
? sysRow('知識圖譜', '● 正常・三元組 ' + (sys.graph.triplets == null ? '?' : sys.graph.triplets), 'ok')
|
||||
: sysRow('知識圖譜', '● 打不通', 'bad'));
|
||||
// Arcrun#100:「服務活著嗎」與「庫裡有幾條」拆兩列。混一列時,圖服務打不通會把
|
||||
// 「其實有 1854 條」整個吞掉,畫面看起來就像知識庫是空的。數字讀不到寫「讀不到」,不寫 0。
|
||||
var gOk = !!(sys.graph && sys.graph.ok);
|
||||
var tri = sys.graph && sys.graph.triplets != null ? sys.graph.triplets : null;
|
||||
rows.push(sysRow('知識圖譜服務', gOk ? '● 正常' : '● 打不通', gOk ? 'ok' : 'bad'));
|
||||
rows.push(sysRow('三元組(關聯)', tri == null ? '讀不到' : tri.toLocaleString() + ' 條', tri == null ? 'off' : ''));
|
||||
rows.push(sysRow('工作流', sys.workflow_total == null ? '讀不到' : sys.workflow_total + ' 條', sys.workflow_total == null ? 'off' : ''));
|
||||
// 精耕層 wiki 卡(leo 2026-07-07 裁:14-E 遺產總數 deprecated 不再顯示,只顯示真的新的;
|
||||
// 三元組/已嵌入 已各有一列)
|
||||
|
||||
@@ -934,14 +934,15 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
fetch(API_BASE + '/console/kb-scale-data')
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (d) {
|
||||
if (!d) return;
|
||||
var n = function (v) { return v == null ? '?' : v.toLocaleString(); };
|
||||
// #100:讀不到就明說讀不到(原本靜默 return,會把上一輪的舊數字留在畫面上)
|
||||
if (!d) { $('se-scale').textContent = '精耕層 讀不到(規模統計讀取失敗,不影響搜尋)'; return; }
|
||||
var n = function (v) { return v == null ? '讀不到' : v.toLocaleString(); };
|
||||
var parts = ['wiki 卡 ' + n(d.wiki_card_total), '三元組 ' + n(d.triplets_total), '已嵌入 ' + n(d.embedded)];
|
||||
var latest = d.wiki_card_latest_ago_minutes;
|
||||
$('se-scale').textContent = '精耕層 ' + parts.join('・') +
|
||||
(latest != null && latest >= 0 ? '・最近寫入 ' + ckAge(latest) : '');
|
||||
})
|
||||
.catch(function () { /* 規模感拿不到不擋搜尋 */ });
|
||||
.catch(function () { $('se-scale').textContent = '精耕層 讀不到(規模統計讀取失敗,不影響搜尋)'; });
|
||||
}
|
||||
$('se-sem').addEventListener('click', function () {
|
||||
S.semantic = !S.semantic;
|
||||
@@ -1504,7 +1505,7 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
]).then(function (rs) {
|
||||
var svc = rs[0].status === 'fulfilled' ? rs[0].value : {};
|
||||
var kb = rs[1].status === 'fulfilled' ? rs[1].value : null;
|
||||
var n = function (v) { return v == null ? '?' : v.toLocaleString(); };
|
||||
var n = function (v) { return v == null ? '讀不到' : v.toLocaleString(); };
|
||||
var rows = '';
|
||||
rows += '<div class="kvline"><span class="muted">服務</span><span class="mono" style="font-size:14px">' + esc(svc.service || 'arcrun-cypher-executor') + '</span></div>';
|
||||
rows += '<div class="kvline"><span class="muted">版本</span><span class="mono" style="color:var(--amber)">' + esc(svc.version || '—') + '</span></div>';
|
||||
|
||||
@@ -1486,7 +1486,14 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
$('se-q').value = name;
|
||||
doGraphSearch(name);
|
||||
}
|
||||
// 讀不到就明說「讀不到」——標題列**絕不**留著 0 或舊數字(Arcrun#100:leo 看到
|
||||
// 「0 個實體・0 條關聯」以為要去上傳文件,其實庫裡有 1854 條,只是這支讀失敗了)。
|
||||
function mapUnavailable(html) {
|
||||
$('map-meta').textContent = '讀不到';
|
||||
$('map-box').innerHTML = '<div class="err" style="padding:30px 10px">' + html + '</div>';
|
||||
}
|
||||
function loadMap() {
|
||||
$('map-meta').textContent = '';
|
||||
$('map-box').innerHTML = '<div class="muted" style="padding:30px 10px">載入總圖中…</div>';
|
||||
$('map-md-link').innerHTML = SOURCE_WEB_BASE
|
||||
? ':<a href="' + esc(SOURCE_WEB_BASE + '/system-dev/wiki/00-MAP.md') + '" target="_blank" rel="noopener" style="color:var(--amber)">00-MAP.md ↗</a>'
|
||||
@@ -1495,14 +1502,31 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
.then(function (r) { return safeJson(r).then(function (d) { return { ok: r.ok, status: r.status, d: d }; }); })
|
||||
.then(function (x) {
|
||||
if (guard401(x.status)) return;
|
||||
if (!x.ok) { $('map-box').innerHTML = '<div class="err">' + esc(x.d.error || ('總圖載入失敗(HTTP ' + x.status + ')')) + '</div>'; return; }
|
||||
var nodes = x.d.nodes || [];
|
||||
var edges = x.d.edges || [];
|
||||
$('map-meta').textContent = nodes.length + ' 個實體・' + edges.length + ' 條關聯' + (x.d.truncated ? '・已達上限截斷' : '');
|
||||
if (!x.ok) { mapUnavailable(esc(x.d.error || ('總圖載入失敗(HTTP ' + x.status + ')'))); return; }
|
||||
// Arcrun#100:「0」只准在後端確認過真的是 0 的時候出現。
|
||||
// 形狀不對 → 讀不到(不是空庫);nodes 為空但 empty_confirmed 不成立 → 讀不到。
|
||||
if (!Array.isArray(x.d.nodes) || !Array.isArray(x.d.edges)) {
|
||||
mapUnavailable('總圖回應格式不對——沒有拿到關聯資料。這不代表知識庫是空的。');
|
||||
return;
|
||||
}
|
||||
var nodes = x.d.nodes, edges = x.d.edges;
|
||||
var total = typeof x.d.triplets_total === 'number' ? x.d.triplets_total : null;
|
||||
if (!nodes.length && x.d.empty_confirmed !== true) {
|
||||
mapUnavailable(x.d.empty_reason === 'scope_mismatch'
|
||||
? '讀不到你這個帳號的關聯資料——知識庫裡有三元組'
|
||||
+ (total ? '(本帳號範圍算到 ' + total.toLocaleString() + ' 條)' : '')
|
||||
+ ',但這張圖一條都抽不出來。<br>'
|
||||
+ '<b>這不是「還沒有關聯」,不用去上傳文件</b>;比較像資料的歸屬範圍對不上,請通知管理員。'
|
||||
: '讀不到知識庫的關聯資料,無法確認庫裡有沒有關聯。<br>'
|
||||
+ '<b>這不是「還沒有關聯」,不用去上傳文件</b>——是這次讀取失敗,請稍後重整或通知管理員。');
|
||||
return;
|
||||
}
|
||||
$('map-meta').textContent = nodes.length + ' 個實體・' + edges.length + ' 條關聯'
|
||||
+ (total !== null && x.d.truncated ? '(全庫共 ' + total.toLocaleString() + ' 條,已達單次上限)' : x.d.truncated ? '・已達上限截斷' : '');
|
||||
if (!nodes.length) { $('map-box').innerHTML = '<div class="muted" style="padding:30px 10px">知識庫還沒有任何關聯——上傳文件後 AI 會自動織網。</div>'; return; }
|
||||
renderMap(nodes, edges);
|
||||
})
|
||||
.catch(function (e) { $('map-box').innerHTML = '<div class="err">請求失敗:' + esc(friendlyErr(e)) + '</div>'; });
|
||||
.catch(function (e) { mapUnavailable('請求失敗:' + esc(friendlyErr(e))); });
|
||||
}
|
||||
function renderMap(nodes, edges) {
|
||||
var N = nodes.length;
|
||||
|
||||
Reference in New Issue
Block a user