forked from xiaohei/taiji-AI-PAD
更新超级管理查看资源分配
This commit is contained in:
@@ -0,0 +1,676 @@
|
||||
# 超级管理员查看渠道资源分配接口文档
|
||||
|
||||
> **版本**: v1.0.0
|
||||
> **更新时间**: 2026-01-13
|
||||
> **说明**: 超级管理员查看渠道已分配的资源详情,包括自定义Agent、平台Agent、模型供应商、模型等
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [接口概述](#接口概述)
|
||||
2. [接口详情](#接口详情)
|
||||
3. [数据结构说明](#数据结构说明)
|
||||
4. [使用场景](#使用场景)
|
||||
5. [前端调用示例](#前端调用示例)
|
||||
|
||||
---
|
||||
|
||||
## 接口概述
|
||||
|
||||
| 接口 | 路径 | 方法 | 权限 | 说明 |
|
||||
|------|------|------|------|------|
|
||||
| 查看渠道资源分配详情 | `/api/admin/channels/{channel_id}/allocated-resources` | GET | super_admin, billing_admin, operations_admin | 查看指定渠道被分配的所有资源详情 |
|
||||
|
||||
### 权限说明
|
||||
|
||||
- **super_admin**: 可查看所有渠道的资源分配
|
||||
- **billing_admin / operations_admin**: 可查看所有渠道的资源分配
|
||||
|
||||
---
|
||||
|
||||
## 接口详情
|
||||
|
||||
### 基本信息
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|-----|
|
||||
| **接口路径** | `GET /api/admin/channels/{channel_id}/allocated-resources` |
|
||||
| **后端文件** | `services/mcp-server/app/routes/admin.py` |
|
||||
| **后端状态** | ✅ 已实现 |
|
||||
| **权限要求** | super_admin, billing_admin, operations_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/allocated-resources" \
|
||||
-H "Authorization: Bearer $SUPER_ADMIN_TOKEN"
|
||||
```
|
||||
|
||||
### 响应参数
|
||||
|
||||
#### 成功响应 (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"channelId": "string (UUID)",
|
||||
"channelName": "string",
|
||||
"channelEmail": "string",
|
||||
"channelStatus": "string",
|
||||
"createdAt": "string (ISO 8601)",
|
||||
"channelCredit": "number",
|
||||
"commissionRate": "number",
|
||||
"customAgentQuota": {
|
||||
"cpuQuota": "number",
|
||||
"memoryQuota": "number",
|
||||
"cpuAllocatedToTenants": "number",
|
||||
"memoryAllocatedToTenants": "number",
|
||||
"cpuAvailable": "number",
|
||||
"memoryAvailable": "number"
|
||||
} | null,
|
||||
"platformAgents": [
|
||||
{
|
||||
"templateName": "string",
|
||||
"templateDisplayName": "string",
|
||||
"podQuota": "integer",
|
||||
"podUsed": "integer",
|
||||
"podAllocatedToTenants": "integer",
|
||||
"podAvailable": "integer",
|
||||
"cpuPerPod": "string",
|
||||
"memoryPerPod": "string",
|
||||
"allocatedAt": "string (ISO 8601)"
|
||||
}
|
||||
],
|
||||
"modelProviders": [
|
||||
{
|
||||
"providerId": "string (UUID)",
|
||||
"providerName": "string",
|
||||
"providerType": "string",
|
||||
"status": "string",
|
||||
"models": [
|
||||
{
|
||||
"modelName": "string",
|
||||
"rpmLimit": "integer",
|
||||
"tpmLimit": "integer",
|
||||
"maxBudget": "number | null",
|
||||
"budgetDuration": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"models": [
|
||||
{
|
||||
"modelName": "string",
|
||||
"providerName": "string | null",
|
||||
"rpmLimit": "integer",
|
||||
"tpmLimit": "integer",
|
||||
"maxBudget": "number | null",
|
||||
"budgetDuration": "string",
|
||||
"allocatedToTenants": "integer"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"totalCustomAgentCpuQuota": "number",
|
||||
"totalCustomAgentMemoryQuota": "number",
|
||||
"totalPlatformAgentPodQuota": "integer",
|
||||
"totalPlatformAgentPodUsed": "integer",
|
||||
"totalModelProviders": "integer",
|
||||
"totalModels": "integer",
|
||||
"totalTenantsWithResources": "integer"
|
||||
}
|
||||
},
|
||||
"message": "获取渠道资源分配详情成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应字段说明
|
||||
|
||||
| 字段路径 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `data.channelId` | string | 渠道ID |
|
||||
| `data.channelName` | string | 渠道名称 |
|
||||
| `data.channelEmail` | string | 渠道邮箱 |
|
||||
| `data.channelStatus` | string | 渠道状态 (active/inactive/suspended) |
|
||||
| `data.createdAt` | string | 渠道创建时间 (ISO 8601格式) |
|
||||
| `data.channelCredit` | number | 渠道信用额度 |
|
||||
| `data.commissionRate` | number | 渠道佣金比例 |
|
||||
|
||||
**自定义Agent配额 (customAgentQuota)**
|
||||
|
||||
| 字段路径 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `cpuQuota` | number | CPU配额上限(核心数) |
|
||||
| `memoryQuota` | number | 内存配额上限(GB) |
|
||||
| `cpuAllocatedToTenants` | number | 已分配给租户的CPU(核心数) |
|
||||
| `memoryAllocatedToTenants` | number | 已分配给租户的内存(GB) |
|
||||
| `cpuAvailable` | number | 剩余可分配CPU(核心数) |
|
||||
| `memoryAvailable` | number | 剩余可分配内存(GB) |
|
||||
|
||||
**平台Agent配额 (platformAgents)**
|
||||
|
||||
| 字段路径 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `templateName` | string | 模板技术名称 (如 echo_agent) |
|
||||
| `templateDisplayName` | string | 模板显示名称 (如 Echo测试服务) |
|
||||
| `podQuota` | integer | 该模板的Pod配额数量 |
|
||||
| `podUsed` | integer | 已使用的Pod数量(运行中) |
|
||||
| `podAllocatedToTenants` | integer | 已分配给租户的Pod数量 |
|
||||
| `podAvailable` | integer | 剩余可分配Pod数量 |
|
||||
| `cpuPerPod` | string | 每个Pod的CPU配置 (如 100m) |
|
||||
| `memoryPerPod` | string | 每个Pod的内存配置 (如 256Mi) |
|
||||
| `allocatedAt` | string | 分配时间 (ISO 8601格式) |
|
||||
|
||||
**模型供应商 (modelProviders)**
|
||||
|
||||
| 字段路径 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `providerId` | string | 供应商ID |
|
||||
| `providerName` | string | 供应商名称 (如 OpenAI、Anthropic) |
|
||||
| `providerType` | string | 供应商类型 (如 openai、anthropic) |
|
||||
| `status` | string | 供应商状态 (active/inactive) |
|
||||
| `models` | array | 该供应商下的模型列表 |
|
||||
|
||||
**模型配额 (models)**
|
||||
|
||||
| 字段路径 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `modelName` | string | 模型全名 (如 taiji/gpt-4o) |
|
||||
| `providerName` | string/null | 所属供应商名称 |
|
||||
| `rpmLimit` | integer | RPM限制(每分钟请求数) |
|
||||
| `tpmLimit` | integer | TPM限制(每分钟Token数) |
|
||||
| `maxBudget` | number/null | 最大预算限额 |
|
||||
| `budgetDuration` | string | 预算周期 (monthly/daily) |
|
||||
| `allocatedToTenants` | integer | 已分配给租户的数量 |
|
||||
|
||||
**汇总统计 (summary)**
|
||||
|
||||
| 字段路径 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `totalCustomAgentCpuQuota` | number | 自定义Agent总CPU配额 |
|
||||
| `totalCustomAgentMemoryQuota` | number | 自定义Agent总内存配额 |
|
||||
| `totalPlatformAgentPodQuota` | integer | 平台Agent总Pod配额 |
|
||||
| `totalPlatformAgentPodUsed` | integer | 平台Agent已使用Pod数 |
|
||||
| `totalModelProviders` | integer | 模型供应商数量 |
|
||||
| `totalModels` | integer | 模型总数 |
|
||||
| `totalTenantsWithResources` | integer | 有资源分配的租户数 |
|
||||
|
||||
### 实际响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"channelId": "6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6",
|
||||
"channelName": "示例渠道",
|
||||
"channelEmail": "channel@example.com",
|
||||
"channelStatus": "active",
|
||||
"createdAt": "2026-01-01T00:00:00.000000",
|
||||
"channelCredit": 100000.0,
|
||||
"commissionRate": 0.15,
|
||||
"customAgentQuota": {
|
||||
"cpuQuota": 20.0,
|
||||
"memoryQuota": 40.0,
|
||||
"cpuAllocatedToTenants": 12.0,
|
||||
"memoryAllocatedToTenants": 24.0,
|
||||
"cpuAvailable": 8.0,
|
||||
"memoryAvailable": 16.0
|
||||
},
|
||||
"platformAgents": [
|
||||
{
|
||||
"templateName": "echo_agent",
|
||||
"templateDisplayName": "Echo 测试服务",
|
||||
"podQuota": 10,
|
||||
"podUsed": 3,
|
||||
"podAllocatedToTenants": 6,
|
||||
"podAvailable": 4,
|
||||
"cpuPerPod": "100m",
|
||||
"memoryPerPod": "256Mi",
|
||||
"allocatedAt": "2026-01-05T10:30:00.000000"
|
||||
},
|
||||
{
|
||||
"templateName": "code_agent",
|
||||
"templateDisplayName": "代码执行服务",
|
||||
"podQuota": 5,
|
||||
"podUsed": 2,
|
||||
"podAllocatedToTenants": 3,
|
||||
"podAvailable": 2,
|
||||
"cpuPerPod": "200m",
|
||||
"memoryPerPod": "512Mi",
|
||||
"allocatedAt": "2026-01-06T14:20:00.000000"
|
||||
}
|
||||
],
|
||||
"modelProviders": [
|
||||
{
|
||||
"providerId": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"providerName": "OpenAI",
|
||||
"providerType": "openai",
|
||||
"status": "active",
|
||||
"models": [
|
||||
{
|
||||
"modelName": "taiji/gpt-4o",
|
||||
"rpmLimit": 1000,
|
||||
"tpmLimit": 100000,
|
||||
"maxBudget": 5000.0,
|
||||
"budgetDuration": "monthly"
|
||||
},
|
||||
{
|
||||
"modelName": "taiji/gpt-4o-mini",
|
||||
"rpmLimit": 2000,
|
||||
"tpmLimit": 200000,
|
||||
"maxBudget": 2000.0,
|
||||
"budgetDuration": "monthly"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"providerId": "660e8400-e29b-41d4-a716-446655440001",
|
||||
"providerName": "Anthropic",
|
||||
"providerType": "anthropic",
|
||||
"status": "active",
|
||||
"models": [
|
||||
{
|
||||
"modelName": "taiji/claude-3-opus",
|
||||
"rpmLimit": 500,
|
||||
"tpmLimit": 50000,
|
||||
"maxBudget": 10000.0,
|
||||
"budgetDuration": "monthly"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"models": [
|
||||
{
|
||||
"modelName": "taiji/gpt-4o",
|
||||
"providerName": "OpenAI",
|
||||
"rpmLimit": 1000,
|
||||
"tpmLimit": 100000,
|
||||
"maxBudget": 5000.0,
|
||||
"budgetDuration": "monthly",
|
||||
"allocatedToTenants": 3
|
||||
},
|
||||
{
|
||||
"modelName": "taiji/gpt-4o-mini",
|
||||
"providerName": "OpenAI",
|
||||
"rpmLimit": 2000,
|
||||
"tpmLimit": 200000,
|
||||
"maxBudget": 2000.0,
|
||||
"budgetDuration": "monthly",
|
||||
"allocatedToTenants": 5
|
||||
},
|
||||
{
|
||||
"modelName": "taiji/claude-3-opus",
|
||||
"providerName": "Anthropic",
|
||||
"rpmLimit": 500,
|
||||
"tpmLimit": 50000,
|
||||
"maxBudget": 10000.0,
|
||||
"budgetDuration": "monthly",
|
||||
"allocatedToTenants": 2
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"totalCustomAgentCpuQuota": 20.0,
|
||||
"totalCustomAgentMemoryQuota": 40.0,
|
||||
"totalPlatformAgentPodQuota": 15,
|
||||
"totalPlatformAgentPodUsed": 5,
|
||||
"totalModelProviders": 2,
|
||||
"totalModels": 3,
|
||||
"totalTenantsWithResources": 5
|
||||
}
|
||||
},
|
||||
"message": "获取渠道资源分配详情成功"
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
|
||||
| HTTP状态码 | 错误说明 | 响应示例 |
|
||||
|------------|----------|----------|
|
||||
| 400 | 无效的渠道ID格式 | `{"success": false, "detail": "无效的渠道ID格式"}` |
|
||||
| 403 | 权限不足 | `{"success": false, "detail": "权限不足,无法查看渠道资源"}` |
|
||||
| 404 | 渠道不存在 | `{"success": false, "detail": "渠道不存在"}` |
|
||||
|
||||
---
|
||||
|
||||
## 数据结构说明
|
||||
|
||||
### 渠道状态 (channelStatus)
|
||||
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| `active` | 活跃状态 |
|
||||
| `inactive` | 已停用 |
|
||||
| `suspended` | 已暂停 |
|
||||
|
||||
### 供应商状态 (status)
|
||||
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| `active` | 正常可用 |
|
||||
| `inactive` | 已停用 |
|
||||
| `error` | 连接异常 |
|
||||
|
||||
### 预算周期 (budgetDuration)
|
||||
|
||||
| 值 | 说明 |
|
||||
|----|------|
|
||||
| `monthly` | 月度预算 |
|
||||
| `daily` | 每日预算 |
|
||||
|
||||
### CPU/内存格式
|
||||
|
||||
| 格式 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| CPU (millicores) | Kubernetes CPU格式 | `100m` = 0.1核, `500m` = 0.5核 |
|
||||
| Memory (MiB/GiB) | Kubernetes 内存格式 | `256Mi` = 256MB, `2Gi` = 2GB |
|
||||
|
||||
---
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景1: 超级管理员审查渠道资源配置
|
||||
|
||||
超级管理员需要全面了解某个渠道被分配了哪些资源,以及这些资源的使用情况。
|
||||
|
||||
```bash
|
||||
# 查看渠道 "示例渠道" 的所有资源分配
|
||||
curl -X GET "http://localhost:8002/api/admin/channels/6e6fc470-76f8-4bb1-8ea4-625dc5b12bc6/allocated-resources" \
|
||||
-H "Authorization: Bearer $SUPER_ADMIN_TOKEN"
|
||||
```
|
||||
|
||||
### 场景2: 资源规划与调配
|
||||
|
||||
通过查看各渠道的资源分配和使用情况,进行合理的资源规划:
|
||||
|
||||
- **查看自定义Agent配额使用率**: `cpuAllocatedToTenants / cpuQuota`
|
||||
- **查看平台Agent使用率**: `podUsed / podQuota`
|
||||
- **了解模型分配情况**: 通过 `allocatedToTenants` 了解每个模型被多少租户使用
|
||||
|
||||
### 场景3: 计费审计
|
||||
|
||||
计费管理员可以通过此接口了解渠道的资源配置和信用额度,辅助计费审计工作。
|
||||
|
||||
---
|
||||
|
||||
## 前端调用示例
|
||||
|
||||
### JavaScript/TypeScript
|
||||
|
||||
```typescript
|
||||
interface CustomAgentQuota {
|
||||
cpuQuota: number;
|
||||
memoryQuota: number;
|
||||
cpuAllocatedToTenants: number;
|
||||
memoryAllocatedToTenants: number;
|
||||
cpuAvailable: number;
|
||||
memoryAvailable: number;
|
||||
}
|
||||
|
||||
interface PlatformAgentQuota {
|
||||
templateName: string;
|
||||
templateDisplayName: string;
|
||||
podQuota: number;
|
||||
podUsed: number;
|
||||
podAllocatedToTenants: number;
|
||||
podAvailable: number;
|
||||
cpuPerPod: string;
|
||||
memoryPerPod: string;
|
||||
allocatedAt: string;
|
||||
}
|
||||
|
||||
interface ModelInfo {
|
||||
modelName: string;
|
||||
rpmLimit: number;
|
||||
tpmLimit: number;
|
||||
maxBudget: number | null;
|
||||
budgetDuration: string;
|
||||
}
|
||||
|
||||
interface ModelProviderInfo {
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
providerType: string;
|
||||
status: string;
|
||||
models: ModelInfo[];
|
||||
}
|
||||
|
||||
interface ChannelModelInfo extends ModelInfo {
|
||||
providerName: string | null;
|
||||
allocatedToTenants: number;
|
||||
}
|
||||
|
||||
interface ResourceSummary {
|
||||
totalCustomAgentCpuQuota: number;
|
||||
totalCustomAgentMemoryQuota: number;
|
||||
totalPlatformAgentPodQuota: number;
|
||||
totalPlatformAgentPodUsed: number;
|
||||
totalModelProviders: number;
|
||||
totalModels: number;
|
||||
totalTenantsWithResources: number;
|
||||
}
|
||||
|
||||
interface ChannelAllocatedResources {
|
||||
channelId: string;
|
||||
channelName: string;
|
||||
channelEmail: string;
|
||||
channelStatus: string;
|
||||
createdAt: string;
|
||||
channelCredit: number;
|
||||
commissionRate: number;
|
||||
customAgentQuota: CustomAgentQuota | null;
|
||||
platformAgents: PlatformAgentQuota[];
|
||||
modelProviders: ModelProviderInfo[];
|
||||
models: ChannelModelInfo[];
|
||||
summary: ResourceSummary;
|
||||
}
|
||||
|
||||
interface ChannelAllocatedResourcesResponse {
|
||||
success: boolean;
|
||||
data: ChannelAllocatedResources;
|
||||
message: string;
|
||||
}
|
||||
|
||||
// API 调用函数
|
||||
async function getChannelAllocatedResources(channelId: string): Promise<ChannelAllocatedResourcesResponse> {
|
||||
const response = await fetch(
|
||||
`${API_BASE_URL}/api/admin/channels/${channelId}/allocated-resources`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
async function displayChannelResources(channelId: string) {
|
||||
try {
|
||||
const result = await getChannelAllocatedResources(channelId);
|
||||
|
||||
if (result.success) {
|
||||
const { data } = result;
|
||||
|
||||
console.log(`渠道: ${data.channelName}`);
|
||||
console.log(`状态: ${data.channelStatus}`);
|
||||
console.log(`信用额度: ¥${data.channelCredit}`);
|
||||
|
||||
// 自定义Agent配额
|
||||
if (data.customAgentQuota) {
|
||||
const { cpuQuota, cpuAllocatedToTenants, memoryQuota, memoryAllocatedToTenants } = data.customAgentQuota;
|
||||
console.log(`自定义Agent CPU: ${cpuAllocatedToTenants}/${cpuQuota} 核`);
|
||||
console.log(`自定义Agent 内存: ${memoryAllocatedToTenants}/${memoryQuota} GB`);
|
||||
}
|
||||
|
||||
// 平台Agent配额
|
||||
console.log(`平台Agent模板数: ${data.platformAgents.length}`);
|
||||
data.platformAgents.forEach(agent => {
|
||||
console.log(` - ${agent.templateDisplayName}: ${agent.podUsed}/${agent.podQuota} Pods`);
|
||||
});
|
||||
|
||||
// 模型统计
|
||||
console.log(`模型供应商数: ${data.summary.totalModelProviders}`);
|
||||
console.log(`模型总数: ${data.summary.totalModels}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取渠道资源失败:', error);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### React Hook 示例
|
||||
|
||||
```typescript
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
function useChannelAllocatedResources(channelId: string | null) {
|
||||
const [data, setData] = useState<ChannelAllocatedResources | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!channelId) return;
|
||||
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const result = await getChannelAllocatedResources(channelId);
|
||||
if (result.success) {
|
||||
setData(result.data);
|
||||
} else {
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err : new Error('Unknown error'));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [channelId]);
|
||||
|
||||
return { data, loading, error };
|
||||
}
|
||||
|
||||
// 组件使用
|
||||
function ChannelResourcesPanel({ channelId }: { channelId: string }) {
|
||||
const { data, loading, error } = useChannelAllocatedResources(channelId);
|
||||
|
||||
if (loading) return <div>加载中...</div>;
|
||||
if (error) return <div>错误: {error.message}</div>;
|
||||
if (!data) return null;
|
||||
|
||||
return (
|
||||
<div className="channel-resources">
|
||||
<h2>{data.channelName} - 资源分配详情</h2>
|
||||
|
||||
{/* 自定义Agent配额卡片 */}
|
||||
{data.customAgentQuota && (
|
||||
<ResourceCard title="自定义Agent配额">
|
||||
<ProgressBar
|
||||
label="CPU"
|
||||
used={data.customAgentQuota.cpuAllocatedToTenants}
|
||||
total={data.customAgentQuota.cpuQuota}
|
||||
unit="核"
|
||||
/>
|
||||
<ProgressBar
|
||||
label="内存"
|
||||
used={data.customAgentQuota.memoryAllocatedToTenants}
|
||||
total={data.customAgentQuota.memoryQuota}
|
||||
unit="GB"
|
||||
/>
|
||||
</ResourceCard>
|
||||
)}
|
||||
|
||||
{/* 平台Agent配额列表 */}
|
||||
<ResourceCard title="平台Agent配额">
|
||||
{data.platformAgents.map(agent => (
|
||||
<div key={agent.templateName}>
|
||||
<span>{agent.templateDisplayName}</span>
|
||||
<ProgressBar
|
||||
label="Pods"
|
||||
used={agent.podUsed}
|
||||
total={agent.podQuota}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</ResourceCard>
|
||||
|
||||
{/* 模型列表 */}
|
||||
<ResourceCard title="模型配额">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>模型</th>
|
||||
<th>供应商</th>
|
||||
<th>RPM</th>
|
||||
<th>TPM</th>
|
||||
<th>已分配租户</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.models.map(model => (
|
||||
<tr key={model.modelName}>
|
||||
<td>{model.modelName}</td>
|
||||
<td>{model.providerName || '-'}</td>
|
||||
<td>{model.rpmLimit}</td>
|
||||
<td>{model.tpmLimit}</td>
|
||||
<td>{model.allocatedToTenants}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</ResourceCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与现有接口的对比
|
||||
|
||||
| 特性 | 现有接口 `/api/admin/channels/{channel_id}/resources` | 新接口 `/api/admin/channels/{channel_id}/allocated-resources` |
|
||||
|------|------------------------------------------------------|---------------------------------------------------------------|
|
||||
| 自定义Agent配额 | 只有配额总量 | 配额+已分配+可用量 |
|
||||
| 平台Agent | 只有Agent列表 | 每个模板的配额详情+使用情况 |
|
||||
| 模型信息 | 只有模型名称列表 | 供应商+模型+RPM/TPM限制+分配情况 |
|
||||
| 渠道信息 | 无 | 包含渠道基本信息 |
|
||||
| 汇总统计 | 无 | 完整的资源汇总统计 |
|
||||
|
||||
---
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.0.0 (2026-01-13)
|
||||
|
||||
- 初始版本
|
||||
- 实现超级管理员查看渠道资源分配详情接口
|
||||
- 支持自定义Agent、平台Agent、模型供应商、模型的完整资源查看
|
||||
- 包含资源使用率和分配统计
|
||||
|
||||
Reference in New Issue
Block a user