feat: 渠道展示、订阅套餐、系统配置全功能
- 新增 Channel / SubscriptionPlan / SystemConfig 三个数据模型 - Order 模型扩展支持订阅订单(order_type, plan_id, subscription_group_id) - Sub2API client 新增分组查询、订阅分配/续期、用户订阅查询 - 订单服务支持订阅履约流程(CAS 锁 + 分组消失安全处理) - 管理后台:渠道管理、订阅套餐管理、系统配置、Sub2API 分组同步 - 用户页面:双 Tab UI(按量付费/包月订阅)、渠道卡片、充值弹窗、订阅确认 - PaymentForm 支持 fixedAmount 固定金额模式 - 订单状态 API 返回 failedReason 用于订阅异常展示 - 数据库迁移脚本
This commit is contained in:
@@ -13,6 +13,8 @@ const createOrderSchema = z.object({
|
||||
src_host: z.string().max(253).optional(),
|
||||
src_url: z.string().max(2048).optional(),
|
||||
is_mobile: z.boolean().optional(),
|
||||
order_type: z.enum(['balance', 'subscription']).optional(),
|
||||
plan_id: z.string().optional(),
|
||||
});
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
@@ -25,7 +27,7 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ error: '参数错误', details: parsed.error.flatten().fieldErrors }, { status: 400 });
|
||||
}
|
||||
|
||||
const { token, amount, payment_type, src_host, src_url, is_mobile } = parsed.data;
|
||||
const { token, amount, payment_type, src_host, src_url, is_mobile, order_type, plan_id } = parsed.data;
|
||||
|
||||
// 通过 token 解析用户身份
|
||||
let userId: number;
|
||||
@@ -36,12 +38,14 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ error: '无效的 token,请重新登录', code: 'INVALID_TOKEN' }, { status: 401 });
|
||||
}
|
||||
|
||||
// Validate amount range
|
||||
if (amount < env.MIN_RECHARGE_AMOUNT || amount > env.MAX_RECHARGE_AMOUNT) {
|
||||
return NextResponse.json(
|
||||
{ error: `充值金额需在 ${env.MIN_RECHARGE_AMOUNT} - ${env.MAX_RECHARGE_AMOUNT} 之间` },
|
||||
{ status: 400 },
|
||||
);
|
||||
// 订阅订单跳过金额范围校验(价格由服务端套餐决定)
|
||||
if (order_type !== 'subscription') {
|
||||
if (amount < env.MIN_RECHARGE_AMOUNT || amount > env.MAX_RECHARGE_AMOUNT) {
|
||||
return NextResponse.json(
|
||||
{ error: `充值金额需在 ${env.MIN_RECHARGE_AMOUNT} - ${env.MAX_RECHARGE_AMOUNT} 之间` },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate payment type is enabled
|
||||
@@ -60,6 +64,8 @@ export async function POST(request: NextRequest) {
|
||||
isMobile: is_mobile,
|
||||
srcHost: src_host,
|
||||
srcUrl: src_url,
|
||||
orderType: order_type,
|
||||
planId: plan_id,
|
||||
});
|
||||
|
||||
// 不向客户端暴露 userName / userBalance 等隐私字段
|
||||
|
||||
Reference in New Issue
Block a user