// 后台通用脚本:统一 API 调用 + 登录态校验 + WeUI 风格 toast function api(url, opts) { opts = opts || {}; opts.credentials = 'include'; opts.headers = Object.assign({ 'Content-Type': 'application/json' }, opts.headers || {}); return fetch(url, opts).then(function (r) { if (r.status === 401 && url.indexOf('/api/admin/login') < 0 && url.indexOf('/api/admin/me') < 0) { location.href = '/admin/login.html'; throw new Error('未登录'); } return r.json(); }); } function requireLogin() { return api('/api/admin/me').catch(function () { location.href = '/admin/login.html'; }); } function logout() { api('/api/admin/logout', { method: 'POST' }).then(function () { location.href = '/admin/login.html'; }); } // 浮动 toast(自动消失,不再依赖页面 #tip 元素) function toast(msg, ok) { var t = document.getElementById('__yz_toast'); if (!t) { t = document.createElement('div'); t.id = '__yz_toast'; t.className = 'yz-toast'; document.body.appendChild(t); } t.textContent = msg; t.className = 'yz-toast show ' + (ok ? 'yz-toast--ok' : 'yz-toast--err'); clearTimeout(t._timer); t._timer = setTimeout(function () { t.className = 'yz-toast'; }, 2400); } function el(id) { return document.getElementById(id); } function esc(s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); } function fmt(n) { return '¥' + Number(n).toFixed(2); }