Files
taiji-AI-PAD/Docs/项目文档/计费仪表板概览接口文档.md
T
2026-03-13 02:53:27 +00:00

466 lines
10 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.
# 计费仪表板概览接口文档
## 接口信息
**接口路径**: `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": 50000.0
},
"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余额(1 EU = 1 美元) |
| cash | float | 当前现金余额(美元),与 eu 相等(1 美元 = 1 EU) |
### 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` - 计费历史