wechat_login_service.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. """微信小程序登录业务:openid + 手机号一致性校验。"""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from typing import Optional, Tuple
  5. from sqlalchemy.orm import Session
  6. from app.crud.user import user_crud
  7. from app.models.models import SysUser
  8. from app.services.wechat_mini_auth import normalize_cn_mobile, phones_match
  9. def resolve_wechat_login_by_openid_only(
  10. db: Session, *, openid: str
  11. ) -> Tuple[Optional[SysUser], Optional[str], Optional[int]]:
  12. """已绑定 openid 时静默换票(无需手机号授权)。"""
  13. oid = (openid or "").strip()
  14. if not oid:
  15. return None, "微信未返回 openid", 400
  16. bound = user_crud.get_by_wx_openid(db, oid)
  17. if not bound:
  18. return None, "请授权手机号登录,或使用账号密码登录", 400
  19. if getattr(bound, "status", "1") != "1":
  20. return None, "账号已停用", 403
  21. return bound, None, None
  22. def resolve_wechat_login_user(
  23. db: Session, *, openid: str, phone: str
  24. ) -> Tuple[Optional[SysUser], Optional[str], Optional[int]]:
  25. """
  26. 根据 openid + 本次授权手机号解析可登录员工。
  27. Returns:
  28. (user, error_message, error_code)
  29. 成功时 error_message/error_code 为 None;失败时 user 为 None。
  30. """
  31. oid = (openid or "").strip()
  32. if not oid:
  33. return None, "微信未返回 openid", 400
  34. if not normalize_cn_mobile(phone):
  35. return None, "请授权手机号登录,或使用账号密码登录", 400
  36. bound = user_crud.get_by_wx_openid(db, oid)
  37. if bound:
  38. if not phones_match(getattr(bound, "phone_no", None), phone):
  39. return (
  40. None,
  41. "授权手机号与绑定账号不一致,请使用账号密码登录或联系管理员",
  42. 401,
  43. )
  44. return bound, None, None
  45. users = user_crud.list_active_by_phone_no(db, phone)
  46. if not users:
  47. return None, "未找到与该手机号匹配的员工账号,请使用账号密码登录", 401
  48. if len(users) > 1:
  49. return None, "手机号对应多个账号,请使用账号密码登录", 400
  50. user = users[0]
  51. other = user_crud.get_by_wx_openid(db, oid)
  52. if other and other.id != user.id:
  53. return None, "该微信已绑定其他账号", 409
  54. existing_oid = (getattr(user, "wx_openid", None) or "").strip()
  55. if existing_oid and existing_oid != oid:
  56. return None, "该账号已绑定其他微信,请联系管理员", 409
  57. user.wx_openid = oid
  58. user.update_time = datetime.now()
  59. db.add(user)
  60. db.commit()
  61. db.refresh(user)
  62. return user, None, None