193 lines
5.8 KiB
Python
193 lines
5.8 KiB
Python
|
|
# =============================================================================
|
|||
|
|
# 企微IT智能服务台 — 员工模型
|
|||
|
|
# =============================================================================
|
|||
|
|
# 说明:对应数据库 employees 表,存储通过 OAuth2 认证的员工信息
|
|||
|
|
# US-7 扩展:增加 corp_id 字段支持上下游互联企业场景
|
|||
|
|
# 主企业(亿企赢总部): corp_id = 主企业 corp_id
|
|||
|
|
# 下游企业(亿企赢): corp_id = 下游企业 corp_id
|
|||
|
|
# 复合唯一键 (corp_id, employee_id) 确保跨企业员工标识唯一
|
|||
|
|
# =============================================================================
|
|||
|
|
|
|||
|
|
import uuid
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
from sqlalchemy import DateTime, Index, JSON, String, UniqueConstraint
|
|||
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|||
|
|
|
|||
|
|
from app.database import Base
|
|||
|
|
|
|||
|
|
|
|||
|
|
class Employee(Base):
|
|||
|
|
"""员工模型 — 对应 employees 表。
|
|||
|
|
|
|||
|
|
通过 OAuth2 认证后记录员工信息,支持跨企业场景(US-7)。
|
|||
|
|
与 Conversation.employee_id 通过 (corp_id, employee_id) 关联。
|
|||
|
|
|
|||
|
|
Attributes:
|
|||
|
|
id: 主键(UUID,数据库自动生成)
|
|||
|
|
corp_id: 企业微信企业ID(主企业或下游企业)
|
|||
|
|
employee_id: 员工UserID(企业内唯一)
|
|||
|
|
name: 员工姓名
|
|||
|
|
department: 部门(JSON数组字符串)
|
|||
|
|
position: 岗位
|
|||
|
|
mobile: 手机号
|
|||
|
|
email: 邮箱
|
|||
|
|
avatar: 头像URL
|
|||
|
|
status: 激活状态(1=已激活, 2=已禁用, 4=未激活)
|
|||
|
|
last_login_at: 最后登录时间
|
|||
|
|
created_at: 创建时间
|
|||
|
|
updated_at: 更新时间
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
# 表名
|
|||
|
|
__tablename__ = "employees"
|
|||
|
|
|
|||
|
|
# --------------------------------------------------------------------------
|
|||
|
|
# 字段定义
|
|||
|
|
# --------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
# 主键:UUID
|
|||
|
|
id: Mapped[str] = mapped_column(
|
|||
|
|
String(36),
|
|||
|
|
primary_key=True,
|
|||
|
|
default=lambda: str(uuid.uuid4()),
|
|||
|
|
comment="员工记录唯一标识",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 企业微信企业ID(主企业或下游企业)
|
|||
|
|
# US-7: 用于区分不同企业的员工,格式如 "wwa8c87970b2011f41"
|
|||
|
|
corp_id: Mapped[str] = mapped_column(
|
|||
|
|
String(64),
|
|||
|
|
nullable=False,
|
|||
|
|
comment="企业微信企业ID",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 员工UserID(企业内唯一)
|
|||
|
|
# 注意:不同企业的 userid 可能重复,需配合 corp_id 使用
|
|||
|
|
employee_id: Mapped[str] = mapped_column(
|
|||
|
|
String(64),
|
|||
|
|
nullable=False,
|
|||
|
|
comment="企微员工UserID(企业内唯一)",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 员工姓名
|
|||
|
|
name: Mapped[str] = mapped_column(
|
|||
|
|
String(128),
|
|||
|
|
nullable=False,
|
|||
|
|
default="",
|
|||
|
|
comment="员工姓名",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 部门(JSON数组字符串,如 "[1, 2, 3]")
|
|||
|
|
department: Mapped[str] = mapped_column(
|
|||
|
|
String(512),
|
|||
|
|
nullable=False,
|
|||
|
|
default="",
|
|||
|
|
comment="部门ID列表(JSON数组)",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 岗位
|
|||
|
|
position: Mapped[str] = mapped_column(
|
|||
|
|
String(128),
|
|||
|
|
nullable=False,
|
|||
|
|
default="",
|
|||
|
|
comment="岗位",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 手机号
|
|||
|
|
mobile: Mapped[str] = mapped_column(
|
|||
|
|
String(32),
|
|||
|
|
nullable=False,
|
|||
|
|
default="",
|
|||
|
|
comment="手机号",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 邮箱
|
|||
|
|
email: Mapped[str] = mapped_column(
|
|||
|
|
String(128),
|
|||
|
|
nullable=False,
|
|||
|
|
default="",
|
|||
|
|
comment="邮箱",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 头像URL
|
|||
|
|
avatar: Mapped[str] = mapped_column(
|
|||
|
|
String(512),
|
|||
|
|
nullable=False,
|
|||
|
|
default="",
|
|||
|
|
comment="头像URL",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 激活状态(企微通讯录返回: 1=已激活, 2=已禁用, 4=未激活)
|
|||
|
|
status: Mapped[int] = mapped_column(
|
|||
|
|
default=1,
|
|||
|
|
comment="激活状态: 1=已激活, 2=已禁用, 4=未激活",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# IT技能等级(7级: bronze/silver/gold/platinum/diamond/star/king)
|
|||
|
|
it_level: Mapped[str] = mapped_column(
|
|||
|
|
String(20),
|
|||
|
|
nullable=False,
|
|||
|
|
default="silver",
|
|||
|
|
comment="IT技能等级",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 等级来源(system: 系统自动评定, manual: 坐席手动调整, assessment: 评估结果)
|
|||
|
|
it_level_source: Mapped[str] = mapped_column(
|
|||
|
|
String(20),
|
|||
|
|
nullable=False,
|
|||
|
|
default="system",
|
|||
|
|
comment="等级来源",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 坐席备注(JSON 格式,存储坐席对员工的备注信息)
|
|||
|
|
notes: Mapped[dict] = mapped_column(
|
|||
|
|
JSON,
|
|||
|
|
nullable=False,
|
|||
|
|
default=dict,
|
|||
|
|
comment="坐席备注",
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 最后登录时间
|
|||
|
|
last_login_at: Mapped[datetime] = mapped_column(
|
|||
|
|
DateTime(timezone=True),
|
|||
|
|
nullable=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__ = (
|
|||
|
|
# 复合唯一约束:同一企业内 employee_id 唯一
|
|||
|
|
UniqueConstraint("corp_id", "employee_id", name="uq_employee_corp"),
|
|||
|
|
# 按 corp_id 查询(查询某企业所有员工)
|
|||
|
|
Index("idx_employees_corp_id", "corp_id"),
|
|||
|
|
# 按 employee_id 查询
|
|||
|
|
Index("idx_employees_employee_id", "employee_id"),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
def __repr__(self) -> str:
|
|||
|
|
"""员工对象的字符串表示。"""
|
|||
|
|
return (
|
|||
|
|
f"<Employee(corp_id={self.corp_id}, employee_id={self.employee_id}, "
|
|||
|
|
f"name={self.name})>"
|
|||
|
|
)
|