diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index 5dee083..849862f 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -108,40 +108,46 @@ class OpenidRequest(BaseModel): @router.post("/openid-login") async def openid_login(req: OpenidRequest) -> TokenResponse: - """仅传 openid → 调 CRMEB 获取用户信息 → 创建/更新 User → 返回 token""" + """仅传 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"] + # 尝试从 CRMEB 拉取用户资料;失败(新用户/网络)时降级为匿名建档,openid 即身份 + nickname, phone, avatar = "", "", "" + try: + 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: + info = data.get("data") or {} + nickname = (info.get("nickname") or "").strip() + phone = (info.get("phone") or "").strip() + avatar = (info.get("avatar") or "").strip() + except Exception: + pass # CRMEB 不可用时仍允许 openid 建档 # 查找或创建用户 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, + name=nickname, + phone=phone or None, + avatar_url=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"] + if nickname: + user.name = nickname + if phone: + user.phone = phone + if avatar: + user.avatar_url = avatar await user.save() token = _build_token(user) diff --git a/frontend/src/app/pages/ProfilePage.tsx b/frontend/src/app/pages/ProfilePage.tsx index f475f4b..9b8f81d 100644 --- a/frontend/src/app/pages/ProfilePage.tsx +++ b/frontend/src/app/pages/ProfilePage.tsx @@ -24,6 +24,7 @@ import { Button } from "../components/ui/button"; import { Card } from "../components/ui/card"; import { Badge } from "../components/ui/badge"; import { useUser, getPregnancyStage } from "../context/UserContext"; +import bridge from "../services/bridge"; interface UserInfo { name: string; @@ -287,6 +288,22 @@ export function ProfilePage() { + + {/* 微信授权登录:未绑定手机号时显示,点击跳小程序登录页完善资料 */} + {!user.phone && ( +
+ 绑定手机号后可同步头像昵称,数据不丢失 +
+