feat(POSTV1-03): 增加本机测试直达入口
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run

This commit is contained in:
suyx
2026-08-05 14:53:20 +08:00
parent f7cac5dabf
commit 92434aec17
9 changed files with 297 additions and 2 deletions
+19
View File
@@ -124,6 +124,25 @@ button {
margin-inline: auto;
}
.auth-test-entry {
margin-bottom: 18px;
border-bottom: 1px solid #b4b4af;
padding-bottom: 18px;
}
.auth-test-entry .auth-primary {
margin-top: 0;
border-color: #111111;
background: #111111;
color: #f2f500;
}
.auth-test-entry .auth-primary:disabled {
border-color: #777773;
background: #deded9;
color: #777773;
}
.auth-tabs {
display: grid;
grid-template-columns: 1fr 1fr;
+44
View File
@@ -77,6 +77,9 @@ export function UserAuthPage() {
const [sendState, setSendState] = useState<SendState>("idle");
const [countdown, setCountdown] = useState(0);
const [error, setError] = useState<string>();
const [localTestAvailable, setLocalTestAvailable] = useState(false);
const [localTestError, setLocalTestError] = useState<string>();
const [localTestSubmitting, setLocalTestSubmitting] = useState(false);
const [submitting, setSubmitting] = useState(false);
const emailValid = /^[^@\s]+@[^@\s]+$/.test(email);
const registrationReady = Boolean(
@@ -93,6 +96,18 @@ export function UserAuthPage() {
return () => window.clearInterval(timer);
}, [countdown]);
useEffect(() => {
const controller = new AbortController();
void fetch("/api/v1/auth/local-test", { credentials: "same-origin", signal: controller.signal })
.then(async (response) => {
if (!response.ok || !response.headers.get("content-type")?.includes("application/json")) return;
const body = await response.json() as { available?: boolean };
if (body.available === true) setLocalTestAvailable(true);
})
.catch(() => undefined);
return () => controller.abort();
}, []);
useEffect(() => {
if (!noticeOpen) return;
const previousOverflow = document.body.style.overflow;
@@ -255,6 +270,27 @@ export function UserAuthPage() {
}
}
async function enterLocalTest() {
if (localTestSubmitting) return;
setLocalTestSubmitting(true);
setLocalTestError(undefined);
try {
const response = await fetch("/api/v1/auth/local-test", {
credentials: "same-origin",
method: "POST",
});
if (!response.ok) {
setLocalTestError("本机测试会话未能建立,请重试。");
return;
}
window.location.assign("/app");
} catch {
setLocalTestError("本机测试会话未能建立,请重试。");
} finally {
setLocalTestSubmitting(false);
}
}
return (
<>
<main className="auth-page">
@@ -271,6 +307,14 @@ export function UserAuthPage() {
<section className="auth-content">
<a className="auth-admin-link" href="/admin/login"></a>
<div className="auth-panel">
{localTestAvailable ? (
<div className="auth-test-entry">
<button className="auth-primary" disabled={localTestSubmitting} onClick={enterLocalTest} type="button">
{localTestSubmitting ? "正在进入" : "直接进入本机测试"}
</button>
{localTestError ? <p className="auth-error" role="alert">{localTestError}</p> : null}
</div>
) : null}
<div className="auth-tabs" role="tablist" aria-label="认证方式">
<button
aria-selected={mode === "login"}