feat: 套餐有效期支持日/周/月单位,订阅履约改用兑换码流程,UI层次感优化

- Prisma: SubscriptionPlan 新增 validityUnit 字段 (day/week/month)
- 新增 subscription-utils.ts 计算实际天数及格式化显示
- Sub2API client createAndRedeem 支持 subscription 类型 (group_id, validity_days)
- 订阅履约从 assignSubscription 改为 createAndRedeem,在 Sub2API 留痕
- 订单创建动态计算天数(月单位按自然月差值)
- 管理后台表单支持有效期数值+单位下拉
- 前端 ChannelCard 渠道卡片视觉层次优化(模型标签渐变、倍率突出、闪电图标)
- 按量付费 banner 改为渐变背景+底部倍率说明标签
- 帮助/客服信息区块添加到充值、订阅、支付全流程页面
- 移除系统配置独立页面入口,subscriptions API 返回用户信息
This commit is contained in:
erio
2026-03-13 21:19:22 +08:00
parent 9096271307
commit 687336cfd8
16 changed files with 672 additions and 1027 deletions

View File

@@ -1,6 +1,6 @@
import { NextRequest, NextResponse } from 'next/server';
import { verifyAdminToken, unauthorizedResponse } from '@/lib/admin-auth';
import { getUserSubscriptions } from '@/lib/sub2api/client';
import { getUserSubscriptions, getUser } from '@/lib/sub2api/client';
export async function GET(request: NextRequest) {
if (!(await verifyAdminToken(request))) return unauthorizedResponse(request);
@@ -18,7 +18,10 @@ export async function GET(request: NextRequest) {
return NextResponse.json({ error: '无效的 user_id' }, { status: 400 });
}
const subscriptions = await getUserSubscriptions(parsedUserId);
const [subscriptions, user] = await Promise.all([
getUserSubscriptions(parsedUserId),
getUser(parsedUserId).catch(() => null),
]);
// 如果提供了 group_id 筛选,过滤结果
const groupId = searchParams.get('group_id');
@@ -26,7 +29,10 @@ export async function GET(request: NextRequest) {
? subscriptions.filter((s) => s.group_id === Number(groupId))
: subscriptions;
return NextResponse.json({ subscriptions: filtered });
return NextResponse.json({
subscriptions: filtered,
user: user ? { id: user.id, username: user.username, email: user.email } : null,
});
} catch (error) {
console.error('Failed to query subscriptions:', error);
return NextResponse.json({ error: '查询订阅信息失败' }, { status: 500 });