feat: polish wallet recharge cards

This commit is contained in:
JetSprow
2026-05-01 03:41:30 +10:00
parent 035ac9266a
commit 0c8b402f3e
15 changed files with 774 additions and 103 deletions

View File

@@ -2,6 +2,7 @@
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { prisma } from "@/lib/prisma";
import { requireAdmin } from "@/lib/require-auth";
import { actorFromSession, recordAuditLog } from "@/services/audit";
import { createRechargeCards } from "@/services/wallet";
@@ -62,3 +63,53 @@ export async function createAdminRechargeCards(formData: FormData) {
revalidatePath("/admin/plans");
revalidatePath("/store");
}
export async function deleteAdminRechargeCard(cardId: string) {
const session = await requireAdmin();
const id = z.string().min(1, "充值卡不存在").parse(cardId);
const card = await prisma.rechargeCard.findUnique({
where: { id },
include: {
plan: { select: { id: true, name: true } },
redeemedBy: { select: { email: true, name: true } },
},
});
if (!card) {
throw new Error("充值卡不存在或已被删除");
}
const releasesPlanStock =
card.type === "PLAN"
&& card.status === "UNUSED"
&& (!card.expiresAt || card.expiresAt > new Date());
await prisma.rechargeCard.delete({ where: { id } });
await recordAuditLog({
actor: actorFromSession(session),
action: "recharge_card.delete",
targetType: "RechargeCard",
targetId: card.id,
targetLabel: card.code,
message: releasesPlanStock
? `删除套餐充值卡 ${card.code},已释放套餐库存`
: `删除充值卡 ${card.code}`,
metadata: {
code: card.code,
type: card.type,
status: card.status,
planId: card.planId,
planName: card.plan?.name ?? null,
redeemedBy: card.redeemedBy?.email ?? null,
redeemedAt: card.redeemedAt?.toISOString() ?? null,
releasesPlanStock,
},
});
revalidatePath("/admin/commerce");
revalidatePath("/admin/plans");
revalidatePath("/store");
return { releasesPlanStock };
}

View File

@@ -2,6 +2,7 @@
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { prisma } from "@/lib/prisma";
import { requireAuth } from "@/lib/require-auth";
import { createWalletRechargeOrder, redeemRechargeCard } from "@/services/wallet";
@@ -23,8 +24,40 @@ export async function createWalletRecharge(formData: FormData) {
export async function redeemWalletCard(formData: FormData) {
const session = await requireAuth();
const data = redeemSchema.parse(Object.fromEntries(formData));
await redeemRechargeCard(session.user.id, data.code);
const result = await redeemRechargeCard(session.user.id, data.code);
revalidatePath("/wallet");
revalidatePath("/subscriptions");
revalidatePath("/dashboard");
return result;
}
export async function cancelWalletRecharge(rechargeId: string) {
const session = await requireAuth();
const recharge = await prisma.walletRechargeOrder.findFirst({
where: { id: rechargeId, userId: session.user.id },
select: { id: true, status: true },
});
if (!recharge) {
throw new Error("充值订单不存在");
}
if (recharge.status !== "PENDING") {
throw new Error("这笔充值订单已经不在待支付状态");
}
await prisma.walletRechargeOrder.update({
where: { id: rechargeId },
data: {
status: "CANCELLED",
paymentMethod: null,
paymentRef: null,
paymentUrl: null,
tradeNo: null,
expireAt: null,
note: null,
},
});
revalidatePath("/wallet");
revalidatePath(`/wallet/recharge/${rechargeId}`);
}