1.7
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"""念念回音服务"""
|
||||
|
||||
import hashlib
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import select, or_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.miss_echo import MissEcho
|
||||
from app.models.user import User
|
||||
from app.websocket.events import EventType
|
||||
from app.websocket.manager import manager
|
||||
|
||||
|
||||
class EchoService:
|
||||
def __init__(self, db: AsyncSession):
|
||||
self.db = db
|
||||
|
||||
async def send_echo(self, from_user_id: str, to_user_id: str,
|
||||
message: str | None = None) -> dict:
|
||||
"""发送一片回音叶"""
|
||||
if from_user_id == to_user_id:
|
||||
raise ValueError("不能给自己回音")
|
||||
|
||||
# 校验目标用户存在
|
||||
target_result = await self.db.execute(select(User).where(User.id == to_user_id))
|
||||
if not target_result.scalars().first():
|
||||
raise ValueError("目标用户不存在")
|
||||
|
||||
# 派生叶子种子
|
||||
today = datetime.utcnow().strftime("%Y%m%d")
|
||||
seed = hashlib.md5(f"echo:{from_user_id}:{to_user_id}:{today}".encode()).hexdigest()[:16]
|
||||
|
||||
is_online = manager.is_online(to_user_id)
|
||||
|
||||
echo = MissEcho(
|
||||
id=str(uuid.uuid4()),
|
||||
from_user_id=from_user_id,
|
||||
to_user_id=to_user_id,
|
||||
leaf_seed=seed,
|
||||
message=message,
|
||||
delivered_online=is_online,
|
||||
)
|
||||
self.db.add(echo)
|
||||
await self.db.flush()
|
||||
|
||||
# 发送者信息
|
||||
from_result = await self.db.execute(select(User).where(User.id == from_user_id))
|
||||
from_user = from_result.scalars().first()
|
||||
|
||||
payload = {
|
||||
"id": echo.id,
|
||||
"from_user_id": from_user_id,
|
||||
"from_username": from_user.username if from_user else "未知",
|
||||
"from_nickname": from_user.nickname if from_user else None,
|
||||
"from_avatar": from_user.avatar_url if from_user else None,
|
||||
"leaf_seed": seed,
|
||||
"message": message,
|
||||
"delivered_online": is_online,
|
||||
"created_at": echo.created_at.isoformat(),
|
||||
}
|
||||
|
||||
# 在线则实时推送,离线则在用户下次打开时收到(落入花园)
|
||||
if is_online:
|
||||
await manager.send_to_user(to_user_id, EventType.ECHO_SEND, payload)
|
||||
|
||||
return payload
|
||||
|
||||
async def get_echoes(self, user_id: str, limit: int = 30) -> list[dict]:
|
||||
"""获取我收到的回音(花园里飘落的叶子)"""
|
||||
result = await self.db.execute(
|
||||
select(MissEcho).where(
|
||||
or_(
|
||||
MissEcho.to_user_id == user_id,
|
||||
MissEcho.from_user_id == user_id,
|
||||
)
|
||||
).order_by(MissEcho.created_at.desc()).limit(limit)
|
||||
)
|
||||
echoes = []
|
||||
for e in result.scalars().all():
|
||||
from_result = await self.db.execute(select(User).where(User.id == e.from_user_id))
|
||||
fu = from_result.scalars().first()
|
||||
echoes.append({
|
||||
"id": e.id,
|
||||
"from_user_id": e.from_user_id,
|
||||
"to_user_id": e.to_user_id,
|
||||
"from_username": fu.username if fu else "未知",
|
||||
"from_nickname": fu.nickname if fu else None,
|
||||
"from_avatar": fu.avatar_url if fu else None,
|
||||
"leaf_seed": e.leaf_seed,
|
||||
"message": e.message,
|
||||
"delivered_online": e.delivered_online,
|
||||
"is_received": e.to_user_id == user_id,
|
||||
"created_at": e.created_at.isoformat(),
|
||||
})
|
||||
return echoes
|
||||
Reference in New Issue
Block a user