's'
This commit is contained in:
74
app/api/join/by-wechat/route.ts
Normal file
74
app/api/join/by-wechat/route.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
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";
|
||||
|
||||
const empty = {
|
||||
hasRecord: false,
|
||||
record: null,
|
||||
isComplete: false,
|
||||
isWechatFriend: false,
|
||||
isApproved: false,
|
||||
isRejected: false,
|
||||
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)}`);
|
||||
if (status === 200 && data && typeof data === "object") {
|
||||
return NextResponse.json(data);
|
||||
}
|
||||
} catch {
|
||||
// salonapi 不可用,回退到直连 PocketBase
|
||||
}
|
||||
|
||||
const token = await getAdminToken();
|
||||
if (!token) {
|
||||
return NextResponse.json(empty);
|
||||
}
|
||||
|
||||
const pb = getPocketBaseConfig();
|
||||
const base = pb.url.replace(/\/$/, "");
|
||||
const escaped = wechatId.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
||||
const filter = encodeURIComponent(`wechatId = "${escaped}"`);
|
||||
|
||||
try {
|
||||
const res = await fetch(
|
||||
`${base}/api/collections/${pb.joinCollection}/records?filter=${filter}&sort=-created&perPage=1`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
cache: "no-store",
|
||||
}
|
||||
);
|
||||
if (!res.ok) return NextResponse.json(empty);
|
||||
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 NextResponse.json({
|
||||
hasRecord,
|
||||
record: rec,
|
||||
isComplete,
|
||||
isWechatFriend,
|
||||
isApproved,
|
||||
isRejected,
|
||||
vip,
|
||||
});
|
||||
} catch {
|
||||
return NextResponse.json(empty);
|
||||
}
|
||||
}
|
||||
@@ -46,12 +46,7 @@ export async function POST(request: NextRequest) {
|
||||
const region = String(formData.region || "").trim();
|
||||
const availableTime = String(formData.available_time || "").trim();
|
||||
const isVolunteer = !!formData.is_volunteer;
|
||||
if (!intro && (status || activityType || whyJoin || region || availableTime)) {
|
||||
const extra = [status && `状态:${status}`, activityType && `活动偏好:${activityType}`, whyJoin && `原因:${whyJoin}`, region && `区域:${region}`, availableTime && `时间:${availableTime}`].filter(Boolean).join(" | ");
|
||||
intro = extra;
|
||||
}
|
||||
|
||||
const isDigitalNomad = session === "digital-nomad";
|
||||
/** reason 仅存自我介绍,不合并其他字段 */
|
||||
const contact = wechatOrPhone || wechat || phone;
|
||||
if (!nickname || !session || !agreeRules) {
|
||||
return NextResponse.json(
|
||||
@@ -69,18 +64,19 @@ export async function POST(request: NextRequest) {
|
||||
const userId = getUserIdFromCookie(request) || generateAnonId();
|
||||
|
||||
const ageRangeForRecord = ageRange || "";
|
||||
/** occupation: 职业/城市,reason: 仅自我介绍 */
|
||||
const occupationValue = profession || city;
|
||||
|
||||
const record = {
|
||||
const record: Record<string, unknown> = {
|
||||
user_id: userId,
|
||||
nickname,
|
||||
occupation: isDigitalNomad ? profession : city,
|
||||
occupation: occupationValue,
|
||||
reason: intro,
|
||||
wechatId: wechat || wechatOrPhone,
|
||||
xiaohongshu_url: xiaohongshuUrl,
|
||||
gender,
|
||||
education: education,
|
||||
gradYear: graduationYear,
|
||||
phone: phone || wechatOrPhone,
|
||||
single: "",
|
||||
media: xiaohongshuAvatarUrl,
|
||||
type: session,
|
||||
@@ -90,7 +86,9 @@ export async function POST(request: NextRequest) {
|
||||
first_time: firstTime,
|
||||
is_volunteer: isVolunteer,
|
||||
};
|
||||
|
||||
if (phone.trim()) {
|
||||
record.phone = phone.trim();
|
||||
}
|
||||
try {
|
||||
const { status, data } = await postSalonApi(request, "/api/salon/join", record);
|
||||
if (status >= 500) {
|
||||
@@ -135,26 +133,28 @@ async function tryPocketBaseDirect(
|
||||
const base = pb.url.replace(/\/$/, "");
|
||||
const url = `${base}/api/collections/${pb.joinCollection}/records`;
|
||||
|
||||
const reasonParts = [record.reason, record.age_range, record.first_time];
|
||||
if (record.xiaohongshu_url) reasonParts.push(`小红书:${record.xiaohongshu_url}`);
|
||||
const body: Record<string, unknown> = {
|
||||
user_id: record.user_id,
|
||||
nickname: record.nickname,
|
||||
occupation: record.occupation ?? "",
|
||||
reason: reasonParts.filter(Boolean).join(" | "),
|
||||
reason: record.reason ?? "",
|
||||
wechatId: record.wechatId ?? "",
|
||||
gender: record.gender ?? "",
|
||||
education: record.education ?? "",
|
||||
gradYear: record.gradYear ?? "",
|
||||
phone: record.phone ?? "",
|
||||
single: record.single ?? "",
|
||||
media: record.media ?? "",
|
||||
type: record.type ?? "",
|
||||
order_id: record.order_id ?? "",
|
||||
amount: record.amount ?? 0,
|
||||
is_volunteer: record.is_volunteer ?? false,
|
||||
xiaohongshu_url: record.xiaohongshu_url ?? "",
|
||||
is_volunteer: record.is_volunteer ?? false,
|
||||
age_range: record.age_range ?? "",
|
||||
first_time: record.first_time ?? "",
|
||||
};
|
||||
if (record.phone != null && String(record.phone).trim()) {
|
||||
body.phone = record.phone;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
|
||||
@@ -13,7 +13,7 @@ export async function GET() {
|
||||
const base = pb.url.replace(/\/$/, "");
|
||||
|
||||
try {
|
||||
const filter = encodeURIComponent('is_volunteer=true');
|
||||
const filter = encodeURIComponent('is_volunteer=true && is_approved=true');
|
||||
const res = await fetch(
|
||||
`${base}/api/collections/${pb.joinCollection}/records?filter=${filter}&sort=-created&perPage=20`,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user