|
|
@@ -10,10 +10,14 @@ from datetime import datetime
|
|
|
from sqlalchemy import select, update, func, insert
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
from database import db_manager
|
|
|
-from models_db import User, UserUIState, UserBackgroundImage, BackgroundImage
|
|
|
+from models_db import User, UserUIState, UserBackgroundImage, BackgroundImage, UserAvatar
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
+# 默认头像 ID
|
|
|
+DEFAULT_AVATAR_ID = "avatar_default"
|
|
|
+REGISTERED_AVATAR_ID = "avatar_registered_cap"
|
|
|
+
|
|
|
LEVEL_THRESHOLDS_MS: Tuple[Tuple[int, int], ...] = (
|
|
|
(5, 240_000),
|
|
|
(4, 120_000),
|
|
|
@@ -72,6 +76,58 @@ class UserService:
|
|
|
# 背景图片初始化失败不应该影响用户创建,只记录日志
|
|
|
logger.warning(f"⚠️ 初始化用户背景图片失败: user_id={user_id}, error={e}")
|
|
|
|
|
|
+ async def _init_user_avatar(self, session: AsyncSession, user_id: str, user_type: str = "guest") -> None:
|
|
|
+ """
|
|
|
+ 初始化用户头像(添加到已获得列表)
|
|
|
+
|
|
|
+ Args:
|
|
|
+ session: 数据库会话
|
|
|
+ user_id: 用户ID
|
|
|
+ user_type: 用户类型(guest 或 registered)
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ # 游客用户只分配默认头像
|
|
|
+ # 注册用户同时分配默认头像和注册赠送头像
|
|
|
+ avatars_to_add = []
|
|
|
+
|
|
|
+ if user_type == "registered":
|
|
|
+ # 注册用户:默认头像 + 注册赠送头像
|
|
|
+ avatars_to_add = [
|
|
|
+ (DEFAULT_AVATAR_ID, "default", "system_init"),
|
|
|
+ (REGISTERED_AVATAR_ID, "register", "register_bonus"),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ # 游客用户:只分配默认头像
|
|
|
+ avatars_to_add = [
|
|
|
+ (DEFAULT_AVATAR_ID, "default", "system_init"),
|
|
|
+ ]
|
|
|
+
|
|
|
+ for avatar_id, obtained_type, obtained_source in avatars_to_add:
|
|
|
+ # 检查是否已存在,避免重复添加
|
|
|
+ result = await session.execute(
|
|
|
+ select(UserAvatar).where(
|
|
|
+ UserAvatar.user_id == user_id,
|
|
|
+ UserAvatar.avatar_id == avatar_id
|
|
|
+ )
|
|
|
+ )
|
|
|
+ existing = result.scalar_one_or_none()
|
|
|
+
|
|
|
+ if not existing:
|
|
|
+ user_avatar = UserAvatar(
|
|
|
+ user_id=user_id,
|
|
|
+ avatar_id=avatar_id,
|
|
|
+ obtained_type=obtained_type,
|
|
|
+ obtained_source=obtained_source
|
|
|
+ )
|
|
|
+ session.add(user_avatar)
|
|
|
+ logger.debug(f"✅ 为用户初始化头像: user_id={user_id}, avatar_id={avatar_id}, user_type={user_type}")
|
|
|
+ else:
|
|
|
+ logger.debug(f"⏭️ 用户已拥有头像: user_id={user_id}, avatar_id={avatar_id}")
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ # 头像初始化失败不应该影响用户创建,只记录日志
|
|
|
+ logger.warning(f"⚠️ 初始化用户头像失败: user_id={user_id}, error={e}")
|
|
|
+
|
|
|
async def _generate_temp_username(self, session: AsyncSession) -> str:
|
|
|
"""
|
|
|
生成临时用户名(格式:User + 7位随机数字)
|
|
|
@@ -163,9 +219,18 @@ class UserService:
|
|
|
# 初始化背景图片
|
|
|
await self._init_user_background_image(session, user_id)
|
|
|
|
|
|
+ # 初始化默认头像
|
|
|
+ await self._init_user_avatar(session, user_id, user_type="guest")
|
|
|
+
|
|
|
await session.commit()
|
|
|
await session.refresh(user)
|
|
|
|
|
|
+ # 初始化 user_ui_states 的 current_avatar_id(游客用户使用默认头像)
|
|
|
+ await self.upsert_user_ui_state(
|
|
|
+ user_id=user_id,
|
|
|
+ current_avatar_id=DEFAULT_AVATAR_ID
|
|
|
+ )
|
|
|
+
|
|
|
logger.info(f"✅ 创建游客用户成功: user_id={user_id}, username={username}, bot_name={bot_name}")
|
|
|
|
|
|
return {
|
|
|
@@ -562,9 +627,18 @@ class UserService:
|
|
|
# 初始化背景图片
|
|
|
await self._init_user_background_image(session, user_id)
|
|
|
|
|
|
+ # 初始化头像(注册用户:默认头像 + 注册赠送头像)
|
|
|
+ await self._init_user_avatar(session, user_id, user_type="registered")
|
|
|
+
|
|
|
await session.commit()
|
|
|
await session.refresh(user)
|
|
|
|
|
|
+ # 初始化 user_ui_states 的 current_avatar_id(注册用户优先使用注册赠送头像)
|
|
|
+ await self.upsert_user_ui_state(
|
|
|
+ user_id=user_id,
|
|
|
+ current_avatar_id=REGISTERED_AVATAR_ID
|
|
|
+ )
|
|
|
+
|
|
|
logger.info(f"✅ 手机号注册成功: user_id={user_id}, phone={phone}")
|
|
|
return user.to_dict()
|
|
|
except Exception as e:
|
|
|
@@ -613,9 +687,18 @@ class UserService:
|
|
|
# 初始化背景图片
|
|
|
await self._init_user_background_image(session, user_id)
|
|
|
|
|
|
+ # 初始化头像(注册用户:默认头像 + 注册赠送头像)
|
|
|
+ await self._init_user_avatar(session, user_id, user_type="registered")
|
|
|
+
|
|
|
await session.commit()
|
|
|
await session.refresh(user)
|
|
|
|
|
|
+ # 初始化 user_ui_states 的 current_avatar_id(注册用户优先使用注册赠送头像)
|
|
|
+ await self.upsert_user_ui_state(
|
|
|
+ user_id=user_id,
|
|
|
+ current_avatar_id=REGISTERED_AVATAR_ID
|
|
|
+ )
|
|
|
+
|
|
|
logger.info(f"✅ 邮箱注册成功: user_id={user_id}, email={email}")
|
|
|
return user.to_dict()
|
|
|
except Exception as e:
|
|
|
@@ -666,9 +749,18 @@ class UserService:
|
|
|
# 初始化背景图片
|
|
|
await self._init_user_background_image(session, user_id)
|
|
|
|
|
|
+ # 初始化头像(注册用户:默认头像 + 注册赠送头像)
|
|
|
+ await self._init_user_avatar(session, user_id, user_type="registered")
|
|
|
+
|
|
|
await session.commit()
|
|
|
await session.refresh(user)
|
|
|
|
|
|
+ # 初始化 user_ui_states 的 current_avatar_id(注册用户优先使用注册赠送头像)
|
|
|
+ await self.upsert_user_ui_state(
|
|
|
+ user_id=user_id,
|
|
|
+ current_avatar_id=REGISTERED_AVATAR_ID
|
|
|
+ )
|
|
|
+
|
|
|
logger.info(f"✅ 微信注册成功: user_id={user_id}, openid={openid}")
|
|
|
return user.to_dict()
|
|
|
except Exception as e:
|
|
|
@@ -751,9 +843,18 @@ class UserService:
|
|
|
# 初始化背景图片
|
|
|
await self._init_user_background_image(session, user_id)
|
|
|
|
|
|
+ # 初始化头像(注册用户:默认头像 + 注册赠送头像)
|
|
|
+ await self._init_user_avatar(session, user_id, user_type="registered")
|
|
|
+
|
|
|
await session.commit()
|
|
|
await session.refresh(user)
|
|
|
|
|
|
+ # 初始化 user_ui_states 的 current_avatar_id(注册用户优先使用注册赠送头像)
|
|
|
+ await self.upsert_user_ui_state(
|
|
|
+ user_id=user_id,
|
|
|
+ current_avatar_id=REGISTERED_AVATAR_ID
|
|
|
+ )
|
|
|
+
|
|
|
logger.info(
|
|
|
f"✅ QQ注册成功: user_id={user_id}, openid={openid}, unionid={unionid}"
|
|
|
)
|