feat: openid-login + avatar_url 修复

- 后端: 新增 /auth/openid-login 接口(调 CRMEB 补齐用户信息)
- 后端: config.py 新增 crmeb_base_url / crmeb_api_key 配置
- 后端: api.ts 新增 openid-login 接口声明
- 前端: LoginPage 改为走 openid-login(openid 单参登录)
- 前端: UserContext 修复 avatar_url 未映射导致头像不显示的问题
This commit is contained in:
2026-05-27 22:24:14 +08:00
parent bceb4f4619
commit 96a938e11b
5 changed files with 79 additions and 36 deletions

View File

@@ -5,6 +5,7 @@ import os
from fastapi import APIRouter, HTTPException
from jose import jwt
import httpx
from pydantic import BaseModel
from app.config import settings
@@ -101,6 +102,57 @@ async def params_login(req: ParamsLoginRequest) -> TokenResponse:
)
class OpenidRequest(BaseModel):
openid: str
@router.post("/openid-login")
async def openid_login(req: OpenidRequest) -> TokenResponse:
"""仅传 openid → 调 CRMEB 获取用户信息 → 创建/更新 User → 返回 token"""
if not settings.crmeb_base_url or not settings.crmeb_api_key:
raise HTTPException(status_code=500, detail="CRMEB 未配置")
async with httpx.AsyncClient() as client:
resp = await client.get(
f"{settings.crmeb_base_url}/api/internal/user-info",
params={"openid": req.openid},
headers={"X-Internal-Key": settings.crmeb_api_key},
timeout=10,
)
data = resp.json()
if data.get("code") != 200:
raise HTTPException(status_code=400, detail="获取用户信息失败")
info = data["data"]
# 查找或创建用户
user = await User.find_one(User.openid == req.openid)
if not user:
user = User(
openid=req.openid,
name=info.get("nickname", "") or "",
phone=info.get("phone") or None,
avatar_url=info.get("avatar") or None,
)
await user.insert()
else:
user.name = info.get("nickname", "") or user.name
if info.get("phone"):
user.phone = info["phone"]
if info.get("avatar"):
user.avatar_url = info["avatar"]
await user.save()
token = _build_token(user)
return TokenResponse(
token=token,
user_id=str(user.id),
openid=user.openid,
mobile=user.phone or "",
)
@router.post("/dev-login")
async def dev_login() -> TokenResponse:
"""开发环境:使用固定测试账号,不依赖微信"""