|
|
@@ -8,6 +8,7 @@ from sqlalchemy.orm import Session
|
|
|
|
|
|
from app.core.database import get_db
|
|
|
from app.core.response import error_response, success_response
|
|
|
+from app.services import wx_qr_session
|
|
|
from app.services.web_login_tokens import issue_web_login_tokens
|
|
|
from app.services.wechat_login_service import resolve_wechat_login_user
|
|
|
from app.services.wechat_mini_auth import (
|
|
|
@@ -56,3 +57,65 @@ def wechat_login(body: dict, db: Session = Depends(get_db)):
|
|
|
except ValueError as exc:
|
|
|
return error_response(403, str(exc))
|
|
|
return success_response(data)
|
|
|
+
|
|
|
+
|
|
|
+@router.post("/web-qr-scanned", response_model=dict)
|
|
|
+def web_qr_scanned(body: dict):
|
|
|
+ raw = (body.get("sessionId") or body.get("scene") or "").strip()
|
|
|
+ sid = wx_qr_session.resolve_session_id(raw) or raw
|
|
|
+ data = wx_qr_session.get_session(sid)
|
|
|
+ if not data or data.get("status") in ("expired", "consumed"):
|
|
|
+ return error_response(400, "二维码已过期,请在电脑上刷新后重扫")
|
|
|
+ wx_qr_session.mark_scanned(sid)
|
|
|
+ return success_response({"ok": True})
|
|
|
+
|
|
|
+
|
|
|
+@router.post("/web-qr-confirm", response_model=dict)
|
|
|
+def web_qr_confirm(body: dict, db: Session = Depends(get_db)):
|
|
|
+ raw = (body.get("sessionId") or body.get("scene") or "").strip()
|
|
|
+ sid = wx_qr_session.resolve_session_id(raw) or raw
|
|
|
+ data = wx_qr_session.get_session(sid)
|
|
|
+ if not data or data.get("status") in ("expired", "consumed", "failed"):
|
|
|
+ return error_response(400, "二维码已过期,请在电脑上刷新后重扫")
|
|
|
+ if data.get("status") == "success":
|
|
|
+ return success_response({"ok": True, "message": "电脑端即将登录"})
|
|
|
+
|
|
|
+ wx_qr_session.mark_scanned(sid)
|
|
|
+
|
|
|
+ login_code = (body.get("loginCode") or "").strip()
|
|
|
+ phone_code = (body.get("phoneCode") or "").strip()
|
|
|
+ if not login_code or not phone_code:
|
|
|
+ wx_qr_session.mark_failed(sid, "需要授权手机号才能完成扫码登录")
|
|
|
+ return error_response(400, "需要授权手机号才能完成扫码登录")
|
|
|
+
|
|
|
+ try:
|
|
|
+ sess = code2session(login_code)
|
|
|
+ phone = get_phone_number(phone_code)
|
|
|
+ except WechatMiniAuthError as exc:
|
|
|
+ wx_qr_session.mark_failed(sid, str(exc))
|
|
|
+ return error_response(400, str(exc))
|
|
|
+
|
|
|
+ user, err_msg, err_code = resolve_wechat_login_user(
|
|
|
+ db, openid=sess["openid"], phone=phone
|
|
|
+ )
|
|
|
+ if err_msg:
|
|
|
+ wx_qr_session.mark_failed(sid, err_msg)
|
|
|
+ return error_response(err_code or 400, err_msg)
|
|
|
+
|
|
|
+ unionid = (sess.get("unionid") or "").strip()
|
|
|
+ if unionid and not (getattr(user, "wx_unionid", None) or "").strip():
|
|
|
+ user.wx_unionid = unionid
|
|
|
+ user.update_time = datetime.now()
|
|
|
+ db.add(user)
|
|
|
+ db.commit()
|
|
|
+ db.refresh(user)
|
|
|
+
|
|
|
+ try:
|
|
|
+ tokens = issue_web_login_tokens(db, user)
|
|
|
+ except ValueError as exc:
|
|
|
+ wx_qr_session.mark_failed(sid, str(exc))
|
|
|
+ return error_response(403, str(exc))
|
|
|
+
|
|
|
+ if not wx_qr_session.mark_success(sid, tokens):
|
|
|
+ return error_response(400, "二维码已过期,请在电脑上刷新后重扫")
|
|
|
+ return success_response({"ok": True, "message": "电脑端即将登录,可关闭本页"})
|