diff --git a/app/api/join/by-wechat/route.ts b/app/api/join/by-wechat/route.ts
index ddbd95e..2d96cc0 100644
--- a/app/api/join/by-wechat/route.ts
+++ b/app/api/join/by-wechat/route.ts
@@ -13,29 +13,10 @@ const empty = {
vip: false,
};
-/** 按 wechatId 查询 solanRed 记录,优先 salonapi */
-export async function GET(request: NextRequest) {
- const wechatId = request.nextUrl.searchParams.get("wechat_id")?.trim();
- if (!wechatId) {
- return NextResponse.json(empty);
- }
-
- try {
- const { status, data } = await getSalonApi(
- request,
- `/api/salon/join/by-wechat?wechat_id=${encodeURIComponent(wechatId)}`,
- { timeoutMs: 8000 }
- );
- if (status === 200 && data && typeof data === "object") {
- return NextResponse.json(data);
- }
- } catch {
- // salonapi 不可用,回退到直连 PocketBase
- }
-
+async function getPocketBaseJoinByWechat(wechatId: string) {
const token = await getAdminToken();
if (!token) {
- return NextResponse.json(empty);
+ return null;
}
const pb = getPocketBaseConfig();
@@ -45,7 +26,7 @@ export async function GET(request: NextRequest) {
try {
const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 8000);
+ const timeoutId = setTimeout(() => controller.abort(), 4000);
const res = await fetch(
`${base}/api/collections/${pb.joinCollection}/records?filter=${filter}&sort=-created&perPage=1`,
{
@@ -54,7 +35,7 @@ export async function GET(request: NextRequest) {
signal: controller.signal,
}
).finally(() => clearTimeout(timeoutId));
- if (!res.ok) return NextResponse.json(empty);
+ if (!res.ok) return null;
const data = await res.json();
const items = Array.isArray(data?.items) ? data.items : [];
const rec = items[0] ?? null;
@@ -66,7 +47,7 @@ export async function GET(request: NextRequest) {
const isRejected = !!rec?.is_rejected;
const vip = !!rec?.vip;
- return NextResponse.json({
+ return {
hasRecord,
record: rec,
isComplete,
@@ -74,8 +55,36 @@ export async function GET(request: NextRequest) {
isApproved,
isRejected,
vip,
- });
+ };
} catch {
- return NextResponse.json(empty);
+ return null;
}
}
+
+/** 按 wechatId 查询 solanRed 记录。优先 salonapi(记录由其创建,线上部署时更可靠),失败时回退直连 PocketBase */
+export async function GET(request: NextRequest) {
+ const wechatId = request.nextUrl.searchParams.get("wechat_id")?.trim();
+ if (!wechatId) {
+ return NextResponse.json(empty);
+ }
+
+ try {
+ const { status, data } = await getSalonApi(
+ request,
+ `/api/salon/join/by-wechat?wechat_id=${encodeURIComponent(wechatId)}`,
+ { timeoutMs: 6000 }
+ );
+ if (status === 200 && data && typeof data === "object") {
+ return NextResponse.json(data);
+ }
+ } catch {
+ /* salonapi 不可用,回退直连 PocketBase */
+ }
+
+ const pbData = await getPocketBaseJoinByWechat(wechatId);
+ if (pbData) {
+ return NextResponse.json(pbData);
+ }
+
+ return NextResponse.json(empty);
+}
diff --git a/app/join/page.tsx b/app/join/page.tsx
index e88dfaa..fd7b44c 100644
--- a/app/join/page.tsx
+++ b/app/join/page.tsx
@@ -77,6 +77,28 @@ interface UserRecord {
vip: boolean;
}
+const EMPTY_USER_RECORD: UserRecord = {
+ hasRecord: false,
+ record: null,
+ isComplete: false,
+ isWechatFriend: false,
+ isApproved: false,
+ isRejected: false,
+ vip: false,
+};
+
+function toUserRecord(data: Partial