194c44c
use axum::extract::{Json, Path, Query, State};
use export::rest::{AppResponseData, NoData};
use jwt::Session;
use jwt::share::session::require_uid;
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<Uuid>,
}
#[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<DraftDto>),
(status = 400, description = "bad request", body = AppResponseData<NoData>),
(status = 401, description = "authentication required", body = AppResponseData<NoData>)
)
)]
pub async fn upsert_draft(
State(service): State<ChatService>,
session: Session,
Path(room_id): Path<Uuid>,
Json(cmd): Json<UpsertDraftCmd>,
) -> Result<AppResponseData<DraftDto>, ApiError> {
let uid = require_uid(&session)?;
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<Option<DraftDto>>),
(status = 404, description = "not found", body = AppResponseData<NoData>),
(status = 401, description = "authentication required", body = AppResponseData<NoData>)
)
)]
pub async fn get_draft(
State(service): State<ChatService>,
session: Session,
Path(room_id): Path<Uuid>,
Query(q): Query<DraftQuery>,
) -> Result<AppResponseData<Option<DraftDto>>, ApiError> {
let uid = require_uid(&session)?;
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<export::pagination::Page<DraftDto>>),
(status = 401, description = "unauthorized", body = AppResponseData<NoData>),
(status = 404, description = "resource not found", body = AppResponseData<NoData>)
)
)]
pub async fn list_my_drafts(
State(service): State<ChatService>,
session: Session,
Query(page): Query<export::pagination::PageQuery>,
) -> Result<AppResponseData<export::pagination::Page<DraftDto>>, ApiError> {
let uid = require_uid(&session)?;
let drafts = service.list_my_drafts(uid).await?;
Ok(AppResponseData::ok(export::pagination::paginate(
drafts, &page,
)))
}
#[utoipa::path(
delete,
path = "/chat/rooms/{room_id}/draft",
tag = "chat",
description = "删除当前用户在指定房间或话题中的输入草稿。",
params(("room_id" = Uuid, Path), ("thread_id" = Option<Uuid>, Query, description = "thread scope")),
responses(
(status = 200, description = "draft deleted", body = AppResponseData<NoData>),
(status = 404, description = "no draft", body = AppResponseData<NoData>),
(status = 401, description = "authentication required", body = AppResponseData<NoData>)
)
)]
pub async fn delete_draft(
State(service): State<ChatService>,
session: Session,
Path(room_id): Path<Uuid>,
Query(q): Query<DraftQuery>,
) -> Result<AppResponseData<NoData>, ApiError> {
let uid = require_uid(&session)?;
service.delete_draft(uid, room_id, q.thread_id).await?;
Ok(AppResponseData::empty())
}