/** * Admin Affiliate API endpoints * Manage per-user affiliate (邀请返利) configurations: * exclusive invite codes (overrides aff_code) and exclusive rebate rates. */ import { apiClient } from '../client' import type { PaginatedResponse } from '@/types' export interface AffiliateAdminEntry { user_id: number email: string username: string aff_code: string aff_code_custom: boolean aff_rebate_rate_percent?: number | null aff_count: number } export interface ListAffiliateUsersParams { page?: number page_size?: number search?: string } export interface ListAffiliateRecordsParams { page?: number page_size?: number search?: string start_at?: string end_at?: string sort_by?: string sort_order?: 'asc' | 'desc' timezone?: string } export interface AffiliateInviteRecord { inviter_id: number inviter_email: string inviter_username: string invitee_id: number invitee_email: string invitee_username: string aff_code: string total_rebate: number created_at: string } export interface AffiliateRebateRecord { order_id: number out_trade_no: string inviter_id: number inviter_email: string inviter_username: string invitee_id: number invitee_email: string invitee_username: string order_amount: number pay_amount: number rebate_amount: number payment_type: string order_status: string created_at: string } export interface AffiliateTransferRecord { ledger_id: number user_id: number user_email: string username: string amount: number current_balance: number remaining_quota: number frozen_quota: number history_quota: number created_at: string } export interface AffiliateUserOverview { user_id: number email: string username: string aff_code: string rebate_rate_percent: number invited_count: number rebated_invitee_count: number available_quota: number history_quota: number } export interface UpdateAffiliateUserRequest { aff_code?: string aff_rebate_rate_percent?: number | null /** Set true to explicitly clear the per-user rate (sets it to NULL). */ clear_rebate_rate?: boolean } export interface BatchSetRateRequest { user_ids: number[] aff_rebate_rate_percent?: number | null /** Set true to clear rates instead of setting. */ clear?: boolean } export interface SimpleUser { id: number email: string username: string } export async function listUsers( params: ListAffiliateUsersParams = {}, ): Promise> { const { data } = await apiClient.get>( '/admin/affiliates/users', { params: { page: params.page ?? 1, page_size: params.page_size ?? 20, search: params.search ?? '', }, }, ) return data } export async function lookupUsers(q: string): Promise { const { data } = await apiClient.get( '/admin/affiliates/users/lookup', { params: { q } }, ) return data } export async function updateUserSettings( userId: number, payload: UpdateAffiliateUserRequest, ): Promise<{ user_id: number }> { const { data } = await apiClient.put<{ user_id: number }>( `/admin/affiliates/users/${userId}`, payload, ) return data } export async function clearUserSettings( userId: number, ): Promise<{ user_id: number }> { const { data } = await apiClient.delete<{ user_id: number }>( `/admin/affiliates/users/${userId}`, ) return data } export async function batchSetRate( payload: BatchSetRateRequest, ): Promise<{ affected: number }> { const { data } = await apiClient.post<{ affected: number }>( '/admin/affiliates/users/batch-rate', payload, ) return data } function recordParams(params: ListAffiliateRecordsParams = {}) { return { page: params.page ?? 1, page_size: params.page_size ?? 20, search: params.search ?? '', start_at: params.start_at || undefined, end_at: params.end_at || undefined, sort_by: params.sort_by || undefined, sort_order: params.sort_order || undefined, timezone: params.timezone || undefined, } } export async function listInviteRecords( params: ListAffiliateRecordsParams = {}, ): Promise> { const { data } = await apiClient.get>( '/admin/affiliates/invites', { params: recordParams(params) }, ) return data } export async function listRebateRecords( params: ListAffiliateRecordsParams = {}, ): Promise> { const { data } = await apiClient.get>( '/admin/affiliates/rebates', { params: recordParams(params) }, ) return data } export async function listTransferRecords( params: ListAffiliateRecordsParams = {}, ): Promise> { const { data } = await apiClient.get>( '/admin/affiliates/transfers', { params: recordParams(params) }, ) return data } export async function getUserOverview( userId: number, ): Promise { const { data } = await apiClient.get( `/admin/affiliates/users/${userId}/overview`, ) return data } export const affiliatesAPI = { listUsers, lookupUsers, updateUserSettings, clearUserSettings, batchSetRate, listInviteRecords, listRebateRecords, listTransferRecords, getUserOverview, } export default affiliatesAPI