diff --git a/video-gen-api/app/api/v1/notifications.py b/video-gen-api/app/api/v1/notifications.py index 9f52748f..114c0232 100644 --- a/video-gen-api/app/api/v1/notifications.py +++ b/video-gen-api/app/api/v1/notifications.py @@ -8,7 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_db, get_current_user from app.models.user import User from app.models.notification import Notification -from app.schemas.notification import NotificationOut, NotificationListOut, UnreadCountOut +from app.schemas.notification import NotificationListOut, NotificationCreditsOut, UnreadCountOut from app.services.auth import decode_access_token from app.services.notification import ( get_notifications, @@ -112,7 +112,8 @@ async def list_notifications( db: AsyncSession = Depends(get_db), ): items, total = await get_notifications(db, current_user.id, page, page_size, is_read) - return {"items": items, "total": total} + credits = NotificationCreditsOut(balance=round(float(current_user.credits or 0.0), 2)) + return {"items": items, "total": total, "credits": credits} @router.put("/{notification_id}/read") diff --git a/video-gen-api/app/enums/__init__.py b/video-gen-api/app/enums/__init__.py index 09dc9cb9..f326ab29 100644 --- a/video-gen-api/app/enums/__init__.py +++ b/video-gen-api/app/enums/__init__.py @@ -10,3 +10,4 @@ from app.enums.generation_task import * from app.enums.recent_generation import * from app.enums.generation_status import * from app.enums.sms import * +from app.enums.notification import * diff --git a/video-gen-api/app/enums/notification.py b/video-gen-api/app/enums/notification.py new file mode 100644 index 00000000..ab8be2ce --- /dev/null +++ b/video-gen-api/app/enums/notification.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +from enum import StrEnum + + +class NotificationType(StrEnum): + """通知类型。""" + + SYSTEM = "system" + CREDIT = "credit" + VIDEO = "video" + GENERATION = "generation" + PAYMENT = "payment" + RECHARGE = "recharge" + UNKNOWN = "unknown" + + +NOTIFICATION_TYPE_LABELS = { + NotificationType.SYSTEM.value: "系统通知", + NotificationType.CREDIT.value: "积分通知", + NotificationType.VIDEO.value: "视频通知", + NotificationType.GENERATION.value: "生成通知", + NotificationType.PAYMENT.value: "支付通知", + NotificationType.RECHARGE.value: "充值通知", + NotificationType.UNKNOWN.value: "未知通知", +} diff --git a/video-gen-api/app/schemas/notification.py b/video-gen-api/app/schemas/notification.py index 93d2f272..4ccf374f 100644 --- a/video-gen-api/app/schemas/notification.py +++ b/video-gen-api/app/schemas/notification.py @@ -1,22 +1,45 @@ -from pydantic import BaseModel +from __future__ import annotations +from pydantic import BaseModel, Field, field_validator + +from app.enums.notification import NotificationType from app.schemas.common import NaiveDatetime +class NotificationCreditsOut(BaseModel): + """通知轮询接口携带的当前用户积分信息。""" + + balance: float = Field(..., description="当前用户最新积分余额") + + class NotificationOut(BaseModel): id: str title: str content: str - type: str + type: NotificationType is_read: bool created_at: NaiveDatetime + @field_validator("type", mode="before") + @classmethod + def normalize_type(cls, value): + """兼容历史数据或后台自定义通知类型,避免响应模型校验失败。""" + if isinstance(value, NotificationType): + return value + if value is None: + return NotificationType.UNKNOWN + try: + return NotificationType(str(value)) + except ValueError: + return NotificationType.UNKNOWN + model_config = {"from_attributes": True} class NotificationListOut(BaseModel): items: list[NotificationOut] total: int + credits: NotificationCreditsOut class UnreadCountOut(BaseModel):