140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { getPocketBaseConfig } from "@/config/services.config";
|
|
import { getAdminToken } from "@/app/lib/pocketbase/admin";
|
|
|
|
import { COOKIE_NAME } from "@/app/lib/auth-cookie";
|
|
|
|
function getUserIdFromCookie(request: NextRequest): string | null {
|
|
const cookie = request.cookies.get(COOKIE_NAME)?.value;
|
|
if (!cookie) return null;
|
|
try {
|
|
const payload = JSON.parse(Buffer.from(cookie, "base64url").toString("utf-8"));
|
|
return payload?.userId ?? null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const userId = getUserIdFromCookie(request);
|
|
if (!userId) {
|
|
return NextResponse.json({ ok: false, error: "请先登录" }, { status: 401 });
|
|
}
|
|
const body = await request.json();
|
|
const formData = body && typeof body === "object" ? body : {};
|
|
|
|
const {
|
|
nickname,
|
|
gender,
|
|
single,
|
|
profession,
|
|
intro,
|
|
wechat,
|
|
education,
|
|
graduationYear,
|
|
phone,
|
|
media: mediaUrl,
|
|
} = formData;
|
|
|
|
const record: Record<string, string | number> = {
|
|
nickname: nickname || "",
|
|
occupation: profession || "",
|
|
reason: intro || "",
|
|
single: single || "",
|
|
wechatId: wechat || "",
|
|
gender: gender || "",
|
|
education: education || "",
|
|
gradYear: graduationYear || "",
|
|
phone: phone || "",
|
|
user_id: userId,
|
|
amount: 0,
|
|
order_id: "",
|
|
type: "",
|
|
};
|
|
|
|
if (mediaUrl && typeof mediaUrl === "string") {
|
|
(record as Record<string, string>)["media"] = mediaUrl;
|
|
}
|
|
|
|
const pb = getPocketBaseConfig();
|
|
const collection = pb.joinCollection;
|
|
const base = pb.url.replace(/\/$/, "");
|
|
|
|
const doUpsert = async (authToken: string) => {
|
|
const headers: Record<string, string> = {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${authToken}`,
|
|
};
|
|
|
|
const filter = `user_id="${userId}"`;
|
|
const listRes = await fetch(
|
|
`${base}/api/collections/${collection}/records?filter=${encodeURIComponent(filter)}&perPage=1`,
|
|
{ headers: { Authorization: `Bearer ${authToken}` }, cache: "no-store" }
|
|
);
|
|
const listData = await listRes.json().catch(() => ({}));
|
|
const existing = (listData?.items ?? [])[0];
|
|
|
|
if (existing?.id) {
|
|
const patchBody: Record<string, string | number> = {
|
|
nickname: record.nickname,
|
|
occupation: record.occupation,
|
|
reason: record.reason,
|
|
single: record.single,
|
|
wechatId: record.wechatId,
|
|
gender: record.gender,
|
|
education: record.education,
|
|
gradYear: record.gradYear,
|
|
phone: record.phone,
|
|
};
|
|
if ("media" in record) patchBody.media = record.media as string;
|
|
return fetch(`${base}/api/collections/${collection}/records/${existing.id}`, {
|
|
method: "PATCH",
|
|
headers,
|
|
body: JSON.stringify(patchBody),
|
|
});
|
|
}
|
|
return fetch(`${base}/api/collections/${collection}/records`, {
|
|
method: "POST",
|
|
headers,
|
|
body: JSON.stringify(record),
|
|
});
|
|
};
|
|
|
|
const token = await getAdminToken();
|
|
if (!token) {
|
|
return NextResponse.json({ ok: false, error: "服务配置错误" }, { status: 500 });
|
|
}
|
|
|
|
const res = await doUpsert(token);
|
|
|
|
if (!res.ok) {
|
|
const errText = await res.text();
|
|
console.error("PocketBase create error:", res.status, errText);
|
|
let errMsg = "提交失败,请稍后重试";
|
|
try {
|
|
const errJson = JSON.parse(errText);
|
|
if (errJson?.message) errMsg = errJson.message;
|
|
if (errJson?.data && typeof errJson.data === "object") {
|
|
const details = Object.entries(errJson.data)
|
|
.map(([k, v]) => `${k}: ${(v as { message?: string })?.message || v}`)
|
|
.join("; ");
|
|
if (details) errMsg += ` (${details})`;
|
|
}
|
|
} catch {
|
|
if (errText.length < 200) errMsg = errText;
|
|
}
|
|
return NextResponse.json({ ok: false, error: errMsg }, { status: 500 });
|
|
}
|
|
|
|
return NextResponse.json({ ok: true, user_id: userId });
|
|
} catch (e) {
|
|
const msg = e instanceof Error ? e.message : String(e);
|
|
console.error("Join API error:", e);
|
|
return NextResponse.json(
|
|
{ ok: false, error: `提交失败: ${msg}` },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|