fix: 订阅套餐 API features 字段序列化及返回格式修复

- POST/PUT 写入前 JSON.stringify(features),修复数组写入 TEXT 列报错
- GET/POST/PUT 返回时统一字段映射(validDays/enabled/groupName/features 数组)
This commit is contained in:
erio
2026-03-13 22:30:20 +08:00
parent bc9ae8370c
commit 38156bd4ef
2 changed files with 41 additions and 6 deletions

View File

@@ -37,7 +37,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
if (body.validity_unit !== undefined && ['day', 'week', 'month'].includes(body.validity_unit)) {
data.validityUnit = body.validity_unit;
}
if (body.features !== undefined) data.features = body.features;
if (body.features !== undefined) data.features = body.features ? JSON.stringify(body.features) : null;
if (body.for_sale !== undefined) data.forSale = body.for_sale;
if (body.sort_order !== undefined) data.sortOrder = body.sort_order;
@@ -47,9 +47,20 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
});
return NextResponse.json({
...plan,
id: plan.id,
groupId: String(plan.groupId),
groupName: null,
name: plan.name,
description: plan.description,
price: Number(plan.price),
originalPrice: plan.originalPrice ? Number(plan.originalPrice) : null,
validDays: plan.validityDays,
validityUnit: plan.validityUnit,
features: plan.features ? JSON.parse(plan.features) : [],
sortOrder: plan.sortOrder,
enabled: plan.forSale,
createdAt: plan.createdAt,
updatedAt: plan.updatedAt,
});
} catch (error) {
console.error('Failed to update subscription plan:', error);

View File

@@ -11,21 +11,34 @@ export async function GET(request: NextRequest) {
orderBy: { sortOrder: 'asc' },
});
// 并发检查每个套餐对应的 Sub2API 分组是否仍然存在
// 并发检查每个套餐对应的 Sub2API 分组是否仍然存在,并获取分组名称
const results = await Promise.all(
plans.map(async (plan) => {
let groupExists = false;
let groupName: string | null = null;
try {
const group = await getGroup(plan.groupId);
groupExists = group !== null;
groupName = group?.name ?? null;
} catch {
groupExists = false;
}
return {
...plan,
id: plan.id,
groupId: String(plan.groupId),
groupName,
name: plan.name,
description: plan.description,
price: Number(plan.price),
originalPrice: plan.originalPrice ? Number(plan.originalPrice) : null,
validDays: plan.validityDays,
validityUnit: plan.validityUnit,
features: plan.features ? JSON.parse(plan.features) : [],
sortOrder: plan.sortOrder,
enabled: plan.forSale,
groupExists,
createdAt: plan.createdAt,
updatedAt: plan.updatedAt,
};
}),
);
@@ -69,7 +82,7 @@ export async function POST(request: NextRequest) {
originalPrice: original_price ?? null,
validityDays: validity_days ?? 30,
validityUnit: ['day', 'week', 'month'].includes(validity_unit) ? validity_unit : 'day',
features: features ?? null,
features: features ? JSON.stringify(features) : null,
forSale: for_sale ?? false,
sortOrder: sort_order ?? 0,
},
@@ -77,9 +90,20 @@ export async function POST(request: NextRequest) {
return NextResponse.json(
{
...plan,
id: plan.id,
groupId: String(plan.groupId),
groupName: null,
name: plan.name,
description: plan.description,
price: Number(plan.price),
originalPrice: plan.originalPrice ? Number(plan.originalPrice) : null,
validDays: plan.validityDays,
validityUnit: plan.validityUnit,
features: plan.features ? JSON.parse(plan.features) : [],
sortOrder: plan.sortOrder,
enabled: plan.forSale,
createdAt: plan.createdAt,
updatedAt: plan.updatedAt,
},
{ status: 201 },
);