feat: sync latest ARR implementation

This commit is contained in:
Wyndham ARR
2026-07-31 15:11:42 +08:00
parent d6f8a747fa
commit bf7939dd1a
185 changed files with 17527 additions and 2260 deletions

View File

@@ -4,6 +4,7 @@
const colors = ["#2563eb", "#0f9f6e", "#7a5af8", "#f79009", "#06aed5", "#e0528d", "#64748b", "#84cc16"];
const BUSINESS_TIME_ZONE = "Asia/Bangkok";
const $ = (selector) => document.querySelector(selector);
let csrf = "";
function escapeHtml(value) {
return String(value ?? "").replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
@@ -28,8 +29,18 @@
return new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits: 0 }).format(amount);
}
async function api(path) {
const response = await fetch(path, { credentials: "same-origin" });
function redirectToLogin() {
window.location.replace("/login?next=%2Fh5");
}
async function api(path, options = {}) {
const headers = new Headers(options.headers || {});
if (options.method && options.method !== "GET") headers.set("X-ARR-CSRF", csrf);
const response = await fetch(path, { ...options, headers, credentials: "same-origin" });
if (response.status === 401) {
redirectToLogin();
throw new Error("登录状态已失效");
}
const payload = await response.json();
if (!response.ok || !payload.ok) throw new Error(payload?.error?.message || "数据读取失败");
return payload.data;
@@ -107,6 +118,28 @@
async function boot() {
const connection = $("#h5-connection");
try {
const session = await api("/api/session");
csrf = session.csrf_token;
const logout = $("#h5-logout");
if (session.username) {
logout.hidden = false;
logout.disabled = false;
logout.title = `${session.username} · 退出登录`;
logout.addEventListener("click", async () => {
logout.disabled = true;
try {
await api("/api/logout", { method: "POST" });
window.location.replace("/login");
} catch (error) {
notify(error.message || "退出登录失败,请重试");
logout.disabled = false;
}
});
}
} catch (_) {
return;
}
try {
const health = await api("/api/health");
connection.classList.add(health.database_ready ? "ready" : "error");