This commit is contained in:
eric
2026-03-16 12:04:56 -05:00
parent b8fa250897
commit 3ba00e9a93
2 changed files with 50 additions and 18 deletions

View File

@@ -133,6 +133,28 @@ async function tryPocketBaseDirect(
const pb = getPocketBaseConfig();
const base = pb.url.replace(/\/$/, "");
const wechatId = String(record.wechatId ?? "").trim();
if (wechatId) {
const escaped = wechatId.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
const filter = encodeURIComponent(`wechatId = "${escaped}"`);
const checkRes = await fetch(
`${base}/api/collections/${pb.joinCollection}/records?filter=${filter}&perPage=1`,
{
headers: { Authorization: `Bearer ${token}` },
cache: "no-store",
}
);
if (checkRes.ok) {
const checkData = await checkRes.json();
if (Array.isArray((checkData as { items?: unknown[] }).items) && (checkData as { items: unknown[] }).items.length > 0) {
return NextResponse.json(
{ ok: false, error: "该微信号已报名,请勿重复提交" },
{ status: 400 }
);
}
}
}
const url = `${base}/api/collections/${pb.joinCollection}/records`;
const qualify = !!(record.qualify ?? false);

View File

@@ -142,7 +142,8 @@ export default function JoinPage() {
const [paying, setPaying] = useState(false);
const initialWechatCheckDone = useRef(false);
const lastSubmitTime = useRef(0);
const SUBMIT_THROTTLE_MS = 2000;
const submittingRef = useRef(false);
const SUBMIT_THROTTLE_MS = 3000;
const fetchByWechat = async (w: string) => {
if (!w.trim()) return;
@@ -247,24 +248,12 @@ export default function JoinPage() {
setError(null);
const now = Date.now();
if (now - lastSubmitTime.current < SUBMIT_THROTTLE_MS) {
return;
}
if (submittingRef.current) return;
if (now - lastSubmitTime.current < SUBMIT_THROTTLE_MS) return;
if (userRecord?.hasRecord) {
setError("该微信号已报名,请勿重复提交");
return;
}
try {
const checkRes = await fetch(`/api/join/by-wechat?wechat_id=${encodeURIComponent(wechat.trim())}`, { cache: "no-store" });
const checkData = await checkRes.json();
if (checkData?.hasRecord) {
setError("该微信号已报名,请勿重复提交");
fetchByWechat(wechat.trim());
return;
}
} catch {
/* 校验失败时继续提交,由后端兜底 */
}
if (xiaohongshuUrl.trim() && urlError) {
setError("请先修正小红书链接");
return;
@@ -285,9 +274,22 @@ export default function JoinPage() {
setError("请选择性别");
return;
}
submittingRef.current = true;
lastSubmitTime.current = now;
setSubmitting(true);
try {
const checkRes = await fetch(`/api/join/by-wechat?wechat_id=${encodeURIComponent(wechat.trim())}`, { cache: "no-store" });
const checkData = await checkRes.json();
if (checkData?.hasRecord) {
setError("该微信号已报名,请勿重复提交");
fetchByWechat(wechat.trim());
submittingRef.current = false;
setSubmitting(false);
return;
}
const formGenderFemale = gender === "女" || gender === "female";
const postCountOk = (profile?.postCount ?? 0) > 10;
const qualify = formGenderFemale && postCountOk;
@@ -318,7 +320,7 @@ export default function JoinPage() {
why_join: "",
region: "",
available_time: "",
qualify, // 女性且小红书帖子>10 时自动通过审核
qualify,
is_volunteer: fromVolunteer,
}),
});
@@ -328,11 +330,19 @@ export default function JoinPage() {
}
setQualify(qualify);
setSubmitted(true);
// 提交成功后立即按微信号查询,用真实记录状态展示(审核中/审核通过等),避免刷新后状态不一致
fetchByWechat(wechat.trim());
try {
await fetchByWechat(wechat.trim());
} catch {
try {
localStorage.setItem(WECHAT_STORAGE_KEY, wechat.trim());
} catch {}
window.location.replace("/join");
return;
}
} catch (err) {
setError(err instanceof Error ? err.message : "网络错误,请重试");
} finally {
submittingRef.current = false;
setSubmitting(false);
}
};