1.7
This commit is contained in:
@@ -12,6 +12,7 @@ from app.models.conversation_member import ConversationMember
|
||||
from app.models.message import Message
|
||||
from app.models.friend import Friend
|
||||
from app.models.user import User
|
||||
from app.websocket.manager import manager
|
||||
|
||||
|
||||
# 阶段定义:分数 -> (阶段索引, 名称, emoji)
|
||||
@@ -89,6 +90,72 @@ class TreeService:
|
||||
)
|
||||
return count_result.scalar() or 0
|
||||
|
||||
async def _count_messages_in_days(self, user_id: str, friend_id: str, days: int = 7) -> int:
|
||||
"""统计近 N 天两人私聊消息数(心跳 BPM 用)"""
|
||||
result = await self.db.execute(
|
||||
select(Conversation).join(ConversationMember)
|
||||
.where(
|
||||
Conversation.type == "private",
|
||||
ConversationMember.user_id == user_id,
|
||||
)
|
||||
)
|
||||
conv_id = None
|
||||
for conv in result.scalars().all():
|
||||
member_result = await self.db.execute(
|
||||
select(ConversationMember).where(
|
||||
ConversationMember.conversation_id == conv.id,
|
||||
ConversationMember.user_id == friend_id,
|
||||
)
|
||||
)
|
||||
if member_result.scalars().first():
|
||||
conv_id = conv.id
|
||||
break
|
||||
if not conv_id:
|
||||
return 0
|
||||
from datetime import datetime, timedelta
|
||||
since = datetime.utcnow() - timedelta(days=days)
|
||||
count_result = await self.db.execute(
|
||||
select(func.count(Message.id)).where(
|
||||
Message.conversation_id == conv_id,
|
||||
Message.is_deleted == False,
|
||||
Message.created_at >= since,
|
||||
)
|
||||
)
|
||||
return count_result.scalar() or 0
|
||||
|
||||
async def get_heartbeat(self, user_id: str, friend_id: str) -> dict:
|
||||
"""获取心跳同步数据:BPM 由近7天消息数决定"""
|
||||
from app.models.user import User
|
||||
msg_7d = await self._count_messages_in_days(user_id, friend_id, 7)
|
||||
|
||||
# BPM 映射
|
||||
if msg_7d == 0:
|
||||
bpm = 42 # 沉睡
|
||||
elif msg_7d < 30:
|
||||
bpm = 54 # 平静
|
||||
elif msg_7d < 100:
|
||||
bpm = 66 # 正常
|
||||
elif msg_7d < 300:
|
||||
bpm = 78 # 活跃
|
||||
else:
|
||||
bpm = 90 # 热烈
|
||||
|
||||
# 对方信息
|
||||
friend_result = await self.db.execute(select(User).where(User.id == friend_id))
|
||||
friend = friend_result.scalars().first()
|
||||
is_online = manager.is_online(friend_id) if friend else False
|
||||
|
||||
return {
|
||||
"friend_id": friend_id,
|
||||
"friend_name": friend.nickname or friend.username if friend else "未知",
|
||||
"friend_avatar": friend.avatar_url if friend else None,
|
||||
"bpm": bpm,
|
||||
"msg_7d": msg_7d,
|
||||
"is_online": is_online,
|
||||
# leaf_seed 用于渲染对方的迷你叶(确定性)
|
||||
"friend_leaf_seed": (friend_id or "0")[:16].ljust(16, '0'),
|
||||
}
|
||||
|
||||
async def get_tree(self, user_id: str, friend_id: str) -> dict:
|
||||
"""获取好友之树"""
|
||||
tree = await self._get_or_create_tree_row(user_id, friend_id)
|
||||
|
||||
Reference in New Issue
Block a user