docs: 移动蓝绿部署指南到 troubleshooting 目录

This commit is contained in:
Simon
2026-07-05 17:03:36 +08:00
parent ab90db3d3d
commit ca7c6d937a
91 changed files with 4841 additions and 406 deletions
+111 -2
View File
@@ -4,16 +4,27 @@
# 说明:提供员工相关的管理接口
# 接口列表:
# PUT /api/employees/{employee_id}/it-level — 更新员工IT技能等级
# POST /api/employees/{employee_id}/avatar/refresh — 手动刷新员工头像
# =============================================================================
from typing import Optional
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field, field_validator
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
import redis.asyncio as aioredis
from app.utils.response import success_response
from app.schemas.employee import VALID_IT_LEVELS, VALID_LEVEL_SOURCES
from app.database import get_db
from app.core.config import settings
from app.models.employee import Employee
from app.dependencies import dep_redis
# 导入日志
import logging
logger = logging.getLogger(__name__)
# 创建路由器
router = APIRouter(prefix="/employees", tags=["员工管理"])
@@ -114,3 +125,101 @@ async def update_employee_it_level(
it_level_source=request.source,
message=f"IT等级已从 {level_names.get(old_level, old_level)} 调整为 {level_names.get(request.it_level, request.it_level)}",
).model_dump())
# --------------------------------------------------------------------------
# 头像刷新 API
# --------------------------------------------------------------------------
class AvatarRefreshResponse(BaseModel):
"""头像刷新响应 Schema。"""
employee_id: str
avatar: str
message: str
async def get_redis() -> aioredis.Redis:
"""获取Redis客户端依赖"""
redis = await dep_redis()
if redis is None:
raise HTTPException(status_code=500, detail="Redis连接不可用")
return redis
@router.post("/{employee_id}/avatar/refresh", response_model=dict)
async def refresh_employee_avatar(
employee_id: str,
db: AsyncSession = Depends(get_db),
redis: aioredis.Redis = Depends(get_redis),
):
"""手动刷新员工头像。
调用企微通讯录API获取最新头像URL,更新数据库并刷新Redis缓存。
支持手动触发头像更新,适用于头像URL过期或需要立即更新的场景。
Args:
employee_id: 员工ID
Returns:
更新后的头像URL
"""
from datetime import datetime
from app.services.session_service import SessionService
# 1. 查找员工记录
result = await db.execute(
select(Employee).where(
Employee.employee_id == employee_id,
Employee.corp_id == settings.wecom_corp_id
)
)
employee = result.scalars().first()
if not employee:
raise HTTPException(status_code=404, detail=f"员工不存在: {employee_id}")
# 2. 使用 SessionService 从企微API获取最新头像
session_service = SessionService(db, redis_client=redis)
new_avatar = ""
try:
# 调用企微API获取最新头像
from app.services.wecom_service import WeComService
wecom_service = WeComService()
user_info = await wecom_service.get_user_info(employee_id)
new_avatar = user_info.get("avatar", "")
logger.info(f"企微API返回头像: employee_id={employee_id}, avatar={'有值(' + str(len(new_avatar)) + '字符)' if new_avatar else ''}")
# 3. 更新数据库
employee.avatar = new_avatar
employee.avatar_updated_at = datetime.utcnow()
await db.commit()
# 4. 刷新Redis缓存
cache_key = f"employee:avatar:{employee_id}"
if redis:
try:
if new_avatar:
await redis.setex(cache_key, SessionService.AVATAR_CACHE_TTL, new_avatar)
else:
# 如果头像为空,删除缓存
await redis.delete(cache_key)
except Exception as e:
logger.warning(f"刷新Redis头像缓存失败: employee_id={employee_id}, error={e}")
return success_response(data=AvatarRefreshResponse(
employee_id=employee_id,
avatar=new_avatar,
message="头像刷新成功" if new_avatar else "企微API未返回头像,已使用原头像",
).model_dump())
except Exception as e:
logger.error(f"刷新头像失败: employee_id={employee_id}, error={e}")
# 返回原头像,不阻塞流程
return success_response(data=AvatarRefreshResponse(
employee_id=employee_id,
avatar=employee.avatar,
message=f"头像刷新失败,使用原头像: {str(e)}",
).model_dump())