WIP-CHECKPOINT[auth-refactor]: 固化工程师崩溃前部分成果 + 同树其他未提交WIP(仅源码,不含密钥/二进制)-- 待重激活工程师续作

This commit is contained in:
Simon
2026-07-07 21:52:11 +08:00
parent 242c1967ff
commit fab75760e0
203 changed files with 21504 additions and 3345 deletions
+56 -29
View File
@@ -12,14 +12,19 @@
import logging
import os
from datetime import datetime
from typing import Optional
import redis.asyncio as aioredis
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.config import settings
from app.database import get_db
from app.dependencies import get_redis
from app.models.employee import Employee
from app.services.token_service import TokenService
from app.utils.response import success_response
logger = logging.getLogger(__name__)
@@ -67,6 +72,7 @@ async def dev_login(
department: str = Query("信息技术部", description="部门"),
avatar: Optional[str] = Query(None, description="头像 URL(可选)"),
redis: aioredis.Redis = Depends(get_redis),
db: AsyncSession = Depends(get_db),
):
"""开发模式 Mock 登录。
@@ -105,23 +111,51 @@ async def dev_login(
login_source="dev",
)
# Mock 登录时同步写入 employees 表(便于坐席端显示员工姓名)
from sqlalchemy import select
stmt = select(Employee).where(Employee.employee_id == userid)
result = await db.execute(stmt)
employee = result.scalars().first()
if employee:
# 更新已有记录
employee.name = name
employee.department = department
employee.avatar = avatar or ""
employee.avatar_updated_at = datetime.utcnow()
else:
# 创建新记录
employee = Employee(
corp_id=settings.wecom_corp_id,
employee_id=userid,
name=name,
department=department,
position="",
avatar=avatar or "",
avatar_updated_at=datetime.utcnow(),
)
db.add(employee)
# 清 Redis 头像缓存,确保下次读取数据库最新头像(要求 C:清缓存 + 更新时间一致)
if avatar:
try:
await redis.delete(f"employee:avatar:{userid}")
except Exception as e:
logger.warning(f"删除头像Redis缓存失败: userid={userid}, error={e}")
await db.commit()
logger.info(f"🧪 [DEV] 同步员工信息到 employees 表: userid={userid}, name={name}")
logger.info(f"🧪 [DEV] Mock 登录成功: userid={userid}, roles={roles}")
return {
"code": 0,
"message": "ok",
"data": {
"token": token,
"user": {
"userid": userid,
"name": name,
"department": department,
"avatar": avatar or "",
"roles": roles,
"login_source": "dev",
},
return success_response(data={
"token": token,
"user": {
"userid": userid,
"name": name,
"department": department,
"avatar": avatar or "",
"roles": roles,
"login_source": "dev",
},
}
})
# -----------------------------------------------------------------------------
@@ -133,11 +167,7 @@ async def dev_list_users():
if not _dev_mode_enabled():
raise HTTPException(status_code=403, detail="DEV_MODE not enabled")
return {
"code": 0,
"message": "ok",
"data": PRESET_DEV_USERS,
}
return success_response(data=PRESET_DEV_USERS)
# -----------------------------------------------------------------------------
@@ -149,13 +179,10 @@ async def dev_health():
if not _dev_mode_enabled():
raise HTTPException(status_code=403, detail="DEV_MODE not enabled")
return {
"code": 0,
"data": {
"dev_mode": True,
"env": os.getenv("APP_ENV", "unknown"),
"database_url": os.getenv("DATABASE_URL", "not set")[:50] + "...",
"redis_url": os.getenv("REDIS_URL", "not set"),
"preset_users": len(PRESET_DEV_USERS),
},
}
return success_response(data={
"dev_mode": True,
"env": os.getenv("APP_ENV", "unknown"),
"database_url": os.getenv("DATABASE_URL", "not set")[:50] + "...",
"redis_url": os.getenv("REDIS_URL", "not set"),
"preset_users": len(PRESET_DEV_USERS),
})