Initialize crypto_monitor_user (user edition) from monitor codebase.
Retarget git remote, install path, and deploy docs from crypto_monitor to crypto_monitor_user. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* 使用说明:中控 docs/help MD 章节.
|
||||
*/
|
||||
(function () {
|
||||
const page = document.getElementById("page-help");
|
||||
if (!page) return;
|
||||
|
||||
const tocEl = document.getElementById("help-toc-nav");
|
||||
const statusEl = document.getElementById("help-load-status");
|
||||
const docBody = document.getElementById("help-doc-body");
|
||||
const docSource = document.getElementById("help-doc-source");
|
||||
|
||||
let sectionsMeta = [];
|
||||
let activeKey = "quickstart";
|
||||
let cache = {};
|
||||
let bound = false;
|
||||
|
||||
async function apiFetch(url) {
|
||||
const r = await fetch(url, { credentials: "same-origin" });
|
||||
const data = await r.json();
|
||||
if (!r.ok || !data.ok) throw new Error((data && data.msg) || r.statusText || "请求失败");
|
||||
return data;
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
return String(s ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """);
|
||||
}
|
||||
|
||||
function sectionFromHash() {
|
||||
const h = (window.location.hash || "").replace(/^#/, "").trim().toLowerCase();
|
||||
if (!h) return null;
|
||||
return sectionsMeta.some((s) => s.key === h) ? h : null;
|
||||
}
|
||||
|
||||
function setHash(key) {
|
||||
const next = `#${key}`;
|
||||
if (window.location.hash !== next) {
|
||||
history.replaceState(null, "", `/help${next}`);
|
||||
}
|
||||
}
|
||||
|
||||
function renderToc() {
|
||||
if (!tocEl) return;
|
||||
tocEl.innerHTML = sectionsMeta
|
||||
.map(
|
||||
(s) =>
|
||||
`<button type="button" class="help-toc-item${s.key === activeKey ? " is-active" : ""}" data-key="${esc(s.key)}">${esc(s.label)}</button>`
|
||||
)
|
||||
.join("");
|
||||
tocEl.querySelectorAll(".help-toc-item").forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
const key = btn.getAttribute("data-key");
|
||||
if (!key || key === activeKey) return;
|
||||
activeKey = key;
|
||||
setHash(key);
|
||||
renderToc();
|
||||
void loadSection(key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderSection(data) {
|
||||
if (docBody) docBody.innerHTML = data.content_html || "";
|
||||
if (docSource) {
|
||||
docSource.textContent = data.md_source ? `来源: ${data.md_source}` : "";
|
||||
}
|
||||
if (statusEl) statusEl.textContent = "";
|
||||
}
|
||||
|
||||
async function loadSection(key) {
|
||||
if (cache[key]) {
|
||||
renderSection(cache[key]);
|
||||
return;
|
||||
}
|
||||
if (statusEl) statusEl.textContent = "加载中…";
|
||||
try {
|
||||
const data = await apiFetch(`/api/help/${encodeURIComponent(key)}`);
|
||||
cache[key] = data;
|
||||
renderSection(data);
|
||||
} catch (err) {
|
||||
if (statusEl) statusEl.textContent = "";
|
||||
if (docBody) docBody.innerHTML = `<p class="muted">${esc(err.message || "加载失败")}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMeta() {
|
||||
const data = await apiFetch("/api/help/meta");
|
||||
sectionsMeta = data.sections || [];
|
||||
const fromHash = sectionFromHash();
|
||||
if (fromHash) activeKey = fromHash;
|
||||
else if (sectionsMeta.length && !sectionsMeta.some((s) => s.key === activeKey)) {
|
||||
activeKey = sectionsMeta[0].key;
|
||||
}
|
||||
renderToc();
|
||||
await loadSection(activeKey);
|
||||
if (!sectionFromHash() && activeKey) setHash(activeKey);
|
||||
}
|
||||
|
||||
function bindOnce() {
|
||||
if (bound) return;
|
||||
bound = true;
|
||||
window.addEventListener("hashchange", () => {
|
||||
const key = sectionFromHash();
|
||||
if (!key || key === activeKey) return;
|
||||
activeKey = key;
|
||||
renderToc();
|
||||
void loadSection(key);
|
||||
});
|
||||
}
|
||||
|
||||
window.hubHelpPage = {
|
||||
init() {
|
||||
bindOnce();
|
||||
void loadMeta().catch((err) => {
|
||||
if (statusEl) statusEl.textContent = "";
|
||||
if (docBody) docBody.innerHTML = `<p class="muted">${esc(err.message || "加载失败")}</p>`;
|
||||
});
|
||||
},
|
||||
destroy() {},
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user