100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
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 });
|
||
}
|