From 4e4df248ca22150d7489ad101c10df7b91b8c37e Mon Sep 17 00:00:00 2001 From: Karlcarlo Date: Fri, 31 Jul 2026 15:04:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20openid=20=E5=8D=B3=E5=8F=AF=E5=8C=BA?= =?UTF-8?q?=E5=88=86=E7=94=A8=E6=88=B7=20=E2=80=94=20openid-login=20?= =?UTF-8?q?=E9=99=8D=E7=BA=A7=E5=BB=BA=E6=A1=A3=EF=BC=88CRMEB=20=E6=9F=A5?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E4=B9=9F=E5=BB=BA=E6=A1=A3=EF=BC=89+=20?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=B8=AD=E5=BF=83=E5=BE=AE=E4=BF=A1=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E7=99=BB=E5=BD=95=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/routers/auth.py | 50 ++++++++++++++------------ frontend/src/app/pages/ProfilePage.tsx | 17 +++++++++ 2 files changed, 45 insertions(+), 22 deletions(-) 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 && ( +
+ +

+ 绑定手机号后可同步头像昵称,数据不丢失 +

+
+ )} {/* 基本信息 */}