Your Name 66fd760b9a
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
feat: update enhance pro configuration
2026-05-07 19:54:02 +08:00

164 lines
5.3 KiB
TypeScript

import { NextResponse } from "next/server";
import { desc, eq } from "drizzle-orm";
import { auth } from "@/app/(auth)/auth";
import { db } from "@/lib/db";
import { paymentOrder, systemSettings } from "@/lib/db/schema";
import {
getPointsLedgerByUserId,
getPointsSystemConfig,
getUserById,
} from "@/lib/db/queries";
import {
defaultMembershipConfig,
defaultMembershipUserOverrides,
getMembershipPlanById,
normalizeMembershipConfig,
normalizeMembershipUserOverrides,
resolveMembershipPlanIdForUser,
} from "@/lib/membership/config";
const MEMBERSHIP_CONFIG_KEY = "membership_config";
const MEMBERSHIP_USER_OVERRIDES_KEY = "membership_user_plan_overrides";
function mapLedgerReasonLabel(reason: string) {
if (reason === "image_generation") return "图片生成";
if (reason === "model3d_generation") return "3D模型生成";
if (reason === "world3d_generation") return "3D世界生成";
if (reason === "video_generation") return "视频生成";
if (reason === "enhance_pro_generation") return "图像增强 Pro";
if (reason === "enhance_pro_refund") return "图像增强 Pro 失败退回";
if (reason === "deduct") return "管理员扣减";
if (reason === "gift") return "管理员赠送";
if (reason === "recharge") return "积分充值";
if (reason === "adjust") return "积分调整";
return reason || "积分变动";
}
function formatLedgerDetail(reason: string, note: string | null | undefined) {
if (reason === "recharge") {
return "充值积分";
}
const trimmedNote = typeof note === "string" ? note.trim() : "";
return trimmedNote || mapLedgerReasonLabel(reason);
}
export async function GET() {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const [
dbUser,
pointsConfig,
ledger,
paymentOrders,
configSetting,
overridesSetting,
] =
await Promise.all([
getUserById({ id: session.user.id }),
getPointsSystemConfig(),
getPointsLedgerByUserId({ userId: session.user.id, limit: 200 }),
db
.select({
id: paymentOrder.id,
amountCents: paymentOrder.amountCents,
status: paymentOrder.status,
createdAt: paymentOrder.createdAt,
})
.from(paymentOrder)
.where(eq(paymentOrder.userId, session.user.id))
.orderBy(desc(paymentOrder.createdAt))
.limit(100),
db
.select()
.from(systemSettings)
.where(eq(systemSettings.key, MEMBERSHIP_CONFIG_KEY))
.limit(1)
.then((rows) => rows[0]),
db
.select()
.from(systemSettings)
.where(eq(systemSettings.key, MEMBERSHIP_USER_OVERRIDES_KEY))
.limit(1)
.then((rows) => rows[0]),
]);
const membershipConfig = configSetting?.value
? normalizeMembershipConfig(configSetting.value)
: defaultMembershipConfig;
const membershipOverrides = overridesSetting?.value
? normalizeMembershipUserOverrides(overridesSetting.value)
: defaultMembershipUserOverrides;
const currentPlanId = resolveMembershipPlanIdForUser(
session.user.id,
session.user.email,
membershipConfig,
membershipOverrides
);
const currentPlan = getMembershipPlanById(membershipConfig, currentPlanId);
const usageRecords = ledger.map((item) => ({
id: item.id,
detail: formatLedgerDetail(item.reason, item.note),
status: item.amount < 0 ? "consumed" : "earned",
amount: item.amount,
createdAt: item.createdAt?.toISOString() || new Date().toISOString(),
}));
const rechargeRecords = paymentOrders.map((order) => ({
id: order.id,
date: order.createdAt?.toISOString() || new Date().toISOString(),
category: "积分充值",
amount: Number((order.amountCents / 100).toFixed(2)),
status:
order.status === "paid"
? "completed"
: order.status === "pending"
? "pending"
: "failed",
invoice: "-",
}));
const giftedRecords = ledger
.filter((item) => item.reason === "gift")
.map((item) => ({
id: item.id,
date: item.createdAt?.toISOString() || new Date().toISOString(),
category: "积分赠送",
amount: item.amount,
status: "completed",
invoice: "-",
}));
const billingRecords = [...rechargeRecords, ...giftedRecords].sort((a, b) => {
return new Date(b.date).getTime() - new Date(a.date).getTime();
});
return NextResponse.json({
profile: {
name: dbUser?.name || session.user.name || "",
email: dbUser?.email || session.user.email || "",
currentPlanName: currentPlan.name,
currentPlanId,
availablePoints: pointsConfig.enabled
? Math.max(0, Number(dbUser?.pointsBalance || 0))
: currentPlan.monthlyCredits,
monthlyCredits: currentPlan.monthlyCredits,
dailyFreeCredits: currentPlan.dailyFreeCredits,
},
usageRecords,
billingRecords,
});
} catch (error) {
console.error("[Account Center API] Error:", error);
return NextResponse.json(
{ error: "Failed to fetch account center data" },
{ status: 500 }
);
}
}