62 lines
2.9 KiB
Python
62 lines
2.9 KiB
Python
from sqlalchemy import Float, ForeignKey, Index, Integer, String, Text, text
|
||
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
||
from app.models.base import Base, TimestampMixin
|
||
|
||
|
||
class ApiUsageLog(Base, TimestampMixin):
|
||
"""API 调用详细消耗记录表。
|
||
|
||
记录每次 API 请求的完整消费信息,包括:
|
||
- 扣除金额和退回金额
|
||
- 模型详情(名称、分辨率、时长等)
|
||
- 对应的生成任务 ID
|
||
- 操作类型(扣除/退回)
|
||
"""
|
||
|
||
__tablename__ = "api_usage_logs"
|
||
__table_args__ = (
|
||
Index("idx_api_usage_logs_api_key_created", "api_key_id", "created_at"),
|
||
Index("idx_api_usage_logs_task_id", "api_generation_task_id"),
|
||
Index("idx_api_usage_logs_action", "price_action"),
|
||
)
|
||
|
||
id: Mapped[str] = mapped_column(String(32), primary_key=True)
|
||
api_key_id: Mapped[str] = mapped_column(
|
||
String(32), ForeignKey("api_keys.id", ondelete="CASCADE"), nullable=False, index=True
|
||
)
|
||
api_generation_task_id: Mapped[str | None] = mapped_column(
|
||
String(32), ForeignKey("api_generation_tasks.id", ondelete="SET NULL"), nullable=True
|
||
)
|
||
|
||
# === 操作类型 ===
|
||
price_action: Mapped[str] = mapped_column(String(16), nullable=False, comment="deduct=扣除, refund=退回")
|
||
|
||
# === 请求信息 ===
|
||
request_type: Mapped[str] = mapped_column(String(32), nullable=False, comment="video_create|image_generate")
|
||
model_name: Mapped[str] = mapped_column(String(128), nullable=False)
|
||
gen_type: Mapped[str] = mapped_column(String(16), nullable=False)
|
||
resolution: Mapped[str | None] = mapped_column(String(16), nullable=True)
|
||
duration: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||
|
||
# === 金额信息 ===
|
||
credits_cost: Mapped[float] = mapped_column(Float, default=0.0, server_default="0.0", comment="实际扣除金额")
|
||
refund_amount: Mapped[float] = mapped_column(Float, default=0.0, server_default="0.0", comment="退回金额")
|
||
quota_before: Mapped[float | None] = mapped_column(Float, nullable=True, comment="操作前配额余额")
|
||
quota_after: Mapped[float | None] = mapped_column(Float, nullable=True, comment="操作后配额余额")
|
||
|
||
# === Token 用量 ===
|
||
tokens_used: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
|
||
request_duration_ms: Mapped[int] = mapped_column(Integer, default=0, server_default="0", comment="端到端耗时")
|
||
|
||
# === 价格明细(JSON) ===
|
||
price_detail_json: Mapped[str | None] = mapped_column(Text, nullable=True, comment="价格计算明细JSON")
|
||
|
||
# === 结果 ===
|
||
status: Mapped[str] = mapped_column(String(32), nullable=False, comment="success|failed")
|
||
error_message: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||
error_code: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||
|
||
# === 调试 ===
|
||
request_payload_json: Mapped[str | None] = mapped_column(Text, nullable=True, comment="原始请求快照")
|