plc_control/web/feeder/js/api.js

88 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { dom } from "./dom.js";
export function setStatus(text) {
dom.statusText.textContent = text;
}
// ── Toast ─────────────────────────────────────────
function getContainer() {
let el = document.getElementById("toast-container");
if (!el) {
el = document.createElement("div");
el.id = "toast-container";
document.body.appendChild(el);
}
return el;
}
const ICONS = { error: "✕", warning: "!", success: "✓", info: "i" };
/**
* 显示 toast 通知。
* @param {string} title 主要文字
* @param {object} [opts]
* @param {string} [opts.message] 次要说明文字
* @param {"error"|"warning"|"success"|"info"} [opts.level="error"]
* @param {number} [opts.duration=4000] 自动关闭毫秒数0 表示不自动关闭
* @param {boolean} [opts.shake=false] 出现时加抖动动画
* @returns {{ dismiss: () => void }}
*/
export function showToast(title, { message, level = "error", duration = 4000, shake = false } = {}) {
const container = getContainer();
const el = document.createElement("div");
el.className = `toast ${level}${shake ? " shake" : ""}`;
el.innerHTML = `
<span class="toast-icon">${ICONS[level] ?? "i"}</span>
<div class="toast-body">
<div class="toast-title">${title}</div>
${message ? `<div class="toast-message">${message}</div>` : ""}
</div>`;
const dismiss = () => {
if (!el.parentNode) return;
el.classList.remove("shake");
el.classList.add("hiding");
el.addEventListener("animationend", () => el.remove(), { once: true });
};
el.addEventListener("click", dismiss);
container.appendChild(el);
if (duration > 0) setTimeout(dismiss, duration);
return { dismiss };
}
// ── apiFetch ──────────────────────────────────────
export async function apiFetch(url, options = {}) {
const response = await fetch(url, {
headers: { "Content-Type": "application/json" },
...options,
});
if (!response.ok) {
const text = (await response.text()) || response.statusText;
showToast(`请求失败 ${response.status}`, { message: text });
throw new Error(text);
}
if (response.status === 204) {
return null;
}
const contentType = response.headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return response.json();
}
return response.text();
}
export function withStatus(task) {
return task.catch((error) => {
setStatus(error.message || "请求失败");
});
}