106 lines
3.4 KiB
Rust
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 })
|
|
}
|
|
}
|