Initial commit: 心理咨询预约系统
PHP 前后端一体:首页咨询师列表、预约表单、管理后台、二维码准入与邮件通知;敏感配置与提交数据通过 .gitignore 排除。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
120
js/admin.js
Normal file
120
js/admin.js
Normal file
@@ -0,0 +1,120 @@
|
||||
let isLoggedIn = false;
|
||||
|
||||
function formatTime(iso) {
|
||||
if (!iso) return "-";
|
||||
try {
|
||||
const d = new Date(iso);
|
||||
return d.toLocaleString("zh-CN", { hour12: false });
|
||||
} catch {
|
||||
return iso;
|
||||
}
|
||||
}
|
||||
|
||||
function renderSubmissionCard(item) {
|
||||
const card = document.createElement("article");
|
||||
card.className = "submission-card";
|
||||
const doctorInfo = item.doctorName ? `${item.doctorName}` : "未指定咨询师";
|
||||
card.innerHTML = `
|
||||
<div class="submission-card__time">${formatTime(item.createdAt)}</div>
|
||||
<div class="submission-card__row"><strong>昵称:</strong>${escapeHtml(item.nickname || "-")}</div>
|
||||
<div class="submission-card__row"><strong>性别:</strong>${escapeHtml(item.gender || "-")}</div>
|
||||
<div class="submission-card__row"><strong>联系电话:</strong>${escapeHtml(item.contact || "-")}</div>
|
||||
<div class="submission-card__row"><strong>咨询师:</strong>${escapeHtml(doctorInfo)}</div>
|
||||
<p class="submission-card__desc">${escapeHtml(item.description || "(无描述)")}</p>
|
||||
`;
|
||||
return card;
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
const div = document.createElement("div");
|
||||
div.textContent = str;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function showLogin() {
|
||||
document.getElementById("login-section").style.display = "block";
|
||||
document.getElementById("dashboard-section").style.display = "none";
|
||||
isLoggedIn = false;
|
||||
}
|
||||
|
||||
function showDashboard() {
|
||||
document.getElementById("login-section").style.display = "none";
|
||||
document.getElementById("dashboard-section").style.display = "block";
|
||||
isLoggedIn = true;
|
||||
}
|
||||
|
||||
async function loadSubmissions() {
|
||||
const listEl = document.getElementById("submission-list");
|
||||
listEl.innerHTML = "<p>加载中…</p>";
|
||||
|
||||
try {
|
||||
const res = await apiGet("submissions.php", true);
|
||||
const items = res.data || [];
|
||||
document.getElementById("submission-count").textContent = items.length;
|
||||
|
||||
if (items.length === 0) {
|
||||
listEl.innerHTML = '<p class="admin-empty">暂无提交记录</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
listEl.innerHTML = "";
|
||||
items.forEach((item) => listEl.appendChild(renderSubmissionCard(item)));
|
||||
} catch (e) {
|
||||
if (e.message && e.message.includes("未登录")) {
|
||||
showLogin();
|
||||
return;
|
||||
}
|
||||
listEl.innerHTML = '<p class="admin-empty">加载失败</p>';
|
||||
showToast(e.message || "加载失败");
|
||||
}
|
||||
}
|
||||
|
||||
async function tryAutoLogin() {
|
||||
try {
|
||||
const res = await apiGet("check.php", true);
|
||||
if (res.loggedIn) {
|
||||
showDashboard();
|
||||
await loadSubmissions();
|
||||
return true;
|
||||
}
|
||||
} catch (_) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
function downloadExport(format) {
|
||||
window.location.href = `${API_BASE}/export.php?format=${format}`;
|
||||
}
|
||||
|
||||
async function initAdmin() {
|
||||
document.getElementById("login-form").addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
const user = document.getElementById("admin-user").value.trim();
|
||||
const password = document.getElementById("admin-password").value;
|
||||
|
||||
try {
|
||||
await apiPost("login.php", { user, password }, true);
|
||||
showToast("登录成功");
|
||||
showDashboard();
|
||||
await loadSubmissions();
|
||||
} catch (err) {
|
||||
showToast(err.message || "登录失败");
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("logout-btn").addEventListener("click", async () => {
|
||||
try {
|
||||
await apiPost("logout.php", {}, true);
|
||||
} catch (_) {}
|
||||
showLogin();
|
||||
showToast("已退出");
|
||||
});
|
||||
|
||||
document.getElementById("export-json").addEventListener("click", () => downloadExport("json"));
|
||||
document.getElementById("export-csv").addEventListener("click", () => downloadExport("csv"));
|
||||
document.getElementById("refresh-btn").addEventListener("click", loadSubmissions);
|
||||
|
||||
const ok = await tryAutoLogin();
|
||||
if (!ok) showLogin();
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", initAdmin);
|
||||
Reference in New Issue
Block a user