Files
psychological-counseling/js/api.js
litianming 08ce60344d Initial commit: 心理咨询预约系统
PHP 前后端一体:首页咨询师列表、预约表单、管理后台、二维码准入与邮件通知;敏感配置与提交数据通过 .gitignore 排除。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 10:17:09 +08:00

86 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.
/** 基于当前页面 URL 解析 api 路径,适配根目录或子目录部署 */
function apiUrl(endpoint) {
return new URL(`api/${endpoint}`, window.location.href).href;
}
/** 静态资源追加版本号,避免手机浏览器缓存旧 CSS/JS/图片 */
function assetUrl(path) {
if (!path || /^https?:\/\//i.test(path)) return path;
const v = window.__ASSET_V__ || "";
if (!v) return path;
const sep = path.includes("?") ? "&" : "?";
return `${path}${sep}v=${encodeURIComponent(v)}`;
}
async function parseResponse(res) {
const text = await res.text();
if (!text) {
return {};
}
try {
return JSON.parse(text);
} catch {
const hint = res.status === 404
? "接口不存在,请确认 api 目录已上传"
: res.status >= 500
? "服务器错误,请检查 PHP 与 data 目录写权限"
: "服务器返回异常,请确认 PHP 已启用";
throw new Error(`${hint}HTTP ${res.status}`);
}
}
async function apiGet(endpoint, useCredentials = false) {
const res = await fetch(apiUrl(endpoint), {
credentials: useCredentials ? "include" : "same-origin",
});
const data = await parseResponse(res);
if (!res.ok) {
throw new Error(data.message || `请求失败HTTP ${res.status}`);
}
return data;
}
async function apiPost(endpoint, body, useCredentials = false, timeoutMs = 30000) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
let res;
try {
res = await fetch(apiUrl(endpoint), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
credentials: useCredentials ? "include" : "same-origin",
signal: controller.signal,
});
} catch (e) {
clearTimeout(timer);
if (e.name === "AbortError") {
throw new Error("请求超时,数据可能已保存,请稍后刷新或联系管理员");
}
throw new Error("网络请求失败,请检查网络或域名是否正确");
}
clearTimeout(timer);
const data = await parseResponse(res);
if (!res.ok) {
throw new Error(data.message || `提交失败HTTP ${res.status}`);
}
return data;
}
function showToast(message, duration = 2500) {
const existing = document.querySelector(".toast");
if (existing) existing.remove();
const el = document.createElement("div");
el.className = "toast";
el.textContent = message;
document.body.appendChild(el);
setTimeout(() => el.remove(), duration);
}
/** 供管理端下载使用 */
const API_BASE = (() => {
const u = new URL("api/", window.location.href);
return u.pathname.replace(/\/$/, "");
})();