feat: 双Token认证(Access 2h/Refresh 7d) + 通知系统(转交/驳回自动推送)

This commit is contained in:
2026-08-07 11:44:04 +08:00
parent dc97a7385f
commit b71c5a2d07
16 changed files with 426 additions and 41 deletions

View File

@ -4,6 +4,7 @@ from app.models.production_order import ProductionOrder
from app.models.product import Product
from app.models.task import Task, TaskRecord
from app.models.task_log import TaskLog
from app.models.notification import Notification
__all__ = [
"Base",
"ProductionOrder",
@ -11,4 +12,5 @@ __all__ = [
"Task",
"TaskRecord",
"TaskLog",
"Notification",
]

View File

@ -0,0 +1,52 @@
"""通知模型 — 任务转交/驳回等事件的消息提醒"""
import uuid
from datetime import datetime
from sqlalchemy import String, DateTime, Boolean, ForeignKey, Text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.models.base import Base
from app.core.time_utils import get_beijing_time
# 通知类型常量
NOTIFY_TRANSFER = "TRANSFER" # 新任务派发/转交
NOTIFY_REJECT = "REJECT" # 品质驳回
class Notification(Base):
__tablename__ = "notifications"
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4,
)
user_id: Mapped[str] = mapped_column(
String(64), nullable=False, index=True, comment="接收人ID(逻辑外键→老系统)",
)
title: Mapped[str] = mapped_column(
String(200), nullable=False, comment="通知标题",
)
content: Mapped[str] = mapped_column(
Text, nullable=False, comment="通知内容详情",
)
type: Mapped[str] = mapped_column(
String(20), nullable=False, comment="通知类型: TRANSFER(转交派发) | REJECT(驳回)",
)
task_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(as_uuid=True), ForeignKey("tasks.id", ondelete="SET NULL"), nullable=True, comment="关联任务ID",
)
is_read: Mapped[bool] = mapped_column(
Boolean, default=False, comment="是否已读",
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=get_beijing_time, comment="创建时间",
)
def __repr__(self) -> str:
return f"<Notification {self.type} → {self.user_id}>"

View File

@ -84,6 +84,7 @@ class Task(Base):
)
child_tasks: Mapped[list["Task"]] = relationship(
"Task", back_populates="parent_task", lazy="selectin",
order_by="Task.created_at",
)
records: Mapped[list["TaskRecord"]] = relationship(
"TaskRecord", back_populates="task", lazy="selectin", cascade="all, delete-orphan",