This commit is contained in:
aaron 2025-02-27 18:55:21 +08:00
parent 46fe81658f
commit 944644e371

View File

@ -4,7 +4,7 @@ import time
import logging import logging
from app.core.config import settings from app.core.config import settings
from typing import Dict, Any, Optional, List from typing import Dict, Any, Optional, List
import aiohttp
class WecomClient: class WecomClient:
"""企业微信客户端""" """企业微信客户端"""
@ -12,64 +12,63 @@ class WecomClient:
self.corp_id = settings.WECHAT_CORP_ID self.corp_id = settings.WECHAT_CORP_ID
self.corp_secret = settings.WECHAT_CORP_SECRET self.corp_secret = settings.WECHAT_CORP_SECRET
self.access_token = None self.access_token = None
self.token_expires_at = 0
async def get_access_token(self) -> str: async def get_access_token(self) -> str:
"""获取访问令牌""" """获取访问令牌"""
# 检查令牌是否过期
if self.access_token and time.time() < self.token_expires_at:
return self.access_token
# 获取新令牌
url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={self.corp_id}&corpsecret={self.corp_secret}"
try: try:
response = requests.get(url) url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
result = response.json() params = {
"corpid": self.corp_id,
"corpsecret": self.corp_secret
}
async with aiohttp.ClientSession() as session:
async with session.get(url, params=params) as response:
result = await response.json()
if result.get("errcode") == 0: if result.get("errcode") == 0:
self.access_token = result.get("access_token") self.access_token = result["access_token"]
self.token_expires_at = time.time() + result.get("expires_in") - 200 # 提前200秒过期
return self.access_token return self.access_token
else: else:
logging.error(f"获取企业微信访问令牌失败: {result}") raise Exception(f"获取access_token失败: {result}")
return None
except Exception as e: except Exception as e:
logging.exception(f"获取企业微信访问令牌异常: {str(e)}") logging.error(f"获取access_token异常: {str(e)}")
return None return None
async def code2session(self, code: str) -> Optional[Dict[str, Any]]: async def code2session(self, js_code: str) -> Optional[Dict[str, Any]]:
""" """
小程序code转换为企业微信userid 小程序登录凭证校验
Args:
code: 小程序用户的code
Returns:
Dict: 包含userid或pending_id的字典
""" """
token = await self.get_access_token()
if not token:
return None
url = f"https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token={token}&js_code={code}&grant_type=authorization_code"
try: try:
response = requests.get(url) # 1. 获取 access_token
result = response.json() access_token = await self.get_access_token()
if not access_token:
raise Exception("获取access_token失败")
# 2. 调用 jscode2session 接口
url = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session"
params = {
"access_token": access_token,
"js_code": js_code,
"grant_type": "authorization_code"
}
async with aiohttp.ClientSession() as session:
async with session.get(url, params=params) as response:
result = await response.json()
if result.get("errcode") == 0: if result.get("errcode") == 0:
return { return {
"userid": result.get("userid"), "userid": result.get("userid"),
"pending_id": result.get("pending_id") "pending_id": result.get("pending_id"),
"session_key": result.get("session_key")
} }
else: else:
logging.error(f"小程序code转换失败: {result}") logging.error(f"code2session失败: {result}")
return None return None
except Exception as e: except Exception as e:
logging.exception(f"小程序code转换异常: {str(e)}") logging.error(f"code2session异常: {str(e)}")
return None return None
wecom_client = WecomClient() wecom_client = WecomClient()