Files
J-Board-Lite/src/actions/user/subscription-transfer.ts
2026-05-01 04:39:15 +10:00

98 lines
3.5 KiB
TypeScript

"use server";
import { revalidatePath } from "next/cache";
import { z } from "zod";
import { requireAuth } from "@/lib/require-auth";
import { getErrorMessage } from "@/lib/errors";
import { actorFromSession } from "@/services/audit";
import {
acceptSubscriptionTransfer,
cancelSubscriptionTransfer,
createSubscriptionTransfer,
rejectSubscriptionTransfer,
} from "@/services/subscription-transfer";
const createTransferSchema = z.object({
subscriptionId: z.string().trim().min(1, "请选择要 Push 的套餐"),
recipientEmail: z.string().trim().email("请输入正确的接收方邮箱"),
password: z.string().min(1, "请输入当前账户密码"),
feePayer: z.enum(["SENDER", "RECIPIENT"]),
});
const transferIdSchema = z.string().trim().min(1, "套餐 Push 不存在");
type UserTransferActionResult = { ok: true; id?: string } | { ok: false; error: string };
function revalidateTransferViews(subscriptionId?: string) {
revalidatePath("/subscriptions");
revalidatePath("/subscriptions/push");
revalidatePath("/wallet");
if (subscriptionId) revalidatePath(`/subscriptions/${subscriptionId}`);
}
export async function createUserSubscriptionTransfer(formData: FormData): Promise<UserTransferActionResult> {
try {
const session = await requireAuth();
const data = createTransferSchema.parse(Object.fromEntries(formData));
const transfer = await createSubscriptionTransfer({
senderId: session.user.id,
recipientEmail: data.recipientEmail,
subscriptionId: data.subscriptionId,
password: data.password,
feePayer: data.feePayer,
actor: actorFromSession(session),
});
revalidateTransferViews(data.subscriptionId);
return { ok: true, id: transfer.id };
} catch (error) {
return { ok: false, error: getErrorMessage(error, "发起套餐 Push 失败") };
}
}
export async function acceptUserSubscriptionTransfer(transferId: string): Promise<UserTransferActionResult> {
try {
const session = await requireAuth();
const id = transferIdSchema.parse(transferId);
const transfer = await acceptSubscriptionTransfer({
transferId: id,
recipientId: session.user.id,
actor: actorFromSession(session),
});
revalidateTransferViews(transfer.subscriptionId);
return { ok: true };
} catch (error) {
return { ok: false, error: getErrorMessage(error, "接收套餐 Push 失败") };
}
}
export async function rejectUserSubscriptionTransfer(transferId: string): Promise<UserTransferActionResult> {
try {
const session = await requireAuth();
const id = transferIdSchema.parse(transferId);
const transfer = await rejectSubscriptionTransfer({
transferId: id,
recipientId: session.user.id,
actor: actorFromSession(session),
});
revalidateTransferViews(transfer.subscriptionId);
return { ok: true };
} catch (error) {
return { ok: false, error: getErrorMessage(error, "拒收套餐 Push 失败") };
}
}
export async function cancelUserSubscriptionTransfer(transferId: string): Promise<UserTransferActionResult> {
try {
const session = await requireAuth();
const id = transferIdSchema.parse(transferId);
const transfer = await cancelSubscriptionTransfer({
transferId: id,
senderId: session.user.id,
actor: actorFromSession(session),
});
revalidateTransferViews(transfer.subscriptionId);
return { ok: true };
} catch (error) {
return { ok: false, error: getErrorMessage(error, "取消套餐 Push 失败") };
}
}