You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
6.9KB

  1. from pydantic import BaseModel, ValidationError
  2. from dataclasses import dataclass, asdict
  3. from typing import List
  4. from enum import Enum, unique
  5. from fastapi import HTTPException
  6. from functools import wraps
  7. from fastapi import Request
  8. import time
  9. @dataclass
  10. class AgentConfig(BaseModel):
  11. chatroomIdWhiteList: List[str] = []
  12. agentTokenId: str
  13. agentEnabled: bool=True
  14. addContactsFromChatroomIdWhiteList: List[str] = []
  15. chatWaitingMsgEnabled: bool
  16. privateGroupChatEnabled: bool=False
  17. @dataclass
  18. class AddGroupContactsHistory(BaseModel):
  19. chatroomId:str
  20. wxid:str
  21. contactWixd:str
  22. addTime:int
  23. @unique
  24. class OperationType(Enum):
  25. ADD_FRIEND = 2
  26. ACCEPT_FRIEND = 3
  27. REJECT_FRIEND = 4
  28. # 聊天内容类型
  29. @unique
  30. class MessageContentType(Enum):
  31. TEXT = 1
  32. IMAGE = 2
  33. VOICE = 3
  34. VIDEO = 4
  35. FILE = 5
  36. LOCATION = 6
  37. LINK = 7
  38. SYSTEM = 8
  39. UNKNOWN = 9
  40. # Group_TEXT = 11
  41. # Group_IMAGE = 12
  42. # Group_VOICE = 13
  43. # Group_VIDEO = 14
  44. # Group_FILE = 15
  45. # Group_LOCATION = 16
  46. # Group_LINK = 17
  47. # Group_SYSTEM = 18
  48. # Group_UNKNOWN = 19
  49. # Group_NOTICE = 20
  50. # 聊天方式:私聊还是群聊
  51. @unique
  52. class ChatType(Enum):
  53. PRIVATE = 1
  54. GROUP = 2
  55. @dataclass
  56. class WxChatMessage(BaseModel):
  57. contentType:int
  58. chatType:int
  59. belongToWxid:str
  60. fromWxid:str
  61. toWxid:str
  62. content:str
  63. Timestamp:int
  64. def validate_wxid(func):
  65. @wraps(func)
  66. async def wrapper(request: Request, *args, **kwargs):
  67. # 从 kwargs 中获取 wxid,如果不存在,则从请求体中获取
  68. wxid = kwargs.get("wxid")
  69. if wxid is None:
  70. # 异步获取请求体
  71. body = await request.json()
  72. wxid = body.get("wxid")
  73. # 如果 wxid 仍然为空,返回错误
  74. if not wxid:
  75. return {"code": 400, "message": "wxid 不能为空"}
  76. # 验证 wxid 是否存在
  77. k, loginfo = await request.app.state.gewe_service.get_login_info_by_wxid_async(wxid)
  78. if not k:
  79. return {"code": 404, "message": f"{wxid} 没有对应的登录信息"}
  80. login_status=loginfo.get('status','0')
  81. if login_status != '1':
  82. return {"code": 401, "message": f"{wxid} 已经离线"}
  83. # 将 k 和 loginfo 注入到路由函数的参数中
  84. # kwargs["loginfo_key"] = k
  85. # kwargs["loginfo"] = loginfo
  86. # 如果验证通过,继续执行原始函数
  87. return await func(request, *args, **kwargs)
  88. return wrapper
  89. def auth_required_time(f):
  90. @wraps(f)
  91. async def decorated_function(request: Request, *args, **kwargs):
  92. try:
  93. body = await request.json()
  94. wxid = body.get("wxid")
  95. if not wxid:
  96. return {"code": 400, "message": "wxid 不能为空"}
  97. # 模拟获取登录信息
  98. loginfo = {"status": "1", "create_at": time.time() - 2 * 24 * 60 * 60, "tokenId": "token123", "appId": "app123"}
  99. login_status = loginfo.get('status', '0')
  100. if login_status != '1':
  101. return {"code": 401, "message": f"{wxid} 已经离线"}
  102. creation_timestamp = int(loginfo.get('create_at', time.time()))
  103. current_timestamp = time.time()
  104. three_days_seconds = 3 * 24 * 60 * 60 # 三天的秒数
  105. diff_flag = (current_timestamp - creation_timestamp) >= three_days_seconds
  106. if not diff_flag:
  107. return {'code': 401, 'message': '用户创建不够三天,不能使用该功能'}
  108. kwargs['token_id'] = loginfo.get('tokenId')
  109. kwargs['app_id'] = loginfo.get('appId')
  110. return await f(*args, **kwargs)
  111. except ValidationError as e:
  112. raise HTTPException(status_code=422, detail=str(e))
  113. return decorated_function
  114. # def auth_required_time(f):
  115. # @wraps(f)
  116. # async def decorated_function(request: Request, *args, **kwargs):
  117. # try:
  118. # body = await request.json()
  119. # print("Received body:", body) # 打印请求体
  120. # wxid = body.get("wxid")
  121. # if not wxid:
  122. # return {"code": 400, "message": "wxid 不能为空"}
  123. # # 模拟获取登录信息
  124. # loginfo = {"status": "1", "create_at": time.time() - 2 * 24 * 60 * 60, "tokenId": "token123", "appId": "app123"}
  125. # login_status = loginfo.get('status', '0')
  126. # if login_status != '1':
  127. # return {"code": 401, "message": f"{wxid} 已经离线"}
  128. # creation_timestamp = int(loginfo.get('create_at', time.time()))
  129. # current_timestamp = time.time()
  130. # three_days_seconds = 3 * 24 * 60 * 60 # 三天的秒数
  131. # diff_flag = (current_timestamp - creation_timestamp) >= three_days_seconds
  132. # if not diff_flag:
  133. # return {'code': 401, 'message': '用户创建不够三天,不能使用该功能'}
  134. # kwargs['token_id'] = loginfo.get('tokenId')
  135. # kwargs['app_id'] = loginfo.get('appId')
  136. # return await f(*args, **kwargs)
  137. # except Exception as e:
  138. # raise HTTPException(status_code=422, detail=f"请求体解析失败: {str(e)}")
  139. # return decorated_function
  140. from functools import wraps
  141. import time
  142. from fastapi import Request, HTTPException
  143. def auth_required_time(f):
  144. @wraps(f)
  145. async def decorated_function(request: Request, *args, **kwargs):
  146. try:
  147. # 解析 JSON 只调用一次
  148. body = await request.json()
  149. wxid = body.get("wxid")
  150. if not wxid:
  151. raise HTTPException(status_code=400, detail="wxid 不能为空")
  152. # 调用异步方法获取登录信息
  153. k, loginfo = await request.app.state.gewe_service.get_login_info_by_wxid_async(wxid)
  154. if not k:
  155. raise HTTPException(status_code=404, detail=f"{wxid} 没有对应的登录信息")
  156. login_status = loginfo.get('status', '0')
  157. if login_status != '1':
  158. raise HTTPException(status_code=401, detail=f"{wxid} 已经离线")
  159. # 计算创建时间差
  160. creation_timestamp = int(loginfo.get('create_at', time.time()))
  161. current_timestamp = time.time()
  162. three_days_seconds = 3 * 24 * 60 * 60 # 三天的秒数
  163. if (current_timestamp - creation_timestamp) < three_days_seconds:
  164. raise HTTPException(status_code=401, detail="用户创建不够三天,不能使用该功能")
  165. # 注入 token_id 和 app_id
  166. kwargs['token_id'] = loginfo.get('tokenId')
  167. kwargs['app_id'] = loginfo.get('appId')
  168. # 需要 `await` 调用被装饰的异步函数
  169. return await f(request, *args, **kwargs)
  170. except HTTPException as e:
  171. return {"code": e.status_code, "message": e.detail}
  172. return decorated_function