feat: 后台抽奖活动管理(Stage 1)
- 服务层:12 个 /v1/admin/lottery 接口封装与 API 类型定义 - 活动列表:状态筛选、上架/暂停(带确认)、编辑、管理、发次数 - 奖品管理:3×3 九宫格可视化编辑、概率预览、保底奖警告、佣金元↔分转换、无限库存 - 规则设置:chance_sources 动态编辑,eligibility 简单/高级(JSON)双模式,本地 rulecaps 校验(深度≤8/节点≤64/≤8KB),Stage 1 未接线警示 - 手动发次数:自动生成幂等 source_ref - 路由 /dashboard/lottery、Commerce 菜单项、en-US/zh-CN 双语文案 - 对接文档见 vpn/aaaa.txt(Stage 1)
This commit is contained in:
+115
@@ -3300,4 +3300,119 @@ declare namespace API {
|
||||
};
|
||||
|
||||
type AdminWithdrawalLog = WithdrawalLog;
|
||||
|
||||
type LotteryPrizeType =
|
||||
| 'vpn_duration'
|
||||
| 'commission'
|
||||
| 'none'
|
||||
| 'crypto'
|
||||
| 'physical'
|
||||
| 'manual_other'
|
||||
| 'coupon'
|
||||
| 'points';
|
||||
|
||||
type LotteryActivityStatus = 'draft' | 'running' | 'paused' | 'ended';
|
||||
|
||||
type LotteryChanceSourceType =
|
||||
| 'daily_signin'
|
||||
| 'new_subscription'
|
||||
| 'invite_success'
|
||||
| 'manual_grant';
|
||||
|
||||
type LotteryEligibilityNode = {
|
||||
op?: 'AND' | 'OR';
|
||||
children?: LotteryEligibilityNode[];
|
||||
type?: string;
|
||||
params?: Record<string, any>;
|
||||
};
|
||||
|
||||
type LotteryChanceSource = {
|
||||
source: LotteryChanceSourceType;
|
||||
amount: number;
|
||||
daily_limit?: number;
|
||||
};
|
||||
|
||||
type LotteryPrize = {
|
||||
id: number;
|
||||
activity_id: number;
|
||||
slot: number;
|
||||
type: LotteryPrizeType;
|
||||
name: string;
|
||||
icon_url: string;
|
||||
config: Record<string, any>;
|
||||
weight: number;
|
||||
total_stock: number | null;
|
||||
is_fallback: boolean;
|
||||
sold_out?: boolean;
|
||||
};
|
||||
|
||||
type LotteryActivity = {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
start_at: number; // Unix 秒
|
||||
end_at: number; // Unix 秒
|
||||
status: LotteryActivityStatus;
|
||||
grid_size: number;
|
||||
eligibility?: LotteryEligibilityNode | Record<string, never> | null;
|
||||
chance_sources?: LotteryChanceSource[];
|
||||
unmet_action?: string;
|
||||
prizes?: LotteryPrize[];
|
||||
};
|
||||
|
||||
type CreateLotteryActivityRequest = {
|
||||
title: string;
|
||||
description: string;
|
||||
start_at: number;
|
||||
end_at: number;
|
||||
grid_size: number;
|
||||
eligibility: LotteryEligibilityNode | Record<string, never> | null;
|
||||
chance_sources: LotteryChanceSource[];
|
||||
unmet_action: string;
|
||||
};
|
||||
|
||||
type UpdateLotteryActivityRequest = CreateLotteryActivityRequest & { id: number };
|
||||
|
||||
type GetLotteryActivityListParams = { page: number; size: number; status?: string };
|
||||
|
||||
type GetLotteryActivityListResponse = { total: number; list: LotteryActivity[] };
|
||||
|
||||
type GetLotteryActivityDetailParams = { id: number };
|
||||
|
||||
type PublishLotteryActivityRequest = { id: number };
|
||||
|
||||
type PauseLotteryActivityRequest = { id: number };
|
||||
|
||||
type UpdateLotteryActivityRulesRequest = {
|
||||
id: number;
|
||||
eligibility: LotteryEligibilityNode | Record<string, never> | null;
|
||||
chance_sources: LotteryChanceSource[];
|
||||
};
|
||||
|
||||
type CreateLotteryPrizeRequest = {
|
||||
activity_id: number;
|
||||
slot: number;
|
||||
type: LotteryPrizeType;
|
||||
name: string;
|
||||
icon_url: string;
|
||||
config: Record<string, any>;
|
||||
weight: number;
|
||||
total_stock: number | null;
|
||||
is_fallback: boolean;
|
||||
};
|
||||
|
||||
type UpdateLotteryPrizeRequest = CreateLotteryPrizeRequest & { id: number };
|
||||
|
||||
type DeleteLotteryPrizeRequest = { id: number };
|
||||
|
||||
type GetLotteryPrizeListParams = { activity_id: number };
|
||||
|
||||
type GetLotteryPrizeListResponse = { total?: number; list: LotteryPrize[] };
|
||||
|
||||
type GrantLotteryChancesRequest = {
|
||||
activity_id: number;
|
||||
user_id: number;
|
||||
amount: number;
|
||||
source_ref: string;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user