chore: initial baseline with P0-safety .gitignore

This commit is contained in:
Simon
2026-06-14 16:49:18 +08:00
commit 63262292d7
510 changed files with 146008 additions and 0 deletions
+492
View File
@@ -0,0 +1,492 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台 Pydantic Schema
# =============================================================================
# 说明:定义管理后台专用请求/响应数据结构
# 包含:仪表盘、配置管理、坐席管理、集成配置、快速回复审核、
# 分配模式、会话监控、全局搜索等全部 Schema
# =============================================================================
from datetime import datetime
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field
# ==========================================================================
# 配置管理 Schema
# ==========================================================================
class ConfigItemResponse(BaseModel):
"""单个配置项响应 Schema。
Attributes:
key: 配置键
value: 配置值
description: 配置说明
value_type: 值类型(boolean/number/string/json_array/json_object
"""
key: str = Field(..., description="配置键")
value: str = Field(..., description="配置值")
description: str = Field(default="", description="配置说明")
value_type: str = Field(default="string", description="值类型: boolean/number/string/json_array/json_object")
model_config = {"from_attributes": True}
class ConfigGroupResponse(BaseModel):
"""配置分组响应 Schema。
按功能前缀将配置项分组,方便前端展示。
Attributes:
name: 分组名称
key_prefix: 配置键前缀
items: 该分组下的配置项列表
"""
name: str = Field(..., description="分组名称")
key_prefix: str = Field(..., description="配置键前缀")
items: List[ConfigItemResponse] = Field(default_factory=list, description="配置项列表")
class ConfigUpdateRequest(BaseModel):
"""配置更新请求 Schema。
Attributes:
value: 新的配置值
"""
value: str = Field(..., min_length=1, description="新的配置值")
class ConfigHistoryItem(BaseModel):
"""配置变更历史条目 Schema。
Attributes:
id: 日志ID
config_key: 配置键
old_value: 变更前的值
new_value: 变更后的值
changed_by: 变更操作人 agent_id
changed_by_name: 变更操作人姓名
changed_at: 变更时间
"""
id: str = Field(..., description="日志ID")
config_key: str = Field(..., description="配置键")
old_value: str = Field(..., description="变更前的值")
new_value: str = Field(..., description="变更后的值")
changed_by: str = Field(..., description="变更操作人 agent_id")
changed_by_name: str = Field(default="", description="变更操作人姓名")
changed_at: datetime = Field(..., description="变更时间")
model_config = {"from_attributes": True}
class ConfigHistoryResponse(BaseModel):
"""配置变更历史响应 Schema。
Attributes:
items: 变更历史条目列表
"""
items: List[ConfigHistoryItem] = Field(default_factory=list, description="变更历史列表")
# ==========================================================================
# 坐席管理 Schema
# ==========================================================================
class AgentCreateRequest(BaseModel):
"""创建坐席请求 Schema。
Attributes:
user_id: 企微用户ID
name: 坐席姓名
role: 角色(admin=组长, agent=坐席)
skill_tags: 技能标签列表
max_load: 最大同时服务数
"""
user_id: str = Field(..., min_length=1, max_length=64, description="企微用户ID")
name: str = Field(..., min_length=1, max_length=128, description="坐席姓名")
role: str = Field(default="agent", description="角色: admin=组长, agent=坐席")
skill_tags: List[str] = Field(default_factory=list, description="技能标签列表")
max_load: int = Field(default=5, ge=1, le=50, description="最大同时服务数")
class AgentUpdateRequest(BaseModel):
"""更新坐席请求 Schema。
所有字段可选,只更新传入的字段。
Attributes:
role: 角色
skill_tags: 技能标签列表
max_load: 最大同时服务数
"""
role: Optional[str] = Field(None, description="角色: admin=组长, agent=坐席")
skill_tags: Optional[List[str]] = Field(None, description="技能标签列表")
max_load: Optional[int] = Field(None, ge=1, le=50, description="最大同时服务数")
class AdminAgentResponse(BaseModel):
"""管理后台坐席响应 Schema(含角色/技能标签/今日结单数)。
Attributes:
id: 坐席ID
user_id: 企微用户ID
name: 坐席姓名
status: 坐席状态
role: 角色
skill_tags: 技能标签列表
current_load: 当前服务会话数
max_load: 最大同时服务数
today_resolved: 今日结单数
created_at: 创建时间
updated_at: 更新时间
"""
id: str
user_id: str
name: str
status: str
role: str = "agent"
skill_tags: List[str] = []
current_load: int = 0
max_load: int = 5
today_resolved: int = 0
otp_secret: Optional[str] = None
otp_enabled: bool = False
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# =========================================================================
# 集成配置 Schema
# =========================================================================
class IntegrationConfig(BaseModel):
"""集成系统配置 Schema(通用,支持 url_key 和 access_key 两种模式)。
Attributes:
# url_key 模式(Dify / RAGFlow
api_url: API 地址
api_key_set: API Key 是否已设置
# access_key 模式(火绒安全)
access_key_id_set: AccessKey ID 是否已设置
access_key_secret_set: AccessKey Secret 是否已设置
base_url: 内网 Base URL
"""
# url_key 模式(Dify / RAGFlow
api_url: str = Field(default="", description="API 地址")
api_key_set: bool = Field(default=False, description="API Key 是否已设置")
# access_key 模式(火绒安全)
access_key_id_set: bool = Field(default=False, description="AccessKey ID 是否已设置")
access_key_secret_set: bool = Field(default=False, description="AccessKey Secret 是否已设置")
base_url: Optional[str] = Field(default=None, description="内网 Base URL")
# account_password 模式(联软LV7000
api_account_set: bool = Field(default=False, description="API账号是否已设置")
api_password_set: bool = Field(default=False, description="API密码是否已设置")
class IntegrationResponse(BaseModel):
"""集成系统响应 Schema。
Attributes:
id: 集成系统ID(如 dify/ragflow/huorong
name: 集成系统名称
status: 连接状态(connected/partial/disconnected/pending
configurable: 是否可配置
config_type: 配置类型(url_key/access_key),前端据此显示不同表单
config: 配置信息(不可配置时为 None)
"""
id: str = Field(..., description="集成系统ID")
name: str = Field(..., description="集成系统名称")
status: str = Field(default="disconnected", description="连接状态: connected/partial/disconnected/pending")
configurable: bool = Field(default=False, description="是否可配置")
config_type: Optional[str] = Field(default=None, description="配置类型: url_key/access_key/account_password")
config: Optional[IntegrationConfig] = Field(default=None, description="配置信息")
class IntegrationUpdateRequest(BaseModel):
"""集成系统配置更新请求 Schema。
支持三种模式:
- url_key 模式(Dify / RAGFlow):传入 api_url + api_key
- access_key 模式(火绒安全):传入 access_key_id + access_key_secret + base_url
- account_password 模式(联软LV7000):传入 api_account + api_password + base_url + validate_key(可选)
Attributes:
# url_key 模式
api_url: API 地址(可选,火绒/联软模式不需要)
api_key: API Key(可选,火绒/联软模式不需要)
# access_key 模式(火绒)
access_key_id: AccessKey ID(可选)
access_key_secret: AccessKey Secret(可选)
base_url: 内网 Base URL(可选)
# account_password 模式(联软)
api_account: API账号(可选,联软模式)
api_password: API密码(可选,联软模式)
validate_key: 验证密钥(可选,联软模式)
"""
# url_key 模式(Dify / RAGFlow
api_url: Optional[str] = Field(default=None, description="API 地址(Dify/RAGFlow 模式)")
api_key: Optional[str] = Field(default=None, description="API KeyDify/RAGFlow 模式)")
# access_key 模式(火绒安全)
access_key_id: Optional[str] = Field(default=None, description="AccessKey ID(火绒模式)")
access_key_secret: Optional[str] = Field(default=None, description="AccessKey Secret(火绒模式)")
base_url: Optional[str] = Field(default=None, description="内网 Base URL(火绒/联软模式)")
# account_password 模式(联软LV7000
api_account: Optional[str] = Field(default=None, description="API账号(联软模式)")
api_password: Optional[str] = Field(default=None, description="API密码(联软模式)")
validate_key: Optional[str] = Field(default=None, description="验证密钥(联软模式,可选)")
# ==========================================================================
# 快速回复审核 Schema
# ==========================================================================
class QuickReplyReviewRequest(BaseModel):
"""快速回复审核请求 Schema。
Attributes:
action: 审核动作(approve=通过, reject=驳回)
reason: 审核原因/意见(驳回时建议填写)
"""
action: str = Field(..., description="审核动作: approve/reject")
reason: str = Field(default="", description="审核原因/意见")
class AdminQuickReplyResponse(BaseModel):
"""管理后台快速回复响应 Schema(含审核信息)。
Attributes:
id: 模板ID
category: 分类
title: 模板标题
content: 模板内容
variables: 可用变量列表
status: 状态
version: 版本号
submitted_by: 提交人 agent_id
submitted_by_name: 提交人姓名
sort_order: 排序权重
created_at: 创建时间
updated_at: 更新时间
"""
id: str
category: str
title: str
content: str
variables: List[str]
status: str = "approved"
version: int = 1
submitted_by: Optional[str] = None
submitted_by_name: str = ""
sort_order: int = 0
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
# ==========================================================================
# 分配模式 Schema
# ==========================================================================
class AssignmentModeItem(BaseModel):
"""分配模式条目 Schema。
Attributes:
id: 模式ID
name: 模式名称
enabled: 是否启用
locked: 是否锁定(阶段一锁定部分模式)
unlock_at: 解锁阶段说明
"""
id: str = Field(..., description="模式ID")
name: str = Field(..., description="模式名称")
enabled: bool = Field(default=False, description="是否启用")
locked: bool = Field(default=True, description="是否锁定")
unlock_at: str = Field(default="", description="解锁阶段说明")
class AssignmentModeResponse(BaseModel):
"""分配模式响应 Schema。
Attributes:
current_mode: 当前启用的分配模式
modes: 所有分配模式列表
"""
current_mode: str = Field(default="manual", description="当前分配模式")
modes: List[AssignmentModeItem] = Field(default_factory=list, description="分配模式列表")
class AssignmentModeUpdateRequest(BaseModel):
"""分配模式更新请求 Schema。
Attributes:
mode: 要切换的分配模式ID
"""
mode: str = Field(..., description="分配模式ID")
# ==========================================================================
# 仪表盘 Schema
# ==========================================================================
class SystemAlertItem(BaseModel):
"""单条系统告警 Schema。
与前端 SystemAlert 接口对齐,支持结构化告警展示。
Attributes:
type: 告警类型(如 quick_reply_pending / agent_offline / system_error
content: 告警内容描述
submitter: 提交人姓名(仅快速回复待审核类告警有值)
time: 告警发生时间(ISO 8601 格式)
severity: 严重程度(info/warning/critical
"""
type: str = Field(..., description="告警类型")
content: str = Field(..., description="告警内容")
submitter: Optional[str] = Field(default=None, description="提交人")
time: str = Field(..., description="告警时间")
severity: str = Field(default="info", description="严重程度: info/warning/critical")
class IntegrationHealthItem(BaseModel):
"""集成系统健康状态条目 Schema。
Attributes:
system: 系统名称
status: 连接状态
"""
system: str = Field(..., description="系统名称")
status: str = Field(default="disconnected", description="连接状态")
class DashboardOverviewResponse(BaseModel):
"""仪表盘总览响应 Schema。
Attributes:
online_agents: 在线坐席数
today_conversations: 今日会话数
avg_response_time: 平均响应时间(阶段一占位)
ai_hit_rate: AI 命中率(阶段一占位)
pending_reviews: 待审核快速回复数
system_alerts: 系统告警列表
integrations_health: 集成系统健康状态
"""
online_agents: int = Field(default=0, description="在线坐席数")
today_conversations: int = Field(default=0, description="今日会话数")
avg_response_time: str = Field(default="", description="平均响应时间(阶段一占位)")
ai_hit_rate: str = Field(default="", description="AI命中率(阶段一占位)")
pending_reviews: int = Field(default=0, description="待审核快速回复数")
system_alerts: List[SystemAlertItem] = Field(default_factory=list, description="系统告警列表")
integrations_health: List[IntegrationHealthItem] = Field(default_factory=list, description="集成系统健康状态")
# ==========================================================================
# 会话监控 Schema
# ==========================================================================
class SessionStats(BaseModel):
"""会话统计 Schema。
Attributes:
in_progress: 服务中会话数
queued: 排队中会话数
resolved_today: 今日已结单数
alerts: 告警数
"""
in_progress: int = Field(default=0, description="服务中会话数")
queued: int = Field(default=0, description="排队中会话数")
resolved_today: int = Field(default=0, description="今日已结单数")
alerts: int = Field(default=0, description="告警数")
class SessionItem(BaseModel):
"""会话条目 Schema(监控列表用)。
Attributes:
id: 会话ID
employee_name: 员工姓名
status: 会话状态
assigned_agent_name: 负责坐席姓名
urgency_score: 紧急度评分
created_at: 创建时间
last_message_summary: 最后消息摘要
"""
id: str = Field(..., description="会话ID")
employee_name: str = Field(default="", description="员工姓名")
status: str = Field(default="queued", description="会话状态")
assigned_agent_name: str = Field(default="", description="负责坐席姓名")
urgency_score: int = Field(default=1, description="紧急度评分")
created_at: datetime = Field(..., description="创建时间")
last_message_summary: str = Field(default="", description="最后消息摘要")
class MonitorSessionsResponse(BaseModel):
"""会话监控响应 Schema。
Attributes:
stats: 会话统计
items: 会话列表
"""
stats: SessionStats = Field(..., description="会话统计")
items: List[SessionItem] = Field(default_factory=list, description="会话列表")
# ==========================================================================
# 全局搜索 Schema
# ==========================================================================
class SearchItem(BaseModel):
"""搜索结果条目 Schema。
Attributes:
type: 结果类型(config/agent/quick_reply
id: 对象ID
name: 对象名称/标题
route: 前端路由路径
"""
type: str = Field(..., description="结果类型: config/agent/quick_reply")
id: str = Field(..., description="对象ID")
name: str = Field(..., description="对象名称/标题")
route: str = Field(..., description="前端路由路径")
class SearchResponse(BaseModel):
"""搜索结果响应 Schema。
Attributes:
items: 搜索结果列表
"""
items: List[SearchItem] = Field(default_factory=list, description="搜索结果列表")