package v1 import ( "encoding/json" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" ) // === 仪表盘 === type AdminDashboardReq struct { g.Meta `path:"/dashboard" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"仪表盘统计"` } type AdminDashboardRes struct { Tenants int `json:"tenants"` Members int `json:"members"` ActiveChannels int `json:"active_channels"` Today *DayStats `json:"today"` Yesterday *DayStats `json:"yesterday"` Month *MonthStats `json:"month"` IpBlacklist *IpBlacklistStats `json:"ip_blacklist"` } // IpBlacklistStats IP 黑名单拦截统计(数据存 Redis 缓存,不落库;读取失败时仅回 enabled) type IpBlacklistStats struct { Enabled bool `json:"enabled"` // 黑名单当前是否启用 Total int64 `json:"total"` // 累计拦截总次数 List []IpBlacklistBlockedItem `json:"list"` // 按拦截次数倒序,最多 TOP 20 } type IpBlacklistBlockedItem struct { Ip string `json:"ip"` Count int64 `json:"count"` } type DayStats struct { Requests int `json:"requests"` ActiveTenants int `json:"active_tenants"` InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` TotalCost float64 `json:"total_cost"` SuccessRate float64 `json:"success_rate"` } type MonthStats struct { Requests int `json:"requests"` InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` TotalCost float64 `json:"total_cost"` Revenue float64 `json:"revenue"` } type AdminDashboardTrendsReq struct { g.Meta `path:"/dashboard/trends" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"趋势数据"` Days int `json:"days" d:"30" v:"between:1,90" dc:"天数"` } type AdminDashboardTrendsRes struct { List []map[string]any `json:"list"` } type AdminDashboardTopTenantsReq struct { g.Meta `path:"/dashboard/top-tenants" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"TOP租户"` Days int `json:"days" d:"30" v:"between:1,90" dc:"天数"` } type AdminDashboardTopTenantsRes struct { List []map[string]any `json:"list"` } type AdminDashboardModelDistributionReq struct { g.Meta `path:"/dashboard/model-distribution" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"模型分布"` Days int `json:"days" d:"30" v:"between:1,90" dc:"天数"` } type AdminDashboardModelDistributionRes struct { List []map[string]any `json:"list"` } type AdminDashboardChannelHealthReq struct { g.Meta `path:"/dashboard/channel-health" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"渠道健康概览"` } type ChannelHealthItem struct { ChannelId int64 `json:"channel_id"` ChannelName string `json:"channel_name"` Status string `json:"status"` HealthScore float64 `json:"health_score"` SuccessRate float64 `json:"success_rate"` LatencyMs int `json:"latency_ms"` } type AdminDashboardChannelHealthRes struct { List []ChannelHealthItem `json:"list"` } type AdminDashboardRecentAlertsReq struct { g.Meta `path:"/dashboard/recent-alerts" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"最近告警"` } type RecentAlertItem struct { Id int64 `json:"id"` RuleName string `json:"rule_name"` Level string `json:"level"` Status string `json:"status"` TriggerMessage string `json:"trigger_message"` CreatedAt string `json:"created_at"` } type AdminDashboardRecentAlertsRes struct { List []RecentAlertItem `json:"list"` } // 模型费用按小时堆叠统计(堆叠柱状图) type AdminDashboardModelHourlyReq struct { g.Meta `path:"/dashboard/model-hourly-cost" method:"get" mime:"json" tags:"管理后台-仪表盘" summary:"模型小时费用堆叠"` Hours int `json:"hours" d:"24" v:"between:1,168" dc:"统计小时数(rolling,最近 N 小时)"` TopN int `json:"top_n" d:"8" v:"between:1,20" dc:"展示模型数量(其余归为其他)"` } type ModelHourlySeriesItem struct { Model string `json:"model"` Data []float64 `json:"data"` // 对应 Hours 各时间点的费用 } type AdminDashboardModelHourlyRes struct { Hours []string `json:"hours"` // X 轴时间标签 Models []string `json:"models"` // 图例(含"其他") Series []ModelHourlySeriesItem `json:"series"` // 每个模型一条 series } // === 用量日志 === // AdminUsageLogFilter 用量日志共用筛选条件(列表 / 统计汇总 / 导出三个接口共用,保证筛选口径一致) type AdminUsageLogFilter struct { ID int64 `json:"id" dc:"用量记录ID"` TenantID int64 `json:"tenant_id" dc:"租户ID"` UserID int64 `json:"user_id" dc:"用户ID"` ApiKeyID int64 `json:"api_key_id" dc:"API Key ID"` ChannelID int64 `json:"channel_id" dc:"渠道ID"` Model string `json:"model" dc:"模型名称"` Status string `json:"status" dc:"状态"` RequestType int `json:"request_type" dc:"请求类型: 1=同步, 2=流式, 3=异步, 4=WebSocket"` UpstreamRequestId string `json:"upstream_request_id" dc:"上游请求ID(精确匹配,排障反查用)"` StartDate string `json:"start_date" dc:"开始时间(YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss)"` EndDate string `json:"end_date" dc:"结束时间(YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss)"` } type AdminUsageLogListReq struct { g.Meta `path:"/usage-logs" method:"get" mime:"json" tags:"管理后台-用量" summary:"用量日志列表"` Page int `json:"page" d:"1" dc:"页码"` PageSize int `json:"page_size" d:"20" v:"between:1,100" dc:"每页数量"` AdminUsageLogFilter `json:",inline"` // 嵌入共用筛选条件 } // AdminUsageLogListItem 用量日志列表项:仅表格列与悬浮明细(Token / 费用分解)所需字段。 // 纯关联 ID(user_id / project_id / channel_id)与排查大字段(billing_snapshot、 // user_agent、error_message、request_id 等)不进列表,统一经详情接口按需获取。 type AdminUsageLogListItem struct { Id int64 `json:"id"` TenantId int64 `json:"tenant_id"` TenantName string `json:"tenant_name"` Username string `json:"username"` ProjectName string `json:"project_name"` ApiKeyId int64 `json:"api_key_id"` ApiKeyName string `json:"api_key_name"` ChannelName string `json:"channel_name"` ModelName string `json:"model_name"` UpstreamModel string `json:"upstream_model"` RequestType int `json:"request_type"` BillingMode string `json:"billing_mode"` InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` CacheCreationTokens int `json:"cache_creation_tokens"` CacheReadTokens int `json:"cache_read_tokens"` CacheCreation5mTokens int `json:"cache_creation_5m_tokens"` CacheCreation1hTokens int `json:"cache_creation_1h_tokens"` ReasoningTokens int `json:"reasoning_tokens"` AudioInputTokens int `json:"audio_input_tokens"` AudioOutputTokens int `json:"audio_output_tokens"` ImageOutputTokens int `json:"image_output_tokens"` InputCost float64 `json:"input_cost"` OutputCost float64 `json:"output_cost"` CacheCreationCost float64 `json:"cache_creation_cost"` CacheReadCost float64 `json:"cache_read_cost"` TotalCost float64 `json:"total_cost"` ActualCost float64 `json:"actual_cost"` RateMultiplier float64 `json:"rate_multiplier"` LatencyMs int `json:"latency_ms"` FirstTokenMs int `json:"first_token_ms"` Status string `json:"status"` RetryIndex int `json:"retry_index"` CreatedAt *gtime.Time `json:"created_at"` } type AdminUsageLogListRes struct { List []*AdminUsageLogListItem `json:"list"` Total int `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // AdminUsageLogItem 用量日志全量字段结构体(详情接口专用,列表用上方的精简 ListItem) type AdminUsageLogItem struct { Id int64 `json:"id"` TenantId int64 `json:"tenant_id"` TenantName string `json:"tenant_name"` UserId int64 `json:"user_id"` Username string `json:"username"` ProjectId int64 `json:"project_id"` ProjectName string `json:"project_name"` ApiKeyId int64 `json:"api_key_id"` ApiKeyName string `json:"api_key_name"` ChannelId int64 `json:"channel_id"` ChannelName string `json:"channel_name"` ChannelType int `json:"channel_type"` ModelName string `json:"model_name"` RequestedModel string `json:"requested_model"` UpstreamModel string `json:"upstream_model"` RelayMode string `json:"relay_mode"` RequestType int `json:"request_type"` InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` CacheCreationTokens int `json:"cache_creation_tokens"` CacheReadTokens int `json:"cache_read_tokens"` CacheCreation5mTokens int `json:"cache_creation_5m_tokens"` CacheCreation1hTokens int `json:"cache_creation_1h_tokens"` ReasoningTokens int `json:"reasoning_tokens"` AudioInputTokens int `json:"audio_input_tokens"` AudioOutputTokens int `json:"audio_output_tokens"` ImageOutputTokens int `json:"image_output_tokens"` InputCost float64 `json:"input_cost"` OutputCost float64 `json:"output_cost"` CacheCreationCost float64 `json:"cache_creation_cost"` CacheReadCost float64 `json:"cache_read_cost"` TotalCost float64 `json:"total_cost"` ActualCost float64 `json:"actual_cost"` Currency string `json:"currency"` BillingMode string `json:"billing_mode"` BillingSource string `json:"billing_source"` RateMultiplier float64 `json:"rate_multiplier"` LatencyMs int `json:"latency_ms"` FirstTokenMs int `json:"first_token_ms"` Status string `json:"status"` ErrorMessage string `json:"error_message"` RetryIndex int `json:"retry_index"` ClientIp string `json:"client_ip"` UserAgent string `json:"user_agent"` ServiceTier string `json:"service_tier"` ReasoningEffort string `json:"reasoning_effort"` StreamEndReason string `json:"stream_end_reason"` ImageCount int `json:"image_count"` ImageSize string `json:"image_size"` PreDeductAmount float64 `json:"pre_deduct_amount"` RefundAmount float64 `json:"refund_amount"` SupplementAmount float64 `json:"supplement_amount"` BillingSummary string `json:"billing_summary"` BillingSnapshot string `json:"billing_snapshot"` InboundEndpoint string `json:"inbound_endpoint"` RequestId string `json:"request_id"` TaskId string `json:"task_id"` UpstreamRequestId string `json:"upstream_request_id"` CreatedAt *gtime.Time `json:"created_at"` } // AdminUsageLogDetailReq 用量日志详情(列表只返回表格展示字段, // billing_snapshot / billing_summary / user_agent / error_message 等大字段经此接口按需获取) type AdminUsageLogDetailReq struct { g.Meta `path:"/usage-logs/{id}" method:"get" mime:"json" tags:"管理后台-用量" summary:"用量日志详情"` Id int64 `json:"id" in:"path" v:"min:1" dc:"用量记录ID"` } // AdminUsageLogDetailRes 详情对象平铺进统一响应的 data 字段(json:"-" + 自定义 MarshalJSON, // 与 RequestAuditLogDetailRes 同一模式),避免统一包装后再多包一层 data type AdminUsageLogDetailRes struct { Data *AdminUsageLogItem `json:"-"` } func (r *AdminUsageLogDetailRes) MarshalJSON() ([]byte, error) { return json.Marshal(r.Data) } // AdminUsageLogSummaryReq 用量日志统计请求(复用筛选条件,不包含分页) type AdminUsageLogSummaryReq struct { g.Meta `path:"/usage-logs/summary" method:"get" mime:"json" tags:"管理后台-用量" summary:"用量日志统计汇总"` AdminUsageLogFilter `json:",inline"` // 嵌入共用筛选条件 } // AdminUsageLogSummary 用量日志统计汇总 type AdminUsageLogSummaryRes struct { TotalCost float64 `json:"total_cost" dc:"总费用(USD)"` TotalOutputTokens int64 `json:"total_output_tokens" dc:"总输出token数"` CacheReadRatio float64 `json:"cache_read_ratio" dc:"缓存读取占比(%)"` } // === 计费记录 === type AdminBillingRecordListReq struct { g.Meta `path:"/billing-records" method:"get" mime:"json" tags:"管理后台-用量" summary:"计费记录列表"` Page int `json:"page" d:"1" dc:"页码"` PageSize int `json:"page_size" d:"20" v:"between:1,100" dc:"每页数量"` TenantID int64 `json:"tenant_id" dc:"租户ID"` } type AdminBillingRecordItem struct { Id int64 `json:"id"` TenantId int64 `json:"tenant_id"` TenantName string `json:"tenant_name"` UserId int64 `json:"user_id"` UserName string `json:"user_name"` ChannelId int64 `json:"channel_id"` ChannelName string `json:"channel_name"` ModelName string `json:"model_name"` RelayMode string `json:"relay_mode"` InputTokens int `json:"input_tokens"` OutputTokens int `json:"output_tokens"` InputPrice float64 `json:"input_price"` OutputPrice float64 `json:"output_price"` TotalCost float64 `json:"total_cost"` Currency string `json:"currency"` Status string `json:"status"` SettledAt *gtime.Time `json:"settled_at"` CreatedAt *gtime.Time `json:"created_at"` } type AdminBillingRecordListRes struct { List []*AdminBillingRecordItem `json:"list"` Total int `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // === 钱包管理 === type AdminWalletListReq struct { g.Meta `path:"/wallets" method:"get" mime:"json" tags:"管理后台-钱包" summary:"钱包列表"` Page int `json:"page" d:"1" dc:"页码"` PageSize int `json:"page_size" d:"20" v:"between:1,100" dc:"每页数量"` } type AdminWalletItem struct { Id int64 `json:"id"` TenantId int64 `json:"tenant_id"` Balance float64 `json:"balance"` FrozenBalance float64 `json:"frozen_balance"` WarningThreshold float64 `json:"warning_threshold"` Currency string `json:"currency"` CreatedAt *gtime.Time `json:"created_at"` UpdatedAt *gtime.Time `json:"updated_at"` } type AdminWalletListRes struct { List []*AdminWalletItem `json:"list"` Total int `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } type AdminWalletInfoReq struct { g.Meta `path:"/wallets/{tenant_id}" method:"get" mime:"json" tags:"管理后台-钱包" summary:"钱包详情"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` } type AdminWalletInfoRes struct { Balance float64 `json:"balance"` FrozenBalance float64 `json:"frozen_balance"` WarningThreshold *float64 `json:"warning_threshold"` } type AdminWalletAdjustReq struct { g.Meta `path:"/wallets/{tenant_id}/adjust" method:"post" mime:"json" tags:"管理后台-钱包" summary:"调整余额"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` Amount float64 `json:"amount" v:"required" dc:"调整金额(正数充值,负数扣减)"` Description string `json:"description" dc:"调整说明"` } type AdminWalletAdjustRes struct{} type AdminWalletOfflineRechargeReq struct { g.Meta `path:"/wallets/{tenant_id}/offline-recharge" method:"post" mime:"json" tags:"管理后台-钱包" summary:"线下充值入账"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` Amount float64 `json:"amount" v:"required|min:0.01" dc:"线下入账金额(人民币 CNY),按平台汇率换算为 USD 到账"` TransactionNo string `json:"transaction_no" dc:"银行转账流水号(选填,用于对账与防重复入账)"` Description string `json:"description" v:"required" dc:"入账说明(必填,如客户名称、转账原因)"` } type AdminWalletOfflineRechargeRes struct { CreditedUSD float64 `json:"credited_usd" dc:"实际入账美元金额"` Rate float64 `json:"rate" dc:"使用的 CNY→USD 汇率"` Balance float64 `json:"balance" dc:"入账后总余额(USD)"` } type AdminWalletTransactionListReq struct { g.Meta `path:"/wallets/{tenant_id}/transactions" method:"get" mime:"json" tags:"管理后台-钱包" summary:"交易流水"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` Page int `json:"page" d:"1" dc:"页码"` PageSize int `json:"page_size" d:"20" v:"between:1,100" dc:"每页数量"` Type string `json:"type" dc:"交易类型"` } type AdminWalletTransactionItem struct { ID int64 `json:"id"` Type string `json:"type"` Amount float64 `json:"amount"` BalanceAfter float64 `json:"balance_after"` FrozenAfter float64 `json:"frozen_after"` Description string `json:"description"` UserId int64 `json:"user_id"` Username string `json:"username"` RequestId string `json:"request_id"` ModelName string `json:"model_name"` CreatedAt string `json:"created_at"` } type AdminWalletTransactionListRes struct { List []*AdminWalletTransactionItem `json:"list"` Total int `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // AdminWalletFrozenItemListReq 冻结明细列表请求(预扣追踪表中 status=frozen 的记录) type AdminWalletFrozenItemListReq struct { g.Meta `path:"/wallets/{tenant_id}/frozen-items" method:"get" mime:"json" tags:"管理后台-钱包" summary:"冻结明细列表"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` } // AdminWalletFrozenItem 单笔冻结明细 type AdminWalletFrozenItem struct { RequestID string `json:"request_id" dc:"请求ID"` ModelName string `json:"model_name" dc:"模型名称"` Amount float64 `json:"amount" dc:"冻结金额(USD)"` CreatedAt string `json:"created_at" dc:"冻结时间"` AgeSeconds int64 `json:"age_seconds" dc:"已冻结时长(秒)"` Releasable bool `json:"releasable" dc:"是否可释放(false 时 block_reason 说明原因)"` NeedForce bool `json:"need_force" dc:"是否需要强制释放(冻结时长过短,可能仍有请求进行中)"` BlockReason string `json:"block_reason" dc:"不可释放原因(如关联异步任务进行中)"` TaskStatus string `json:"task_status" dc:"关联异步任务状态(无关联时为空)"` } type AdminWalletFrozenItemListRes struct { List []*AdminWalletFrozenItem `json:"list"` } // AdminWalletFrozenReleaseReq 按笔释放冻结请求 type AdminWalletFrozenReleaseReq struct { g.Meta `path:"/wallets/{tenant_id}/frozen-items/release" method:"post" mime:"json" tags:"管理后台-钱包" summary:"释放单笔冻结"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` RequestID string `json:"request_id" v:"required" dc:"要释放的冻结项请求ID"` Force bool `json:"force" dc:"强制释放(冻结时长不足保护期时必须显式传 true)"` Reason string `json:"reason" v:"required" dc:"释放原因(必填,写入审计)"` } type AdminWalletFrozenReleaseRes struct { ReleasedAmount float64 `json:"released_amount" dc:"实际释放金额(USD)"` } // AdminWalletFrozenReleaseAllReq 一键释放全部冻结请求 type AdminWalletFrozenReleaseAllReq struct { g.Meta `path:"/wallets/{tenant_id}/frozen-items/release-all" method:"post" mime:"json" tags:"管理后台-钱包" summary:"一键释放全部冻结"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` Force bool `json:"force" dc:"是否强制释放保护期内(冻结不足 10 分钟)的冻结项"` Reason string `json:"reason" v:"required" dc:"释放原因(必填,写入审计)"` } // AdminWalletFrozenReleaseAllRes 一键释放结果 type AdminWalletFrozenReleaseAllRes struct { ReleasedCount int64 `json:"released_count" dc:"实际释放笔数"` ReleasedAmount float64 `json:"released_amount" dc:"实际释放金额合计(USD)"` SkippedCount int64 `json:"skipped_count" dc:"跳过笔数(任务关联/待结算/保护期未强制)"` SkippedReasons []string `json:"skipped_reasons" dc:"跳过原因摘要(去重)"` } type AdminWalletSetWarningThresholdReq struct { g.Meta `path:"/wallets/{tenant_id}/warning-threshold" method:"put" mime:"json" tags:"管理后台-钱包" summary:"设置预警阈值"` TenantID int64 `json:"tenant_id" in:"path" v:"required|min:1" dc:"租户ID"` Threshold float64 `json:"threshold" v:"min:0" dc:"预警阈值"` } type AdminWalletSetWarningThresholdRes struct{} // AdminUsageLogExportReq 导出用量日志请求 type AdminUsageLogExportReq struct { g.Meta `path:"/usage-logs/export" method:"get" mime:"json" tags:"管理后台-用量" summary:"导出用量日志"` Format string `json:"format" in:"query" d:"csv" v:"in:csv,xlsx" dc:"导出格式:csv / xlsx"` AdminUsageLogFilter `json:",inline"` // 嵌入共用筛选条件 } type AdminUsageLogExportRes struct{} // AdminBillingRecordExportReq 导出计费记录请求 type AdminBillingRecordExportReq struct { g.Meta `path:"/billing-records/export" method:"get" mime:"json" tags:"管理后台-用量" summary:"导出计费记录"` Format string `json:"format" in:"query" d:"csv" v:"in:csv,xlsx" dc:"导出格式:csv / xlsx"` TenantID int64 `json:"tenant_id" in:"query" dc:"租户ID"` } type AdminBillingRecordExportRes struct{} // === 交易流水 === type AdminTransactionListReq struct { g.Meta `path:"/transactions" method:"get" mime:"json" tags:"管理后台-交易" summary:"交易流水列表"` Page int `json:"page" d:"1" dc:"页码"` PageSize int `json:"page_size" d:"20" v:"between:1,100" dc:"每页数量"` TenantID int64 `json:"tenant_id" dc:"租户ID"` Type string `json:"type" dc:"交易类型:consume/recharge/adjust"` Username string `json:"username" dc:"用户名(模糊匹配)"` ModelName string `json:"model_name" dc:"模型名称(模糊匹配)"` StartDate string `json:"start_date" dc:"开始日期"` EndDate string `json:"end_date" dc:"结束日期"` } type AdminTransactionItem struct { Id int64 `json:"id"` TenantId int64 `json:"tenant_id"` TenantName string `json:"tenant_name"` Type string `json:"type"` Amount float64 `json:"amount"` BalanceAfter float64 `json:"balance_after"` Description string `json:"description"` UserId int64 `json:"user_id"` Username string `json:"username"` RequestId string `json:"request_id"` ModelName string `json:"model_name"` CreatedAt string `json:"created_at"` } type AdminTransactionListRes struct { List []*AdminTransactionItem `json:"list"` Total int `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` }