use crate::prelude2::*;
use std::str::FromStr;
use actix_multipart::Field;
use futures_util::TryStreamExt as _;
use crate::commons::{extract_filename, field_to_futures_reader};
use crate::core::auth0::Requestor;
use crate::core::auth0::UserId;
use actix_web::http::header;
use mongodb::bson::doc;
use crate::sitepages::upload0::{UploadType, GRID_FS_DATABASE_NAME};
pub async fn upload_files(
mut payload: actix_multipart::Multipart,
request: HttpRequest,
ac: web::Data<AppContext>,
user_id: web::ReqData<UserId>,
requestor: web::ReqData<Requestor>,
) -> impl Responder {
let user_id = user_id.into_inner();
let user_details = requestor.user();
let content_length = match request.headers().get(header::CONTENT_LENGTH) {
Some(val) => val.to_str().unwrap_or("0").parse().unwrap(),
None => 0,
};
if content_length == 0 {
return request.json(200, R::failed(400, "文件为空!".to_string()));
}
let mut upload_type: Option<String> = None;
let mut file_field: Option<Field> = None;
let mut field_name;
while let Ok(Some(mut field)) = payload.try_next().await {
if field.name().is_none() {
continue;
}
field_name = field.name().unwrap();
if field_name == "upload_type" {
while let Ok(Some(_chunk)) = field.try_next().await {
if let Ok(value) = std::str::from_utf8(&_chunk) {
upload_type = Some(value.to_string());
break;
}
}
continue;
}
if field_name != "file0" {
continue;
}
file_field = Some(field);
}
if file_field.is_none() {
return request.json(200, R::failed(400, "file0 is required!".to_string()));
}
let file_field = file_field.unwrap();
let file_name = extract_filename(&file_field)?;
if let Some(upload_type) = upload_type {
match UploadType::from_str(&upload_type) {
Ok(upload_type) => {
if let Some(_file_type) = file_field.content_type() {
let mime_type = _file_type.to_string();
let stream = field_to_futures_reader(file_field);
let metadata = doc! {
"user_id": &user_id.0,
"resource_id": &user_details.resource_id,
"upload_type": upload_type.as_str(),
"mime_type": mime_type,
"created_at": crate::commons::timestamp_millis()
};
let id = ac
.mongo()
.save_stream_with_opts(&GRID_FS_DATABASE_NAME, &file_name, stream, metadata)
.await?;
request.json(200, R::ok(id))
} else {
request.json(200, R::failed(400, "upload_type unknow!".to_string()))
}
}
Err(_) => request.json(
200,
R::failed(400, format!("不支持的视频上传类型: {}", upload_type)),
),
}
} else {
request.json(200, R::failed(400, "upload_type is required!".to_string()))
}
}