chore: 整理项目结构,清理归档文件,更新部署配置

This commit is contained in:
Simon
2026-07-04 21:01:39 +08:00
parent 8bd4ab0366
commit 64ff1bf7d5
508 changed files with 43575 additions and 14129 deletions
+84
View File
@@ -0,0 +1,84 @@
# =============================================================================
# 管理服务模块 (admin)
# =============================================================================
# 说明:管理后台相关服务,包括仪表盘、配置、坐席管理、集成配置等
#
# 本模块包含:
# - AdminDashboardService: 仪表盘服务
# - AdminConfigService: 配置管理服务
# - AdminAgentService: 坐席管理服务
# - AdminIntegrationService: 集成管理服务
# - AdminModerationService: 审核管理服务
# - AdminMonitoringService: 监控管理服务
# - AdminAuditService: 审计服务
#
# 迁移说明:
# 旧导入路径:from app.services import get_dashboard_overview
# 新导入路径:from app.services.admin import get_dashboard_overview
# 两者均支持(向后兼容)
# =============================================================================
# 重新导出管理服务函数(保持兼容)
from app.services.admin_service import (
get_dashboard_overview,
get_config_groups,
update_config,
get_config_history,
list_admin_agents,
create_agent,
update_agent,
delete_agent,
get_integrations,
update_integration,
list_pending_quick_replies,
review_quick_reply,
get_assignment_mode,
update_assignment_mode,
get_monitor_sessions,
global_search,
list_audit_conversations,
get_audit_conversation_detail,
get_agent_performance,
get_system_logs,
)
# 拆分后的服务类(新)
from app.services.admin.admin_dashboard_service import AdminDashboardService
from app.services.admin.admin_config_service import AdminConfigService
from app.services.admin.admin_agent_service import AdminAgentService
from app.services.admin.admin_integration_service import AdminIntegrationService
from app.services.admin.admin_moderation_service import AdminModerationService
from app.services.admin.admin_monitoring_service import AdminMonitoringService
from app.services.admin.admin_audit_service import AdminAuditService
__all__ = [
# 兼容旧导入
"get_dashboard_overview",
"get_config_groups",
"update_config",
"get_config_history",
"list_admin_agents",
"create_agent",
"update_agent",
"delete_agent",
"get_integrations",
"update_integration",
"list_pending_quick_replies",
"review_quick_reply",
"get_assignment_mode",
"update_assignment_mode",
"get_monitor_sessions",
"global_search",
"list_audit_conversations",
"get_audit_conversation_detail",
"get_agent_performance",
"get_system_logs",
# 新服务类
"AdminDashboardService",
"AdminConfigService",
"AdminAgentService",
"AdminIntegrationService",
"AdminModerationService",
"AdminMonitoringService",
"AdminAuditService",
]
@@ -0,0 +1,159 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台坐席管理服务
# =============================================================================
import logging
from datetime import datetime
from typing import Any, Dict, List, Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.agent import Agent
logger = logging.getLogger(__name__)
class AdminAgentService:
"""管理后台坐席管理服务。
提供坐席的增删改查功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def list_agents(
self,
is_active: Optional[bool] = None,
) -> List[Dict[str, Any]]:
"""获取坐席列表。
Args:
is_active: 是否激活(可选)
Returns:
List[Dict]: 坐席列表
"""
stmt = select(Agent)
if is_active is not None:
stmt = stmt.where(Agent.is_active == is_active) # noqa: E712
stmt = stmt.order_by(Agent.name)
result = await self.db.execute(stmt)
agents = result.scalars().all()
return [
{
"agent_id": a.agent_id,
"name": a.name,
"is_active": a.is_active,
"max_sessions": a.max_sessions,
"created_at": a.created_at.isoformat() if a.created_at else None,
}
for a in agents
]
async def create_agent(
self,
agent_id: str,
name: str,
max_sessions: int = 5,
) -> Dict[str, Any]:
"""创建坐席。
Args:
agent_id: 坐席ID
name: 坐席名称
max_sessions: 最大服务会话数
Returns:
Dict: 创建的坐席信息
"""
# 检查是否已存在
stmt = select(Agent).where(Agent.agent_id == agent_id)
result = await self.db.execute(stmt)
existing = result.scalar_one_or_none()
if existing:
raise ValueError(f"坐席已存在: {agent_id}")
agent = Agent(
agent_id=agent_id,
name=name,
max_sessions=max_sessions,
is_active=True,
)
self.db.add(agent)
await self.db.flush()
logger.info(f"创建坐席: {agent_id} - {name}")
return {
"agent_id": agent.agent_id,
"name": agent.name,
"is_active": agent.is_active,
"max_sessions": agent.max_sessions,
}
async def update_agent(
self,
agent_id: str,
name: Optional[str] = None,
max_sessions: Optional[int] = None,
is_active: Optional[bool] = None,
) -> Dict[str, Any]:
"""更新坐席信息。
Args:
agent_id: 坐席ID
name: 坐席名称(可选)
max_sessions: 最大服务会话数(可选)
is_active: 是否激活(可选)
Returns:
Dict: 更新后的坐席信息
"""
stmt = select(Agent).where(Agent.agent_id == agent_id)
result = await self.db.execute(stmt)
agent = result.scalar_one_or_none()
if not agent:
raise ValueError(f"坐席不存在: {agent_id}")
if name is not None:
agent.name = name
if max_sessions is not None:
agent.max_sessions = max_sessions
if is_active is not None:
agent.is_active = is_active
self.db.add(agent)
await self.db.flush()
logger.info(f"更新坐席: {agent_id}")
return {
"agent_id": agent.agent_id,
"name": agent.name,
"is_active": agent.is_active,
"max_sessions": agent.max_sessions,
}
async def delete_agent(self, agent_id: str) -> None:
"""删除坐席(软删除)。
Args:
agent_id: 坐席ID
"""
stmt = select(Agent).where(Agent.agent_id == agent_id)
result = await self.db.execute(stmt)
agent = result.scalar_one_or_none()
if not agent:
raise ValueError(f"坐席不存在: {agent_id}")
# 软删除:设置为非激活
agent.is_active = False
self.db.add(agent)
await self.db.flush()
logger.info(f"删除坐席: {agent_id}")
@@ -0,0 +1,209 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台审计服务
# =============================================================================
import logging
from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional
from sqlalchemy import and_, desc, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.agent import Agent
from app.models.conversation import Conversation
logger = logging.getLogger(__name__)
class AdminAuditService:
"""管理后台审计服务。
提供会话审计、坐席绩效和系统日志功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def list_audit_conversations(
self,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
agent_id: Optional[str] = None,
page: int = 1,
page_size: int = 50,
) -> Dict[str, Any]:
"""获取审计会话列表。
Args:
start_date: 开始日期 (ISO格式)
end_date: 结束日期 (ISO格式)
agent_id: 坐席ID(可选)
page: 页码
page_size: 每页数量
Returns:
Dict: 审计数据
"""
conditions = [Conversation.status == "resolved"]
if start_date:
start = datetime.fromisoformat(start_date)
conditions.append(Conversation.updated_at >= start)
if end_date:
end = datetime.fromisoformat(end_date)
conditions.append(Conversation.updated_at <= end)
if agent_id:
conditions.append(Conversation.assigned_agent_id == agent_id)
# 查询会话
stmt = select(Conversation).where(and_(*conditions))
stmt = stmt.order_by(desc(Conversation.updated_at))
stmt = stmt.offset((page - 1) * page_size).limit(page_size)
result = await self.db.execute(stmt)
sessions = result.scalars().all()
# 查询总数
count_stmt = select(func.count(Conversation.id)).where(and_(*conditions))
count_result = await self.db.execute(count_stmt)
total = count_result.scalar() or 0
return {
"conversations": [
{
"id": str(s.id),
"employee_name": s.employee_name,
"department": s.department,
"assigned_agent_id": s.assigned_agent_id,
"status": s.status,
"urgency_score": s.urgency_score,
"impact_scope": s.impact_scope,
"created_at": s.created_at.isoformat() if s.created_at else None,
"updated_at": s.updated_at.isoformat() if s.updated_at else None,
}
for s in sessions
],
"total": total,
"page": page,
"page_size": page_size,
}
async def get_audit_conversation_detail(
self,
conversation_id: str,
) -> Dict[str, Any]:
"""获取审计会话详情。
Args:
conversation_id: 会话ID
Returns:
Dict: 会话详情
"""
stmt = select(Conversation).where(Conversation.id == conversation_id)
result = await self.db.execute(stmt)
conversation = result.scalar_one_or_none()
if not conversation:
raise ValueError(f"会话不存在: {conversation_id}")
return {
"id": str(conversation.id),
"employee_id": conversation.employee_id,
"employee_name": conversation.employee_name,
"department": conversation.department,
"position": conversation.position,
"level": conversation.level,
"assigned_agent_id": conversation.assigned_agent_id,
"collaborating_agent_ids": conversation.collaborating_agent_ids,
"status": conversation.status,
"urgency_score": conversation.urgency_score,
"tags": conversation.tags,
"emotion_state": conversation.emotion_state,
"impact_scope": conversation.impact_scope,
"is_blocking": conversation.is_blocking,
"last_message_summary": conversation.last_message_summary,
"created_at": conversation.created_at.isoformat() if conversation.created_at else None,
"updated_at": conversation.updated_at.isoformat() if conversation.updated_at else None,
}
async def get_agent_performance(
self,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
) -> List[Dict[str, Any]]:
"""获取坐席绩效数据。
Args:
start_date: 开始日期 (ISO格式)
end_date: 结束日期 (ISO格式)
Returns:
List[Dict]: 绩效数据列表
"""
# 构建日期条件
conditions = [Conversation.status == "resolved"]
if start_date:
start = datetime.fromisoformat(start_date)
conditions.append(Conversation.updated_at >= start)
if end_date:
end = datetime.fromisoformat(end_date)
conditions.append(Conversation.updated_at <= end)
# 按坐席分组统计
stmt = select(
Conversation.assigned_agent_id,
func.count(Conversation.id).label("resolved_count"),
func.avg(Conversation.urgency_score).label("avg_urgency"),
).where(and_(*conditions)).group_by(Conversation.assigned_agent_id)
result = await self.db.execute(stmt)
rows = result.fetchall()
# 补充坐席名称
agent_stmt = select(Agent.agent_id, Agent.name)
agent_result = await self.db.execute(agent_stmt)
agent_map = {a.agent_id: a.name for a in agent_result.fetchall()}
performance = []
for row in rows:
if row.assigned_agent_id:
performance.append({
"agent_id": row.assigned_agent_id,
"agent_name": agent_map.get(row.assigned_agent_id, "未知"),
"resolved_count": row.resolved_count,
"avg_urgency": float(row.avg_urgency or 0),
})
return sorted(performance, key=lambda x: x["resolved_count"], reverse=True)
async def get_system_logs(
self,
level: Optional[str] = None,
page: int = 1,
page_size: int = 50,
) -> Dict[str, Any]:
"""获取系统日志。
Args:
level: 日志级别 (可选)
page: 页码
page_size: 每页数量
Returns:
Dict: 日志数据
"""
# TODO: 实现系统日志查询
# 当前日志存储在文件系统中,未持久化到数据库
# 后续可考虑接入日志服务(如 ELK)
return {
"logs": [],
"total": 0,
"page": page,
"page_size": page_size,
}
@@ -0,0 +1,161 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台配置服务
# =============================================================================
import json
import logging
from datetime import datetime
from typing import Any, Dict, List, Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.system_config import SystemConfig
logger = logging.getLogger(__name__)
# 配置分组映射
CONFIG_GROUP_MAP = {
"hand_raise": {
"label": "举手相关",
"keys": ["hand_raise_keywords"],
},
"emotion": {
"label": "情绪识别",
"keys": [
"emotion_keywords_angry",
"emotion_keywords_urgent",
"emotion_keywords_worried",
],
},
"urgency": {
"label": "紧急度评分",
"keys": [
"urgency_base_keyword_score",
"urgency_emotion_bonus",
"urgency_vip_bonus",
"urgency_repeat_bonus",
],
},
"queue": {
"label": "队列设置",
"keys": ["polling_interval_seconds"],
},
"token": {
"label": "令牌设置",
"keys": ["access_token_buffer_seconds"],
},
"emergency": {
"label": "应急模式",
"keys": ["emergency_mode"],
},
}
class AdminConfigService:
"""管理后台配置服务。
提供系统配置管理功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def get_config_groups(self) -> List[Dict[str, Any]]:
"""获取配置分组列表。
Returns:
List[Dict]: 配置分组列表
"""
# 查询所有配置
stmt = select(SystemConfig)
result = await self.db.execute(stmt)
configs = result.scalars().all()
# 按分组整理
config_map = {c.config_key: c for c in configs}
groups = []
for group_id, group_info in CONFIG_GROUP_MAP.items():
group_configs = []
for key in group_info["keys"]:
if key in config_map:
config = config_map[key]
value = config.config_value
# 尝试解析 JSON
if value and value.startswith("["):
try:
value = json.loads(value)
except Exception:
pass
group_configs.append({
"key": config.config_key,
"value": value,
"description": config.description,
})
if group_configs:
groups.append({
"id": group_id,
"label": group_info["label"],
"configs": group_configs,
})
logger.debug(f"获取配置分组: {len(groups)} 个分组")
return groups
async def update_config(
self,
key: str,
value: Any,
) -> Dict[str, Any]:
"""更新配置。
Args:
key: 配置键
value: 配置值
Returns:
Dict: 更新后的配置
"""
# 查询配置
stmt = select(SystemConfig).where(SystemConfig.config_key == key)
result = await self.db.execute(stmt)
config = result.scalar_one_or_none()
if not config:
raise ValueError(f"配置项不存在: {key}")
# 序列化值
if isinstance(value, (list, dict)):
serialized_value = json.dumps(value, ensure_ascii=False)
else:
serialized_value = str(value)
config.config_value = serialized_value
config.updated_at = datetime.now()
self.db.add(config)
await self.db.flush()
logger.info(f"更新配置: {key} = {serialized_value}")
return {
"key": key,
"value": value,
}
async def get_config_history(
self,
key: str,
) -> List[Dict[str, Any]]:
"""获取配置历史变更记录。
Args:
key: 配置键
Returns:
List[Dict]: 变更历史列表
"""
# TODO: 实现配置历史记录功能
# 当前 SystemConfig 表没有 history 字段
return []
@@ -0,0 +1,125 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台仪表盘服务
# =============================================================================
import logging
from datetime import datetime, timedelta, timezone
from typing import Optional
from sqlalchemy import and_, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.agent import Agent
from app.models.conversation import Conversation
from app.models.message import Message
logger = logging.getLogger(__name__)
class AdminDashboardService:
"""管理后台仪表盘服务。
提供系统概览数据统计功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def get_dashboard_overview(
self,
) -> dict:
"""获取仪表盘概览数据。
Returns:
dict: 包含各项统计指标的字典
"""
now = datetime.now(timezone.utc)
today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
week_start = today_start - timedelta(days=7)
month_start = today_start.replace(day=1)
# 1. 今日新建会话数
today_new_stmt = select(func.count(Conversation.id)).where(
Conversation.created_at >= today_start
)
today_new_result = await self.db.execute(today_new_stmt)
today_new_count = today_new_result.scalar() or 0
# 2. 今日结单数
today_resolved_stmt = select(func.count(Conversation.id)).where(
and_(
Conversation.status == "resolved",
Conversation.updated_at >= today_start,
)
)
today_resolved_result = await self.db.execute(today_resolved_stmt)
today_resolved_count = today_resolved_result.scalar() or 0
# 3. 今日平均响应时间(秒)- 粗略估算
# 假设响应时间 = 第一个消息到首次接单的时间
# 实际应通过会话时间戳计算
# 4. 当前排队数
queued_stmt = select(func.count(Conversation.id)).where(
Conversation.status == "queued"
)
queued_result = await self.db.execute(queued_stmt)
queued_count = queued_result.scalar() or 0
# 5. 当前服务中数
serving_stmt = select(func.count(Conversation.id)).where(
Conversation.status == "serving"
)
serving_result = await self.db.execute(serving_stmt)
serving_count = serving_result.scalar() or 0
# 6. 当前在线坐席数
# 实际应通过 Redis 或 Agent 表的 online_status 字段获取
online_agents_stmt = select(func.count(Agent.id)).where(
Agent.is_active == True # noqa: E712
)
online_agents_result = await self.db.execute(online_agents_stmt)
online_agents_count = online_agents_result.scalar() or 0
# 7. 本周会话趋势(按天统计)
weekly_stmt = select(
func.date(Conversation.created_at).label("date"),
func.count(Conversation.id).label("count"),
).where(
Conversation.created_at >= week_start
).group_by(
func.date(Conversation.created_at)
).order_by(
func.date(Conversation.created_at)
)
weekly_result = await self.db.execute(weekly_stmt)
weekly_trend = [
{"date": str(row.date), "count": row.count}
for row in weekly_result.fetchall()
]
# 8. 各状态会话数
status_counts_stmt = select(
Conversation.status,
func.count(Conversation.id).label("count"),
).group_by(Conversation.status)
status_result = await self.db.execute(status_counts_stmt)
status_counts = {
row.status: row.count for row in status_result.fetchall()
}
# 9. 平均满意度评分(如果有)
# 暂时返回 0,后续接入满意度功能后补充
logger.debug("获取仪表盘概览数据完成")
return {
"today_new": today_new_count,
"today_resolved": today_resolved_count,
"avg_response_time": 0, # TODO: 计算平均响应时间
"queued": queued_count,
"serving": serving_count,
"online_agents": online_agents_count,
"weekly_trend": weekly_trend,
"status_counts": status_counts,
"satisfaction_score": 0, # TODO: 满意度评分
}
@@ -0,0 +1,149 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台集成管理服务
# =============================================================================
import json
import logging
from typing import Any, Dict, List, Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.system_config import SystemConfig
logger = logging.getLogger(__name__)
# 预定义的集成配置模板
INTEGRATION_TEMPLATES = {
"dify": {
"name": "Dify",
"description": "AI 对话服务",
"type": "url_key",
"fields": ["base_url", "api_key"],
},
"ragflow": {
"name": "RAGFlow",
"description": "知识库检索",
"type": "url_key",
"fields": ["base_url", "api_key"],
},
"huorong": {
"name": "火绒安全",
"description": "终端安全",
"type": "access_key",
"fields": ["access_key_id", "access_key_secret"],
},
"lianruan": {
"name": "联软",
"description": "终端管理",
"type": "account_password",
"fields": ["base_url", "username", "password"],
},
}
class AdminIntegrationService:
"""管理后台集成管理服务。
提供外部系统集成配置功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def get_integrations(self) -> List[Dict[str, Any]]:
"""获取集成列表。
Returns:
List[Dict]: 集成列表
"""
# 查询所有集成配置
stmt = select(SystemConfig).where(
SystemConfig.config_key.like("integration_%")
)
result = await self.db.execute(stmt)
configs = result.scalars().all()
# 整理为集成列表
integrations = []
for template_id, template in INTEGRATION_TEMPLATES.items():
config_key = f"integration_{template_id}_config"
enabled_key = f"integration_{template_id}_enabled"
# 查找配置
config_value = None
enabled = False
for c in configs:
if c.config_key == config_key:
try:
config_value = json.loads(c.config_value)
except Exception:
config_value = c.config_value
elif c.config_key == enabled_key:
enabled = c.config_value == "true"
integrations.append({
"id": template_id,
"name": template["name"],
"description": template["description"],
"type": template["type"],
"enabled": enabled,
"config": config_value,
})
logger.debug(f"获取集成列表: {len(integrations)}")
return integrations
async def update_integration(
self,
integration_id: str,
enabled: bool,
config: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""更新集成配置。
Args:
integration_id: 集成ID
enabled: 是否启用
config: 配置(可选)
Returns:
Dict: 更新后的集成信息
"""
if integration_id not in INTEGRATION_TEMPLATES:
raise ValueError(f"不支持的集成: {integration_id}")
template = INTEGRATION_TEMPLATES[integration_id]
# 更新启用状态
enabled_key = f"integration_{integration_id}_enabled"
await self._upsert_system_config(enabled_key, "true" if enabled else "false")
# 更新配置
if config:
config_key = f"integration_{integration_id}_config"
config_value = json.dumps(config, ensure_ascii=False)
await self._upsert_system_config(config_key, config_value)
logger.info(f"更新集成: {integration_id}, enabled={enabled}")
return {
"id": integration_id,
"name": template["name"],
"enabled": enabled,
"config": config,
}
async def _upsert_system_config(self, key: str, value: str) -> None:
"""插入或更新系统配置。"""
stmt = select(SystemConfig).where(SystemConfig.config_key == key)
result = await self.db.execute(stmt)
config = result.scalar_one_or_none()
if config:
config.config_value = value
else:
config = SystemConfig(config_key=key, config_value=value)
self.db.add(config)
await self.db.flush()
@@ -0,0 +1,83 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台审核服务
# =============================================================================
import logging
from typing import Any, Dict, List, Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.quick_reply_template import QuickReplyTemplate
logger = logging.getLogger(__name__)
class AdminModerationService:
"""管理后台审核服务。
提供快速回复审核功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def list_pending_quick_replies(
self,
) -> List[Dict[str, Any]]:
"""获取待审核的快速回复列表。
Returns:
List[Dict]: 待审核列表
"""
stmt = select(QuickReplyTemplate).where(
QuickReplyTemplate.status == "pending"
)
result = await self.db.execute(stmt)
templates = result.scalars().all()
return [
{
"id": t.id,
"category": t.category,
"title": t.title,
"content": t.content,
"variables": t.variables,
"sort_order": t.sort_order,
"created_at": t.created_at.isoformat() if t.created_at else None,
}
for t in templates
]
async def review_quick_reply(
self,
template_id: int,
approved: bool,
) -> Dict[str, Any]:
"""审核快速回复。
Args:
template_id: 模板ID
approved: 是否通过
Returns:
Dict: 审核结果
"""
stmt = select(QuickReplyTemplate).where(
QuickReplyTemplate.id == template_id
)
result = await self.db.execute(stmt)
template = result.scalar_one_or_none()
if not template:
raise ValueError(f"快速回复模板不存在: {template_id}")
template.status = "approved" if approved else "rejected"
self.db.add(template)
await self.db.flush()
logger.info(f"审核快速回复: {template_id}, approved={approved}")
return {
"id": template.id,
"status": template.status,
}
@@ -0,0 +1,130 @@
# =============================================================================
# 企微IT智能服务台 — 管理后台监控服务
# =============================================================================
import logging
from datetime import datetime, timedelta, timezone
from typing import Any, Dict, List, Optional
from sqlalchemy import and_, desc, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.agent import Agent
from app.models.conversation import Conversation
logger = logging.getLogger(__name__)
class AdminMonitoringService:
"""管理后台监控服务。
提供会话监控和分配模式管理功能。
"""
def __init__(self, db: AsyncSession):
self.db = db
async def get_monitor_sessions(
self,
status: Optional[str] = None,
page: int = 1,
page_size: int = 50,
) -> Dict[str, Any]:
"""获取监控会话列表。
Args:
status: 状态过滤(可选)
page: 页码
page_size: 每页数量
Returns:
Dict: 监控数据
"""
conditions = []
if status:
conditions.append(Conversation.status == status)
# 查询会话
stmt = select(Conversation)
if conditions:
stmt = stmt.where(and_(*conditions))
stmt = stmt.order_by(desc(Conversation.updated_at))
stmt = stmt.offset((page - 1) * page_size).limit(page_size)
result = await self.db.execute(stmt)
sessions = result.scalars().all()
# 查询总数
from sqlalchemy import func
count_stmt = select(func.count(Conversation.id))
if conditions:
count_stmt = count_stmt.where(and_(*conditions))
count_result = await self.db.execute(count_stmt)
total = count_result.scalar() or 0
return {
"sessions": [
{
"id": str(s.id),
"employee_name": s.employee_name,
"status": s.status,
"assigned_agent_id": s.assigned_agent_id,
"urgency_score": s.urgency_score,
"last_message_at": s.last_message_at.isoformat() if s.last_message_at else None,
"last_message_summary": s.last_message_summary,
}
for s in sessions
],
"total": total,
"page": page,
"page_size": page_size,
}
async def get_assignment_mode(self) -> Dict[str, str]:
"""获取当前分配模式。
Returns:
Dict: 分配模式
"""
from app.models.system_config import SystemConfig
stmt = select(SystemConfig).where(
SystemConfig.config_key == "assignment_mode"
)
result = await self.db.execute(stmt)
config = result.scalar_one_or_none()
return {
"mode": config.config_value if config else "auto",
}
async def update_assignment_mode(
self,
mode: str,
) -> Dict[str, str]:
"""更新分配模式。
Args:
mode: 分配模式 (auto/manual)
Returns:
Dict: 更新后的分配模式
"""
from app.models.system_config import SystemConfig
stmt = select(SystemConfig).where(
SystemConfig.config_key == "assignment_mode"
)
result = await self.db.execute(stmt)
config = result.scalar_one_or_none()
if config:
config.config_value = mode
else:
config = SystemConfig(config_key="assignment_mode", config_value=mode)
self.db.add(config)
await self.db.flush()
logger.info(f"更新分配模式: {mode}")
return {"mode": mode}