fix(portal): 拿掉登記新庫/設定頁補常駐入口(下載小幫手+AI 金鑰)

leo 07-27 走完安裝後三點回饋:

1) 「登記新庫」是設計錯誤 —— leo:「應該是同步小幫手抓到的庫就顯示在上面,
   沒有人工登記的選項。」人工登記只會製造對不上的空庫。
   移除表單+對應 JS;說明改為「裝好同步小幫手並選好資料夾後,每個資料夾會自動
   成為一個庫出現在下面,不需要人工新增。下面還是空的,代表小幫手還沒裝好或還沒選資料夾。」

2) AI 金鑰與下載連結只存在一次性的「還差 N 步」卡片,按了「稍後再說」或裝完就
   再也找不到 —— 換金鑰/換電腦重新下載都沒入口。
   設定頁新增兩個常駐面板:「同步小幫手」(下載)與「AI 問答金鑰」(可隨時更換),
   共用既有 API POST /portal/admin/chat-key。

3) 修 window.ARCRUN_CFG → ARCRUN_CONFIG(與 721 行既有用法一致,原為筆誤)

驗證:ad-nl-create 殘留 0 / st-daemon-dl 2 / st-key-save 2 / ARCRUN_CFG 0
抽出頁面 3 個 script 區塊 node --check 語法通過
This commit is contained in:
2026-07-27 16:26:52 +08:00
parent 139d4c5ed1
commit d7fab7c6aa
+52 -33
View File
@@ -331,6 +331,25 @@
<div id="st-pw-status" style="font-size:14px;min-height:1.2em"></div> <div id="st-pw-status" style="font-size:14px;min-height:1.2em"></div>
</div> </div>
</div> </div>
<!-- 07-27 leo:金鑰與下載原本只在一次性的「還差 N 步」卡片裡,按了「稍後再說」
或裝完就再也找不到。換金鑰/換電腦重新下載都需要常駐入口,故搬進設定頁。 -->
<div class="panel">
<div style="font-size:17px;font-weight:600">同步小幫手</div>
<div style="margin-top:4px;font-size:14px;line-height:1.65;color:rgba(var(--ink-rgb),.55)">把你電腦上的資料夾變成知識庫。換電腦或重裝時可以再下載一次。</div>
<div style="margin-top:12px">
<a class="btn3" id="st-daemon-dl" href="#" style="display:inline-block;padding:11px 18px;border-radius:10px;text-decoration:none">下載 Mac 版</a>
<div style="margin-top:8px;font-size:13px;line-height:1.7;color:rgba(var(--ink-rgb),.5)">封測版未簽章,第一次請右鍵→打開。裝好第一次開啟時,貼上這個網址+你的帳號密碼就連上了。</div>
</div>
</div>
<div class="panel">
<div style="font-size:17px;font-weight:600">AI 問答金鑰</div>
<div style="margin-top:4px;font-size:14px;line-height:1.65;color:rgba(var(--ink-rgb),.55)">用來啟用「問 AI」。到 <a href="https://aistudio.google.com" target="_blank" rel="noopener">aistudio.google.com</a> 免費申請。金鑰只存在你自己的知識庫裡。</div>
<div style="margin-top:12px;display:flex;flex-direction:column;gap:10px">
<input type="password" id="st-key" class="txt" placeholder="貼上 Google AI 金鑰(留空=不變更)" autocomplete="off">
<button class="btn" id="st-key-save">儲存金鑰</button>
<div id="st-key-status" style="font-size:14px;min-height:1.2em"></div>
</div>
</div>
<button class="btn3" id="st-logout" style="padding:14px;font-size:16px;border-radius:11px">登出</button> <button class="btn3" id="st-logout" style="padding:14px;font-size:16px;border-radius:11px">登出</button>
</div> </div>
</div> </div>
@@ -356,17 +375,9 @@
<div class="sechead">庫目錄管理</div> <div class="sechead">庫目錄管理</div>
<div style="margin-bottom:12px;padding:12px 15px;border-radius:11px;background:rgba(var(--amber-rgb),.06);border:1px dashed rgba(var(--amber-rgb),.35);font-size:13.5px;line-height:1.7;color:rgba(var(--ink-rgb),.65)"> <div style="margin-bottom:12px;padding:12px 15px;border-radius:11px;background:rgba(var(--amber-rgb),.06);border:1px dashed rgba(var(--amber-rgb),.35);font-size:13.5px;line-height:1.7;color:rgba(var(--ink-rgb),.65)">
這裡是「庫」的登記簿——條目歸哪個庫由資料導入(ingest)時蓋章決定;未蓋章的舊資料一律視同 <b style="color:var(--ink)">general</b>。標了「圖譜來源」的庫決定誰能用圖譜模式(全都沒標=預設 general)。 <!-- 07-27 leo:拿掉「登記新庫」——庫由「同步小幫手」看守資料夾時自動蓋章產生,
</div> 人工登記只會製造對不上的空庫。這裡只做「已存在的庫」的管理。 -->
<div class="panel"> 裝好<b style="color:var(--ink)">同步小幫手</b>並選好要看守的資料夾之後,每個資料夾會自動成為一個「庫」出現在下面——<b style="color:var(--ink)">不需要人工新增</b>。下面還是空的,代表小幫手還沒裝好或還沒選資料夾。標了「圖譜來源」的庫決定誰能用圖譜模式(全都沒標=預設 general)。
<div style="font-size:16px;font-weight:600;margin-bottom:12px">登記新庫</div>
<div class="formrow">
<input type="text" id="ad-nl-name" class="txt" placeholder="庫名(英數 _ -,例:finance" autocomplete="off">
<input type="text" id="ad-nl-display" class="txt" placeholder="顯示名(例:財務庫)" autocomplete="off">
<input type="text" id="ad-nl-desc" class="txt" placeholder="描述(可留空)" autocomplete="off">
<button class="btn" id="ad-nl-create" style="flex:none;padding:0 20px">登記</button>
</div>
<div id="ad-nl-status" class="err" style="font-size:14px;min-height:1.2em;margin-top:8px"></div>
</div> </div>
<div class="listcol" id="ad-libs"><div class="muted">載入中…</div></div> <div class="listcol" id="ad-libs"><div class="muted">載入中…</div></div>
</div> </div>
@@ -656,6 +667,36 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
}) })
.catch(function (e) { $('login-submit').disabled = false; $('login-status').textContent = friendlyErr(e); }); .catch(function (e) { $('login-submit').disabled = false; $('login-status').textContent = friendlyErr(e); });
} }
// 07-27:設定頁的常駐入口(下載小幫手/換 AI 金鑰)——與一次性卡片同一組 API
(function () {
var dl = $('st-daemon-dl');
if (dl) {
var u = (window.ARCRUN_CONFIG && window.ARCRUN_CONFIG.daemonDownload)
|| 'https://raw.githubusercontent.com/youlinhsieh/arcrun-rag-bundles/main/daemon/ArcrunRAG-mac-unsigned.zip';
dl.setAttribute('href', u);
}
var kb = $('st-key-save');
if (kb) kb.addEventListener('click', function () {
var k = ($('st-key').value || '').trim();
var m = $('st-key-status');
if (!k) { m.textContent = '請先貼上金鑰'; m.style.color = ''; return; }
kb.disabled = true; m.textContent = '儲存中…'; m.style.color = '';
fetch(API_BASE + '/portal/admin/chat-key', {
method: 'POST',
headers: Object.assign({ 'Content-Type': 'application/json' }, authHeaders()),
body: JSON.stringify({ key: k })
}).then(function (r) { return r.json().then(function (d) { return { ok: r.ok, d: d }; }); })
.then(function (x) {
kb.disabled = false;
if (guard401(x.status)) return;
if (!x.ok) { m.textContent = (x.d && x.d.error) || '儲存失敗'; m.style.color = '#b4462f'; return; }
$('st-key').value = '';
m.textContent = '已儲存,AI 問答可以用了'; m.style.color = '#3f7a4f';
})
.catch(function (e) { kb.disabled = false; m.textContent = friendlyErr(e); m.style.color = '#b4462f'; });
});
})();
$('st-logout').addEventListener('click', function () { $('st-logout').addEventListener('click', function () {
fetch(API_BASE + '/portal/logout', { method: 'POST', headers: authHeaders() }).catch(function () { /* 盡力而為 */ }); fetch(API_BASE + '/portal/logout', { method: 'POST', headers: authHeaders() }).catch(function () { /* 盡力而為 */ });
dropSession(); dropSession();
@@ -1369,28 +1410,6 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
.catch(function (e) { $('ad-nu-create').disabled = false; st.textContent = friendlyErr(e); }); .catch(function (e) { $('ad-nu-create').disabled = false; st.textContent = friendlyErr(e); });
}); });
// 登記新庫
$('ad-nl-create').addEventListener('click', function () {
var name = $('ad-nl-name').value.trim();
var st = $('ad-nl-status');
if (!name) { st.textContent = '請填庫名(英數 _ -'; return; }
st.textContent = '';
$('ad-nl-create').disabled = true;
adminApi('POST', '/portal/admin/libraries', {
name: name,
display_name: $('ad-nl-display').value.trim(),
description: $('ad-nl-desc').value.trim()
})
.then(function (x) {
$('ad-nl-create').disabled = false;
if (guard401(x.status)) return;
if (!x.ok) { st.textContent = x.d.error || ('登記失敗(HTTP ' + x.status + ''); return; }
$('ad-nl-name').value = ''; $('ad-nl-display').value = ''; $('ad-nl-desc').value = '';
toast('庫已登記');
loadAdmin();
})
.catch(function (e) { $('ad-nl-create').disabled = false; st.textContent = friendlyErr(e); });
});
// 「全部知識庫」勾選 → 其餘庫勾選框連動停用(存的就是 ["*"],個別勾選無意義) // 「全部知識庫」勾選 → 其餘庫勾選框連動停用(存的就是 ["*"],個別勾選無意義)
document.addEventListener('change', function (ev) { document.addEventListener('change', function (ev) {