493 lines
17 KiB
Python
493 lines
17 KiB
Python
# =============================================================================
|
||
# 企微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 Key(Dify/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="搜索结果列表")
|