forked from xiaohei/taiji-AI-PAD
更新租户配额
This commit is contained in:
@@ -0,0 +1,748 @@
|
||||
# 渠道租户资源分配查看接口文档
|
||||
|
||||
> **版本**: 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<TenantsResourcesResponse> {
|
||||
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<TenantsResourcesSummaryResponse> {
|
||||
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)
|
||||
|
||||
- 初始版本
|
||||
- 实现超级管理员查看渠道租户资源分配接口
|
||||
- 实现渠道管理员查看租户资源分配汇总接口
|
||||
|
||||
Reference in New Issue
Block a user