Files
taiji-AI-PAD/Docs/项目文档/计费仪表板概览接口文档.md
T

10 KiB
Raw Blame History

计费仪表板概览接口文档

接口信息

接口路径: GET /api/user/dashboard/billing-overview

功能: 获取用户计费和资源使用的完整仪表板数据

认证: 需要 Bearer Token

权限: 租户用户(user角色)


响应数据结构

完整示例

{
  "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

// 使用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示例

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 未授权

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "未提供有效的认证令牌"
  }
}

500 服务器错误

{
  "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 - 计费历史