portal 設定頁加版本卡:顯示目前版本+落後紅點+一鍵更新(帶 email,t154 免辨識碼)
leo 08-02:「不顯示的話用戶不知道要不要更新」「發現落後就按一下開啟 install 直接帶它的 email 和辨識碼」。 比法=自己的 bundle_version(cypher /health)vs 最新版(安裝器 /api/latest), semver 逐段數字比(避免 1.4.10 < 1.4.9 的字串比錯誤); 舊格式版本(日期+sha)一律判為落後,舊實例才會被正確提示更新。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -329,6 +329,22 @@
|
|||||||
<div class="view page narrow" id="v-settings">
|
<div class="view page narrow" id="v-settings">
|
||||||
<div class="pagehead"><span class="t">設定</span></div>
|
<div class="pagehead"><span class="t">設定</span></div>
|
||||||
<div class="setcol">
|
<div class="setcol">
|
||||||
|
<!-- 🆕 2026-08-02(leo:「不顯示的話用戶不知道要不要更新」+「發現落後就按一下開啟 install」):
|
||||||
|
版本卡放設定頁第一張——用戶想「我是不是舊的」時第一眼就看到。
|
||||||
|
落後時直接給一顆帶 email 的更新按鈕(安裝器 t154 對既有實例免辨識碼),
|
||||||
|
不要求用戶理解版本號、找網址、翻辨識碼。 -->
|
||||||
|
<div class="panel" id="st-ver-panel">
|
||||||
|
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap">
|
||||||
|
<div style="min-width:0;flex:1">
|
||||||
|
<div style="font-size:17px;font-weight:600;display:flex;align-items:center;gap:8px">
|
||||||
|
版本
|
||||||
|
<span id="st-ver-dot" style="display:none;width:9px;height:9px;border-radius:50%;background:#C2492E" title="有新版本"></span>
|
||||||
|
</div>
|
||||||
|
<div id="st-ver-line" style="margin-top:4px;font-size:14px;line-height:1.65;color:rgba(var(--ink-rgb),.55)">查詢中…</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn" id="st-ver-update" style="display:none">立即更新</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div style="font-size:17px;font-weight:600;margin-bottom:10px">我的帳號</div>
|
<div style="font-size:17px;font-weight:600;margin-bottom:10px">我的帳號</div>
|
||||||
<div id="st-me"><div class="muted">載入中…</div></div>
|
<div id="st-me"><div class="muted">載入中…</div></div>
|
||||||
@@ -1736,11 +1752,80 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return {
|
|||||||
if (ev.target && ev.target.id === 'ad-otp-close') $('ad-otp').innerHTML = '';
|
if (ev.target && ev.target.id === 'ad-otp-close') $('ad-otp').innerHTML = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── 版本檢查(2026-08-02)──────────────────────────────────────────────
|
||||||
|
// leo 的兩個要求:
|
||||||
|
// ②「不顯示的話用戶不知道要不要更新」→ 一定要有目前版本
|
||||||
|
// ③「白癡化,發現落後就按一下開啟 install 直接帶它的 email 和辨識碼」
|
||||||
|
// → 落後才出現按鈕,且自動帶 email;辨識碼不必帶(安裝器 t154 對既有實例免碼)
|
||||||
|
//
|
||||||
|
// 比法:自己的版本(cypher /health 的 bundle_version)vs 最新版(安裝器 /api/latest)。
|
||||||
|
// 兩邊都是 semver(例 1.4.2),用數字逐段比,不用字串比('1.4.10' < '1.4.9' 會出錯)。
|
||||||
|
var INSTALLER_ORIGIN = 'https://install.arcrun.dev';
|
||||||
|
|
||||||
|
function cmpSemver(a, b) {
|
||||||
|
var x = String(a || '').split('.').map(Number);
|
||||||
|
var y = String(b || '').split('.').map(Number);
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
var d = (x[i] || 0) - (y[i] || 0);
|
||||||
|
if (d) return d < 0 ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadVersion() {
|
||||||
|
var line = $('st-ver-line');
|
||||||
|
var dot = $('st-ver-dot');
|
||||||
|
var btn = $('st-ver-update');
|
||||||
|
if (!line) return;
|
||||||
|
|
||||||
|
var mineP = fetch(window.ARCRUN_API_BASE + '/health', { cache: 'no-store' })
|
||||||
|
.then(function (r) { return r.ok ? r.json() : null; })
|
||||||
|
.then(function (j) { return (j && j.bundle_version) || ''; })
|
||||||
|
.catch(function () { return ''; });
|
||||||
|
var latestP = fetch(INSTALLER_ORIGIN + '/api/latest')
|
||||||
|
.then(function (r) { return r.ok ? r.json() : null; })
|
||||||
|
.then(function (j) { return (j && j.release) || ''; })
|
||||||
|
.catch(function () { return ''; });
|
||||||
|
|
||||||
|
Promise.all([mineP, latestP]).then(function (res) {
|
||||||
|
var mine = res[0], latest = res[1];
|
||||||
|
|
||||||
|
if (!mine) { line.textContent = '無法讀取目前版本(知識庫服務可能正在啟動)'; return; }
|
||||||
|
// 舊實例的 bundle_version 是舊格式(2026-07-31+8e83589),比不了 semver。
|
||||||
|
// 這種情況一律當成「落後」——因為新版才會寫 semver 進來。
|
||||||
|
var mineIsSemver = /^\d+\.\d+\.\d+$/.test(mine);
|
||||||
|
|
||||||
|
if (!latest) {
|
||||||
|
line.textContent = '目前版本 ' + mine + '(暫時查不到最新版,稍後再試)';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var behind = !mineIsSemver || cmpSemver(mine, latest) < 0;
|
||||||
|
if (!behind) {
|
||||||
|
line.innerHTML = '目前版本 <strong>' + esc(mine) + '</strong> 已是最新版';
|
||||||
|
dot.style.display = 'none';
|
||||||
|
btn.style.display = 'none';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
line.innerHTML = '目前版本 <strong>' + esc(mineIsSemver ? mine : '較舊版本') + '</strong>'
|
||||||
|
+ ' → 最新版 <strong>' + esc(latest) + '</strong><br>'
|
||||||
|
+ '<span style="color:#C2492E">有新版可以更新。按「立即更新」會開啟安裝頁,用你原本的 Cloudflare 帳號重新安裝一次即可,知識庫內容不會動到。</span>';
|
||||||
|
dot.style.display = 'inline-block';
|
||||||
|
btn.style.display = '';
|
||||||
|
btn.onclick = function () {
|
||||||
|
// 帶 email 讓安裝頁預填;既有實例更新免辨識碼(安裝器 t154)
|
||||||
|
var email = (S.profile && S.profile.email) || '';
|
||||||
|
var url = INSTALLER_ORIGIN + '/' + (email ? '?email=' + encodeURIComponent(email) : '');
|
||||||
|
window.open(url, '_blank', 'noopener');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ── 設定 ──
|
// ── 設定 ──
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
var p = S.profile;
|
var p = S.profile;
|
||||||
if (!p) { $('st-me').innerHTML = '<div class="muted">載入中…</div>'; return; }
|
if (!p) { $('st-me').innerHTML = '<div class="muted">載入中…</div>'; return; }
|
||||||
if (window._loadAiConfig) window._loadAiConfig();
|
if (window._loadAiConfig) window._loadAiConfig();
|
||||||
|
loadVersion();
|
||||||
var libs = p.libraries || [];
|
var libs = p.libraries || [];
|
||||||
var libHtml = libs.indexOf('*') >= 0
|
var libHtml = libs.indexOf('*') >= 0
|
||||||
? '<span class="tag green">全部知識庫</span>'
|
? '<span class="tag green">全部知識庫</span>'
|
||||||
|
|||||||
Reference in New Issue
Block a user