Compare commits
2 Commits
30d3104e76
...
0e97812c03
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e97812c03 | |||
| a4ac682ad0 |
@ -26,6 +26,11 @@ class BindOpenIdRequest(BaseModel):
|
||||
open_id: str
|
||||
|
||||
|
||||
class BindOpenIdByCodeRequest(BaseModel):
|
||||
"""通过 wx.login code 绑定微信 OpenID"""
|
||||
code: str
|
||||
|
||||
|
||||
@router.post("/login")
|
||||
def login(
|
||||
payload: LoginRequest, # 登录请求体,包含用户名、密码、角色类型
|
||||
@ -51,7 +56,7 @@ def wechat_login(
|
||||
"""微信手机号一键登录接口
|
||||
|
||||
用途:通过微信手机号授权登录,自动匹配系统用户并绑定 open_id。
|
||||
请求参数:WechatLoginRequest(code、encrypted_data、iv)。
|
||||
请求参数:WechatLoginRequest(code、phone_code)。
|
||||
返回值:登录结果,包含 token 等认证信息。
|
||||
权限要求:无需认证(公开接口)。
|
||||
"""
|
||||
@ -103,3 +108,20 @@ def bind_openid(
|
||||
"""
|
||||
wechat_notification_service.bind_open_id(session, current_user["user_id"], payload.open_id)
|
||||
return success_payload({"success": True})
|
||||
|
||||
|
||||
@router.post("/bind-openid-by-code")
|
||||
def bind_openid_by_code(
|
||||
payload: BindOpenIdByCodeRequest, # 通过 code 绑定
|
||||
auth_service: AuthService = Depends(get_auth_service), # 注入认证服务
|
||||
session: Session = Depends(get_db_session), # 注入数据库会话
|
||||
current_user: dict = Depends(get_current_user), # 当前登录用户
|
||||
) -> dict:
|
||||
"""通过 wx.login code 绑定微信 OpenID
|
||||
|
||||
用途:密码登录后调用,用 code 换取 open_id 并绑定到当前用户。
|
||||
请求参数:BindOpenIdByCodeRequest(code - wx.login 获取的临时凭证)。
|
||||
返回值:绑定结果 {"success": true}。
|
||||
权限要求:必须已登录。
|
||||
"""
|
||||
return success_payload(auth_service.bind_openid_by_code(current_user["user_id"], payload.code, session))
|
||||
|
||||
@ -273,6 +273,40 @@ class AuthService:
|
||||
pass
|
||||
return ""
|
||||
|
||||
def bind_openid_by_code(self, user_id: int, code: str, session: Session | None = None) -> dict:
|
||||
"""通过 wx.login code 绑定 open_id 到指定用户。
|
||||
|
||||
用于密码登录后自动绑定 open_id,为微信订阅消息通知做准备。
|
||||
|
||||
Args:
|
||||
user_id: 用户 ID
|
||||
code: wx.login() 获取的临时凭证
|
||||
session: 数据库会话
|
||||
|
||||
Returns:
|
||||
{"success": True}
|
||||
|
||||
被调用路由: auth.py - POST /auth/bind-openid-by-code
|
||||
"""
|
||||
if session is None:
|
||||
raise AppException(code=ErrorCode.INTERNAL_ERROR, message="数据库连接不可用", status_code=500)
|
||||
|
||||
settings = self.settings
|
||||
if not settings.wechat_app_id or not settings.wechat_app_secret:
|
||||
return {"success": True, "skipped": True}
|
||||
|
||||
_, open_id = self._code2session(code, settings)
|
||||
if not open_id:
|
||||
return {"success": True, "skipped": True}
|
||||
|
||||
user = self.repository.get_user(session, user_id)
|
||||
if user is not None:
|
||||
user.open_id = open_id
|
||||
session.add(user)
|
||||
session.commit()
|
||||
|
||||
return {"success": True}
|
||||
|
||||
def get_me(self, token: str, session: Session | None = None) -> dict | None:
|
||||
"""根据 Token 获取当前用户信息(无需重新登录)。
|
||||
|
||||
|
||||
@ -36,6 +36,21 @@ Page({
|
||||
auth.setToken(data.token);
|
||||
auth.setUser(data);
|
||||
|
||||
// 密码登录成功后自动绑定 open_id(为微信消息通知做准备)
|
||||
try {
|
||||
var loginCode = await new Promise(function (resolve, reject) {
|
||||
wx.login({ success: resolve, fail: reject });
|
||||
});
|
||||
await app.request({
|
||||
url: "/api/auth/bind-openid-by-code",
|
||||
method: "POST",
|
||||
data: { code: loginCode.code },
|
||||
});
|
||||
} catch (bindErr) {
|
||||
// 绑定失败不影响登录
|
||||
console.log("open_id 绑定跳过:", bindErr.message);
|
||||
}
|
||||
|
||||
wx.showToast({
|
||||
title: "欢迎," + (data.real_name || data.username),
|
||||
icon: "success",
|
||||
|
||||
@ -11,8 +11,9 @@ Page({
|
||||
},
|
||||
|
||||
handleGetPhoneNumber: async function (e) {
|
||||
console.log("[DEBUG] getPhoneNumber event:", JSON.stringify(e.detail));
|
||||
if (e.detail.errMsg !== "getPhoneNumber:ok") {
|
||||
this.setData({ message: "您拒绝了手机号授权" });
|
||||
this.setData({ message: "授权失败:" + (e.detail.errMsg || JSON.stringify(e.detail)) });
|
||||
return;
|
||||
}
|
||||
this.setData({ loading: true, message: "" });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user