diff --git a/app/api/join/by-wechat/route.ts b/app/api/join/by-wechat/route.ts index e1b3596..d946442 100644 --- a/app/api/join/by-wechat/route.ts +++ b/app/api/join/by-wechat/route.ts @@ -80,7 +80,7 @@ export async function GET(request: NextRequest) { try { const { status, data } = await getSalonApi( request, - `/api/salon/join/by-wechat?wechat_id=${encodeURIComponent(wechatId)}`, + `/api/salon/join/by-wechat?wechat_id=${encodeURIComponent(wechatId)}&_=${Date.now()}`, { timeoutMs: 6000 } ); if (status === 200 && data && typeof data === "object") { diff --git a/app/components/MyRegistrationStatus.tsx b/app/components/MyRegistrationStatus.tsx index a190fec..171d99f 100644 --- a/app/components/MyRegistrationStatus.tsx +++ b/app/components/MyRegistrationStatus.tsx @@ -3,6 +3,7 @@ import { useEffect, useState } from "react"; import Image from "next/image"; import Link from "next/link"; +import { usePathname } from "next/navigation"; const WECHAT_STORAGE_KEY = "salon_join_wechat"; @@ -76,6 +77,8 @@ export default function MyRegistrationStatus() { } }; + const pathname = usePathname(); + useEffect(() => { if (typeof window === "undefined") return; let cancelled = false; @@ -90,16 +93,23 @@ export default function MyRegistrationStatus() { if (e.persisted && !cancelled) fetchStatus(); }; window.addEventListener("vip:updated", onUpdate); + window.addEventListener("registration:refresh", onUpdate); document.addEventListener("visibilitychange", onVisibilityChange); window.addEventListener("pageshow", onPageShow); return () => { cancelled = true; window.removeEventListener("vip:updated", onUpdate); + window.removeEventListener("registration:refresh", onUpdate); document.removeEventListener("visibilitychange", onVisibilityChange); window.removeEventListener("pageshow", onPageShow); }; }, []); + // 每次进入首页时强制重新拉取,避免预取/缓存导致显示旧状态 + useEffect(() => { + if (pathname === "/") fetchStatus(); + }, [pathname]); + if (loading || !data?.hasRecord || !data.record) return null; const rec = data.record; diff --git a/app/join/page.tsx b/app/join/page.tsx index b5c0bf7..b59f850 100644 --- a/app/join/page.tsx +++ b/app/join/page.tsx @@ -1,6 +1,7 @@ "use client"; import { useState, useEffect, useRef, type FormEvent } from "react"; +import { usePathname } from "next/navigation"; import { useCompleteOrderPolling } from "@/app/hooks/useCompleteOrderPolling"; import Link from "next/link"; import ThemeToggle from "../components/ThemeToggle"; @@ -524,6 +525,15 @@ export default function JoinPage() { retryDelays: [500, 1000, 1500, 2500, 4000], }); + const pathname = usePathname(); + // 每次进入报名页时强制重新拉取,避免预取/缓存导致显示旧状态 + useEffect(() => { + if (pathname === "/join") { + const w = (localStorage.getItem(WECHAT_STORAGE_KEY) || "").trim(); + if (w && WECHAT_REGEX.test(w)) fetchByWechatRef.current(w); + } + }, [pathname]); + // 微信内/手机浏览器支付后:页面可能被关闭或跳转,返回时 notify 可能未到。轮询 fetchByWechat 检测支付成功 // 手机浏览器唤醒微信 app 支付完成后,用户可能直接回 /join,故 h5 也需轮询(参考 nomadvip) useEffect(() => { diff --git a/app/lib/complete-order.ts b/app/lib/complete-order.ts index 2ac2dd1..5ec0e24 100644 --- a/app/lib/complete-order.ts +++ b/app/lib/complete-order.ts @@ -40,6 +40,7 @@ export function applyCompleteSuccess(data: { token?: string; record?: { wechatId } window.dispatchEvent(new CustomEvent("auth:updated")); window.dispatchEvent(new CustomEvent("vip:updated")); + window.dispatchEvent(new CustomEvent("registration:refresh")); if (record?.wechatId) { try { localStorage.setItem(WECHAT_STORAGE_KEY, record.wechatId);