129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
|
|
# =============================================================================
|
||
|
|
# 企微IT智能服务台 — 路由命中事件模型(P1)
|
||
|
|
# =============================================================================
|
||
|
|
# 说明:对应数据库 routing_events 表,记录每次路由推荐事件
|
||
|
|
# 用于后续优化 Prompt 准确率、分析高频非IT业务
|
||
|
|
#
|
||
|
|
# 记录字段:会话ID、员工消息内容、识别的业务类别、推荐联系人、是否点击联系
|
||
|
|
# =============================================================================
|
||
|
|
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
from sqlalchemy import Boolean, DateTime, Float, ForeignKey, Index, Integer, String
|
||
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
|
|
||
|
|
from app.database import Base
|
||
|
|
|
||
|
|
|
||
|
|
class RoutingEvent(Base):
|
||
|
|
"""路由命中事件模型 — 对应 routing_events 表(P1)。
|
||
|
|
|
||
|
|
记录每次路由推荐事件,为后续优化 Prompt 准确率、分析高频非IT业务
|
||
|
|
提供数据支撑。
|
||
|
|
|
||
|
|
Attributes:
|
||
|
|
id: 主键,自增
|
||
|
|
conversation_id: 会话ID(外键)
|
||
|
|
employee_id: 员工ID
|
||
|
|
message_content: 触发路由的员工消息(截断至500字)
|
||
|
|
business_category: 识别的业务类别
|
||
|
|
routing_confidence: 路由置信度
|
||
|
|
contact_id: 推荐的联系人ID(外键)
|
||
|
|
contact_name: 联系人姓名(冗余存储)
|
||
|
|
is_clicked: 员工是否点击了「联系TA」
|
||
|
|
created_at: 创建时间
|
||
|
|
"""
|
||
|
|
|
||
|
|
__tablename__ = "routing_events"
|
||
|
|
|
||
|
|
# 主键:自增整数
|
||
|
|
id: Mapped[int] = mapped_column(
|
||
|
|
Integer,
|
||
|
|
primary_key=True,
|
||
|
|
autoincrement=True,
|
||
|
|
comment="主键",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 会话ID(外键,关联 conversations 表)
|
||
|
|
conversation_id: Mapped[str] = mapped_column(
|
||
|
|
String(36),
|
||
|
|
ForeignKey("conversations.id", ondelete="CASCADE"),
|
||
|
|
nullable=False,
|
||
|
|
comment="会话ID",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 员工ID
|
||
|
|
employee_id: Mapped[str] = mapped_column(
|
||
|
|
String(64),
|
||
|
|
nullable=False,
|
||
|
|
comment="员工ID",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 触发路由的员工消息内容(截断至500字防止过长)
|
||
|
|
message_content: Mapped[str] = mapped_column(
|
||
|
|
String(500),
|
||
|
|
nullable=False,
|
||
|
|
comment="触发路由的员工消息(截断)",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 识别的业务类别(行政/人力资源/财务/法务/行政-物业)
|
||
|
|
business_category: Mapped[str] = mapped_column(
|
||
|
|
String(50),
|
||
|
|
nullable=False,
|
||
|
|
comment="识别的业务类别",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 路由置信度(0.0~1.0,≥0.7 触发名片推荐)
|
||
|
|
routing_confidence: Mapped[float] = mapped_column(
|
||
|
|
Float,
|
||
|
|
nullable=False,
|
||
|
|
comment="路由置信度",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 推荐的联系人ID(外键,关联 business_contacts 表)
|
||
|
|
contact_id: Mapped[int | None] = mapped_column(
|
||
|
|
Integer,
|
||
|
|
ForeignKey("business_contacts.id", ondelete="SET NULL"),
|
||
|
|
nullable=True,
|
||
|
|
default=None,
|
||
|
|
comment="推荐的联系人ID",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 联系人姓名(冗余存储,避免联系人删除后丢失记录)
|
||
|
|
contact_name: Mapped[str] = mapped_column(
|
||
|
|
String(50),
|
||
|
|
nullable=False,
|
||
|
|
comment="联系人姓名(冗余)",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 员工是否点击了「联系TA」按钮
|
||
|
|
is_clicked: Mapped[bool] = mapped_column(
|
||
|
|
Boolean,
|
||
|
|
nullable=False,
|
||
|
|
default=False,
|
||
|
|
comment="是否点击了联系TA",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 创建时间
|
||
|
|
created_at: Mapped[datetime] = mapped_column(
|
||
|
|
DateTime(timezone=True),
|
||
|
|
nullable=False,
|
||
|
|
default=datetime.now,
|
||
|
|
comment="创建时间",
|
||
|
|
)
|
||
|
|
|
||
|
|
# 索引定义
|
||
|
|
__table_args__ = (
|
||
|
|
# 按业务类别查询(分析高频非IT业务)
|
||
|
|
Index("idx_routing_events_category", "business_category"),
|
||
|
|
# 按会话ID查询(查看某会话的路由历史)
|
||
|
|
Index("idx_routing_events_conv", "conversation_id"),
|
||
|
|
)
|
||
|
|
|
||
|
|
def __repr__(self) -> str:
|
||
|
|
"""路由事件对象的字符串表示,方便调试。"""
|
||
|
|
return (
|
||
|
|
f"<RoutingEvent(id={self.id}, conv={self.conversation_id}, "
|
||
|
|
f"category={self.business_category}, confidence={self.routing_confidence})>"
|
||
|
|
)
|