diff --git a/app/core/wechat.py b/app/core/wechat.py index 06397a6..11c635e 100644 --- a/app/core/wechat.py +++ b/app/core/wechat.py @@ -13,6 +13,10 @@ import string from cryptography.x509 import load_pem_x509_certificate from cryptography.hazmat.primitives.ciphers.aead import AESGCM import uuid +from typing import Dict, Any +from sqlalchemy.orm import Session +from sqlalchemy import and_ +from app.models.subscribe import SubscribeDB def generate_random_string(length=32): """生成指定长度的随机字符串""" @@ -432,5 +436,71 @@ class WeChatClient: except Exception as e: raise Exception(f"申请退款失败: {str(e)}") + + async def send_subscribe_message( + self, + openid: str, + template_id: str, + data: Dict[str, Any], + db: Session = None, + user_id: int = None, + page: str = None + ) -> bool: + """ + 发送订阅消息 + :param openid: 用户openid + :param template_id: 模板ID + :param data: 模板数据 + :param db: 数据库会话(可选) + :param user_id: 用户ID(可选,用于检查订阅状态) + :param page: 点击模板卡片后的跳转页面(可选) + :return: 发送是否成功 + """ + try: + # 如果提供了数据库会话和用户ID,检查订阅状态 + if db and user_id: + subscribe = db.query(SubscribeDB).filter( + and_( + SubscribeDB.user_id == user_id, + SubscribeDB.template_id == template_id + ) + ).first() + + # 如果用户没有订阅或拒绝了订阅,则不发送 + if not subscribe or subscribe.action == "reject": + return False + + # 构建消息数据 + message_data = { + "touser": openid, + "template_id": template_id, + "data": { + key: { + "value": value + } for key, value in data.items() + } + } + + # 如果提供了跳转页面 + if page: + message_data["page"] = page + + # 发送订阅消息 + access_token = await self.get_access_token() + url = f"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token}" + + async with aiohttp.ClientSession() as session: + async with session.post(url, json=message_data) as response: + result = await response.json() + + if result.get("errcode") == 0: + return True + + print(f"发送订阅消息失败: {result}") + return False + + except Exception as e: + print(f"发送订阅消息异常: {str(e)}") + return False \ No newline at end of file diff --git a/app/models/user.py b/app/models/user.py index fd2d900..9fa67b3 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -58,6 +58,7 @@ class UserInfo(BaseModel): user_code: str referral_code: Optional[str] = None avatar: Optional[str] = None + optimized_avatar: Optional[str] = None gender: Gender = Gender.UNKNOWN points: int = 0 roles: List[UserRole]