diff --git a/app/api/endpoints/wechat.py b/app/api/endpoints/wechat.py index 64897d8..bfa2631 100644 --- a/app/api/endpoints/wechat.py +++ b/app/api/endpoints/wechat.py @@ -23,6 +23,7 @@ from app.core.point_manager import PointRecordType from app.core.account import AccountManager import logging from app.core.security import get_password_hash +from app.core.wecomclient import WecomClient router = APIRouter() @@ -65,6 +66,13 @@ async def wechat_phone_login( if not phone: return error_response(code=400, message="手机号为空") + # 获取企业微信的 userid + wecom_client = WecomClient() + wecom_info = await wecom_client.miniprogram_to_userid(openid) + print(f"获取到的企业微信用户信息: {wecom_info}") + if not wecom_info: + return error_response(code=400, message="获取企业微信用户id失败") + # 查找或创建用户 user = db.query(UserDB).filter(UserDB.phone == phone).first() if not user: @@ -78,7 +86,9 @@ async def wechat_phone_login( referral_code=request.referral_code, password=get_password_hash("123456"), openid=openid, # 保存 openid - unionid=unionid # 保存 unionid + unionid=unionid, # 保存 unionid + wecom_userid=wecom_info.get("userid"), + wecom_pending_id=wecom_info.get("pending_id") ) db.add(user) db.flush() diff --git a/app/core/wecomclient.py b/app/core/wecomclient.py new file mode 100644 index 0000000..b85ea18 --- /dev/null +++ b/app/core/wecomclient.py @@ -0,0 +1,63 @@ +from typing import Optional, Dict +import aiohttp +import logging +from app.core.config import settings + +class WecomClient: + def __init__(self): + self.corpid = settings.WECHAT_CORP_ID + self.provider_secret = settings.WECHAT_CORP_SECRET + self.access_token = None + + async def get_provider_token(self) -> str: + """获取服务商token""" + try: + url = "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token" + data = { + "corpid": self.corpid, + "provider_secret": self.provider_secret + } + + async with aiohttp.ClientSession() as session: + async with session.post(url, json=data) as response: + result = await response.json() + + if result.get("errcode") == 0: + self.access_token = result["provider_access_token"] + return self.access_token + else: + raise Exception(f"获取provider_token失败: {result}") + + except Exception as e: + logging.error(f"获取provider_token失败: {str(e)}") + raise + + async def miniprogram_to_userid(self, openid: str) -> Optional[Dict]: + """ + 小程序openid转换为企业微信userid + """ + try: + url = "https://qyapi.weixin.qq.com/cgi-bin/service/miniprogram/jscode2session" + params = { + "provider_access_token": await self.get_provider_token(), + "appid": settings.WECHAT_APPID, + "code": openid + } + + async with aiohttp.ClientSession() as session: + async with session.get(url, params=params) as response: + result = await response.json() + + if result.get("errcode") == 0: + data = { + "userid": result.get("userid"), + "pending_id": result.get("pending_id") + } + return data + else: + logging.error(f"openid转换失败: {result}") + return None + + except Exception as e: + logging.error(f"openid转换失败: {str(e)}") + return None \ No newline at end of file diff --git a/app/models/user.py b/app/models/user.py index c35df70..1b2d80f 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -25,9 +25,17 @@ class UserDB(Base): __tablename__ = "users" userid = Column(Integer, primary_key=True,autoincrement=True, index=True) + + # 微信用户信息 openid = Column(String(64), unique=True, nullable=True) unionid = Column(String(64), unique=True, nullable=True) mp_openid = Column(String(64), unique=True, nullable=True) + + # 企业微信用户信息 + wecom_userid = Column(String(64), unique=True, nullable=True) + wecom_pending_id = Column(String(64), unique=True, nullable=True) + + nickname = Column(String(50)) phone = Column(String(11), unique=True, index=True) user_code = Column(String(6), unique=True, nullable=False) @@ -58,6 +66,8 @@ class UserInfo(BaseModel): openid: Optional[str] = None unionid: Optional[str] = None mp_openid: Optional[str] = None + wecom_userid: Optional[str] = None + wecom_pending_id: Optional[str] = None nickname: str phone: str user_code: str