# 渠道租户资源分配查看接口文档 > **版本**: v1.0.0 > **更新时间**: 2026-01-13 > **说明**: 管理员查看渠道下租户被分配的自定义Agent、平台Agent、模型等资源 --- ## 目录 1. [接口概述](#接口概述) 2. [接口1: 超级管理员查看渠道租户资源分配](#接口1-超级管理员查看渠道租户资源分配) 3. [接口2: 渠道管理员查看租户资源分配汇总](#接口2-渠道管理员查看租户资源分配汇总) 4. [数据结构说明](#数据结构说明) --- ## 接口概述 | 接口 | 路径 | 方法 | 权限 | 说明 | |------|------|------|------|------| | 接口1 | `/api/admin/channels/{channel_id}/tenants/resources` | GET | super_admin, billing_admin, operations_admin, channel_admin | 超级管理员查看指定渠道的租户资源分配 | | 接口2 | `/api/channel/tenants/resources/summary` | GET | channel_admin, billing_admin, operations_admin, super_admin | 渠道管理员查看自己渠道的租户资源分配汇总 | ### 权限说明 - **super_admin**: 可查看所有渠道的租户资源分配 - **billing_admin / operations_admin**: 只能查看所属渠道的租户资源分配 - **channel_admin**: 只能查看所属渠道的租户资源分配 --- ## 接口1: 超级管理员查看渠道租户资源分配 ### 基本信息 | 属性 | 值 | |------|-----| | **接口路径** | `GET /api/admin/channels/{channel_id}/tenants/resources` | | **后端文件** | `services/mcp-server/app/routes/admin.py` | | **权限要求** | super_admin, billing_admin, operations_admin, channel_admin | ### 请求参数 #### 路径参数 (Path Parameters) | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | channel_id | string (UUID) | 是 | 渠道ID | `6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6` | #### 请求头 (Headers) | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | Authorization | string | 是 | Bearer Token | `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` | ### 请求示例 ```bash curl -X GET "http://localhost:8002/api/admin/channels/6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6/tenants/resources" \ -H "Authorization: Bearer $TOKEN" ``` ### 响应参数 #### 成功响应 (200 OK) ```json { "success": true, "data": { "channelId": "string", "channelName": "string", "tenants": [ { "tenantId": "string", "tenantName": "string", "tenantEmail": "string", "status": "string", "createdAt": "string (ISO 8601)", "customAgentQuota": { "cpuQuota": "number", "memoryQuota": "number", "cpuUsed": "number", "memoryUsed": "number", "agentCount": "integer" } | null, "platformAgents": [ { "templateName": "string", "podQuota": "integer", "podUsed": "integer", "cpuPerPod": "string", "memoryPerPod": "string" } ], "models": [ { "modelName": "string", "rpmLimit": "integer", "tpmLimit": "integer", "maxBudget": "number | null", "budgetDuration": "string" } ] } ], "summary": { "totalTenants": "integer", "tenantsWithCustomAgents": "integer", "tenantsWithPlatformAgents": "integer", "tenantsWithModels": "integer", "totalCustomAgentCpuQuota": "number", "totalCustomAgentMemoryQuota": "number", "totalCustomAgentCpuUsed": "number", "totalCustomAgentMemoryUsed": "number", "totalPlatformAgentPodQuota": "integer", "totalPlatformAgentPodUsed": "integer" } }, "message": "获取渠道租户资源分配成功" } ``` #### 响应字段说明 | 字段路径 | 类型 | 说明 | |----------|------|------| | `data.channelId` | string | 渠道ID | | `data.channelName` | string | 渠道名称 | | `data.tenants` | array | 租户资源列表 | | `data.tenants[].tenantId` | string | 租户ID | | `data.tenants[].tenantName` | string | 租户名称 | | `data.tenants[].tenantEmail` | string | 租户邮箱 | | `data.tenants[].status` | string | 租户状态 (active/suspended) | | `data.tenants[].createdAt` | string | 创建时间 (ISO 8601格式) | | `data.tenants[].customAgentQuota` | object/null | 自定义Agent配额,无配额时为null | | `data.tenants[].customAgentQuota.cpuQuota` | number | CPU配额上限(核心数) | | `data.tenants[].customAgentQuota.memoryQuota` | number | 内存配额上限(GB) | | `data.tenants[].customAgentQuota.cpuUsed` | number | 已使用CPU(核心数) | | `data.tenants[].customAgentQuota.memoryUsed` | number | 已使用内存(GB) | | `data.tenants[].customAgentQuota.agentCount` | integer | 已创建的自定义Agent数量 | | `data.tenants[].platformAgents` | array | 平台Agent配额列表 | | `data.tenants[].platformAgents[].templateName` | string | 模板名称 | | `data.tenants[].platformAgents[].podQuota` | integer | Pod配额数量 | | `data.tenants[].platformAgents[].podUsed` | integer | 已使用Pod数量 | | `data.tenants[].platformAgents[].cpuPerPod` | string | 每个Pod的CPU配置 | | `data.tenants[].platformAgents[].memoryPerPod` | string | 每个Pod的内存配置 | | `data.tenants[].models` | array | 模型配额列表 | | `data.tenants[].models[].modelName` | string | 模型名称 | | `data.tenants[].models[].rpmLimit` | integer | RPM限制(每分钟请求数) | | `data.tenants[].models[].tpmLimit` | integer | TPM限制(每分钟Token数) | | `data.tenants[].models[].maxBudget` | number/null | 最大预算 | | `data.tenants[].models[].budgetDuration` | string | 预算周期 (monthly/daily) | | `data.summary` | object | 汇总统计 | | `data.summary.totalTenants` | integer | 租户总数 | | `data.summary.tenantsWithCustomAgents` | integer | 有自定义Agent配额的租户数 | | `data.summary.tenantsWithPlatformAgents` | integer | 有平台Agent配额的租户数 | | `data.summary.tenantsWithModels` | integer | 有模型配额的租户数 | | `data.summary.totalCustomAgentCpuQuota` | number | 总自定义Agent CPU配额 | | `data.summary.totalCustomAgentMemoryQuota` | number | 总自定义Agent内存配额 | | `data.summary.totalCustomAgentCpuUsed` | number | 总已使用CPU | | `data.summary.totalCustomAgentMemoryUsed` | number | 总已使用内存 | | `data.summary.totalPlatformAgentPodQuota` | integer | 总平台Agent Pod配额 | | `data.summary.totalPlatformAgentPodUsed` | integer | 总已使用Pod数 | ### 实际响应示例 ```json { "success": true, "data": { "channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6", "channelName": "66", "tenants": [ { "tenantId": "b0d02105-55f8-41a7-b09a-bba8f49a9d62", "tenantName": "xiaohei", "tenantEmail": "xiaohei@qq.com", "status": "active", "createdAt": "2026-01-11T17:08:36.521982", "customAgentQuota": { "cpuQuota": 10.0, "memoryQuota": 20.0, "cpuUsed": 0.0, "memoryUsed": 0.0, "agentCount": 0 }, "platformAgents": [], "models": [] }, { "tenantId": "b00a7b8e-9e8b-463d-9593-a3b4d0006778", "tenantName": "55", "tenantEmail": "55@55.com", "status": "active", "createdAt": "2026-01-09T05:46:46.806711", "customAgentQuota": { "cpuQuota": 8.0, "memoryQuota": 8.0, "cpuUsed": 3.0, "memoryUsed": 5.0, "agentCount": 5 }, "platformAgents": [ { "templateName": "echo_agent", "podQuota": 3, "podUsed": 2, "cpuPerPod": "100m", "memoryPerPod": "256Mi" } ], "models": [ { "modelName": "taiji/gpt-4o-mini", "rpmLimit": 10, "tpmLimit": 10, "maxBudget": 500.0, "budgetDuration": "monthly" }, { "modelName": "taiji/gpt-5", "rpmLimit": 100, "tpmLimit": 100, "maxBudget": 500.0, "budgetDuration": "monthly" } ] }, { "tenantId": "61069bec-2aca-465c-aa58-cebf9b1851a7", "tenantName": "22", "tenantEmail": "22@22.com", "status": "active", "createdAt": "2026-01-09T10:32:23.684369", "customAgentQuota": null, "platformAgents": [ { "templateName": "code_agent", "podQuota": 1, "podUsed": 0, "cpuPerPod": "100m", "memoryPerPod": "256Mi" } ], "models": [ { "modelName": "taiji/gpt-5", "rpmLimit": 100, "tpmLimit": 100, "maxBudget": 500.0, "budgetDuration": "monthly" } ] } ], "summary": { "totalTenants": 3, "tenantsWithCustomAgents": 2, "tenantsWithPlatformAgents": 2, "tenantsWithModels": 2, "totalCustomAgentCpuQuota": 18.0, "totalCustomAgentMemoryQuota": 28.0, "totalCustomAgentCpuUsed": 3.0, "totalCustomAgentMemoryUsed": 5.0, "totalPlatformAgentPodQuota": 4, "totalPlatformAgentPodUsed": 2 } }, "message": "获取渠道租户资源分配成功" } ``` ### 错误响应 | HTTP状态码 | 错误说明 | 响应示例 | |------------|----------|----------| | 400 | 无效的渠道ID格式 | `{"success": false, "detail": "无效的渠道ID格式"}` | | 403 | 权限不足(渠道管理员只能查看所属渠道) | `{"success": false, "detail": "只能查看所属渠道的租户资源"}` | | 404 | 渠道不存在 | `{"success": false, "detail": "渠道不存在"}` | --- ## 接口2: 渠道管理员查看租户资源分配汇总 ### 基本信息 | 属性 | 值 | |------|-----| | **接口路径** | `GET /api/channel/tenants/resources/summary` | | **后端文件** | `services/mcp-server/app/routes/channel.py` | | **权限要求** | channel_admin, billing_admin, operations_admin, super_admin | ### 请求参数 #### 查询参数 (Query Parameters) | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | channel_id | string (UUID) | 条件必填 | 渠道ID(超级管理员必填,其他管理员自动使用所属渠道) | `6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6` | #### 请求头 (Headers) | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | Authorization | string | 是 | Bearer Token | `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` | ### 请求示例 **渠道管理员请求(自动使用所属渠道)**: ```bash curl -X GET "http://localhost:8002/api/channel/tenants/resources/summary" \ -H "Authorization: Bearer $CHANNEL_ADMIN_TOKEN" ``` **超级管理员请求(需要指定channel_id)**: ```bash curl -X GET "http://localhost:8002/api/channel/tenants/resources/summary?channel_id=6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6" \ -H "Authorization: Bearer $SUPER_ADMIN_TOKEN" ``` ### 响应参数 #### 成功响应 (200 OK) ```json { "success": true, "data": { "channelId": "string", "channelName": "string", "channelQuota": { "customAgentQuota": { "cpuQuota": "number", "memoryQuota": "number", "cpuAllocated": "number", "memoryAllocated": "number" } | null, "platformAgents": [ { "templateName": "string", "podQuota": "integer", "podUsed": "integer", "cpuPerPod": "string", "memoryPerPod": "string" } ], "models": ["string"] }, "tenants": [ { "tenantId": "string", "tenantName": "string", "tenantEmail": "string", "status": "string", "subscriptionTier": "string", "balance": "number", "createdAt": "string (ISO 8601)", "customAgentQuota": {...} | null, "platformAgents": [...], "models": [...] } ], "summary": { "totalTenants": "integer", "tenantsWithCustomAgents": "integer", "tenantsWithPlatformAgents": "integer", "tenantsWithModels": "integer", "totalCustomAgentCpuQuota": "number", "totalCustomAgentMemoryQuota": "number", "totalCustomAgentCpuUsed": "number", "totalCustomAgentMemoryUsed": "number", "totalPlatformAgentPodQuota": "integer", "totalPlatformAgentPodUsed": "integer", "totalModelsAllocated": "integer" } }, "message": "获取渠道租户资源分配成功" } ``` #### 响应字段说明(额外字段) 此接口在接口1的基础上,增加以下字段: | 字段路径 | 类型 | 说明 | |----------|------|------| | `data.channelQuota` | object | 渠道自身的配额信息(用于对比) | | `data.channelQuota.customAgentQuota` | object/null | 渠道的自定义Agent配额 | | `data.channelQuota.customAgentQuota.cpuQuota` | number | 渠道CPU配额上限 | | `data.channelQuota.customAgentQuota.memoryQuota` | number | 渠道内存配额上限 | | `data.channelQuota.customAgentQuota.cpuAllocated` | number | 已分配给租户的CPU总量 | | `data.channelQuota.customAgentQuota.memoryAllocated` | number | 已分配给租户的内存总量 | | `data.channelQuota.platformAgents` | array | 渠道的平台Agent配额列表 | | `data.channelQuota.models` | array | 渠道被分配的模型列表 | | `data.tenants[].subscriptionTier` | string | 租户订阅等级 (free/pro/enterprise) | | `data.tenants[].balance` | number | 租户余额 | | `data.summary.totalModelsAllocated` | integer | 总分配模型数 | ### 实际响应示例 ```json { "success": true, "data": { "channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6", "channelName": "66", "channelQuota": { "customAgentQuota": { "cpuQuota": 8.0, "memoryQuota": 8.0, "cpuAllocated": 8.0, "memoryAllocated": 8.0 }, "platformAgents": [ { "templateName": "echo_agent", "podQuota": 3, "podUsed": 0, "cpuPerPod": "100m", "memoryPerPod": "256Mi" } ], "models": [ "gpt-4o" ] }, "tenants": [ { "tenantId": "b0d02105-55f8-41a7-b09a-bba8f49a9d62", "tenantName": "xiaohei", "tenantEmail": "xiaohei@qq.com", "status": "active", "subscriptionTier": "free", "balance": 0, "createdAt": "2026-01-11T17:08:36.521982", "customAgentQuota": { "cpuQuota": 10.0, "memoryQuota": 20.0, "cpuUsed": 0.0, "memoryUsed": 0.0, "agentCount": 0 }, "platformAgents": [], "models": [] }, { "tenantId": "b00a7b8e-9e8b-463d-9593-a3b4d0006778", "tenantName": "55", "tenantEmail": "55@55.com", "status": "active", "subscriptionTier": "free", "balance": 100.0, "createdAt": "2026-01-09T05:46:46.806711", "customAgentQuota": { "cpuQuota": 8.0, "memoryQuota": 8.0, "cpuUsed": 3.0, "memoryUsed": 5.0, "agentCount": 5 }, "platformAgents": [ { "templateName": "echo_agent", "podQuota": 3, "podUsed": 2, "cpuPerPod": "100m", "memoryPerPod": "256Mi" } ], "models": [ { "modelName": "taiji/gpt-4o-mini", "rpmLimit": 10, "tpmLimit": 10, "maxBudget": 500.0, "budgetDuration": "monthly" }, { "modelName": "taiji/gpt-5", "rpmLimit": 100, "tpmLimit": 100, "maxBudget": 500.0, "budgetDuration": "monthly" } ] }, { "tenantId": "61069bec-2aca-465c-aa58-cebf9b1851a7", "tenantName": "22", "tenantEmail": "22@22.com", "status": "active", "subscriptionTier": "free", "balance": 50.0, "createdAt": "2026-01-09T10:32:23.684369", "customAgentQuota": null, "platformAgents": [ { "templateName": "code_agent", "podQuota": 1, "podUsed": 0, "cpuPerPod": "100m", "memoryPerPod": "256Mi" } ], "models": [ { "modelName": "taiji/gpt-5", "rpmLimit": 100, "tpmLimit": 100, "maxBudget": 500.0, "budgetDuration": "monthly" } ] } ], "summary": { "totalTenants": 3, "tenantsWithCustomAgents": 2, "tenantsWithPlatformAgents": 2, "tenantsWithModels": 2, "totalCustomAgentCpuQuota": 18.0, "totalCustomAgentMemoryQuota": 28.0, "totalCustomAgentCpuUsed": 3.0, "totalCustomAgentMemoryUsed": 5.0, "totalPlatformAgentPodQuota": 4, "totalPlatformAgentPodUsed": 2, "totalModelsAllocated": 3 } }, "message": "获取渠道租户资源分配成功" } ``` ### 错误响应 | HTTP状态码 | 错误说明 | 响应示例 | |------------|----------|----------| | 400 | 超级管理员未提供channel_id | `{"success": false, "detail": "超级管理员必须提供 channel_id 参数"}` | | 400 | 无效的渠道ID格式 | `{"success": false, "detail": "无效的渠道ID格式"}` | | 400 | 无法获取渠道ID | `{"success": false, "detail": "无法获取渠道ID"}` | | 404 | 渠道不存在 | `{"success": false, "detail": "渠道不存在"}` | --- ## 数据结构说明 ### 租户状态 (status) | 值 | 说明 | |----|------| | `active` | 活跃状态 | | `suspended` | 已暂停 | | `inactive` | 已停用 | ### 订阅等级 (subscriptionTier) | 值 | 说明 | |----|------| | `free` | 免费版 | | `pro` | 专业版 | | `enterprise` | 企业版 | ### 预算周期 (budgetDuration) | 值 | 说明 | |----|------| | `monthly` | 月度预算 | | `daily` | 每日预算 | ### CPU/内存格式 | 格式 | 说明 | 示例 | |------|------|------| | CPU (millicores) | Kubernetes CPU格式 | `100m` = 0.1核, `500m` = 0.5核 | | Memory (MiB/GiB) | Kubernetes 内存格式 | `256Mi` = 256MB, `2Gi` = 2GB | --- ## 使用场景 ### 场景1: 超级管理员审查渠道资源使用情况 超级管理员需要了解某个渠道下所有租户的资源使用情况,以便进行资源规划和调整。 ```bash # 查看渠道 "66" 的所有租户资源分配 curl -X GET "http://localhost:8002/api/admin/channels/6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6/tenants/resources" \ -H "Authorization: Bearer $SUPER_ADMIN_TOKEN" ``` ### 场景2: 渠道管理员查看配额使用对比 渠道管理员需要了解自己渠道的配额分配情况,以及与租户实际分配的对比。 ```bash # 渠道管理员查看租户资源分配汇总(包含渠道配额对比) curl -X GET "http://localhost:8002/api/channel/tenants/resources/summary" \ -H "Authorization: Bearer $CHANNEL_ADMIN_TOKEN" ``` ### 场景3: 分析资源利用率 通过 summary 字段,可以快速分析资源利用率: - **自定义Agent CPU利用率** = `totalCustomAgentCpuUsed / totalCustomAgentCpuQuota` - **自定义Agent内存利用率** = `totalCustomAgentMemoryUsed / totalCustomAgentMemoryQuota` - **平台Agent Pod利用率** = `totalPlatformAgentPodUsed / totalPlatformAgentPodQuota` --- ## 前端调用示例 ### JavaScript/TypeScript ```typescript // 超级管理员查看渠道租户资源分配 async function getChannelTenantsResources(channelId: string): Promise { const response = await fetch( `${API_BASE_URL}/api/admin/channels/${channelId}/tenants/resources`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, } ); return response.json(); } // 渠道管理员查看租户资源分配汇总 async function getChannelTenantsResourcesSummary(channelId?: string): Promise { const url = channelId ? `${API_BASE_URL}/api/channel/tenants/resources/summary?channel_id=${channelId}` : `${API_BASE_URL}/api/channel/tenants/resources/summary`; const response = await fetch(url, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, }); return response.json(); } ``` ### TypeScript 类型定义 ```typescript interface CustomAgentQuota { cpuQuota: number; memoryQuota: number; cpuUsed: number; memoryUsed: number; agentCount: number; } interface PlatformAgentQuota { templateName: string; podQuota: number; podUsed: number; cpuPerPod: string; memoryPerPod: string; } interface ModelQuota { modelName: string; rpmLimit: number; tpmLimit: number; maxBudget: number | null; budgetDuration: string; } interface TenantResource { tenantId: string; tenantName: string; tenantEmail: string; status: 'active' | 'suspended' | 'inactive'; createdAt: string; subscriptionTier?: string; balance?: number; customAgentQuota: CustomAgentQuota | null; platformAgents: PlatformAgentQuota[]; models: ModelQuota[]; } interface ResourceSummary { totalTenants: number; tenantsWithCustomAgents: number; tenantsWithPlatformAgents: number; tenantsWithModels: number; totalCustomAgentCpuQuota: number; totalCustomAgentMemoryQuota: number; totalCustomAgentCpuUsed: number; totalCustomAgentMemoryUsed: number; totalPlatformAgentPodQuota: number; totalPlatformAgentPodUsed: number; totalModelsAllocated?: number; } interface ChannelQuota { customAgentQuota: { cpuQuota: number; memoryQuota: number; cpuAllocated: number; memoryAllocated: number; } | null; platformAgents: PlatformAgentQuota[]; models: string[]; } interface TenantsResourcesResponse { success: boolean; data: { channelId: string; channelName: string; tenants: TenantResource[]; summary: ResourceSummary; }; message: string; } interface TenantsResourcesSummaryResponse { success: boolean; data: { channelId: string; channelName: string; channelQuota: ChannelQuota; tenants: TenantResource[]; summary: ResourceSummary; }; message: string; } ``` --- ## 更新日志 ### v1.0.0 (2026-01-13) - 初始版本 - 实现超级管理员查看渠道租户资源分配接口 - 实现渠道管理员查看租户资源分配汇总接口