feat(chat): 完善聊天

This commit is contained in:
xingc
2025-04-16 14:44:52 +08:00
parent 02a1589833
commit e3f28ad67c
5 changed files with 110 additions and 79 deletions

View File

@@ -10,6 +10,7 @@ from typing import List, Dict
import redis.asyncio as aioredis
from fastapi import WebSocket
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from core.db.crud import CRUD
@@ -26,19 +27,20 @@ socket_manager = SocketManager()
async def send_new_message(
websocket: WebSocket,
db_session: AsyncSession,
cache: aioredis.Redis,
chats: dict,
current_user: User,
incoming_message: schema.Message,
incoming_message: schema.WSMessage,
):
chat_guid: str = str(incoming_message.chat_guid)
chat: Chat | None = await CRUD(db_session, Chat).get(filters={'chat_guid': chat_guid})
chat: Chat | None = await CRUD(db_session, Chat).get(filters={'guid': chat_guid})
# 判断是否为新聊天
if not chats or chat_guid not in chats:
if chat:
chats[chat_guid] = chat.id
await socket_manager.add_user_to_chat(chat_guid, websocket)
else:
logger.warning(f'chat {chat_guid} not found')
await socket_manager.send_error('聊天尚未添加', websocket)
return
@@ -49,64 +51,59 @@ async def send_new_message(
user_id=current_user.user_id,
chat_id=chat_id,
message_type=incoming_message.message_type,
content=incoming_message.body,
content=incoming_message.content,
)
db_session.add(message)
await db_session.flush()
chat.updated_at = datetime.now()
db_session.add(chat)
await db_session.flush()
await db_session.commit()
await db_session.refresh(message, attribute_names=["user", "chat"])
await db_session.refresh(chat, attribute_names=["users"])
# await db_session.refresh(message, attribute_names=["user", "chat"])
# await db_session.refresh(chat, attribute_names=["users"])
except Exception as exc_info:
await db_session.rollback()
logger.exception(f"[new_message] Exception, rolling back session, detail: {exc_info}")
raise exc_info
send_message_schema = schema.MessageOut(
send_message_schema = schema.WSMessageOut(
type='chat.new_message',
message_id=message.id,
message_guid=message.guid,
message_type=message.message_type,
chat_guid=chat.guid,
user_id=current_user.user_id,
content=message.content,
created_at=message.created_at,
friend_user=current_user,
friend_user=current_user.dict(),
)
send_status_replay = schema.WSMessageOut(
type='chat.send_status_reply',
message_id=message.id,
message_guid=message.guid,
message_type=message.message_type,
chat_guid=chat.guid,
)
await socket_manager.broadcast_to_chat(chat_guid, send_message_schema.dict())
@socket_manager.handler('chat.refresh_unread_messages')
async def refresh_unread_messages(
websocket: WebSocket,
db_session: AsyncSession,
cache: aioredis.Redis,
current_user: User,
message: schema.Message,
):
pass
await socket_manager.broadcast_to_chat(chat_guid, send_message_schema.model_dump_json())
await websocket.send_json(send_status_replay.model_dump_json())
@socket_manager.handler('chat.message_read')
async def read_message(
websocket: WebSocket,
db_session: AsyncSession,
cache: aioredis.Redis,
current_user: User,
message: schema.Message,
incoming_message: schema.WSMessage,
):
last_read_message_id: str | None = message.body
last_read_message_id: str | None = incoming_message.content
if not last_read_message_id:
return
db_crud = CRUD(db_session, ReadStatus)
condition = {
'user_id': current_user.user_id,
'chat_guid': message.chat_guid,
'chat_guid': incoming_message.chat_guid,
}
result = await db_crud.update(filters=condition, data={'last_read_message_id': last_read_message_id})
if result is None:
@@ -117,3 +114,13 @@ async def read_message(
},
filters=condition
)
@socket_manager.handler('chat.ping')
async def ping(
websocket: WebSocket,
db_session: AsyncSession,
current_user: User,
incoming_message: schema.WSMessage,
):
await websocket.send_json({'type': 'chat.send_status_reply', 'status': 'ok'})