import request from './request' import type { DashboardStats, AlertChannelInput, AlertNotifyChannel, ApiClient, ApiCredential, CallbackCredential, CallbackSubscription, CreateManualOrderResult, CreateTestOrderResult, DeliveryBindResult, DeliveryOrderInfo, DeliveryLinkResult, DeliverySubmitResult, FulfillmentOrder, LoginResult, LowBalanceAlertConfig, Merchant, MerchantMember, MerchantMemberGroup, MerchantOption, MerchantOwnerAccount, MerchantRole, MerchantProduct, PageResult, ProductCatalogItem, RechargeApplication, User, WalletAccount, WalletLedgerEntry, LewanProductListResult, UpdateProductRoutingInput, SyncLewanProductInput, } from '../types' export const authApi = { login: async (username: string, password: string) => { const res = await request.post('/auth/login', { username, password }) return res.data.data as LoginResult }, profile: async () => { const res = await request.get('/auth/profile') return res.data.data as User }, changePassword: (data: { current_password: string; new_password: string }) => request.put('/auth/password', data).then((r) => r.data.data), updateCurrentAccount: (data: { current_password: string; username: string; nickname?: string; new_password?: string }) => request.put('/auth/account', data).then((r) => r.data.data as User), } export const dashboardApi = { stats: () => request.get('/dashboard').then((r) => r.data.data as DashboardStats), } export const userApi = { list: (params?: Record) => request.get('/platform/admins', { params }).then((r) => r.data.data as PageResult), create: (data: { username: string; password: string; nickname?: string }) => request.post('/platform/admins', data).then((r) => r.data.data as User), update: (id: number, data: { username: string; nickname?: string; password?: string; status: number }) => request.patch(`/platform/admins/${id}`, data).then((r) => r.data.data as User), remove: (id: number) => request.delete(`/platform/admins/${id}`).then((r) => r.data.data), } export const merchantApi = { current: () => request.get('/merchant').then((r) => r.data.data as { merchant: Merchant; role: string; permissions: string[] }), products: (params?: Record) => request.get('/merchant/products', { params }).then((r) => r.data.data as PageResult), updateProduct: ( id: number, data: { display_name?: string price_amount?: number cost_amount?: number stock?: number status?: 'active' | 'inactive' } ) => request.patch(`/merchant/products/${id}`, data).then((r) => r.data.data), updateProductStatus: (id: number, status: MerchantProduct['status']) => request.patch(`/merchant/products/${id}/status`, { status }).then((r) => r.data.data), deleteProduct: (id: number) => request.delete(`/merchant/products/${id}`).then((r) => r.data.data), orders: (params?: Record) => request.get('/merchant/orders', { params }).then((r) => r.data.data as PageResult), manualOrderProducts: () => request.get('/merchant/orders/products').then((r) => r.data.data as MerchantProduct[]), createTestOrder: (data: { sku: string buyer_reference?: string note?: string order_status?: 'paid' | 'ship_failed' | 'cancelled' }) => request.post('/merchant/orders/test', data).then((r) => r.data.data as CreateTestOrderResult), createManualOrder: (data: { client_order_no: string sku: string quantity: number buyer_reference?: string game_account?: string note?: string }) => request.post('/merchant/orders/manual', data).then((r) => r.data.data as CreateManualOrderResult), cancelOrder: (orderNo: string, reason: string) => request.post(`/merchant/orders/${encodeURIComponent(orderNo)}/cancel`, { reason }).then((r) => r.data.data as { order: FulfillmentOrder; refund_amount: number }), getDeliveryLink: (orderNo: string) => request.get(`/merchant/orders/${encodeURIComponent(orderNo)}/delivery-link`).then((r) => r.data.data as DeliveryLinkResult), revokeDeliveryLink: (orderNo: string) => request.post(`/merchant/orders/${encodeURIComponent(orderNo)}/delivery-link/revoke`).then((r) => r.data.data), restoreDeliveryLink: (orderNo: string) => request.post(`/merchant/orders/${encodeURIComponent(orderNo)}/delivery-link/restore`).then((r) => r.data.data as DeliveryLinkResult), wallet: () => request.get('/merchant/wallet').then((r) => r.data.data as WalletAccount), ledger: (params?: Record) => request.get('/merchant/wallet/ledger', { params }).then((r) => r.data.data as PageResult), apiClients: () => request.get('/merchant/api-clients').then((r) => r.data.data as ApiClient[]), createApiClient: (data: { name: string scopes: string signature_version?: string expires_at?: string }) => request.post('/merchant/api-clients', data).then((r) => r.data.data as ApiCredential), updateApiClientStatus: (id: number, status: ApiClient['status']) => request.patch(`/merchant/api-clients/${id}/status`, { status }).then((r) => r.data.data), deleteApiClient: (id: number) => request.delete(`/merchant/api-clients/${id}`).then((r) => r.data.data), callbacks: () => request.get('/merchant/callbacks').then((r) => r.data.data as CallbackSubscription | null), saveCallback: (data: { url: string; events: string; status: CallbackSubscription['status']; rotate_secret?: boolean }) => request.post('/merchant/callbacks', data).then((r) => r.data.data as CallbackCredential), members: () => request.get('/merchant/members').then((r) => r.data.data as MerchantMember[]), addMember: (data: { user_id?: number; username?: string; password?: string; nickname?: string; role: string; is_default?: boolean }) => request.post('/merchant/members', data).then((r) => r.data.data as MerchantMember), updateMember: (id: number, data: { role: string; status: number; is_default: boolean }) => request.patch(`/merchant/members/${id}`, data).then((r) => r.data.data as MerchantMember), removeMember: (id: number) => request.delete(`/merchant/members/${id}`).then((r) => r.data.data), roles: () => request.get('/merchant/roles').then((r) => r.data.data as MerchantRole[]), createRole: (data: { code: string; name: string; permissions: string[] }) => request.post('/merchant/roles', data).then((r) => r.data.data as MerchantRole), updateRole: (id: number, data: { name: string; permissions: string[] }) => request.patch(`/merchant/roles/${id}`, data).then((r) => r.data.data as MerchantRole), rechargeApplications: (params?: Record) => request.get('/merchant/recharge/applications', { params }).then((r) => r.data.data as PageResult), createRechargeApplication: (data: { amount_cny: number; vouchers: string[]; note?: string }) => // amount_cny 单位:分(1元 = 100分),积分按 1元 = 100积分 折算 request.post('/merchant/recharge/applications', data).then((r) => r.data.data as RechargeApplication), alertConfig: () => request.get('/merchant/recharge/alert-config').then((r) => r.data.data as LowBalanceAlertConfig), saveAlertConfig: (data: { enabled: boolean; threshold_points: number; notify_interval_minutes: number; max_notifications: number }) => request.put('/merchant/recharge/alert-config', data).then((r) => r.data.data as LowBalanceAlertConfig), alertChannels: () => request.get('/merchant/alert-channels').then((r) => r.data.data as AlertNotifyChannel[]), createAlertChannel: (data: AlertChannelInput) => request.post('/merchant/alert-channels', data).then((r) => r.data.data as AlertNotifyChannel), updateAlertChannel: (id: number, data: AlertChannelInput) => request.put(`/merchant/alert-channels/${id}`, data).then((r) => r.data.data as AlertNotifyChannel), deleteAlertChannel: (id: number) => request.delete(`/merchant/alert-channels/${id}`).then((r) => r.data.data), testAlertChannel: (id: number) => request.post(`/merchant/alert-channels/${id}/test`).then((r) => r.data.data), } export const uploadApi = { file: (file: File) => { const form = new FormData() form.append('file', file) return request.post('/upload', form, { headers: { 'Content-Type': 'multipart/form-data' }, timeout: 60000, }).then((r) => r.data.data as { url: string }) }, } export const deliveryApi = { getOrder: (orderNo: string, auth?: { exp?: string; sign?: string }) => request.get(`/delivery/v1/orders/${encodeURIComponent(orderNo)}`, { params: auth }).then((r) => r.data.data as DeliveryOrderInfo), bind: (orderNo: string, gameAccount: string, auth?: { exp?: string; sign?: string }) => request.post( `/delivery/v1/orders/${encodeURIComponent(orderNo)}/bind`, { game_account: gameAccount, }, { params: auth }, ).then((r) => r.data.data as DeliveryBindResult), getBindResult: (orderNo: string, bindUUID: string, auth?: { exp?: string; sign?: string }) => request.get(`/delivery/v1/orders/${encodeURIComponent(orderNo)}/bind-result`, { params: { ...auth, bind_uuid: bindUUID }, }).then((r) => r.data.data as DeliveryBindResult), submit: (orderNo: string, gameAccount: string, bindUUID: string, auth?: { exp?: string; sign?: string }) => request.post( `/delivery/v1/orders/${encodeURIComponent(orderNo)}/submit`, { game_account: gameAccount, bind_uuid: bindUUID, }, { params: auth }, ).then((r) => r.data.data as DeliverySubmitResult), } export const platformApi = { merchantAccounts: (params?: Record) => request.get('/platform/merchant-accounts', { params }).then((r) => r.data.data as PageResult), deleteMerchantAccount: (userId: number) => request.delete(`/platform/merchant-accounts/${userId}`).then((r) => r.data.data), merchants: (params?: Record) => request.get('/platform/merchants', { params }).then((r) => r.data.data as PageResult), // 不分页的精简商户列表,供筛选下拉使用(/platform/merchants 的 size 上限是 100) merchantOptions: () => request.get('/platform/merchant-options').then((r) => r.data.data as MerchantOption[]), // 平台侧跨商户订单视图:不传 merchant_id 即全部商户 orders: (params?: Record) => request.get('/platform/orders', { params }).then((r) => r.data.data as PageResult), createMerchant: (data: { code: string name: string contact_name?: string contact_info?: string owner_user_id?: number owner_username?: string owner_password?: string owner_nickname?: string features?: string fee_type?: 'rate' | 'fixed' fee_rate_bp?: number fee_fixed_amount?: number }) => request.post('/platform/merchants', data).then((r) => r.data.data as Merchant), updateMerchant: (id: number, data: Partial) => request.patch(`/platform/merchants/${id}`, data).then((r) => r.data.data), members: (merchantId: number) => request.get(`/platform/merchants/${merchantId}/members`).then((r) => r.data.data as MerchantMember[]), addMember: ( merchantId: number, data: { user_id?: number; username?: string; password?: string; nickname?: string; role: string; is_default?: boolean }, ) => request.post(`/platform/merchants/${merchantId}/members`, data).then((r) => r.data.data as MerchantMember), updateMember: ( merchantId: number, memberId: number, data: { role: string; status: number; is_default: boolean }, ) => request.patch(`/platform/merchants/${merchantId}/members/${memberId}`, data).then((r) => r.data.data as MerchantMember), removeMember: (merchantId: number, memberId: number) => request.delete(`/platform/merchants/${merchantId}/members/${memberId}`).then((r) => r.data.data), roles: (merchantId: number) => request.get(`/platform/merchants/${merchantId}/roles`).then((r) => r.data.data as MerchantRole[]), productCatalog: () => request.get('/platform/product-catalog').then((r) => r.data.data as ProductCatalogItem[]), merchantProducts: (merchantId: number) => request.get(`/platform/merchants/${merchantId}/products`).then((r) => r.data.data as ProductCatalogItem[]), updateMerchantProduct: (merchantId: number, productId: number, data: Partial) => request.patch(`/platform/merchants/${merchantId}/products/${productId}`, data).then((r) => r.data.data), assignProducts: (merchantId: number, catalogIds: number[]) => request.post(`/platform/merchants/${merchantId}/products/assign`, { catalog_ids: catalogIds }).then((r) => r.data.data as { assigned: number }), wallet: (merchantId: number) => request.get(`/platform/merchants/${merchantId}/wallet`).then((r) => r.data.data as WalletAccount), merchantAccount: (merchantId: number) => request.get(`/platform/merchants/${merchantId}/account`).then((r) => r.data.data as MerchantOwnerAccount[]), updateMerchantAccount: (merchantId: number, data: { user_id: number; username: string; nickname?: string; password?: string; status?: number }) => request.patch(`/platform/merchants/${merchantId}/account`, data).then((r) => r.data.data as MerchantOwnerAccount), walletLedger: (merchantId: number, params?: Record) => request.get(`/platform/merchants/${merchantId}/wallet/ledger`, { params }).then((r) => r.data.data as PageResult), adjustWallet: (merchantId: number, data: { amount: number; idempotency_key: string; note?: string }) => request.post(`/platform/merchants/${merchantId}/wallet/adjust`, data).then((r) => r.data.data as WalletAccount), rechargeApplications: (params?: Record) => request.get('/platform/recharge/applications', { params }).then((r) => r.data.data as PageResult), reviewRechargeApplication: (id: number, data: { approved: boolean; review_note?: string }) => request.post(`/platform/recharge/applications/${id}/review`, data).then((r) => r.data.data as RechargeApplication), } export const lewanApi = { listProducts: (params?: { page?: number; size?: number; keyword?: string }) => request.get('/platform/lewan/products', { params }).then((r) => r.data.data as LewanProductListResult), syncCatalog: (data: SyncLewanProductInput) => request.post('/platform/lewan/sync-catalog', data).then((r) => r.data.data as ProductCatalogItem), batchSyncCatalog: (products: SyncLewanProductInput[]) => request.post('/platform/lewan/batch-sync-catalog', { products }).then((r) => r.data.data as { synced_count: number }), updateRouting: (id: number, data: UpdateProductRoutingInput) => request.put(`/platform/products/${id}/routing`, data).then((r) => r.data.data as { updated: boolean }), } export interface RockConfig { id: number auto_delivery_enabled: boolean base_url: string bearer_token: string username: string points: number min_points_warning: number token_warning_stock: number auto_purchase_enabled: boolean auto_purchase_count: number purchase_cooldown_minutes: number last_purchased_at?: string last_heartbeat_at?: string } export interface RockStats { available_stock: number using_stock: number bound_stock: number redeemed_stock: number mismatch_stock: number abnormal_stock: number upstream_points: number auto_delivery_enabled: boolean token_warning_stock: number auto_purchase_enabled: boolean username: string last_heartbeat_at?: string } export interface RockTokenItem { id: number upstream_token_id: string redeem_code: string color: string region: string status: string assigned_order_no?: string client_order_no?: string expected_uid?: string actual_role_name?: string actual_role_id?: string actual_channel?: string upstream_fulfill_id?: number target_skin?: string target_currency?: string target_currency_quantity?: number mismatch_at?: string mismatch_reason?: string claimed_at?: string bound_at?: string redeemed_at?: string created_at: string } export const rockApi = { getConfig: () => request.get('/platform/rock/config').then((r) => r.data.data as RockConfig), updateConfig: (data: Partial) => request.put('/platform/rock/config', data).then((r) => r.data.data as RockConfig), testConnection: (bearer_token?: string) => request.post('/platform/rock/test-conn', { bearer_token }).then((r) => r.data.data), getStats: () => request.get('/platform/rock/stats').then((r) => r.data.data as RockStats), purchaseTokens: (count = 50) => request.post('/platform/rock/purchase', { count }).then((r) => r.data.data), listTokens: (params?: { page?: number; page_size?: number; status?: string; search?: string }) => request.get('/platform/rock/tokens', { params }).then((r) => r.data.data as { list: RockTokenItem[]; total: number; page: number; page_size: number }), correctExpectedUid: (id: number, expectedUid: string) => request.post(`/platform/rock/tokens/${id}/expected-uid`, { expected_uid: expectedUid }).then((r) => r.data.data as { message?: string; status?: string }), resetToken: (id: number) => request.post(`/platform/rock/tokens/${id}/reset`).then((r) => r.data.data), releaseToken: (id: number) => request.post(`/platform/rock/tokens/${id}/release`).then((r) => r.data.data), }