Files
gitlab-instance-0a899031_salon/app/api/join/by-wechat/route.ts
2026-03-16 20:39:19 -05:00

100 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { NextRequest, NextResponse } from "next/server";
import { getAdminToken } from "@/app/lib/pocketbase/admin";
import { getPocketBaseConfig } from "@/config/services.config";
import { getSalonApi } from "@/app/lib/salonApi";
/** 用户状态必须实时从数据库获取,禁止缓存 */
export const dynamic = "force-dynamic";
const NO_CACHE_HEADERS = {
"Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
Pragma: "no-cache",
Expires: "0",
};
const empty = {
hasRecord: false,
record: null,
isComplete: false,
isWechatFriend: false,
isApproved: false,
isRejected: false,
vip: false,
};
async function getPocketBaseJoinByWechat(wechatId: string) {
const token = await getAdminToken();
if (!token) {
return null;
}
const pb = getPocketBaseConfig();
const base = pb.url.replace(/\/$/, "");
const escaped = wechatId.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
const filter = encodeURIComponent(`wechatId = "${escaped}"`);
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 4000);
const res = await fetch(
`${base}/api/collections/${pb.joinCollection}/records?filter=${filter}&sort=-created&perPage=1`,
{
headers: { Authorization: `Bearer ${token}` },
cache: "no-store",
signal: controller.signal,
}
).finally(() => clearTimeout(timeoutId));
if (!res.ok) return null;
const data = await res.json();
const items = Array.isArray(data?.items) ? data.items : [];
const rec = items[0] ?? null;
const hasRecord = !!rec;
const amount = rec ? Number(rec.amount) || 0 : 0;
const isComplete = hasRecord && !!rec.order_id && amount > 0;
const isWechatFriend = !!rec?.is_wechat_friend;
const isApproved = !!rec?.is_approved;
const isRejected = !!rec?.is_rejected;
const vip = !!rec?.vip;
return {
hasRecord,
record: rec,
isComplete,
isWechatFriend,
isApproved,
isRejected,
vip,
};
} catch {
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, { headers: NO_CACHE_HEADERS });
}
try {
const { status, data } = await getSalonApi(
request,
`/api/salon/join/by-wechat?wechat_id=${encodeURIComponent(wechatId)}&_=${Date.now()}`,
{ timeoutMs: 6000 }
);
if (status === 200 && data && typeof data === "object") {
return NextResponse.json(data, { headers: NO_CACHE_HEADERS });
}
} catch {
/* salonapi 不可用,回退直连 PocketBase */
}
const pbData = await getPocketBaseJoinByWechat(wechatId);
if (pbData) {
return NextResponse.json(pbData, { headers: NO_CACHE_HEADERS });
}
return NextResponse.json(empty, { headers: NO_CACHE_HEADERS });
}