Files
taiji-AI-PAD/Docs/项目文档/超级管理员查看渠道资源分配接口文档.md
T

677 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 超级管理员查看渠道资源分配接口文档
> **版本**: 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、模型供应商、模型的完整资源查看
- 包含资源使用率和分配统计