Files
wecom_it_smart_desk/backend/app/models/login_log.py
T
Simon bea288e414 feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复
== 已部署上线 (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
2026-07-11 23:13:10 +08:00

143 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# 企微IT智能服务台 — 登录日志模型
# =============================================================================
# 说明:对应数据库 login_logs 表,记录所有登录尝试(成功/失败),用于安全审计和故障排查。
# 三端认证重构:统一认证后,所有登录方式(oauth/qrcode/bind)都记录到此表。
# =============================================================================
import uuid
from datetime import datetime
from sqlalchemy import DateTime, Index, String
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class LoginLog(Base):
"""登录日志模型 — 对应 login_logs 表。
记录所有登录尝试(成功/失败),用于安全审计和故障排查。
Attributes:
id: 主键(UUID)
employee_id: 员工UserID(成功登录时有值)
corp_id: 企业ID
login_method: 登录方式(oauth/qrcode/bind)
login_source: 登录来源(h5/agent/admin)
ip_address: 客户端IP
user_agent: 客户端User-Agent
status: 登录状态(success/failed/cancelled)
fail_reason: 失败原因
created_at: 登录时间
"""
# 表名
__tablename__ = "login_logs"
# --------------------------------------------------------------------------
# 字段定义
# --------------------------------------------------------------------------
# 主键:UUID
id: Mapped[str] = mapped_column(
String(36),
primary_key=True,
default=lambda: str(uuid.uuid4()),
comment="登录日志唯一标识",
)
# 员工UserID(成功登录时有值)
employee_id: Mapped[str] = mapped_column(
String(64),
nullable=True,
comment="企微员工UserID(成功登录时有值)",
)
# 企业微信企业ID
corp_id: Mapped[str] = mapped_column(
String(64),
nullable=False,
comment="企业微信企业ID",
)
# 登录方式
# oauth: 企微内OAuth静默授权
# qrcode: 企微外扫码登录
# bind: 互联企业账号绑定
login_method: Mapped[str] = mapped_column(
String(20),
nullable=False,
comment="登录方式: oauth/qrcode/bind",
)
# 登录来源
# h5: 员工H5端
# agent: 坐席端
# admin: 管理后台
login_source: Mapped[str] = mapped_column(
String(20),
nullable=False,
comment="登录来源: h5/agent/admin",
)
# 客户端IPIPv6支持)
ip_address: Mapped[str] = mapped_column(
String(45),
nullable=True,
comment="客户端IP地址",
)
# 客户端User-Agent
user_agent: Mapped[str] = mapped_column(
String(512),
nullable=True,
comment="客户端User-Agent",
)
# 登录状态
# success: 登录成功
# failed: 登录失败
# cancelled: 用户取消/授权超时
status: Mapped[str] = mapped_column(
String(20),
nullable=False,
comment="登录状态: success/failed/cancelled",
)
# 失败原因
fail_reason: Mapped[str] = mapped_column(
String(256),
nullable=True,
comment="失败原因",
)
# 登录时间
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
nullable=False,
default=datetime.now,
comment="登录时间",
)
# --------------------------------------------------------------------------
# 索引和约束定义
# --------------------------------------------------------------------------
__table_args__ = (
# 按员工ID查询登录历史
Index("idx_login_logs_employee_id", "employee_id"),
# 按企业ID查询
Index("idx_login_logs_corp_id", "corp_id"),
# 按登录时间倒序查询(常用)
Index("idx_login_logs_created_at", "created_at"),
# 按状态查询
Index("idx_login_logs_status", "status"),
)
def __repr__(self) -> str:
"""登录日志对象的字符串表示。"""
return (
f"<LoginLog(id={self.id}, employee_id={self.employee_id}, "
f"login_method={self.login_method}, status={self.status})>"
)