feat(portal-ui): 設定頁「匯出診斷檔給我們看」按鈕(檢修孔前端,2026-08-07)
leo 直接指令的簡化版規格:一顆按鈕、按下去下載一個檔案、用戶自己把檔案傳出去—— 同意天然內建在「他自己按、自己傳」這個動作裡,不需要額外授權流程或內部概念外露。 按鈕打 GET /portal/data/diagnostics,把回應存成單一 JSON 檔(不是要解壓的一包) 直接觸發瀏覽器下載,檔名帶時間戳。沿用既有 authHeaders/safeJson/guard401/friendlyErr helper(與同頁其餘按鈕同一套錯誤處理慣例)。 既有前端輕量測試(safejson.test.mjs/os-split.test.mjs)跑過,18/18 全綠,未受影響。
This commit is contained in:
@@ -415,6 +415,18 @@ if (!window.ARCRUN_API_BASE) {
|
||||
文件整理成知識卡的部分,請在<b style="color:var(--ink)">同步小幫手</b>(電腦上的托盤圖示)的「AI 設定…」填一把 Gemini API Key。
|
||||
</div>
|
||||
</div>
|
||||
<!-- 檢修孔(2026-08-07 leo 直接指令):「一顆按鈕在設定裡,按鈕下載一個檔案,
|
||||
把檔案發給我,你看那個檔」。用戶只做兩件事:按一下、把檔案傳出去——不需要
|
||||
理解裡面是什麼。檔案內容只有統計/狀態數字(GET /portal/data/diagnostics),
|
||||
不含任何知識卡內容。 -->
|
||||
<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">
|
||||
<button class="btn3" id="st-diag-export" style="padding:11px 18px;border-radius:10px">匯出診斷檔給我們看</button>
|
||||
<div id="st-diag-status" style="margin-top:8px;font-size:13px;min-height:1.2em;color:rgba(var(--ink-rgb),.5)"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn3" id="st-logout" style="padding:14px;font-size:16px;border-radius:11px">登出</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -924,6 +936,39 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
||||
dropSession();
|
||||
});
|
||||
|
||||
// ── 檢修孔(2026-08-07 leo 直接指令)──────────────────────────────────────
|
||||
// 「按鈕下載一個檔案,把檔案發給我」:按下去打 /portal/data/diagnostics,
|
||||
// 存成單一 JSON 檔(不是要解壓的一包)直接觸發瀏覽器下載。不彈視窗、不要求
|
||||
// 用戶理解內容——他只需要按一下、把跳出來的檔案傳給我們。
|
||||
(function () {
|
||||
var btn = $('st-diag-export');
|
||||
if (!btn) return;
|
||||
btn.addEventListener('click', function () {
|
||||
var st = $('st-diag-status');
|
||||
btn.disabled = true;
|
||||
st.textContent = '匯出中…';
|
||||
fetch(API_BASE + '/portal/data/diagnostics', { headers: authHeaders() })
|
||||
.then(function (r) { return safeJson(r).then(function (d) { return { ok: r.ok, status: r.status, d: d }; }); })
|
||||
.then(function (x) {
|
||||
btn.disabled = false;
|
||||
if (guard401(x.status)) return;
|
||||
if (!x.ok) { st.textContent = '匯出失敗,請稍後再試'; return; }
|
||||
var blob = new Blob([JSON.stringify(x.d, null, 2)], { type: 'application/json' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
var a = document.createElement('a');
|
||||
var stamp = new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-');
|
||||
a.href = url;
|
||||
a.download = 'arcrun-diagnostics-' + stamp + '.json';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
setTimeout(function () { URL.revokeObjectURL(url); }, 2000);
|
||||
st.textContent = '已下載——把這個檔案傳給我們就可以了';
|
||||
})
|
||||
.catch(function (e) { btn.disabled = false; st.textContent = friendlyErr(e); });
|
||||
});
|
||||
})();
|
||||
|
||||
// t87 07-28 leo:知識庫網址 helper(只有 origin,不含 /portal/# 後綴),兩處 UI 共用
|
||||
function copyOriginUrl(btn) {
|
||||
var url = location.origin;
|
||||
|
||||
Reference in New Issue
Block a user