user_service.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. """
  2. 用户服务模块(SQLAlchemy ORM 版本)
  3. """
  4. import uuid
  5. import logging
  6. from typing import Dict, Optional
  7. from datetime import datetime
  8. from sqlalchemy import select, update, func
  9. from sqlalchemy.ext.asyncio import AsyncSession
  10. from database import db_manager
  11. from models_db import User
  12. logger = logging.getLogger(__name__)
  13. class UserService:
  14. """用户管理服务"""
  15. async def create_guest_user(self, username: str = "", bot_name: Optional[str] = None) -> Dict:
  16. """
  17. 创建游客用户
  18. Args:
  19. username: 用户名(默认为空字符串)
  20. bot_name: 用户给机器人取的名字(可选)
  21. Returns:
  22. 用户信息字典(包含user_id)
  23. """
  24. try:
  25. # 生成唯一用户ID
  26. user_id = str(uuid.uuid4())
  27. # 使用 ORM 创建用户
  28. async with db_manager.get_session() as session:
  29. user = User(
  30. user_id=user_id,
  31. username=username,
  32. user_type="guest",
  33. bot_name=bot_name,
  34. )
  35. session.add(user)
  36. await session.commit()
  37. await session.refresh(user)
  38. logger.info(f"✅ 创建游客用户成功: user_id={user_id}, username={username}, bot_name={bot_name}")
  39. return {
  40. "user_id": user_id,
  41. "username": username,
  42. "user_type": "guest",
  43. "bot_name": bot_name,
  44. "created_at": datetime.now().isoformat()
  45. }
  46. except Exception as e:
  47. logger.error(f"❌ 创建用户失败: {e}")
  48. raise
  49. async def get_user(self, user_id: str) -> Optional[Dict]:
  50. """
  51. 获取用户信息
  52. Args:
  53. user_id: 用户ID
  54. Returns:
  55. 用户信息字典,如果不存在返回None
  56. """
  57. try:
  58. async with db_manager.get_session() as session:
  59. result = await session.execute(
  60. select(User).where(User.user_id == user_id)
  61. )
  62. user = result.scalar_one_or_none()
  63. if user:
  64. return user.to_dict()
  65. return None
  66. except Exception as e:
  67. logger.error(f"❌ 获取用户信息失败: user_id={user_id}, error={e}")
  68. return None
  69. async def update_user_last_active(self, user_id: str):
  70. """
  71. 更新用户最后活跃时间
  72. Args:
  73. user_id: 用户ID
  74. """
  75. try:
  76. async with db_manager.get_session() as session:
  77. await session.execute(
  78. update(User)
  79. .where(User.user_id == user_id)
  80. .values(last_active_at=func.now())
  81. )
  82. await session.commit()
  83. except Exception as e:
  84. logger.warning(f"⚠️ 更新用户活跃时间失败: user_id={user_id}, error={e}")
  85. async def update_username(self, user_id: str, username: str) -> bool:
  86. """
  87. 更新用户名
  88. Args:
  89. user_id: 用户ID
  90. username: 用户名
  91. Returns:
  92. 是否更新成功
  93. """
  94. try:
  95. async with db_manager.get_session() as session:
  96. result = await session.execute(
  97. update(User)
  98. .where(User.user_id == user_id)
  99. .values(username=username)
  100. )
  101. await session.commit()
  102. if result.rowcount > 0:
  103. logger.info(f"✅ 更新用户名成功: user_id={user_id}, username={username}")
  104. return True
  105. return False
  106. except Exception as e:
  107. logger.error(f"❌ 更新用户名失败: user_id={user_id}, error={e}")
  108. return False
  109. async def update_bot_name(self, user_id: str, bot_name: str) -> bool:
  110. """
  111. 更新用户给机器人取的名字
  112. Args:
  113. user_id: 用户ID
  114. bot_name: 机器人名字
  115. Returns:
  116. 是否更新成功
  117. """
  118. try:
  119. async with db_manager.get_session() as session:
  120. result = await session.execute(
  121. update(User)
  122. .where(User.user_id == user_id)
  123. .values(bot_name=bot_name)
  124. )
  125. await session.commit()
  126. if result.rowcount > 0:
  127. logger.info(f"✅ 更新机器人名字成功: user_id={user_id}, bot_name={bot_name}")
  128. return True
  129. return False
  130. except Exception as e:
  131. logger.error(f"❌ 更新机器人名字失败: user_id={user_id}, error={e}")
  132. return False
  133. async def update_speech_duration(self, user_id: str, duration_ms: int) -> bool:
  134. """
  135. 更新用户累积说话时长
  136. Args:
  137. user_id: 用户ID
  138. duration_ms: 本次说话时长(毫秒)
  139. Returns:
  140. 是否更新成功
  141. """
  142. try:
  143. if duration_ms <= 0:
  144. return True # 时长无效,跳过更新
  145. async with db_manager.get_session() as session:
  146. # 使用 SQL 表达式更新(原子操作)
  147. await session.execute(
  148. update(User)
  149. .where(User.user_id == user_id)
  150. .values(total_speech_duration_ms=User.total_speech_duration_ms + duration_ms)
  151. )
  152. await session.commit()
  153. logger.info(f"✅ 更新用户说话时长成功: user_id={user_id}, duration_ms={duration_ms}")
  154. return True
  155. except Exception as e:
  156. logger.error(f"❌ 更新用户说话时长失败: user_id={user_id}, error={e}")
  157. return False
  158. # 全局用户服务实例
  159. user_service = UserService()