use ::session::AuthedUser; use api::http::{Json, Path, Query, State}; use api::rest::{AppResponseData, NoData}; use uuid::Uuid; use crate::errors::ApiError; use crate::services::drafts::{DraftDto, UpsertDraftCmd}; use crate::services::service::ChatService; #[derive(Debug, Clone, serde::Deserialize, utoipa::IntoParams, utoipa::ToSchema)] pub struct DraftQuery { pub thread_id: Option, } #[utoipa::path( put, path = "/chat/rooms/{room_id}/draft", tag = "chat", description = "保存房间或话题输入草稿;提交空内容会清除对应草稿。", params(("room_id" = Uuid, Path, description = "room id")), request_body = UpsertDraftCmd, responses( (status = 200, description = "draft saved", body = AppResponseData), (status = 400, description = "bad request", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn upsert_draft( State(service): State, AuthedUser(uid): AuthedUser, Path(room_id): Path, Json(cmd): Json, ) -> Result, ApiError> { let dto = service.upsert_draft(uid, room_id, cmd).await?; Ok(AppResponseData::ok(dto)) } #[utoipa::path( get, path = "/chat/rooms/{room_id}/draft", tag = "chat", description = "读取当前用户在指定房间或话题中的输入草稿。", params(("room_id" = Uuid, Path, description = "room id"), DraftQuery), responses( (status = 200, description = "draft", body = AppResponseData>), (status = 404, description = "not found", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn get_draft( State(service): State, AuthedUser(uid): AuthedUser, Path(room_id): Path, Query(q): Query, ) -> Result>, ApiError> { let dto = service.get_draft(uid, room_id, q.thread_id).await?; Ok(AppResponseData::ok(dto)) } #[utoipa::path( get, path = "/chat/drafts", tag = "chat", description = "分页列出当前用户保存的全部聊天草稿。", responses( (status = 200, description = "my drafts", body = AppResponseData>), (status = 401, description = "unauthorized", body = AppResponseData), (status = 404, description = "resource not found", body = AppResponseData) ) )] pub async fn list_my_drafts( State(service): State, AuthedUser(uid): AuthedUser, Query(page): Query, ) -> Result>, ApiError> { let drafts = service.list_my_drafts(uid).await?; Ok(AppResponseData::ok(api::pagination::paginate( drafts, &page, )?)) } #[utoipa::path( delete, path = "/chat/rooms/{room_id}/draft", tag = "chat", description = "删除当前用户在指定房间或话题中的输入草稿。", params(("room_id" = Uuid, Path), ("thread_id" = Option, Query, description = "thread scope")), responses( (status = 200, description = "draft deleted", body = AppResponseData), (status = 404, description = "no draft", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn delete_draft( State(service): State, AuthedUser(uid): AuthedUser, Path(room_id): Path, Query(q): Query, ) -> Result, ApiError> { service.delete_draft(uid, room_id, q.thread_id).await?; Ok(AppResponseData::empty()) }