use ::session::AuthedUser; use api::http::{Json, Path, Query, Response, State}; use api::pagination::{Page, PageQuery}; use api::rest::{AppResponseData, NoData}; use uuid::Uuid; use crate::errors::ApiError; use crate::services::emojis::{EmojiDto, UploadEmojiCmd}; use crate::services::service::ChatService; use crate::share::lookup::{lookup_space_by_name, require_space_member}; #[utoipa::path( get, path = "/chat/spaces/{space_name}/emojis", tag = "chat", description = "返回指定空间可用的自定义表情列表。", params(("space_name" = String, Path, description = "space name"), PageQuery), responses( (status = 200, description = "emoji list", body = AppResponseData>), (status = 404, description = "not found", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn list_emojis( State(service): State, AuthedUser(uid): AuthedUser, Path(space_name): Path, Query(page): Query, ) -> Result>, ApiError> { let emojis = service.list_emojis(uid, &space_name, page).await?; Ok(AppResponseData::ok(emojis)) } #[utoipa::path( post, path = "/chat/spaces/{space_name}/emojis", tag = "chat", description = "空间管理员上传并登记一个新的自定义表情。", params(("space_name" = String, Path, description = "space name")), request_body = UploadEmojiCmd, responses( (status = 200, description = "emoji created", body = AppResponseData), (status = 403, description = "forbidden", body = AppResponseData), (status = 409, description = "resource already exists", body = AppResponseData), (status = 400, description = "request failed validation", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn upload_emoji( State(service): State, AuthedUser(uid): AuthedUser, Path(space_name): Path, Json(cmd): Json, ) -> Result, ApiError> { let dto = service.upload_emoji(uid, &space_name, cmd).await?; Ok(AppResponseData::ok(dto)) } #[utoipa::path( delete, path = "/chat/spaces/{space_name}/emojis/{emoji_id}", tag = "chat", description = "空间管理员删除空间自定义表情及对应存储对象。", params( ("space_name" = String, Path, description = "space name"), ("emoji_id" = Uuid, Path, description = "emoji id") ), responses( (status = 200, description = "emoji deleted", body = AppResponseData), (status = 404, description = "not found", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn delete_emoji( State(service): State, AuthedUser(uid): AuthedUser, Path((space_name, emoji_id)): Path<(String, Uuid)>, ) -> Result, ApiError> { service.delete_emoji(uid, &space_name, emoji_id).await?; Ok(AppResponseData::empty()) } #[utoipa::path( get, path = "/chat/spaces/{space_name}/emojis/{emoji_id}/image", tag = "chat", description = "返回空间自定义表情的二进制图片内容。", params( ("space_name" = String, Path, description = "space name"), ("emoji_id" = Uuid, Path, description = "emoji id") ), responses( (status = 200, description = "emoji image"), (status = 404, description = "not found", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn emoji_image( State(service): State, AuthedUser(uid): AuthedUser, Path((space_name, emoji_id)): Path<(String, Uuid)>, ) -> Result { let space = lookup_space_by_name(&service, &space_name).await?; require_space_member(&service, &space, uid).await?; let bytes = service.emoji_image(&space, emoji_id).await?; Ok(actix_web::HttpResponse::Ok().body(bytes)) } #[utoipa::path( get, path = "/chat/spaces/{space_name}/emojis/{emoji_id}", tag = "chat", description = "读取单个空间自定义表情的元数据。", params(("space_name" = String, Path), ("emoji_id" = Uuid, Path)), responses( (status = 200, description = "emoji", body = AppResponseData), (status = 404, description = "not found", body = AppResponseData), (status = 401, description = "authentication required", body = AppResponseData) ) )] pub async fn get_emoji( State(service): State, AuthedUser(uid): AuthedUser, Path((space_name, emoji_id)): Path<(String, Uuid)>, ) -> Result, ApiError> { let dto = service.get_emoji(uid, &space_name, emoji_id).await?; Ok(AppResponseData::ok(dto)) }