import { apiClient, request } from "@/services/api/request"; const api = apiClient; export type CreditAccount = { userId: string; availableMicrocredits: number; reservedMicrocredits: number; version: number; createdAt: string; updatedAt: string; }; export type CreditLedgerEntry = { id: string; userId: string; type: "redeem" | "payment_topup" | "admin_grant" | "consume" | "refund" | "admin_adjustment" | "signup_bonus" | "checkin_bonus"; amountMicrocredits: number; availableAfterMicrocredits: number; reservedAfterMicrocredits: number; billingOrderId?: string; paymentOrderId?: string; model?: string; channelId?: string; scene?: string; note?: string; createdAt: string; }; export type WalletSummary = { account: CreditAccount; entries: CreditLedgerEntry[]; total: number; page: number; limit: number; policy: { signupBonusMicrocredits: number; checkinBonusMicrocredits: number; checkedInToday: boolean; }; }; export type CreditPolicy = { signupBonusMicrocredits: number; checkinBonusMicrocredits: number; defaultMultiplierBasisPoints: number; modelMultiplierBasisPoints: Record; }; export type ChannelModel = { id: string; channelId: string; modelKey: string; providerModelKey: string; displayName: string; icon: string; capability: "text" | "image" | "video" | "audio" | ""; protocol?: import("@/lib/model-protocols").ModelProtocol; billingMode: "fixed_request" | "per_second" | "token"; unitPriceMicrocredits: number; inputTokenPriceMicrocredits: number; outputTokenPriceMicrocredits: number; cachedTokenPriceMicrocredits: number; priceConfigured: boolean; enabled: boolean; priceVersion: number; capabilityVersion?: number; capabilityConfig?: import("@/lib/model-capabilities").ModelCapabilityConfig; priceTiers: ChannelModelPriceTier[]; createdAt: string; updatedAt: string; }; export type ChannelModelPriceTier = { id: string; channelModelId: string; selector: Record; selectorKey: string; resolution: string; videoSeconds: number; providerModelKey: string; billingMode: "fixed_request" | "per_second" | "token"; unitPriceMicrocredits: number; inputTokenPriceMicrocredits: number; outputTokenPriceMicrocredits: number; cachedTokenPriceMicrocredits: number; priceConfigured: boolean; enabled: boolean; priceVersion: number; createdAt: string; updatedAt: string; }; // 系统渠道模型的写入合同。标量价格只用于兼容旧管理请求;新的后台界面只提交 priceTiers。 export type ChannelModelMutation = { modelKey: string; providerModelKey?: string; displayName?: string; icon?: string; capability: ChannelModel["capability"]; protocol?: ChannelModel["protocol"]; enabled?: boolean; capabilityConfig?: ChannelModel["capabilityConfig"]; priceTiers?: Array>; billingMode?: ChannelModel["billingMode"]; unitPriceMicrocredits?: number; inputTokenPriceMicrocredits?: number; outputTokenPriceMicrocredits?: number; cachedTokenPriceMicrocredits?: number; priceConfigured?: boolean; }; export type LinuxDOSetting = { enabled: boolean; clientId: string; clientSecret?: string; hasClientSecret: boolean; authorizationUrl: string; tokenUrl: string; userInfoUrl: string; redirectUrl: string; scopes: string[]; clientAuthMethod: "client_secret_post" | "client_secret_basic"; subjectField: string; usernameField: string; displayNameField: string; emailField: string; avatarField: string; updatedAt?: string; }; export type RegistrationSetting = { enabled: boolean; updatedBy?: string; createdAt?: string; updatedAt?: string; }; export type EmailSetting = { enabled: boolean; host: string; port: number; username: string; password?: string; encryption: "starttls" | "tls" | "none"; fromEmail: string; fromName: string; fromNameInherited: boolean; hasPassword: boolean; registrationAllowedDomains: string[]; updatedBy?: string; createdAt?: string; updatedAt?: string; }; export type RedeemBatch = { id: string; amountMicrocredits: number; count: number; note?: string; createdBy: string; expiresAt?: string; createdAt: string; availableCount: number; redeemedCount: number; disabledCount: number; expiredCount: number; }; export type AdminRedeemCode = { id: string; code?: string; codeSuffix: string; status: "unused" | "redeemed" | "disabled" | "expired"; redeemedBy?: string; redeemedUsername?: string; redeemedDisplayName?: string; redeemedAt?: string; redeemedIp?: string; expiresAt?: string; amountMicrocredits: number; }; export type AdminRedeemCodePage = { batch: RedeemBatch; codes: AdminRedeemCode[]; plaintextAvailable: boolean; total: number; page: number; limit: number; }; export type BillingOrder = { id: string; userId: string; taskId?: string; channelId: string; model: string; capability: string; scene: string; billingMode: "fixed_request" | "per_second" | "token"; unitPriceMicrocredits: number; multiplierBasisPoints: number; quantity: number; amountMicrocredits: number; reservedAmountMicrocredits: number; actualAmountMicrocredits: number; refundedAmountMicrocredits: number; inputTokenPriceMicrocredits: number; outputTokenPriceMicrocredits: number; cachedTokenPriceMicrocredits: number; inputTokens: number; outputTokens: number; cachedTokens: number; usageAvailable: boolean; status: "reserved" | "running" | "settled" | "refunded" | "uncertain"; providerRequestId?: string; error?: string; resolvedBy?: string; resolutionNote?: string; createdAt: string; updatedAt: string; }; export function getWallet(page = 1, limit = 30, type = "all") { return request(api.get("/wallet", { params: { type, page, limit } })); } export function redeemCredits(code: string) { return request<{ account: CreditAccount }>(api.post("/wallet/redeem", { code })); } export function checkinCredits() { return request<{ account: CreditAccount; granted: boolean }>(api.post("/wallet/checkin")); } export function getAdminCreditPolicy() { return request<{ policy: CreditPolicy }>(api.get("/admin/settings/credits")); } export function updateAdminCreditPolicy(policy: CreditPolicy) { return request<{ policy: CreditPolicy }>(api.patch("/admin/settings/credits", policy)); } export function getAdminLinuxDOSetting() { return request<{ setting: LinuxDOSetting }>(api.get("/admin/settings/linuxdo")); } export function updateAdminLinuxDOSetting(input: Partial) { return request<{ setting: LinuxDOSetting }>(api.patch("/admin/settings/linuxdo", input)); } export function getAdminRegistrationSetting() { return request<{ setting: RegistrationSetting }>(api.get("/admin/settings/registration")); } export function updateAdminRegistrationSetting(enabled: boolean) { return request<{ setting: RegistrationSetting }>(api.patch("/admin/settings/registration", { enabled })); } export function getAdminEmailSetting() { return request<{ setting: EmailSetting }>(api.get("/admin/settings/email")); } export function updateAdminEmailSetting(input: Partial) { return request<{ setting: EmailSetting }>(api.patch("/admin/settings/email", input)); } export function listAdminChannelModels(channelId: string) { return request<{ models: ChannelModel[] }>(api.get(`/admin/channels/${encodeURIComponent(channelId)}/models`)); } // 管理员从上游读取模型目录;确认导入后才会写入渠道模型,价格和启用仍需人工确认。 export function fetchAdminChannelModels(channelId: string) { return request<{ models: string[] }>(api.post(`/admin/channels/${encodeURIComponent(channelId)}/models/fetch`)); } export function importAdminChannelModels(channelId: string, models: string[]) { return request<{ models: string[]; added: number }>(api.post(`/admin/channels/${encodeURIComponent(channelId)}/models/import`, { models })); } export function testAdminChannelModel(channelId: string, input: Pick & { capabilityConfig?: ChannelModel["capabilityConfig"] }) { return request<{ durationMs: number }>(api.post(`/admin/channels/${encodeURIComponent(channelId)}/models/test`, input, { timeout: 10 * 60 * 1000 })); } export function createAdminChannelModel(channelId: string, input: ChannelModelMutation) { return request<{ model: ChannelModel }>(api.post(`/admin/channels/${encodeURIComponent(channelId)}/models`, input)); } export function updateAdminChannelModel(channelId: string, id: string, input: ChannelModelMutation) { return request<{ model: ChannelModel }>(api.patch(`/admin/channels/${encodeURIComponent(channelId)}/models/${encodeURIComponent(id)}`, input)); } export function deleteAdminChannelModel(channelId: string, id: string) { return request<{ ok: boolean }>(api.delete(`/admin/channels/${encodeURIComponent(channelId)}/models/${encodeURIComponent(id)}`)); } export type AdminFinanceListParams = { keyword?: string; status?: string; validity?: string; page?: number; limit?: number }; export function listAdminRedeemBatches(params: AdminFinanceListParams = {}) { return request<{ batches: RedeemBatch[]; total: number; page: number; limit: number }>(api.get("/admin/redeem-batches", { params })); } export function createAdminRedeemBatch(input: { amountMicrocredits: number; count: number; note?: string; expiresAt?: string }) { return request<{ batch: RedeemBatch; codes: string[] }>(api.post("/admin/redeem-batches", input, { timeout: 30_000 })); } export function listAdminRedeemBatchCodes(batchId: string, params: { status?: string; page?: number; limit?: number } = {}) { return request(api.get(`/admin/redeem-batches/${encodeURIComponent(batchId)}/codes`, { params })); } export function disableAdminRedeemBatch(batchId: string) { return request<{ disabledCount: number }>(api.post(`/admin/redeem-batches/${encodeURIComponent(batchId)}/disable`)); } export function disableAdminRedeemCode(batchId: string, codeId: string) { return request<{ ok: boolean }>(api.post(`/admin/redeem-batches/${encodeURIComponent(batchId)}/codes/${encodeURIComponent(codeId)}/disable`)); } export function adjustAdminUserCredits(userId: string, input: { amountMicrocredits: number; note: string }) { return request<{ account: CreditAccount }>(api.post(`/admin/users/${encodeURIComponent(userId)}/credits/adjust`, input)); } export function listAdminBillingOrders(params: AdminFinanceListParams = {}) { return request<{ orders: BillingOrder[]; total: number; page: number; limit: number }>(api.get("/admin/billing-orders", { params })); } export function resolveAdminBillingOrder(id: string, input: { action: "settle" | "refund"; note: string }) { return request<{ order: BillingOrder }>(api.post(`/admin/billing-orders/${encodeURIComponent(id)}/resolve`, input)); } export function resolveAdminBillingOrders(input: { ids: string[]; action: "settle" | "refund"; note: string }) { return request<{ resolvedCount: number; failed: Array<{ id: string; message: string }> }>(api.post("/admin/billing-orders/batch-resolve", input)); }