dingdanquanliucheng/backend/app/models/business.py

221 lines
12 KiB
Python
Raw Normal View History

from sqlalchemy import Date, DateTime, ForeignKey, Numeric, String, Text, func
2026-05-14 10:15:51 +08:00
from sqlalchemy.orm import Mapped, mapped_column
2026-05-14 13:51:06 +08:00
from backend.app.db import Base
from backend.app.models.base import AuditMixin, TimestampMixin
2026-05-14 10:15:51 +08:00
2026-05-14 13:51:06 +08:00
class Customer(TimestampMixin, AuditMixin, Base):
__tablename__ = "customer"
2026-05-14 10:15:51 +08:00
2026-05-14 13:51:06 +08:00
id: Mapped[int] = mapped_column(primary_key=True)
customer_name: Mapped[str] = mapped_column(String(64), index=True)
mobile: Mapped[str] = mapped_column(String(32), index=True)
address: Mapped[str | None] = mapped_column(String(255), nullable=True)
settlement_type: Mapped[str | None] = mapped_column(String(32), nullable=True)
settlement_days: Mapped[int] = mapped_column(default=0)
customer_type: Mapped[str | None] = mapped_column(String(32), nullable=True)
salesman_id: Mapped[int | None] = mapped_column(nullable=True)
credit_limit: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
2026-05-14 10:15:51 +08:00
2026-05-14 13:51:06 +08:00
class ProductCategory(TimestampMixin, AuditMixin, Base):
__tablename__ = "product_category"
id: Mapped[int] = mapped_column(primary_key=True)
category_name: Mapped[str] = mapped_column(String(64))
category_code: Mapped[str] = mapped_column(String(64), unique=True, index=True)
sort_no: Mapped[int] = mapped_column(default=0)
status: Mapped[int] = mapped_column(default=1)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
class Product(TimestampMixin, AuditMixin, Base):
2026-05-14 10:15:51 +08:00
__tablename__ = "product"
2026-05-14 13:51:06 +08:00
id: Mapped[int] = mapped_column(primary_key=True)
product_name: Mapped[str] = mapped_column(String(64), index=True)
specification: Mapped[str] = mapped_column(String(64), default="")
unit: Mapped[str] = mapped_column(String(32), default="")
category: Mapped[str | None] = mapped_column(String(64), nullable=True)
category_id: Mapped[int | None] = mapped_column(ForeignKey("product_category.id"), nullable=True)
cost_price: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
sale_price: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
status: Mapped[int] = mapped_column(default=1)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
class Supplier(TimestampMixin, AuditMixin, Base):
__tablename__ = "supplier"
id: Mapped[int] = mapped_column(primary_key=True)
supplier_name: Mapped[str] = mapped_column(String(64), index=True)
supplier_type: Mapped[str] = mapped_column(String(32), default="factory")
contact_name: Mapped[str | None] = mapped_column(String(64), nullable=True)
contact_mobile: Mapped[str | None] = mapped_column(String(32), nullable=True)
address: Mapped[str | None] = mapped_column(String(255), nullable=True)
template_type: Mapped[str | None] = mapped_column(String(64), nullable=True)
status: Mapped[int] = mapped_column(default=1)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
class SalesOrder(TimestampMixin, AuditMixin, Base):
2026-05-14 10:15:51 +08:00
__tablename__ = "sales_order"
2026-05-14 13:51:06 +08:00
id: Mapped[int] = mapped_column(primary_key=True)
order_no: Mapped[str] = mapped_column(String(64), unique=True, index=True)
customer_id: Mapped[int | None] = mapped_column(ForeignKey("customer.id"), nullable=True)
customer_name: Mapped[str] = mapped_column(String(64))
customer_mobile: Mapped[str] = mapped_column(String(32))
customer_address: Mapped[str | None] = mapped_column(String(255), nullable=True)
salesman_id: Mapped[int | None] = mapped_column(nullable=True)
order_status: Mapped[str] = mapped_column(String(32), index=True, default="draft")
order_source: Mapped[str | None] = mapped_column(String(64), nullable=True)
delivery_type: Mapped[str | None] = mapped_column(String(64), nullable=True)
factory_id: Mapped[int | None] = mapped_column(ForeignKey("supplier.id"), nullable=True)
sale_price_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
cost_price_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
rebate_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
freight_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
tax_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
other_fee_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
profit_total: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
profit_rate: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
commission_amount: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
cancel_requested_by: Mapped[int | None] = mapped_column(nullable=True)
cancel_requested_at: Mapped[DateTime | None] = mapped_column(DateTime, nullable=True)
cancel_reason: Mapped[str | None] = mapped_column(String(255), nullable=True)
cancel_opinion: Mapped[str | None] = mapped_column(Text, nullable=True)
cancel_previous_status: Mapped[str | None] = mapped_column(String(32), nullable=True)
supplier_text_confirmed_at: Mapped[DateTime | None] = mapped_column(DateTime, nullable=True)
supplier_text_confirmed_by: Mapped[int | None] = mapped_column(nullable=True)
remark: Mapped[str | None] = mapped_column(Text, nullable=True)
class SalesOrderItem(TimestampMixin, AuditMixin, Base):
2026-05-14 10:15:51 +08:00
__tablename__ = "sales_order_item"
2026-05-14 13:51:06 +08:00
id: Mapped[int] = mapped_column(primary_key=True)
order_id: Mapped[int] = mapped_column(ForeignKey("sales_order.id"), index=True)
product_id: Mapped[int | None] = mapped_column(nullable=True)
product_name: Mapped[str] = mapped_column(String(64))
specification: Mapped[str] = mapped_column(String(64), default="")
unit: Mapped[str] = mapped_column(String(32), default="")
quantity: Mapped[float] = mapped_column(Numeric(18, 4), default=0)
sale_price: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
cost_price: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
rebate_amount: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
freight_amount: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
tax_amount: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
other_fee_amount: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
2026-05-14 13:57:32 +08:00
class SalesOrderApproveLog(TimestampMixin, AuditMixin, Base):
__tablename__ = "sales_order_approve_log"
id: Mapped[int] = mapped_column(primary_key=True)
order_id: Mapped[int] = mapped_column(ForeignKey("sales_order.id"), index=True)
approve_type: Mapped[str] = mapped_column(String(32), default="order")
approve_result: Mapped[str] = mapped_column(String(32))
before_status: Mapped[str | None] = mapped_column(String(32), nullable=True)
after_status: Mapped[str | None] = mapped_column(String(32), nullable=True)
approve_opinion: Mapped[str | None] = mapped_column(Text, nullable=True)
operator_id: Mapped[int | None] = mapped_column(nullable=True)
2026-05-14 13:51:06 +08:00
class LogisticsTask(TimestampMixin, AuditMixin, Base):
__tablename__ = "logistics_task"
id: Mapped[int] = mapped_column(primary_key=True)
order_id: Mapped[int] = mapped_column(ForeignKey("sales_order.id"), index=True)
driver_id: Mapped[int] = mapped_column(index=True)
factory_id: Mapped[int | None] = mapped_column(ForeignKey("supplier.id"), nullable=True)
pickup_address: Mapped[str] = mapped_column(String(255))
delivery_address: Mapped[str] = mapped_column(String(255))
pickup_content: Mapped[str] = mapped_column(String(255))
quantity: Mapped[float] = mapped_column(Numeric(18, 4), default=0)
status: Mapped[str] = mapped_column(String(32), default="pending")
created_by: Mapped[int | None] = mapped_column(nullable=True)
canceled_by: Mapped[int | None] = mapped_column(nullable=True)
cancel_reason: Mapped[str | None] = mapped_column(String(255), nullable=True)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
class LogisticsTrace(Base):
__tablename__ = "logistics_trace"
id: Mapped[int] = mapped_column(primary_key=True)
order_id: Mapped[int] = mapped_column(ForeignKey("sales_order.id"), index=True)
task_id: Mapped[int | None] = mapped_column(ForeignKey("logistics_task.id"), nullable=True, index=True)
node_time: Mapped[DateTime] = mapped_column(DateTime)
node_desc: Mapped[str] = mapped_column(String(500))
node_type: Mapped[str | None] = mapped_column(String(64), nullable=True)
source_platform: Mapped[str | None] = mapped_column(String(64), nullable=True)
remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now())
class FileAttachment(Base):
__tablename__ = "file_attachment"
id: Mapped[int] = mapped_column(primary_key=True)
biz_type: Mapped[str] = mapped_column(String(64), index=True)
biz_id: Mapped[int] = mapped_column(index=True)
file_name: Mapped[str] = mapped_column(String(255))
file_url: Mapped[str] = mapped_column(String(1000))
file_type: Mapped[str | None] = mapped_column(String(64), nullable=True)
file_size: Mapped[int | None] = mapped_column(nullable=True)
created_by: Mapped[int | None] = mapped_column(nullable=True)
created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now())
storage_provider: Mapped[str | None] = mapped_column(String(32), nullable=True, default="aliyun_oss")
bucket_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
object_key: Mapped[str | None] = mapped_column(String(1000), nullable=True)
content_type: Mapped[str | None] = mapped_column(String(128), nullable=True)
file_ext: Mapped[str | None] = mapped_column(String(32), nullable=True)
file_category: Mapped[str | None] = mapped_column(String(32), nullable=True)
class CustomerArrears(Base):
__tablename__ = "customer_arrears"
id: Mapped[int] = mapped_column(primary_key=True)
customer_id: Mapped[int] = mapped_column(ForeignKey("customer.id"), index=True)
order_id: Mapped[int] = mapped_column(ForeignKey("sales_order.id"), index=True)
arrears_amount: Mapped[float] = mapped_column(Numeric(18, 2), default=0)
settlement_start_date: Mapped[Date | None] = mapped_column(Date, nullable=True)
due_date: Mapped[Date | None] = mapped_column(Date, nullable=True)
status: Mapped[str] = mapped_column(String(32), default="pending")
reminded_at: Mapped[DateTime | None] = mapped_column(DateTime, nullable=True)
created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now())
class SystemReminder(Base):
__tablename__ = "system_reminder"
id: Mapped[int] = mapped_column(primary_key=True)
reminder_type: Mapped[str] = mapped_column(String(64), index=True)
biz_type: Mapped[str] = mapped_column(String(64), index=True)
biz_id: Mapped[int] = mapped_column(index=True)
receiver_user_id: Mapped[int] = mapped_column(index=True)
reminder_title: Mapped[str] = mapped_column(String(255))
reminder_content: Mapped[str] = mapped_column(String(2000))
status: Mapped[str] = mapped_column(String(32), default="pending")
sent_at: Mapped[DateTime | None] = mapped_column(DateTime, nullable=True)
created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now())
class AIRecognitionLog(Base):
__tablename__ = "ai_recognition_log"
id: Mapped[int] = mapped_column(primary_key=True)
biz_type: Mapped[str] = mapped_column(String(64), index=True)
biz_id: Mapped[int] = mapped_column(index=True)
image_url: Mapped[str] = mapped_column(String(1000))
raw_result: Mapped[str | None] = mapped_column(Text, nullable=True)
confidence: Mapped[float | None] = mapped_column(Numeric(10, 4), nullable=True)
corrected_result: Mapped[str | None] = mapped_column(Text, nullable=True)
created_by: Mapped[int | None] = mapped_column(nullable=True)
created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now())