forked from xiaohei/taiji-AI-PAD
更新agent manager数据接口
This commit is contained in:
@@ -0,0 +1,465 @@
|
||||
# 计费仪表板概览接口文档
|
||||
|
||||
## 接口信息
|
||||
|
||||
**接口路径**: `GET /api/user/dashboard/billing-overview`
|
||||
|
||||
**功能**: 获取用户计费和资源使用的完整仪表板数据
|
||||
|
||||
**认证**: 需要 Bearer Token
|
||||
|
||||
**权限**: 租户用户(user角色)
|
||||
|
||||
---
|
||||
|
||||
## 响应数据结构
|
||||
|
||||
### 完整示例
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "成功获取仪表板数据",
|
||||
"data": {
|
||||
"currentMonth": {
|
||||
"spent": 1250.50,
|
||||
"euConsumed": 12505.0,
|
||||
"avgDailySpent": 125.05,
|
||||
"predictedTotal": 3876.55,
|
||||
"daysElapsed": 10,
|
||||
"totalDays": 31,
|
||||
"currency": "CNY"
|
||||
},
|
||||
"lastMonth": {
|
||||
"spent": 1000.00,
|
||||
"euConsumed": 10000.0
|
||||
},
|
||||
"comparison": {
|
||||
"percentage": 25.1,
|
||||
"direction": "up"
|
||||
},
|
||||
"balance": {
|
||||
"eu": 50000.0,
|
||||
"cash": 5000.00
|
||||
},
|
||||
"euHistory": [
|
||||
{
|
||||
"date": "2026-01-01",
|
||||
"euConsumed": 1200.5,
|
||||
"cost": 120.05,
|
||||
"calls": 150
|
||||
},
|
||||
{
|
||||
"date": "2026-01-02",
|
||||
"euConsumed": 1350.0,
|
||||
"cost": 135.00,
|
||||
"calls": 180
|
||||
}
|
||||
],
|
||||
"costBreakdown": {
|
||||
"categories": [
|
||||
{
|
||||
"category": "platform_agent",
|
||||
"name": "平台Agent",
|
||||
"cost": 450.50,
|
||||
"percentage": 36.0
|
||||
},
|
||||
{
|
||||
"category": "custom_agent",
|
||||
"name": "自定义Agent",
|
||||
"cost": 350.00,
|
||||
"percentage": 28.0
|
||||
},
|
||||
{
|
||||
"category": "model_api",
|
||||
"name": "模型API",
|
||||
"cost": 400.00,
|
||||
"percentage": 32.0
|
||||
},
|
||||
{
|
||||
"category": "other",
|
||||
"name": "其他",
|
||||
"cost": 50.00,
|
||||
"percentage": 4.0
|
||||
}
|
||||
],
|
||||
"total": 1250.50
|
||||
},
|
||||
"resourceUsage": {
|
||||
"resources": [
|
||||
{
|
||||
"type": "cpu",
|
||||
"name": "CPU",
|
||||
"used": 2.5,
|
||||
"limit": 10.0,
|
||||
"unit": "核",
|
||||
"percentage": 25.0
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"name": "内存",
|
||||
"used": 5.0,
|
||||
"limit": 20.0,
|
||||
"unit": "GB",
|
||||
"percentage": 25.0
|
||||
},
|
||||
{
|
||||
"type": "storage",
|
||||
"name": "存储",
|
||||
"used": 0,
|
||||
"limit": 1000,
|
||||
"unit": "GB",
|
||||
"percentage": 0.0
|
||||
},
|
||||
{
|
||||
"type": "api_calls",
|
||||
"name": "API调用",
|
||||
"used": 15000,
|
||||
"limit": 100000,
|
||||
"unit": "次",
|
||||
"percentage": 15.0
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"timestamp": "2026-01-10T12:30:45.123456",
|
||||
"userId": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 数据字段说明
|
||||
|
||||
### currentMonth (当前月份统计)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| spent | float | 本月已消费金额(CNY) |
|
||||
| euConsumed | float | 本月已消费EU(执行单位) |
|
||||
| avgDailySpent | float | 平均每日消费金额 |
|
||||
| predictedTotal | float | 预计月底总消费(基于日均值) |
|
||||
| daysElapsed | int | 本月已过天数 |
|
||||
| totalDays | int | 本月总天数 |
|
||||
| currency | string | 货币类型(CNY) |
|
||||
|
||||
### lastMonth (上月统计)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| spent | float | 上月总消费金额 |
|
||||
| euConsumed | float | 上月总消费EU |
|
||||
|
||||
### comparison (对比数据)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| percentage | float | 与上月对比的百分比变化 |
|
||||
| direction | string | 趋势方向:`up`(上升)、`down`(下降)、`stable`(持平) |
|
||||
|
||||
### balance (余额信息)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| eu | float | 当前EU余额 |
|
||||
| cash | float | 当前现金余额(CNY) |
|
||||
|
||||
### euHistory (EU消费历史)
|
||||
|
||||
数组,每个元素包含:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| date | string | 日期(ISO格式:YYYY-MM-DD) |
|
||||
| euConsumed | float | 当日消费的EU |
|
||||
| cost | float | 当日费用 |
|
||||
| calls | int | 当日调用次数 |
|
||||
|
||||
**时间范围**: 最近30天的数据
|
||||
|
||||
### costBreakdown (费用明细)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| categories | array | 费用分类数组 |
|
||||
| total | float | 总费用 |
|
||||
|
||||
**categories数组元素**:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| category | string | 分类标识:`platform_agent`、`custom_agent`、`model_api`、`other` |
|
||||
| name | string | 分类名称 |
|
||||
| cost | float | 该分类的费用 |
|
||||
| percentage | float | 占总费用的百分比 |
|
||||
|
||||
### resourceUsage (资源使用)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| resources | array | 资源使用数组 |
|
||||
|
||||
**resources数组元素**:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| type | string | 资源类型:`cpu`、`memory`、`storage`、`api_calls` |
|
||||
| name | string | 资源名称 |
|
||||
| used | float/int | 已使用量 |
|
||||
| limit | float/int | 配额上限 |
|
||||
| unit | string | 单位:`核`、`GB`、`次` |
|
||||
| percentage | float | 使用百分比 |
|
||||
|
||||
### metadata (元数据)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| timestamp | string | 数据生成时间(ISO 8601格式) |
|
||||
| userId | string | 用户ID(UUID格式) |
|
||||
|
||||
---
|
||||
|
||||
## 前端调用示例
|
||||
|
||||
### JavaScript/TypeScript
|
||||
|
||||
```javascript
|
||||
// 使用fetch
|
||||
async function getBillingOverview() {
|
||||
try {
|
||||
const response = await fetch('/api/user/dashboard/billing-overview', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
return data.data;
|
||||
} else {
|
||||
throw new Error(data.message || '获取数据失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取计费概览失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用axios
|
||||
import axios from 'axios';
|
||||
|
||||
async function getBillingOverviewAxios() {
|
||||
try {
|
||||
const response = await axios.get('/api/user/dashboard/billing-overview', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
return response.data.data;
|
||||
} catch (error) {
|
||||
console.error('获取计费概览失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### React示例
|
||||
|
||||
```typescript
|
||||
import { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
|
||||
interface BillingOverview {
|
||||
currentMonth: {
|
||||
spent: number;
|
||||
euConsumed: number;
|
||||
avgDailySpent: number;
|
||||
predictedTotal: number;
|
||||
daysElapsed: number;
|
||||
totalDays: number;
|
||||
currency: string;
|
||||
};
|
||||
lastMonth: {
|
||||
spent: number;
|
||||
euConsumed: number;
|
||||
};
|
||||
comparison: {
|
||||
percentage: number;
|
||||
direction: 'up' | 'down' | 'stable';
|
||||
};
|
||||
balance: {
|
||||
eu: number;
|
||||
cash: number;
|
||||
};
|
||||
euHistory: Array<{
|
||||
date: string;
|
||||
euConsumed: number;
|
||||
cost: number;
|
||||
calls: number;
|
||||
}>;
|
||||
costBreakdown: {
|
||||
categories: Array<{
|
||||
category: string;
|
||||
name: string;
|
||||
cost: number;
|
||||
percentage: number;
|
||||
}>;
|
||||
total: number;
|
||||
};
|
||||
resourceUsage: {
|
||||
resources: Array<{
|
||||
type: string;
|
||||
name: string;
|
||||
used: number;
|
||||
limit: number;
|
||||
unit: string;
|
||||
percentage: number;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
function BillingDashboard() {
|
||||
const [overview, setOverview] = useState<BillingOverview | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await axios.get('/api/user/dashboard/billing-overview', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
setOverview(response.data.data);
|
||||
} else {
|
||||
setError(response.data.message || '获取数据失败');
|
||||
}
|
||||
} catch (err) {
|
||||
setError('网络请求失败');
|
||||
console.error(err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
if (loading) return <div>加载中...</div>;
|
||||
if (error) return <div>错误: {error}</div>;
|
||||
if (!overview) return <div>暂无数据</div>;
|
||||
|
||||
return (
|
||||
<div className="billing-dashboard">
|
||||
{/* 本月费用 */}
|
||||
<div className="current-month">
|
||||
<h2>本月费用</h2>
|
||||
<p>已消费: ¥{overview.currentMonth.spent.toFixed(2)}</p>
|
||||
<p>平均每日: ¥{overview.currentMonth.avgDailySpent.toFixed(2)}</p>
|
||||
<p>预计月底: ¥{overview.currentMonth.predictedTotal.toFixed(2)}</p>
|
||||
</div>
|
||||
|
||||
{/* EU消费历史图表 */}
|
||||
<div className="eu-history">
|
||||
<h2>EU消费历史</h2>
|
||||
{/* 这里可以使用图表库如Chart.js、ECharts等 */}
|
||||
{overview.euHistory.map(item => (
|
||||
<div key={item.date}>
|
||||
{item.date}: {item.euConsumed} EU
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 费用明细 */}
|
||||
<div className="cost-breakdown">
|
||||
<h2>费用明细</h2>
|
||||
{overview.costBreakdown.categories.map(cat => (
|
||||
<div key={cat.category}>
|
||||
{cat.name}: ¥{cat.cost.toFixed(2)} ({cat.percentage.toFixed(1)}%)
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 资源使用 */}
|
||||
<div className="resource-usage">
|
||||
<h2>资源使用</h2>
|
||||
{overview.resourceUsage.resources.map(res => (
|
||||
<div key={res.type}>
|
||||
<div>{res.name}</div>
|
||||
<progress value={res.percentage} max={100}></progress>
|
||||
<span>{res.used} / {res.limit} {res.unit}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BillingDashboard;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 错误响应
|
||||
|
||||
### 401 未授权
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "UNAUTHORIZED",
|
||||
"message": "未提供有效的认证令牌"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 500 服务器错误
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "INTERNAL_ERROR",
|
||||
"message": "服务器内部错误"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
1. **缓存策略**: 建议前端缓存数据5分钟,避免频繁请求
|
||||
2. **按需加载**: 可以考虑将历史数据单独请求
|
||||
3. **数据轮询**: 如需实时更新,建议轮询间隔不少于30秒
|
||||
|
||||
---
|
||||
|
||||
## 更新日志
|
||||
|
||||
| 版本 | 日期 | 说明 |
|
||||
|------|------|------|
|
||||
| v1.0.0 | 2026-01-10 | 初始版本,实现完整仪表板数据接口 |
|
||||
|
||||
---
|
||||
|
||||
## 相关接口
|
||||
|
||||
- `GET /api/user/dashboard/stats` - 基础仪表板统计
|
||||
- `GET /api/user/billing/balance` - 余额查询
|
||||
- `GET /api/user/billing/history` - 计费历史
|
||||
Reference in New Issue
Block a user