This commit is contained in:
eric
2026-03-27 19:07:24 -05:00
parent 759875ec36
commit 3eb0334114
8 changed files with 49 additions and 31 deletions

View File

@@ -1,7 +1,9 @@
import { SITE_ID, getPocketBaseConfig } from "@/config/services.config";
const VIP_EMAIL_LINK_COLLECTION = "vip_email_link";
const PB_FETCH_TIMEOUT = Number(process.env.POCKETBASE_FETCH_TIMEOUT) || 10000;
const PB_FETCH_TIMEOUT =
Number(process.env.POCKETBASE_FETCH_TIMEOUT) ||
(process.env.NODE_ENV === "development" ? 30_000 : 15_000);
const PB_ADMIN_TOKEN_TTL_MS = Number(process.env.POCKETBASE_ADMIN_TOKEN_TTL_MS) || 55_000;
let adminTokenCache: { token: string; expiresAt: number } | null = null;

View File

@@ -38,10 +38,14 @@ type RecoveryResult = {
const inflightEmailChecks = new Map<string, Promise<PayjsVipEmailResult | null>>();
const PAYJS_CHECK_BY_EMAIL_TIMEOUT =
Number(process.env.PAYJSAPI_CHECK_BY_EMAIL_TIMEOUT) || 20000;
Number(process.env.PAYJSAPI_CHECK_BY_EMAIL_TIMEOUT) || 20_000;
const PAYJS_CHECK_BY_EMAIL_RETRIES =
Math.max(0, Number(process.env.PAYJSAPI_CHECK_BY_EMAIL_RETRIES) || 1);
const PB_USER_LOGIN_TIMEOUT_MS =
Number(process.env.POCKETBASE_USER_LOGIN_TIMEOUT_MS) ||
(process.env.NODE_ENV === "development" ? 30_000 : 15_000);
function resolvePayApiUrl(request: NextRequest): string {
const payConfig = getPaymentConfig();
const hostHeader = request.headers.get("host") || request.headers.get("x-forwarded-host");
@@ -154,6 +158,7 @@ async function loginPocketBaseUser(
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ identity: email, password }),
cache: "no-store",
signal: AbortSignal.timeout(PB_USER_LOGIN_TIMEOUT_MS),
});
if (!res.ok) {
@@ -301,6 +306,11 @@ export async function POST(request: NextRequest) {
}
try {
const adminTokenPromise = getAdminToken().catch((error) => {
console.error("[check-by-email] getAdminToken failed:", error);
return null;
});
let authData: { token: string; record: PBAuthRecord } | null = null;
let loginError: string | null = null;
try {
@@ -339,10 +349,7 @@ export async function POST(request: NextRequest) {
);
}
const adminToken = await getAdminToken().catch((error) => {
console.error("[check-by-email] getAdminToken failed:", error);
return null;
});
const adminToken = await adminTokenPromise;
if (!adminToken) {
// 管理员 token 获取失败时,降级到 payjsapi 结果,避免直接 500
if (!payjsResult) {

View File

@@ -84,7 +84,7 @@ async function checkVipFromPayjsapi(
userId
)}`;
console.log("[check-by-user] payjsapi request user_id=%s url=%s", userId, url);
const checkTimeout = Number(process.env.PAYJSAPI_CHECK_TIMEOUT) || 15000;
const checkTimeout = Number(process.env.PAYJSAPI_CHECK_TIMEOUT) || 15_000;
const retries = Math.max(0, Number(process.env.PAYJSAPI_CHECK_RETRIES) || 1);
const res = await fetchPayjsVipWithRetry(url, checkTimeout, retries);
if (!res) {
@@ -166,7 +166,7 @@ export async function POST(request: NextRequest) {
let linkedUserId: string | undefined;
let vipFromSite = false;
let vipFromPayments = false;
let vipSource = vip ? "payjsapi" : "none";
let vipSource = "none";
try {
const adminToken = await getAdminToken().catch((error) => {
@@ -206,7 +206,7 @@ export async function POST(request: NextRequest) {
);
}
// PB 命中再请求 payjsapi,避免每次都先走远端网络
// 同机 PB 命中则不再打 payjsapi;仅未命中时再走 payjs与线上极致路径一致
if (!vip) {
payjsResult = await checkVipFromPayjsapi(request, userId);
if (payjsResult?.vip) {