import { adminClient } from '@/shared/api/adminClient' import type { ApiResponse } from '@/shared/api/types' import type { AdminAccountDisplay, AdminAnnouncement, AdminAnnouncementPage, AdminAnnouncementPayload, AdminAnnouncementQuery, AdminAuditLog, AdminAuditPage, AdminAuditQuery, AdminCaptcha, AdminDispute, AdminDisputePage, AdminDisputeQuery, AdminDistributionAnalytics, AdminDistributionInvitationConfig, AdminDistributionOrder, AdminDistributionOrderPage, AdminDistributionOrderQuery, AdminDistributionQrCode, AdminDistributionQrCodePage, AdminDistributionQrCodeQuery, AdminDistributionQrCodeStats, AdminDistributionRule, AdminDistributionRuleQuery, AdminDistributionSettlementBatch, AdminDistributionSettlementItem, AdminDistributionSite, AdminDistributionSiteUpdatePayload, AdminDistributionSMSConfig, AdminDistributionUserPage, AdminDistributionUserQuery, AdminDistributionWallet, AdminDistributionWithdrawal, AdminDistributionWithdrawalPage, AdminSiteAnnouncement, AdminSiteAnnouncementPage, AdminSiteAnnouncementPayload, AdminSiteAnnouncementQuery, AdminListing, AdminListingPage, AdminListingQuery, AdminLoginData, AdminOrderDetail, AdminOrderPage, AdminOrderQuery, AdminPaymentChannel, AdminPaymentConfig, AdminPaymentConfigOption, AdminPaymentConfigPage, AdminPaymentConfigPayload, AdminPaymentConfigQuery, AdminPermission, AdminReceivedListingPage, AdminReceivedListingQuery, AdminRoleDetail, AdminRolePayload, AdminSupportGroup, AdminSupportGroupPayload, AdminSupportMember, AdminStaffAccount, AdminStaffAccountPage, AdminStaffAccountQuery, AdminStaffCreatePayload, AdminStaffUpdatePayload, AdminManualEntry, AdminManualEntryAgentStat, AdminManualEntryOption, AdminManualEntryOptions, AdminManualEntryPage, AdminManualEntryPayload, AdminManualEntryQuery, AdminQuickReply, AdminQuickReplyPayload, AdminTrackingLink, AdminTrackingLinkPage, AdminTrackingLinkPayload, AdminTrackingLinkQuery, AdminTrackingOverview, AdminSyncSiteAccountsPayload, AdminSyncSiteAccountsResult, AdminSystemConfig, AdminSystemConfigUpdatePayload, AdminUser, AdminUserItem, AdminUserPage, AdminUserQuery, AdminWithdrawal, AdminWithdrawalPage, AdminWithdrawalQuery, ApplyAdminDistributionWithdrawalPayload, CreateAdminDistributionQrCodeItem, CreateAdminDistributionRulePayload, CreateAdminDistributionSettlementBatchPayload, DashboardData, FinanceDashboard, FinanceDetailPage, FinanceDisbursementPage, FinanceDisbursementQuery, AdminPaymentPage, AdminPaymentQuery, AdminWalletLedgerPage, AdminWalletLedgerQuery, AdminPickup, AdminPickupAvailableListing, AdminPickupCreatePayload, AdminPickupFinancialAdjustment, AdminPickupPage, AdminPickupProcessEvent, AdminPickupQuery, AdminPickupShop, AdminChatConversation, AdminChatCounts, AdminChatMessage, AdminChatMessagePage, AdminChatPage, AdminQrCode, AdminQrCodePage, AdminQrCodePayload, AdminQrCodeStats, AdminQrCodeUpdatePayload, AdminNotificationPage, AdminPushChannel, AdminPushRule, AdminInvitationConfig, AdminInvitationRelationPage, AdminInviteRebatePage, AdminInviteRebateSummary, AdminBackupStatus, AdminBackupSchedule, AdminCrashCategory, AdminCrashProduct, AdminCrashOrder, AdminCrashConfig, AdminPaged, ManualDisbursementPayload, OperatingExpensePage, OperatingExpensePayload, OperatingExpenseQuery, TestAdminDistributionSMSConfigPayload, UpdateAdminDistributionInvitationConfigPayload, UpdateAdminDistributionQrCodePayload, UpdateAdminDistributionSMSConfigPayload, } from '@/features/admin/types' export async function fetchAdminCaptcha() { const { data } = await adminClient.get>('/admin/auth/captcha') return data.data } export async function loginAdmin( username: string, password: string, captchaId: string, captchaCode: string ) { const { data } = await adminClient.post>('/admin/auth/login', { username, password, captcha_id: captchaId, captcha_code: captchaCode, }) return data.data } export async function fetchAdminMe() { const { data } = await adminClient.get>('/admin/me') return data.data } export async function logoutAdmin() { await adminClient.post('/admin/auth/logout') } export async function changeAdminPassword(oldPassword: string, newPassword: string) { await adminClient.put('/admin/admin-users/me/password', { old_password: oldPassword, new_password: newPassword, }) } export async function fetchAdminDashboard() { const { data } = await adminClient.get>('/admin/dashboard') return data.data } function compactParams(query: T) { return Object.fromEntries( Object.entries(query).filter(([, value]) => value !== '' && value != null) ) } export async function fetchAdminOrders(query: AdminOrderQuery) { const { data } = await adminClient.get>>('/admin/orders', { params: compactParams(query), }) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminOrder(id: number | string) { const { data } = await adminClient.get>(`/admin/orders/${id}`) return data.data } export async function fetchAdminListings(query: AdminListingQuery) { const { data } = await adminClient.get>>('/admin/listings', { params: compactParams(query), }) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminListing(id: number | string) { const { data } = await adminClient.get>(`/admin/listings/${id}`) return data.data } /** 审核队列使用独立接口:权限为 listing:approve,且返回全部待审商品。 */ export async function fetchAdminPendingListings() { const { data } = await adminClient.get>( '/admin/listings/pending' ) return data.data.items ?? [] } export async function approveAdminListing(id: number | string) { const { data } = await adminClient.post>(`/admin/listings/${id}/approve`) return data.data } export async function rejectAdminListing(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/listings/${id}/reject`, { reason } ) return data.data } export async function offlineAdminListing(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/listings/${id}/offline`, { reason } ) return data.data } export async function markAbnormalAdminListing(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/listings/${id}/mark-abnormal`, { reason } ) return data.data } export async function fetchAdminUsers(query: AdminUserQuery) { const params: Record = { ...compactParams(query) } if (query.has_deposit_free_quota) { params.has_deposit_free_quota = true } else { delete params.has_deposit_free_quota } const { data } = await adminClient.get>>('/admin/users', { params, }) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function freezeAdminUser(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/users/${id}/freeze`, { reason } ) return data.data } export async function unfreezeAdminUser(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/users/${id}/unfreeze`, { reason } ) return data.data } export async function setAdminUserDepositFreeQuota(id: number | string, amountCent: number) { const { data } = await adminClient.post>( `/admin/users/${id}/deposit-free-quota`, { amount_cent: amountCent } ) return data.data } export async function adjustAdminUserGrowthPoints( id: number | string, targetPoints: number, reason: string ) { const { data } = await adminClient.post>( `/admin/users/${id}/growth-points`, { target_points: targetPoints, reason } ) return data.data } export async function manualAdminUserRealname( id: number | string, payload: { name: string; id_no: string; reason: string } ) { const { data } = await adminClient.post>( `/admin/users/${id}/manual-realname`, payload ) return data.data } export async function revokeAdminUserRealname(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/users/${id}/revoke-realname`, { reason } ) return data.data } export async function adjustAdminUserWallet( id: number | string, payload: { direction: 'in' | 'out'; amount_cent: number; reason: string; reference_no?: string } ) { const { data } = await adminClient.post>( `/admin/users/${id}/wallet/adjust`, payload ) return data.data } export async function fetchPendingRefundOrders() { const { data } = await adminClient.get>( '/admin/orders/refund-pending' ) return data.data.items ?? [] } export async function approveAdminRefund(id: number | string) { await adminClient.post(`/admin/orders/${id}/refund/approve`) } export async function rejectAdminRefund(id: number | string, action: 'restore' | 'close') { await adminClient.post(`/admin/orders/${id}/refund/reject`, { action }) } export async function fetchAdminWithdrawals(query: AdminWithdrawalQuery) { const { data } = await adminClient.get>>( '/admin/withdrawals', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminWithdrawal(id: number | string) { const { data } = await adminClient.get>( `/admin/withdrawals/${id}` ) return data.data } export async function reviewAdminWithdrawal( id: number | string, approved: boolean, remark: string ) { const { data } = await adminClient.post>( `/admin/withdrawals/${id}/review`, { approved, remark } ) return data.data } export async function confirmAdminWithdrawalPayment( id: number | string, payload: { payment_proof_url?: string; remark?: string } ) { const { data } = await adminClient.post>( `/admin/withdrawals/${id}/confirm-payment`, payload ) return data.data } export async function fetchAdminDisputes(query: AdminDisputeQuery) { const { data } = await adminClient.get>>( '/admin/disputes', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function arbitrateAdminDispute( id: number | string, payload: { result: string remark: string amount_cent?: number actual_coin_consumed_m?: number actual_consumable_amount_cent?: number } ) { const { data } = await adminClient.post>( `/admin/disputes/${id}/arbitrate`, payload ) return data.data } export interface FinanceRangeQuery { start_date?: string end_date?: string } export async function fetchFinanceDashboard(range: FinanceRangeQuery) { const { data } = await adminClient.get>('/admin/finance/dashboard', { params: compactParams(range), }) return data.data } export async function fetchFinanceDetails( query: FinanceRangeQuery & { order_no?: string date_type?: 'created' | 'settled' | 'offline_settled' page?: number page_size?: number } ) { const { data } = await adminClient.get>>( '/admin/finance/details', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminAnnouncements(query: AdminAnnouncementQuery) { const { data } = await adminClient.get>>( '/admin/announcements', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function createAdminAnnouncement(payload: AdminAnnouncementPayload) { const { data } = await adminClient.post>( '/admin/announcements', payload ) return data.data } export async function updateAdminAnnouncement( id: number | string, payload: AdminAnnouncementPayload ) { const { data } = await adminClient.put>( `/admin/announcements/${id}`, { title: payload.title, content: payload.content, category: payload.category, priority: payload.priority, is_pinned: payload.is_pinned, is_important: payload.is_important, is_popup: payload.is_popup, } ) return data.data } export async function publishAdminAnnouncement(id: number | string) { await adminClient.post(`/admin/announcements/${id}/publish`) } export async function archiveAdminAnnouncement(id: number | string) { await adminClient.post(`/admin/announcements/${id}/archive`) } export async function unarchiveAdminAnnouncement(id: number | string) { await adminClient.post(`/admin/announcements/${id}/unarchive`) } export async function deleteAdminAnnouncement(id: number | string) { await adminClient.delete(`/admin/announcements/${id}`) } export async function fetchAdminAuditLogs(query: AdminAuditQuery) { const { data } = await adminClient.get>>('/admin/audit-logs', { params: compactParams(query), }) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export type { AdminAuditLog } export async function fetchAdminSystemConfigs() { const { data } = await adminClient.get>( '/admin/system-configs' ) return data.data.items ?? [] } export async function updateAdminSystemConfig( key: string, payload: AdminSystemConfigUpdatePayload ) { const { data } = await adminClient.put>( `/admin/system-configs/${encodeURIComponent(key)}`, payload ) return data.data } export async function fetchAdminDistributionSites() { const { data } = await adminClient.get>( '/admin/distribution/sites' ) return data.data.items ?? [] } export async function updateAdminDistributionSite( id: number | string, payload: AdminDistributionSiteUpdatePayload ) { const { data } = await adminClient.put>( `/admin/distribution/sites/${id}`, payload ) return data.data } export async function fetchAdminDistributionWallet(id: number | string) { const { data } = await adminClient.get>( `/admin/distribution/sites/${id}/wallet` ) return data.data } export async function fetchAdminDistributionAnalytics(id: number | string) { const { data } = await adminClient.get>( `/admin/distribution/sites/${id}/analytics` ) return data.data } export async function applyAdminDistributionWithdrawal( id: number | string, payload: ApplyAdminDistributionWithdrawalPayload ) { const { data } = await adminClient.post>( `/admin/distribution/sites/${id}/withdrawals`, payload ) return data.data } export async function fetchAdminDistributionWithdrawals( id: number | string, query: { page?: number; page_size?: number } ) { const { data } = await adminClient.get>>( `/admin/distribution/sites/${id}/withdrawals`, { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminDistributionSMSConfig(id: number | string) { const { data } = await adminClient.get>( `/admin/distribution/sites/${id}/sms-config` ) return data.data } export async function updateAdminDistributionSMSConfig( id: number | string, payload: UpdateAdminDistributionSMSConfigPayload ) { const { data } = await adminClient.put>( `/admin/distribution/sites/${id}/sms-config`, payload ) return data.data } export async function testAdminDistributionSMSConfig( id: number | string, payload: TestAdminDistributionSMSConfigPayload ) { const { data } = await adminClient.post>( `/admin/distribution/sites/${id}/sms-config/test`, payload ) return data.data } export async function fetchAdminDistributionInvitationConfig(id: number | string) { const { data } = await adminClient.get>( `/admin/distribution/sites/${id}/invitation-config` ) return data.data } export async function updateAdminDistributionInvitationConfig( id: number | string, payload: UpdateAdminDistributionInvitationConfigPayload ) { const { data } = await adminClient.put>( `/admin/distribution/sites/${id}/invitation-config`, payload ) return data.data } export async function fetchAdminDistributionQrCodes( id: number | string, query: AdminDistributionQrCodeQuery ) { const { data } = await adminClient.get>>( `/admin/distribution/sites/${id}/qrcodes`, { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.limit ?? 20, } } export async function fetchAdminDistributionQrCodeStats(id: number | string) { const { data } = await adminClient.get>>( `/admin/distribution/sites/${id}/qrcodes/stats` ) return { unused_count: data.data.unused_count ?? 0, used_count: data.data.used_count ?? 0, disabled_count: data.data.disabled_count ?? 0, total_count: data.data.total_count ?? 0, } } export async function batchCreateAdminDistributionQrCodes( id: number | string, items: CreateAdminDistributionQrCodeItem[] ) { const { data } = await adminClient.post>( `/admin/distribution/sites/${id}/qrcodes/batch`, { items } ) return data.data } export async function batchDeleteAdminDistributionQrCodes( id: number | string, ids: number[] ) { const { data } = await adminClient.post>( `/admin/distribution/sites/${id}/qrcodes/batch-delete`, { ids } ) return data.data.deleted ?? 0 } export async function updateAdminDistributionQrCode( id: number | string, qrcodeId: number, payload: UpdateAdminDistributionQrCodePayload ) { await adminClient.patch(`/admin/distribution/sites/${id}/qrcodes/${qrcodeId}`, payload) } export async function deleteAdminDistributionQrCode(id: number | string, qrcodeId: number) { await adminClient.delete(`/admin/distribution/sites/${id}/qrcodes/${qrcodeId}`) } export async function fetchAdminDistributionRules(query: AdminDistributionRuleQuery) { const { data } = await adminClient.get>( '/admin/distribution/rules', { params: compactParams(query) } ) return data.data.items ?? [] } export async function createAdminDistributionRule(payload: CreateAdminDistributionRulePayload) { const { data } = await adminClient.post>( '/admin/distribution/rules', payload ) return data.data } export async function updateAdminDistributionRuleStatus( id: number, status: 'draft' | 'active' | 'disabled' ) { const { data } = await adminClient.put>( `/admin/distribution/rules/${id}/status`, { status } ) return data.data } export async function fetchAdminDistributionOrders(query: AdminDistributionOrderQuery) { const { data } = await adminClient.get>>( '/admin/distribution/orders', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminDistributionOrder(id: number) { const { data } = await adminClient.get>( `/admin/distribution/orders/${id}` ) return data.data } export async function fetchAdminDistributionSettlementBatches(siteId: number) { const { data } = await adminClient.get< ApiResponse<{ items?: AdminDistributionSettlementBatch[] }> >('/admin/distribution/settlement-batches', { params: { site_id: siteId } }) return data.data.items ?? [] } export async function createAdminDistributionSettlementBatch( payload: CreateAdminDistributionSettlementBatchPayload ) { const { data } = await adminClient.post>( '/admin/distribution/settlement-batches', payload ) return data.data } export async function fetchAdminDistributionSettlementItems(batchId: number) { const { data } = await adminClient.get< ApiResponse<{ items?: AdminDistributionSettlementItem[] }> >(`/admin/distribution/settlement-batches/${batchId}/items`) return data.data.items ?? [] } export async function settleAdminDistributionSettlementBatch(batchId: number) { const { data } = await adminClient.post>( `/admin/distribution/settlement-batches/${batchId}/settle` ) return data.data } export async function cancelAdminDistributionSettlementBatch(batchId: number) { const { data } = await adminClient.post>( `/admin/distribution/settlement-batches/${batchId}/cancel` ) return data.data } export async function fetchAdminDistributionUsers( siteId: number, query: AdminDistributionUserQuery ) { const { data } = await adminClient.get>>( '/admin/distribution/users', { params: compactParams({ ...query, site_id: siteId }) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, total_users: data.data.total_users ?? 0, order_users: data.data.order_users ?? 0, } } export async function fetchAdminSiteAnnouncements( siteId: number, query: AdminSiteAnnouncementQuery ) { const { data } = await adminClient.get>>( '/admin/distribution/announcements', { params: compactParams({ ...query, site_id: siteId }) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function createAdminSiteAnnouncement( siteId: number, payload: AdminSiteAnnouncementPayload ) { const { data } = await adminClient.post>( '/admin/distribution/announcements', payload, { params: { site_id: siteId } } ) return data.data } export async function updateAdminSiteAnnouncement( siteId: number, id: number, payload: AdminSiteAnnouncementPayload ) { const { data } = await adminClient.put>( `/admin/distribution/announcements/${id}`, payload, { params: { site_id: siteId } } ) return data.data } export async function publishAdminSiteAnnouncement(siteId: number, id: number) { const { data } = await adminClient.post>( `/admin/distribution/announcements/${id}/publish`, {}, { params: { site_id: siteId } } ) return data.data } export async function archiveAdminSiteAnnouncement(siteId: number, id: number) { const { data } = await adminClient.post>( `/admin/distribution/announcements/${id}/archive`, {}, { params: { site_id: siteId } } ) return data.data } export async function unarchiveAdminSiteAnnouncement(siteId: number, id: number) { const { data } = await adminClient.post>( `/admin/distribution/announcements/${id}/unarchive`, {}, { params: { site_id: siteId } } ) return data.data } export async function deleteAdminSiteAnnouncement(siteId: number, id: number) { await adminClient.delete(`/admin/distribution/announcements/${id}`, { params: { site_id: siteId }, }) } export async function fetchAdminReceivedListings( siteId: number, query: AdminReceivedListingQuery ) { const { data } = await adminClient.get>>( '/admin/distribution/received-listings', { params: compactParams({ ...query, site_id: siteId }) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function updateAdminReceivedListingStatus( listingId: number, status: 'published' | 'offline' ) { await adminClient.put(`/admin/distribution/received-listings/${listingId}/status`, { status }) } export async function fetchAdminAccountDisplays(siteId: number, status?: string) { const { data } = await adminClient.get>( '/admin/distribution/accounts', { params: compactParams({ site_id: siteId, status }) } ) return data.data.items ?? [] } export async function updateAdminAccountDisplay( id: number, displayStatus: 'enabled' | 'disabled' ) { const { data } = await adminClient.put>( `/admin/distribution/accounts/${id}/display`, { display_status: displayStatus } ) return data.data } export async function updateAdminAccountMarkup(id: number, shelfRatioDelta: number) { const { data } = await adminClient.put>( `/admin/distribution/accounts/${id}/markup`, { shelf_ratio_delta: shelfRatioDelta } ) return data.data } export async function batchUpdateAdminAccountDisplays( siteId: number, displayIds: number[], targetStatus: 'enabled' | 'disabled' ) { await adminClient.post( '/admin/distribution/accounts/batch-display', { display_ids: displayIds, target_status: targetStatus, }, { params: { site_id: siteId } } ) } export async function batchUpdateAdminAccountMarkup( siteId: number, displayIds: number[], shelfRatioDelta: number ) { await adminClient.post( '/admin/distribution/accounts/batch-markup', { display_ids: displayIds, shelf_ratio_delta: shelfRatioDelta, }, { params: { site_id: siteId } } ) } export async function fetchAdminPaymentChannels(siteId: number) { const { data } = await adminClient.get>( '/admin/distribution/payment-channels', { params: { site_id: siteId } } ) return data.data.items ?? [] } export async function bindAdminPaymentChannel( siteId: number, configId: number, priority: number ) { const { data } = await adminClient.post>( '/admin/distribution/payment-channels', { config_id: configId, priority }, { params: { site_id: siteId } } ) return data.data } export async function unbindAdminPaymentChannel(id: number) { await adminClient.delete(`/admin/distribution/payment-channels/${id}`) } export async function fetchAdminPaymentConfigOptions() { const { data } = await adminClient.get< ApiResponse<{ items?: AdminPaymentConfigOption[] }> >('/admin/payment-configs', { params: { page: 1, page_size: 100 } }) return data.data.items ?? [] } export async function syncAdminDistributionSiteAccounts( siteId: number, payload: AdminSyncSiteAccountsPayload ) { const { data } = await adminClient.post>( `/admin/distribution/sites/${siteId}/sync-accounts`, payload ) return data.data } export async function fetchAdminPaymentConfigs(query: AdminPaymentConfigQuery) { const { data } = await adminClient.get>>( '/admin/payment-configs', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function createAdminPaymentConfig(payload: AdminPaymentConfigPayload) { const { data } = await adminClient.post>( '/admin/payment-configs', payload ) return data.data } export async function updateAdminPaymentConfig( id: number, payload: Partial ) { const { data } = await adminClient.put>( `/admin/payment-configs/${id}`, payload ) return data.data } export async function deleteAdminPaymentConfig(id: number) { await adminClient.delete(`/admin/payment-configs/${id}`) } export async function fetchAdminRoles() { const { data } = await adminClient.get>('/admin/roles') return data.data ?? [] } export async function fetchAdminRole(id: number) { const { data } = await adminClient.get>(`/admin/roles/${id}`) return data.data } export async function createAdminRole(payload: AdminRolePayload) { const { data } = await adminClient.post>('/admin/roles', payload) return data.data } export async function updateAdminRole(id: number, payload: AdminRolePayload) { const { data } = await adminClient.put>( `/admin/roles/${id}`, payload ) return data.data } export async function deleteAdminRole(id: number) { await adminClient.delete(`/admin/roles/${id}`) } export async function fetchAdminPermissions() { const { data } = await adminClient.get>('/admin/permissions') return data.data ?? [] } export async function assignAdminRolePermissions(id: number, permissionIds: number[]) { await adminClient.put(`/admin/roles/${id}/permissions`, { permission_ids: permissionIds }) } export async function fetchAdminSupportGroups() { const { data } = await adminClient.get>( '/admin/chat-support-groups' ) return data.data ?? [] } export async function fetchAdminSupportAdmins() { const { data } = await adminClient.get>( '/admin/chat-support-groups/support-admins' ) return data.data ?? [] } export async function createAdminSupportGroup(payload: AdminSupportGroupPayload) { const { data } = await adminClient.post>( '/admin/chat-support-groups', payload ) return data.data } export async function updateAdminSupportGroup( id: number, payload: AdminSupportGroupPayload ) { const { data } = await adminClient.put>( `/admin/chat-support-groups/${id}`, payload ) return data.data } export async function deleteAdminSupportGroup(id: number) { await adminClient.delete(`/admin/chat-support-groups/${id}`) } export async function assignAdminSupportGroupMembers(id: number, memberIds: number[]) { await adminClient.put(`/admin/chat-support-groups/${id}/members`, { member_ids: memberIds, }) } export async function fetchAdminStaffAccounts(query: AdminStaffAccountQuery = {}) { const { data } = await adminClient.get>>( '/admin/admin-users', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminStaffAccount(id: number) { const { data } = await adminClient.get>( `/admin/admin-users/${id}` ) return data.data } export async function createAdminStaffAccount(payload: AdminStaffCreatePayload) { const { data } = await adminClient.post>( '/admin/admin-users', payload ) return data.data } export async function updateAdminStaffAccount(id: number, payload: AdminStaffUpdatePayload) { const { data } = await adminClient.put>( `/admin/admin-users/${id}`, payload ) return data.data } export async function deleteAdminStaffAccount(id: number) { await adminClient.delete(`/admin/admin-users/${id}`) } export async function assignAdminStaffRoles(id: number, roleIds: number[]) { await adminClient.put(`/admin/admin-users/${id}/roles`, { role_ids: roleIds }) } export async function resetAdminStaffPassword(id: number, newPassword: string) { await adminClient.put(`/admin/admin-users/${id}/password`, { new_password: newPassword }) } export async function fetchAdminManualEntries(query: AdminManualEntryQuery = {}) { const { data } = await adminClient.get>>( '/admin/manual-entries', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function createAdminManualEntry(payload: AdminManualEntryPayload) { const { data } = await adminClient.post>( '/admin/manual-entries', payload ) return data.data.entry } export async function updateAdminManualEntry(id: number, payload: AdminManualEntryPayload) { const { data } = await adminClient.put>( `/admin/manual-entries/${id}`, payload ) return data.data } export async function deleteAdminManualEntry(id: number) { await adminClient.delete(`/admin/manual-entries/${id}`) } export async function fetchAdminManualEntryOptions() { const { data } = await adminClient.get>( '/admin/manual-entries/options' ) return { platforms: data.data?.platforms ?? [], operators: data.data?.operators ?? [], } } export async function createAdminManualEntryOption(payload: { type: string; name: string }) { const { data } = await adminClient.post>( '/admin/manual-entries/options', payload ) return data.data } export async function updateAdminManualEntryOption(id: number, name: string) { const { data } = await adminClient.put>( `/admin/manual-entries/options/${id}`, { name } ) return data.data } export async function deleteAdminManualEntryOption(id: number) { await adminClient.delete(`/admin/manual-entries/options/${id}`) } export async function fetchAdminManualEntryTodayStats() { const { data } = await adminClient.get>( '/admin/manual-entries/today-stats' ) return data.data ?? [] } export async function fetchAdminQuickReplies() { const { data } = await adminClient.get>( '/admin/chats/quick-replies' ) return data.data ?? [] } export async function createAdminQuickReply(payload: AdminQuickReplyPayload) { const { data } = await adminClient.post>( '/admin/chats/quick-replies', payload ) return data.data } export async function updateAdminQuickReply(id: number, payload: AdminQuickReplyPayload) { const { data } = await adminClient.put>( `/admin/chats/quick-replies/${id}`, payload ) return data.data } export async function deleteAdminQuickReply(id: number) { await adminClient.delete(`/admin/chats/quick-replies/${id}`) } export async function fetchAdminTrackingLinks(query: AdminTrackingLinkQuery = {}) { const { data } = await adminClient.get>>( '/admin/tracking-links', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminTrackingOverview() { const { data } = await adminClient.get>( '/admin/tracking-links/overview' ) return data.data } export async function createAdminTrackingLink(payload: AdminTrackingLinkPayload) { const { data } = await adminClient.post>( '/admin/tracking-links', payload ) return data.data } export async function updateAdminTrackingLink(id: number, payload: AdminTrackingLinkPayload) { const { data } = await adminClient.put>( `/admin/tracking-links/${id}`, payload ) return data.data } export async function updateAdminTrackingLinkStatus(id: number, status: string) { const { data } = await adminClient.put>( `/admin/tracking-links/${id}/status`, { status } ) return data.data } export async function fetchFinanceDisbursements(query: FinanceDisbursementQuery) { const { data } = await adminClient.get>>( '/admin/finance/disbursements', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, summary: data.data.summary ?? { record_count: 0, paid_amount_cent: 0, paid_count: 0, payment_pending_amount_cent: 0, payment_pending_count: 0, review_pending_amount_cent: 0, review_pending_count: 0, withdrawal_fee_amount_cent: 0, }, } } export async function createManualDisbursement(payload: ManualDisbursementPayload) { const { data } = await adminClient.post>( '/admin/finance/manual-disbursements', payload ) return data.data } export async function voidManualDisbursement(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/finance/manual-disbursements/${id}/void`, { reason } ) return data.data } export async function fetchOperatingExpenses(query: OperatingExpenseQuery) { const { data } = await adminClient.get>>( '/admin/finance/operating-expenses', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, summary: data.data.summary ?? { record_count: 0, paid_amount_cent: 0, paid_count: 0, }, } } export async function createOperatingExpense(payload: OperatingExpensePayload) { const { data } = await adminClient.post>( '/admin/finance/operating-expenses', payload ) return data.data } export async function voidOperatingExpense(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/finance/operating-expenses/${id}/void`, { reason } ) return data.data } export async function fetchAdminPayments(query: AdminPaymentQuery = {}) { const { data } = await adminClient.get>>( '/admin/payments', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminWalletLedger(query: AdminWalletLedgerQuery = {}) { const { data } = await adminClient.get>>( '/admin/wallet/ledger', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminPickups(query: AdminPickupQuery = {}) { const { data } = await adminClient.get>>('/admin/pickups', { params: compactParams(query), }) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminPickup(id: number | string) { const { data } = await adminClient.get>(`/admin/pickups/${id}`) return data.data } export async function createAdminPickup(payload: AdminPickupCreatePayload) { const { data } = await adminClient.post>('/admin/pickups', payload) return data.data } export async function completeAdminPickup( id: number | string, payload: { settle_amount_cent: number; profit_amount_cent?: number; complete_remark?: string } ) { const { data } = await adminClient.post>( `/admin/pickups/${id}/complete`, payload ) return data.data } export async function cancelAdminPickup(id: number | string, reason: string) { const { data } = await adminClient.post>( `/admin/pickups/${id}/cancel`, { reason } ) return data.data } export async function markAdminPickupOfflineSettlement(id: number | string, remark: string) { const { data } = await adminClient.post>( `/admin/pickups/${id}/offline-settlement`, { remark } ) return data.data } export async function updateAdminPickupProfit( id: number | string, payload: { profit_amount_cent: number; reason?: string } ) { const { data } = await adminClient.put>( `/admin/pickups/${id}/profit`, payload ) return data.data } export async function updateAdminPickupThirdPartyOrderNo(id: number | string, value: string) { const { data } = await adminClient.put>( `/admin/pickups/${id}/third-party-order-no`, { third_party_order_no: value } ) return data.data } export async function fetchAdminPickupShops(platform = '') { const { data } = await adminClient.get>('/admin/pickups/shops', { params: platform ? { platform } : undefined, }) return data.data ?? [] } export async function createAdminPickupShop(payload: { name: string platform?: string sort_order?: number remark?: string }) { const { data } = await adminClient.post>( '/admin/pickups/shops', payload ) return data.data } export async function deleteAdminPickupShop(id: number) { await adminClient.delete(`/admin/pickups/shops/${id}`) } export async function fetchAdminPickupShopOptions(platform = '') { const { data } = await adminClient.get>('/admin/pickups/shop-options', { params: platform ? { platform } : undefined, }) return data.data ?? [] } export async function fetchAdminPickupAvailableListings(query: { keyword?: string source_type?: string page?: number page_size?: number }) { const { data } = await adminClient.get< ApiResponse<{ items?: AdminPickupAvailableListing[]; total?: number }> >('/admin/pickups/available-listings', { params: compactParams(query) }) return { items: data.data.items ?? [], total: data.data.total ?? 0, } } export async function fetchAdminPickupProcessEvents(id: number | string) { const { data } = await adminClient.get>( `/admin/pickups/${id}/process-events` ) return data.data.items ?? [] } export async function fetchAdminPickupFinancialAdjustments(id: number | string) { const { data } = await adminClient.get>( `/admin/pickups/${id}/financial-adjustments` ) return data.data ?? [] } export async function createAdminPickupFinancialAdjustment( id: number | string, payload: { profit_amount_cent?: number; settle_amount_cent?: number; reason: string } ) { const { data } = await adminClient.post>( `/admin/pickups/${id}/financial-adjustments`, payload ) return data.data } export async function settleAdminPickupFinancialAdjustment( adjustmentId: number, remark: string ) { const { data } = await adminClient.post>( `/admin/pickup-financial-adjustments/${adjustmentId}/settle`, { remark } ) return data.data } export async function fetchAdminChats(query: { filter?: string stage?: string keyword?: string page?: number page_size?: number }) { const { data } = await adminClient.get>>('/admin/chats', { params: compactParams(query), }) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminChatCounts(query: { filter?: string stage?: string keyword?: string }) { const { data } = await adminClient.get>('/admin/chats/counts', { params: compactParams(query), }) return data.data } export async function fetchAdminChatDetail(id: number) { const { data } = await adminClient.get>(`/admin/chats/${id}`) return data.data } export async function fetchAdminChatMessages(id: number, page = 1, pageSize = 50) { const { data } = await adminClient.get>>( `/admin/chats/${id}/messages`, { params: { page, page_size: pageSize } } ) return { items: (data.data.items ?? []) as AdminChatMessage[], total: data.data.total ?? 0, page: data.data.page ?? page, page_size: data.data.page_size ?? pageSize, } } export async function sendAdminChatMessage( id: number, payload: { content: string; attachment_urls?: string[] } ) { const { data } = await adminClient.post>( `/admin/chats/${id}/messages`, payload ) return data.data } export async function markAdminChatRead(id: number) { await adminClient.post(`/admin/chats/${id}/read`) } export async function markAllAdminChatsRead() { await adminClient.post('/admin/chats/read-all') } export async function transferAdminChat(id: number, toAdminId: number) { await adminClient.post(`/admin/chats/${id}/transfer`, { to_admin_id: toAdminId }) } export async function updateAdminChatRemark(id: number, remark: string) { await adminClient.post(`/admin/chats/${id}/remark`, { remark }) } export async function fetchAdminChatSupportAdmins() { const { data } = await adminClient.get< ApiResponse> >('/admin/chats/support-admins') return data.data ?? [] } export async function fetchAdminQrCodes(query: { status?: string keyword?: string wecom_renamed?: string bound?: string expire_status?: string page?: number limit?: number }) { const { data } = await adminClient.get<{ data: Partial }>( '/admin/chats/qrcodes', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.limit ?? 20, } } export async function fetchAdminQrCodeStats() { const { data } = await adminClient.get<{ data: AdminQrCodeStats }>('/admin/chats/qrcodes/stats') return data.data } export async function createAdminQrCode(payload: AdminQrCodePayload) { const { data } = await adminClient.post<{ data: AdminQrCode }>('/admin/chats/qrcodes', payload) return data.data } export async function batchCreateAdminQrCodes(items: AdminQrCodePayload[]) { const { data } = await adminClient.post<{ data: AdminQrCode[] }>( '/admin/chats/qrcodes/batch', { items } ) return data.data ?? [] } export async function batchDeleteAdminQrCodes(ids: number[]) { const { data } = await adminClient.post<{ data: { deleted: number } }>( '/admin/chats/qrcodes/batch-delete', { ids } ) return data.data.deleted ?? 0 } export async function updateAdminQrCode(id: number, payload: AdminQrCodeUpdatePayload) { const { data } = await adminClient.patch<{ data: AdminQrCode }>( `/admin/chats/qrcodes/${id}`, payload ) return data.data } export async function deleteAdminQrCode(id: number) { await adminClient.delete(`/admin/chats/qrcodes/${id}`) } export async function fetchAdminNotifications(query: { read?: string page?: number page_size?: number }) { const { data } = await adminClient.get>>( '/admin/notifications', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminNotificationUnreadCount() { const { data } = await adminClient.get>( '/admin/notifications/unread-count' ) return data.data.unread_count ?? 0 } export async function markAdminNotificationRead(id: number) { await adminClient.post(`/admin/notifications/${id}/read`) } export async function markAllAdminNotificationsRead() { await adminClient.put('/admin/notifications/read-all') } export async function fetchPushChannels() { const { data } = await adminClient.get>('/admin/push-channels') return data.data ?? [] } export async function createPushChannel(payload: { name: string type: string config: Record }) { const { data } = await adminClient.post>( '/admin/push-channels', payload ) return data.data } export async function updatePushChannel( id: number, payload: { name?: string; config?: Record; enabled?: boolean } ) { const { data } = await adminClient.put>( `/admin/push-channels/${id}`, payload ) return data.data } export async function deletePushChannel(id: number) { await adminClient.delete(`/admin/push-channels/${id}`) } export async function testPushChannel(id: number) { const { data } = await adminClient.post>( `/admin/push-channels/${id}/test` ) return data.data } export async function fetchPushRules() { const { data } = await adminClient.get>('/admin/push-rules') return data.data ?? [] } export async function updatePushRule( id: number, payload: { enabled?: boolean; threshold?: number; message_template?: string } ) { const { data } = await adminClient.put>( `/admin/push-rules/${id}`, payload ) return data.data } export async function fetchAdminInvitationConfig(siteId?: number) { const { data } = await adminClient.get>( '/admin/invitations/configs', { params: siteId ? { site_id: siteId } : undefined } ) return data.data } export async function updateAdminInvitationConfig(payload: { first_month_rate: number second_month_rate: number subsequent_rate: number enabled: boolean site_id?: number }) { const { data } = await adminClient.put>( '/admin/invitations/configs', payload ) return data.data } export async function fetchAdminInvitationRelations(query: { phone?: string invite_code?: string status?: string page?: number page_size?: number }) { const { data } = await adminClient.get>>( '/admin/invitations', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminInviteRebates(query: { order_no?: string inviter_phone?: string invitee_phone?: string trade_role?: string start_date?: string end_date?: string page?: number page_size?: number }) { const { data } = await adminClient.get>>( '/admin/invitations/rebates', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function fetchAdminInviteRebateSummary(query: { order_no?: string inviter_phone?: string invitee_phone?: string trade_role?: string start_date?: string end_date?: string }) { const { data } = await adminClient.get>( '/admin/invitations/rebates/summary', { params: compactParams(query) } ) return data.data } export async function fetchAdminBackupStatus() { const { data } = await adminClient.get>('/admin/backups/status') return data.data } export async function fetchAdminBackupSchedule() { const { data } = await adminClient.get>( '/admin/backups/schedule' ) return data.data } export async function updateAdminBackupSchedule(payload: AdminBackupSchedule) { const { data } = await adminClient.put>( '/admin/backups/schedule', payload ) return data.data } export async function fetchCrashCategories() { const { data } = await adminClient.get>( '/admin/crash/categories' ) return data.data ?? [] } export async function createCrashCategory(payload: { name: string code?: string sort_order?: number status?: string }) { const { data } = await adminClient.post>( '/admin/crash/categories', payload ) return data.data } export async function updateCrashCategory( id: number, payload: { name?: string; sort_order?: number; status?: string } ) { const { data } = await adminClient.put>( `/admin/crash/categories/${id}`, payload ) return data.data } export async function deleteCrashCategory(id: number) { await adminClient.delete(`/admin/crash/categories/${id}`) } export async function fetchCrashProducts(query: { keyword?: string status?: string category_id?: number page?: number page_size?: number }) { const { data } = await adminClient.get>>>( '/admin/crash/products', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function createCrashProduct(payload: Record) { const { data } = await adminClient.post>( '/admin/crash/products', payload ) return data.data } export async function updateCrashProduct(id: number, payload: Record) { const { data } = await adminClient.put>( `/admin/crash/products/${id}`, payload ) return data.data } export async function deleteCrashProduct(id: number) { await adminClient.delete(`/admin/crash/products/${id}`) } export async function fetchCrashOrders(query: { keyword?: string status?: string page?: number page_size?: number }) { const { data } = await adminClient.get>>>( '/admin/crash/orders', { params: compactParams(query) } ) return { items: data.data.items ?? [], total: data.data.total ?? 0, page: data.data.page ?? query.page ?? 1, page_size: data.data.page_size ?? query.page_size ?? 20, } } export async function receiveCrashOrder(id: number, remark = '') { await adminClient.post(`/admin/crash/orders/${id}/receive`, { remark }) } export async function completeCrashOrder(id: number, remark = '') { await adminClient.post(`/admin/crash/orders/${id}/complete`, { remark }) } export async function cancelCrashOrder(id: number, reason: string) { await adminClient.post(`/admin/crash/orders/${id}/cancel`, { reason }) } export async function refundCrashOrder(id: number, payload: { reason?: string; amount_cent?: number }) { await adminClient.post(`/admin/crash/orders/${id}/refund`, payload) } export async function fetchCrashConfig() { const { data } = await adminClient.get>('/admin/crash/config') return data.data } export async function updateCrashConfig(payload: Partial) { const { data } = await adminClient.put>( '/admin/crash/config', payload ) return data.data } export async function fetchChatAutoWelcome() { const { data } = await adminClient.get>( '/admin/chats/auto-welcome' ) return data.data.message ?? '' } export async function updateChatAutoWelcome(message: string) { const { data } = await adminClient.put>( '/admin/chats/auto-welcome', { message } ) return data.data } export async function fetchListingGroupWelcome() { const { data } = await adminClient.get>( '/admin/chats/listing-group-welcome' ) return data.data.message ?? '' } export async function updateListingGroupWelcome(message: string) { const { data } = await adminClient.put>( '/admin/chats/listing-group-welcome', { message } ) return data.data } export async function recognizeQrCodeGroupName(file: File) { const form = new FormData() form.append('file', file) const { data } = await adminClient.post<{ data: { group_name?: string; text?: string } }>( '/admin/chats/qrcodes/ocr-group-name', form, { headers: { 'Content-Type': 'multipart/form-data' } } ) return data.data }