gitdataai/libs/room/src/thread.rs
2026-04-15 09:08:09 +08:00

106 lines
3.4 KiB
Rust

use crate::error::RoomError;
use crate::service::RoomService;
use crate::ws_context::WsUserContext;
use chrono::Utc;
use models::rooms::{room_message, room_thread};
use sea_orm::*;
use uuid::Uuid;
impl RoomService {
pub async fn room_thread_list(
&self,
room_id: Uuid,
ctx: &WsUserContext,
) -> Result<Vec<super::RoomThreadResponse>, RoomError> {
let user_id = ctx.user_id;
self.require_room_member(room_id, user_id).await?;
let models = room_thread::Entity::find()
.filter(room_thread::Column::Room.eq(room_id))
.order_by_desc(room_thread::Column::LastMessageAt)
.all(&self.db)
.await?;
Ok(models
.into_iter()
.map(super::RoomThreadResponse::from)
.collect())
}
pub async fn room_thread_create(
&self,
room_id: Uuid,
request: super::RoomThreadCreateRequest,
ctx: &WsUserContext,
) -> Result<super::RoomThreadResponse, RoomError> {
let user_id = ctx.user_id;
self.require_room_member(room_id, user_id).await?;
let parent = room_message::Entity::find()
.filter(room_message::Column::Room.eq(room_id))
.filter(room_message::Column::Seq.eq(request.parent_seq))
.one(&self.db)
.await?;
if parent.is_none() {
return Err(RoomError::NotFound("Parent message not found".to_string()));
}
let now = Utc::now();
let participants = serde_json::json!([user_id]);
let model = room_thread::ActiveModel {
id: Set(Uuid::now_v7()),
room: Set(room_id),
parent: Set(request.parent_seq),
created_by: Set(user_id),
participants: Set(participants),
last_message_at: Set(now),
last_message_preview: Set(None),
created_at: Set(now),
updated_at: Set(now),
}
.insert(&self.db)
.await?;
Ok(super::RoomThreadResponse::from(model))
}
pub async fn room_thread_messages(
&self,
thread_id: Uuid,
before_seq: Option<i64>,
after_seq: Option<i64>,
limit: Option<u64>,
ctx: &WsUserContext,
) -> Result<super::RoomMessageListResponse, RoomError> {
let user_id = ctx.user_id;
let thread = room_thread::Entity::find_by_id(thread_id)
.one(&self.db)
.await?
.ok_or_else(|| RoomError::NotFound("Thread not found".to_string()))?;
self.require_room_member(thread.room, user_id).await?;
let mut query =
room_message::Entity::find().filter(room_message::Column::Thread.eq(Some(thread.id)));
if let Some(before_seq) = before_seq {
query = query.filter(room_message::Column::Seq.lt(before_seq));
}
if let Some(after_seq) = after_seq {
query = query.filter(room_message::Column::Seq.gt(after_seq));
}
let total = query.clone().count(&self.db).await? as i64;
let models = query
.order_by_desc(room_message::Column::Seq)
.limit(limit.unwrap_or(50))
.all(&self.db)
.await?;
let mut messages: Vec<super::RoomMessageResponse> = models
.into_iter()
.map(super::RoomMessageResponse::from)
.collect();
messages.reverse();
Ok(super::RoomMessageListResponse { messages, total })
}
}