docs: 移动蓝绿部署指南到 troubleshooting 目录
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
from typing import Any, List, Optional
|
||||
from uuid import UUID
|
||||
|
||||
from sqlalchemy import and_, case, desc, func, select
|
||||
@@ -43,15 +43,18 @@ class SessionService:
|
||||
self,
|
||||
db: AsyncSession,
|
||||
wecom_service: Optional[WecomService] = None,
|
||||
redis_client: Optional[Any] = None,
|
||||
):
|
||||
"""初始化会话状态管理服务。
|
||||
|
||||
Args:
|
||||
db: 异步数据库会话
|
||||
wecom_service: 企微 API 服务(用于坐席接入时发送通知,可选)
|
||||
redis_client: Redis客户端(用于头像缓存,可选)
|
||||
"""
|
||||
self.db = db
|
||||
self.wecom_service = wecom_service
|
||||
self.redis_client = redis_client
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 创建会话
|
||||
@@ -819,12 +822,16 @@ class SessionService:
|
||||
# 邀请功能(P0-09~P0-11):坐席邀请员工/部门加入会话
|
||||
# ======================================================================
|
||||
|
||||
async def _get_employee_avatar(self, employee_id: str) -> str:
|
||||
"""获取员工头像URL。
|
||||
# 头像缓存 TTL:7天
|
||||
AVATAR_CACHE_TTL = 7 * 24 * 60 * 60
|
||||
|
||||
做什么:从 employees 表或企微通讯录API获取头像
|
||||
为什么:邀请参与者时需要展示头像,前端无法单独获取被邀请人头像
|
||||
优先级:employees 表(本地缓存) > 企微API(实时获取)
|
||||
async def _get_employee_avatar(self, employee_id: str) -> str:
|
||||
"""获取员工头像URL(带Redis缓存)。
|
||||
|
||||
优先级:
|
||||
1. Redis 缓存(最快)
|
||||
2. employees 表
|
||||
3. 企微API(获取后存入Redis缓存)
|
||||
|
||||
Args:
|
||||
employee_id: 企微员工UserID
|
||||
@@ -832,25 +839,57 @@ class SessionService:
|
||||
Returns:
|
||||
str: 头像URL,获取不到返回空字符串
|
||||
"""
|
||||
# 1. 优先从 employees 表查(本地缓存,速度快)
|
||||
cache_key = f"employee:avatar:{employee_id}"
|
||||
|
||||
# 1. 优先从 Redis 缓存获取
|
||||
if self.redis_client:
|
||||
try:
|
||||
cached_avatar = await self.redis_client.get(cache_key)
|
||||
if cached_avatar:
|
||||
logger.debug(f"从Redis缓存获取头像: employee_id={employee_id}")
|
||||
return cached_avatar.decode("utf-8") if isinstance(cached_avatar, bytes) else cached_avatar
|
||||
except Exception as e:
|
||||
logger.warning(f"从Redis获取头像缓存失败: employee_id={employee_id}, error={e}")
|
||||
|
||||
# 2. 从 employees 表获取(需要匹配 corp_id)
|
||||
from app.models.employee import Employee
|
||||
from app.core.config import settings
|
||||
result = await self.db.execute(
|
||||
select(Employee.avatar).where(Employee.employee_id == employee_id)
|
||||
select(Employee.avatar).where(
|
||||
Employee.employee_id == employee_id,
|
||||
Employee.corp_id == settings.wecom_corp_id
|
||||
)
|
||||
)
|
||||
row = result.first()
|
||||
if row and row[0]:
|
||||
logger.info(f"从employees表获取头像: employee_id={employee_id}, avatar={row[0][:50]}...")
|
||||
# 存入 Redis 缓存
|
||||
if self.redis_client:
|
||||
try:
|
||||
await self.redis_client.setex(cache_key, self.AVATAR_CACHE_TTL, row[0])
|
||||
except Exception as e:
|
||||
logger.warning(f"存入Redis头像缓存失败: employee_id={employee_id}, error={e}")
|
||||
return row[0]
|
||||
else:
|
||||
logger.info(f"employees表无头像记录: employee_id={employee_id}")
|
||||
|
||||
# 2. employees 表没有,尝试从企微通讯录API获取
|
||||
# 3. employees 表没有,尝试从企微通讯录API获取
|
||||
avatar = ""
|
||||
if self.wecom_service:
|
||||
try:
|
||||
user_info = await self.wecom_service.get_user_info(employee_id)
|
||||
avatar = user_info.get("avatar", "")
|
||||
return avatar
|
||||
logger.info(f"企微API返回头像: employee_id={employee_id}, avatar={'有值(' + str(len(avatar)) + '字符)' if avatar else '空'}")
|
||||
# 存入 Redis 缓存(即使为空也缓存,避免频繁请求API)
|
||||
if self.redis_client and avatar:
|
||||
try:
|
||||
await self.redis_client.setex(cache_key, self.AVATAR_CACHE_TTL, avatar)
|
||||
except Exception as e:
|
||||
logger.warning(f"存入Redis头像缓存失败: employee_id={employee_id}, error={e}")
|
||||
except Exception as e:
|
||||
logger.warning(f"从企微API获取头像失败: employee_id={employee_id}, error={e}")
|
||||
|
||||
return ""
|
||||
return avatar
|
||||
|
||||
async def invite_participants(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user