v3.1 + 批次0: 智能回复重构基线 - ApprovalMatcher + 关键词降级 + 文档速修 + v4.0任务书面化
This commit is contained in:
@@ -9,13 +9,14 @@
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import List, Optional, Tuple
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
from uuid import UUID
|
||||
|
||||
from sqlalchemy import and_, case, desc, func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.conversation import Conversation
|
||||
from app.models.message import Message
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -212,3 +213,108 @@ class SessionQueryService:
|
||||
raise ERR_CONVERSATION_NOT_FOUND
|
||||
|
||||
return conversation
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 获取员工历史消息(跨会话聚合)
|
||||
# --------------------------------------------------------------------------
|
||||
async def get_employee_history_messages(
|
||||
self,
|
||||
employee_id: str,
|
||||
limit: int = 50,
|
||||
before: Optional[str] = None,
|
||||
current_conversation_id: Optional[str] = None,
|
||||
) -> Tuple[List[Message], bool, Dict[str, str]]:
|
||||
"""获取员工的历史消息(跨会话聚合)。
|
||||
|
||||
将同一员工的所有会话消息合并为一条时间线,按时间排序。
|
||||
用于"历史会话"功能,让坐席查看员工过去的所有咨询记录。
|
||||
|
||||
查询逻辑:
|
||||
1. 查询 conversations 表中 employee_id = ? 的所有会话ID
|
||||
2. 查询 messages 表中 conversation_id IN (会话ID列表) 的消息
|
||||
3. 如有 before 参数,获取该消息的 created_at,只查更早的消息
|
||||
4. 按 created_at DESC 排序,取 limit + 1 条(多取1条判断 has_more)
|
||||
5. 对涉及的每个会话,查询其 sender_type='employee' 的最早一条消息,
|
||||
取前20字作为摘要
|
||||
6. 返回消息列表 + has_more + conversation_summaries
|
||||
|
||||
Args:
|
||||
employee_id: 员工企微 UserID
|
||||
limit: 每页消息数量(默认50)
|
||||
before: 游标消息ID,只查该消息之前的消息(向上翻页)
|
||||
current_conversation_id: 当前会话ID(仅用于标记,不影响查询逻辑)
|
||||
|
||||
Returns:
|
||||
tuple: (消息列表, 是否还有更多, {conversation_id: "前20字摘要"})
|
||||
"""
|
||||
# 1. 查询该员工的所有会话ID
|
||||
conv_stmt = select(Conversation.id).where(
|
||||
Conversation.employee_id == employee_id
|
||||
)
|
||||
conv_result = await self.db.execute(conv_stmt)
|
||||
conversation_ids = [row[0] for row in conv_result.all()]
|
||||
|
||||
if not conversation_ids:
|
||||
# 该员工没有任何会话
|
||||
return [], False, {}
|
||||
|
||||
# 2. 构建消息查询(跨会话聚合,按时间倒序)
|
||||
stmt = select(Message).where(
|
||||
Message.conversation_id.in_(conversation_ids)
|
||||
).order_by(Message.created_at.desc())
|
||||
|
||||
# 3. 如有 before 参数,获取该消息的 created_at,只查更早的消息
|
||||
if before:
|
||||
try:
|
||||
before_stmt = select(Message.created_at).where(
|
||||
Message.id == str(before)
|
||||
)
|
||||
before_result = await self.db.execute(before_stmt)
|
||||
before_time = before_result.scalar_one_or_none()
|
||||
if before_time:
|
||||
stmt = stmt.where(Message.created_at < before_time)
|
||||
except Exception:
|
||||
pass # before 参数格式错误,忽略
|
||||
|
||||
# 4. 取 limit + 1 条(多取1条判断 has_more)
|
||||
stmt = stmt.limit(limit + 1)
|
||||
result = await self.db.execute(stmt)
|
||||
messages = list(result.scalars().all())
|
||||
|
||||
# 判断是否还有更多消息
|
||||
has_more = len(messages) > limit
|
||||
if has_more:
|
||||
messages = messages[:limit]
|
||||
|
||||
# 5. 对涉及的每个会话,查询其 sender_type='employee' 的最早一条消息摘要
|
||||
involved_conv_ids = list(set(m.conversation_id for m in messages))
|
||||
conversation_summaries: Dict[str, str] = {}
|
||||
|
||||
for conv_id in involved_conv_ids:
|
||||
# 查询该会话中员工发送的最早一条消息
|
||||
summary_stmt = (
|
||||
select(Message.content)
|
||||
.where(
|
||||
and_(
|
||||
Message.conversation_id == conv_id,
|
||||
Message.sender_type == "employee",
|
||||
)
|
||||
)
|
||||
.order_by(Message.created_at.asc())
|
||||
.limit(1)
|
||||
)
|
||||
summary_result = await self.db.execute(summary_stmt)
|
||||
first_employee_msg = summary_result.scalar_one_or_none()
|
||||
if first_employee_msg:
|
||||
# 取前20字作为摘要
|
||||
conversation_summaries[conv_id] = first_employee_msg[:20]
|
||||
else:
|
||||
conversation_summaries[conv_id] = "未知会话"
|
||||
|
||||
logger.debug(
|
||||
f"查询员工历史消息: employee_id={employee_id}, "
|
||||
f"conv_count={len(conversation_ids)}, "
|
||||
f"msg_count={len(messages)}, has_more={has_more}"
|
||||
)
|
||||
|
||||
return messages, has_more, conversation_summaries
|
||||
|
||||
Reference in New Issue
Block a user