186 lines
9.3 KiB
Python
186 lines
9.3 KiB
Python
"""场外基金运营独立持久化模型。"""
|
|
|
|
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
from typing import Any
|
|
|
|
from sqlalchemy import (
|
|
JSON,
|
|
BigInteger,
|
|
Date,
|
|
DateTime,
|
|
Integer,
|
|
Numeric,
|
|
String,
|
|
Text,
|
|
UniqueConstraint,
|
|
)
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.model.base import Base
|
|
|
|
|
|
class OffsiteFundMail(Base):
|
|
__tablename__ = "offsite_fund_mail"
|
|
__table_args__ = (
|
|
UniqueConstraint("imap_uid", "message_id", name="uk_offsite_mail_source"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
mail_id: Mapped[str] = mapped_column(String(16), unique=True, nullable=False)
|
|
imap_uid: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
message_id: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
received_date: Mapped[date] = mapped_column(Date, nullable=False)
|
|
sender: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
return_path: Mapped[str | None] = mapped_column(String(255))
|
|
auth_result: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
original_eml_path: Mapped[str] = mapped_column(String(500), nullable=False)
|
|
status: Mapped[str] = mapped_column(String(32), nullable=False, default="received")
|
|
retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
last_error: Mapped[str | None] = mapped_column(String(500))
|
|
next_retry_at: Mapped[datetime | None] = mapped_column(DateTime)
|
|
last_attempt_at: Mapped[datetime | None] = mapped_column(DateTime)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteMailCursor(Base):
|
|
"""场外收件箱 UID 游标和处理租约。"""
|
|
|
|
__tablename__ = "offsite_mail_cursor"
|
|
__table_args__ = (
|
|
UniqueConstraint("mailbox", "folder", name="uk_offsite_mail_cursor_scope"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(
|
|
BigInteger().with_variant(Integer, "sqlite"), primary_key=True
|
|
)
|
|
mailbox: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
folder: Mapped[str] = mapped_column(String(64), nullable=False, default="INBOX")
|
|
last_uid: Mapped[str] = mapped_column(String(64), nullable=False, default="0")
|
|
status: Mapped[str] = mapped_column(String(32), nullable=False, default="idle")
|
|
retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
blocked_uid: Mapped[str | None] = mapped_column(String(64))
|
|
blocked_message_id: Mapped[str | None] = mapped_column(String(255))
|
|
last_error: Mapped[str | None] = mapped_column(String(500))
|
|
next_retry_at: Mapped[datetime | None] = mapped_column(DateTime)
|
|
lease_id: Mapped[str | None] = mapped_column(String(64))
|
|
lease_until: Mapped[datetime | None] = mapped_column(DateTime)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteFundAttachment(Base):
|
|
__tablename__ = "offsite_fund_attachment"
|
|
__table_args__ = (
|
|
UniqueConstraint("file_hash", "mail_id", name="uk_offsite_attachment_hash"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
attachment_id: Mapped[str] = mapped_column(String(24), unique=True, nullable=False)
|
|
mail_id: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
filename: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
file_hash: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
media_type: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
size_bytes: Mapped[int] = mapped_column(BigInteger, nullable=False, default=0)
|
|
document_type: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
original_file_path: Mapped[str] = mapped_column(String(500), nullable=False)
|
|
ocr_text: Mapped[str] = mapped_column(Text, nullable=False)
|
|
extracted_fields: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
field_confidence: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
page_evidence: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
status: Mapped[str] = mapped_column(String(32), nullable=False, default="recognized")
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteFundDocument(Base):
|
|
__tablename__ = "offsite_fund_document"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
task_id: Mapped[str] = mapped_column(String(24), unique=True, nullable=False)
|
|
mail_id: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
attachment_id: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
document_type: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
fund_code: Mapped[str | None] = mapped_column(String(32))
|
|
fund_name: Mapped[str | None] = mapped_column(String(255))
|
|
account_identifier: Mapped[str | None] = mapped_column(String(128))
|
|
investor_name: Mapped[str | None] = mapped_column(String(128))
|
|
application_no: Mapped[str | None] = mapped_column(String(128))
|
|
application_date: Mapped[date | None] = mapped_column(Date)
|
|
raw_application_date: Mapped[str | None] = mapped_column(String(64))
|
|
agency: Mapped[str | None] = mapped_column(String(128))
|
|
subscription_amount_yuan: Mapped[Decimal | None] = mapped_column(Numeric(20, 4))
|
|
redemption_shares: Mapped[Decimal | None] = mapped_column(Numeric(20, 4))
|
|
operator_decision: Mapped[str] = mapped_column(String(16), nullable=False, default="未处理")
|
|
status: Mapped[str] = mapped_column(String(32), nullable=False, default="planned")
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteExecutionPlanTask(Base):
|
|
__tablename__ = "offsite_execution_plan_task"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
task_id: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
stage: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
title: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
depends_on: Mapped[list[Any]] = mapped_column(JSON, nullable=False)
|
|
input_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
output_json: Mapped[dict[str, Any] | None] = mapped_column(JSON)
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False, default="待执行")
|
|
error_message: Mapped[str | None] = mapped_column(String(500))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteRuleResult(Base):
|
|
__tablename__ = "offsite_rule_result"
|
|
__table_args__ = (
|
|
UniqueConstraint("task_id", "rule_code", name="uk_offsite_rule_task"),
|
|
)
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
task_id: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
rule_name: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
result: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
document_value: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
database_value: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
calculation: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteQueryRecord(Base):
|
|
__tablename__ = "offsite_query_record"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
task_id: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
natural_language_request: Mapped[str] = mapped_column(Text, nullable=False)
|
|
script_path: Mapped[str] = mapped_column(String(500), nullable=False)
|
|
result_summary: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
error_message: Mapped[str | None] = mapped_column(String(500))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
|
|
|
class OffsiteNotification(Base):
|
|
__tablename__ = "offsite_notification"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
|
|
notification_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
business_key: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
receiver_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
operator_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
agent_draft: Mapped[str] = mapped_column(Text, nullable=False)
|
|
final_content: Mapped[str] = mapped_column(Text, nullable=False)
|
|
payload: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False, default="待发送")
|
|
retry_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
provider_message_id: Mapped[str | None] = mapped_column(String(128))
|
|
failure_reason: Mapped[str | None] = mapped_column(String(500))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
sent_at: Mapped[datetime | None] = mapped_column(DateTime)
|
|
updated_at: Mapped[datetime | None] = mapped_column(DateTime)
|