bea288e414
== 已部署上线 (9项) == - 代办事项真实数据源集成 (企微审批API 8bug修复链) - H5/坐席端 Logo样式统一+绿色背景 - 视频引导页修复 (localStorage key v2) - 坐席端 v9 Vue版本修复 (ElMessage._context) - 截图按钮 v10 修复 (getDisplayMedia user gesture) - 扫码样式恢复+H5扫码登录跳转修复 - H5截图快捷键提示 == 代码完成待部署 (3项) == - 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查) - 会议室预定-小鱼易联终端 (40文件, 40/40测试通过) - IT资产升级审批推送 (asset_service.py) == 需求文档 (2项) == - 坐席端AI辅助消息框-PRD (4项新功能确认) - 坐席端布局优化建议 v2.0 (7天计划) == 新增文档 == - 日报-2026-07-11.md - 知识迭代Bug修复报告-20260711.md - 会议室预定-部署指南.md - CHANGELOG.md 更新 == 测试 == - test_todo_integration.py: 40/40 - test_meetingroom.py: 40/40 - test_bugfix_ki_suggestions.py: 21/21
187 lines
5.8 KiB
Python
187 lines
5.8 KiB
Python
# =============================================================================
|
||
# 企微IT智能服务台 — 业务联系人模型
|
||
# =============================================================================
|
||
# 说明:对应数据库 business_contacts 表,存储非IT业务部门联系人信息
|
||
# 当员工提出的问题不属于IT服务台服务范围时,系统通过 Dify 意图识别
|
||
# 判定业务类别,从本表查询对应联系人,推送名片卡片到聊天中。
|
||
# 员工点击「联系TA」可跳转企微单聊(openEnterpriseChat)。
|
||
#
|
||
# 业务类别(business_category)取值:
|
||
# 行政 / 人力资源 / 财务 / 法务 / 行政-物业
|
||
# =============================================================================
|
||
|
||
from datetime import datetime
|
||
|
||
from sqlalchemy import Boolean, DateTime, Index, Integer, String
|
||
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
||
from app.database import Base
|
||
|
||
|
||
class BusinessContact(Base):
|
||
"""业务联系人模型 — 对应 business_contacts 表。
|
||
|
||
存储非IT业务部门联系人信息,用于路由推荐功能。
|
||
当 Dify 判定消息为非IT业务路由时,按 business_category 查询本表,
|
||
取第一条 is_active=True 的联系人,推送名片卡片。
|
||
|
||
Attributes:
|
||
id: 主键,自增
|
||
name: 联系人姓名
|
||
gender: 性别(male/female)
|
||
department: 部门名称(如「行政部」)
|
||
position: 岗位(如「设备管理岗」)
|
||
responsibility: 负责业务描述(如「打印机/复印机/扫描仪」)
|
||
extension: 分机号
|
||
service_area: 服务区域/办公地点
|
||
wecom_userid: 企微用户ID(用于 openEnterpriseChat 调用)
|
||
avatar_url: 头像URL(为空时用姓名首字渲染)
|
||
business_category: 业务类别(行政/人力资源/财务/法务/行政-物业)
|
||
is_active: 是否启用
|
||
created_at: 创建时间
|
||
updated_at: 更新时间
|
||
"""
|
||
|
||
__tablename__ = "business_contacts"
|
||
|
||
# 主键:自增整数
|
||
id: Mapped[int] = mapped_column(
|
||
Integer,
|
||
primary_key=True,
|
||
autoincrement=True,
|
||
comment="主键",
|
||
)
|
||
|
||
# 联系人姓名
|
||
name: Mapped[str] = mapped_column(
|
||
String(50),
|
||
nullable=False,
|
||
comment="联系人姓名",
|
||
)
|
||
|
||
# 性别(male/female)
|
||
gender: Mapped[str] = mapped_column(
|
||
String(10),
|
||
nullable=False,
|
||
default="male",
|
||
comment="性别(male/female)",
|
||
)
|
||
|
||
# 部门名称
|
||
department: Mapped[str] = mapped_column(
|
||
String(100),
|
||
nullable=False,
|
||
comment="部门名称",
|
||
)
|
||
|
||
# 岗位
|
||
position: Mapped[str] = mapped_column(
|
||
String(100),
|
||
nullable=False,
|
||
comment="岗位",
|
||
)
|
||
|
||
# 负责业务描述
|
||
responsibility: Mapped[str] = mapped_column(
|
||
String(500),
|
||
nullable=False,
|
||
comment="负责业务描述",
|
||
)
|
||
|
||
# 分机号
|
||
extension: Mapped[str | None] = mapped_column(
|
||
String(20),
|
||
nullable=True,
|
||
default=None,
|
||
comment="分机号",
|
||
)
|
||
|
||
# 服务区域/办公地点
|
||
service_area: Mapped[str | None] = mapped_column(
|
||
String(200),
|
||
nullable=True,
|
||
default=None,
|
||
comment="服务区域/办公地点",
|
||
)
|
||
|
||
# 企微用户ID(用于 wx.invoke('openEnterpriseChat', {userids: '...'}) 调用)
|
||
wecom_userid: Mapped[str] = mapped_column(
|
||
String(100),
|
||
nullable=False,
|
||
comment="企微用户ID",
|
||
)
|
||
|
||
# 头像URL(为空时前端用姓名首字渐变色块渲染)
|
||
avatar_url: Mapped[str | None] = mapped_column(
|
||
String(500),
|
||
nullable=True,
|
||
default=None,
|
||
comment="头像URL(为空用姓名首字渲染)",
|
||
)
|
||
|
||
# 业务类别(与 Dify 输出的 business_category 对应)
|
||
# 取值:行政 / 人力资源 / 财务 / 法务 / 行政-物业
|
||
business_category: Mapped[str] = mapped_column(
|
||
String(50),
|
||
nullable=False,
|
||
comment="业务类别(行政/人力资源/财务/法务/行政-物业)",
|
||
)
|
||
|
||
# 是否启用
|
||
is_active: Mapped[bool] = mapped_column(
|
||
Boolean,
|
||
nullable=False,
|
||
default=True,
|
||
comment="是否启用",
|
||
)
|
||
|
||
# 创建时间
|
||
created_at: Mapped[datetime] = mapped_column(
|
||
DateTime(timezone=True),
|
||
nullable=False,
|
||
default=datetime.now,
|
||
comment="创建时间",
|
||
)
|
||
|
||
# 更新时间
|
||
updated_at: Mapped[datetime] = mapped_column(
|
||
DateTime(timezone=True),
|
||
nullable=False,
|
||
default=datetime.now,
|
||
onupdate=datetime.now,
|
||
comment="更新时间",
|
||
)
|
||
|
||
# 索引定义
|
||
__table_args__ = (
|
||
# 按业务类别 + 是否启用查询(路由推荐时使用)
|
||
Index("idx_business_contacts_category", "business_category", "is_active"),
|
||
)
|
||
|
||
def to_dict(self) -> dict:
|
||
"""将联系人信息转为字典(用于 extra_data 透传给前端)。
|
||
|
||
Returns:
|
||
dict: 联系人完整信息
|
||
"""
|
||
return {
|
||
"id": self.id,
|
||
"name": self.name,
|
||
"gender": self.gender,
|
||
"department": self.department,
|
||
"position": self.position,
|
||
"responsibility": self.responsibility,
|
||
"extension": self.extension or "",
|
||
"service_area": self.service_area or "",
|
||
"wecom_userid": self.wecom_userid,
|
||
"avatar_url": self.avatar_url or "",
|
||
"business_category": self.business_category,
|
||
}
|
||
|
||
def __repr__(self) -> str:
|
||
"""联系人对象的字符串表示,方便调试。"""
|
||
return (
|
||
f"<BusinessContact(id={self.id}, name={self.name}, "
|
||
f"category={self.business_category})>"
|
||
)
|