Initial commit: 心理咨询预约系统
PHP 前后端一体:首页咨询师列表、预约表单、管理后台、二维码准入与邮件通知;敏感配置与提交数据通过 .gitignore 排除。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
159
debug.php
Normal file
159
debug.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
require __DIR__ . '/api/bootstrap.php';
|
||||
sendHtmlNoCacheHeaders();
|
||||
$v = getAssetVersion();
|
||||
?><!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<title>系统调试 - 心理咨询</title>
|
||||
<link rel="stylesheet" href="<?= asset('css/base.css') ?>">
|
||||
<link rel="stylesheet" href="<?= asset('css/admin.css') ?>">
|
||||
<style>
|
||||
.debug-page { padding: 16px; max-width: 640px; margin: 0 auto; }
|
||||
.debug-card { background: #fff; border-radius: 12px; padding: 16px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,.06); }
|
||||
.debug-card h2 { font-size: 16px; margin-bottom: 12px; }
|
||||
.debug-row { font-size: 14px; margin-bottom: 8px; line-height: 1.6; word-break: break-all; }
|
||||
.debug-row.ok { color: #40916c; }
|
||||
.debug-row.fail { color: #e54d4d; }
|
||||
.debug-actions { display: flex; flex-direction: column; gap: 8px; }
|
||||
.debug-log { background: #1e1e1e; color: #d4d4d4; padding: 12px; border-radius: 8px; font-size: 12px; white-space: pre-wrap; word-break: break-all; max-height: 320px; overflow: auto; }
|
||||
.debug-note { font-size: 13px; color: #666; line-height: 1.7; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page debug-page">
|
||||
<h1 class="admin-header__title">系统调试</h1>
|
||||
<p class="debug-note">访问地址须带访问令牌,例如:<br><code id="sample-url"></code></p>
|
||||
|
||||
<div class="debug-card">
|
||||
<h2>环境检测</h2>
|
||||
<div id="env-result">加载中…</div>
|
||||
</div>
|
||||
|
||||
<div class="debug-card">
|
||||
<h2>操作</h2>
|
||||
<div class="debug-actions">
|
||||
<button type="button" class="btn btn--primary btn--block" id="btn-refresh">刷新检测</button>
|
||||
<button type="button" class="btn btn--primary btn--block" id="btn-test-submit">测试提交(写入一条记录)</button>
|
||||
<button type="button" class="btn btn--ghost btn--block" id="btn-test-mail">测试邮件(发送全部历史记录)</button>
|
||||
<a href="consult.php" class="btn btn--ghost btn--block" style="text-align:center;line-height:48px">打开预约页</a>
|
||||
<a href="admin.php" class="btn btn--ghost btn--block" style="text-align:center;line-height:48px">管理后台</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="debug-card">
|
||||
<h2>日志</h2>
|
||||
<pre class="debug-log" id="debug-log">等待操作…</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="<?= asset('js/api.js') ?>"></script>
|
||||
<script>
|
||||
function getAccessToken() {
|
||||
return new URLSearchParams(window.location.search).get("access") || "";
|
||||
}
|
||||
|
||||
function diagUrl(action) {
|
||||
const token = getAccessToken();
|
||||
const base = new URL("api/diagnostics.php", window.location.href);
|
||||
if (action) base.searchParams.set("action", action);
|
||||
if (token) base.searchParams.set("access", token);
|
||||
return base.href;
|
||||
}
|
||||
|
||||
function log(msg) {
|
||||
const el = document.getElementById("debug-log");
|
||||
const time = new Date().toLocaleString("zh-CN", { hour12: false });
|
||||
el.textContent = `[${time}] ${msg}\n\n` + el.textContent;
|
||||
}
|
||||
|
||||
function row(label, ok, detail) {
|
||||
return `<div class="debug-row ${ok ? "ok" : "fail"}">${ok ? "✓" : "✗"} ${label}${detail ? ":" + detail : ""}</div>`;
|
||||
}
|
||||
|
||||
async function loadDiagnostics() {
|
||||
const token = getAccessToken();
|
||||
const envEl = document.getElementById("env-result");
|
||||
document.getElementById("sample-url").textContent =
|
||||
window.location.origin + window.location.pathname.replace(/debug\.php$/, "debug.php") + "?access=你的accessToken";
|
||||
|
||||
if (!token) {
|
||||
envEl.innerHTML = row("访问令牌", false, "URL 缺少 ?access= 参数");
|
||||
return;
|
||||
}
|
||||
|
||||
envEl.innerHTML = "检测中…";
|
||||
try {
|
||||
const res = await fetch(diagUrl(), { credentials: "same-origin" });
|
||||
const text = await res.text();
|
||||
let data;
|
||||
try { data = JSON.parse(text); } catch {
|
||||
envEl.innerHTML = row("接口响应", false, `非 JSON(HTTP ${res.status})`);
|
||||
log("GET diagnostics 失败:\n" + text.slice(0, 800));
|
||||
return;
|
||||
}
|
||||
if (!res.ok) throw new Error(data.message || "检测失败");
|
||||
|
||||
const ext = data.extensions || {};
|
||||
envEl.innerHTML = [
|
||||
row("PHP 版本", true, data.phpVersion),
|
||||
row("资源版本", true, data.assetVersion || "-"),
|
||||
row("json 扩展", !!ext.json),
|
||||
row("openssl 扩展", !!ext.openssl),
|
||||
row("data 目录可写", !!data.dataDir?.ok, data.dataDir?.message),
|
||||
row("提交记录数", true, String(data.submissions?.count ?? 0)),
|
||||
row("邮件通知", !!data.mail?.enabled, data.mail?.enabled ? `${data.mail.recipientCount} 个收件人` : "未启用"),
|
||||
row("submit 接口", true, new URL("api/submit.php", window.location.href).href),
|
||||
].join("");
|
||||
|
||||
log("环境检测成功:\n" + JSON.stringify(data, null, 2));
|
||||
} catch (e) {
|
||||
envEl.innerHTML = row("环境检测", false, e.message);
|
||||
log("环境检测异常: " + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function postAction(action) {
|
||||
const token = getAccessToken();
|
||||
if (!token) {
|
||||
alert("请先在 URL 中添加 ?access=访问令牌");
|
||||
return;
|
||||
}
|
||||
log(`开始 ${action}…`);
|
||||
try {
|
||||
const res = await fetch(diagUrl(action), {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: "{}",
|
||||
credentials: "same-origin",
|
||||
});
|
||||
const text = await res.text();
|
||||
let data;
|
||||
try { data = JSON.parse(text); } catch {
|
||||
log(`${action} 失败(HTTP ${res.status},非 JSON):\n` + text.slice(0, 800));
|
||||
alert("请求失败,详见日志");
|
||||
return;
|
||||
}
|
||||
if (!res.ok) throw new Error(data.message || `HTTP ${res.status}`);
|
||||
log(`${action} 成功:\n` + JSON.stringify(data, null, 2));
|
||||
alert(data.message || "操作成功");
|
||||
await loadDiagnostics();
|
||||
} catch (e) {
|
||||
log(`${action} 异常: ` + e.message);
|
||||
alert(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("btn-refresh").addEventListener("click", loadDiagnostics);
|
||||
document.getElementById("btn-test-submit").addEventListener("click", () => postAction("submit"));
|
||||
document.getElementById("btn-test-mail").addEventListener("click", () => postAction("mail"));
|
||||
loadDiagnostics();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user