refactor: modularize api server assets and handlers
This commit is contained in:
122
server-rs/crates/api-server/src/custom_world_ai/assets.rs
Normal file
122
server-rs/crates/api-server/src/custom_world_ai/assets.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use super::*;
|
||||
use super::opening_cg::{
|
||||
map_asset_binding_prepare_error, map_asset_object_prepare_error,
|
||||
map_custom_world_asset_oss_error, map_custom_world_asset_spacetime_error,
|
||||
map_custom_world_generated_image_asset_error,
|
||||
};
|
||||
|
||||
pub(super) async fn persist_custom_world_asset(
|
||||
state: &AppState,
|
||||
owner_user_id: &str,
|
||||
upload: PreparedAssetUpload,
|
||||
mut response: GeneratedAssetResponse,
|
||||
) -> Result<GeneratedAssetResponse, AppError> {
|
||||
let oss_client = state.oss_client().ok_or_else(|| {
|
||||
AppError::from_status(StatusCode::SERVICE_UNAVAILABLE).with_details(json!({
|
||||
"provider": "aliyun-oss",
|
||||
"reason": "OSS 未完成环境变量配置",
|
||||
}))
|
||||
})?;
|
||||
let http_client = reqwest::Client::new();
|
||||
let PreparedAssetUpload {
|
||||
prefix,
|
||||
path_segments,
|
||||
file_name,
|
||||
content_type,
|
||||
body,
|
||||
asset_kind,
|
||||
entity_kind,
|
||||
entity_id,
|
||||
profile_id,
|
||||
slot,
|
||||
source_job_id,
|
||||
} = upload;
|
||||
let file_stem = file_name
|
||||
.rsplit_once('.')
|
||||
.map(|(stem, _)| stem)
|
||||
.unwrap_or(file_name.as_str())
|
||||
.to_string();
|
||||
let prepared = GeneratedImageAssetAdapter::prepare_put_object(GeneratedImageAssetPersistInput {
|
||||
prefix,
|
||||
path_segments,
|
||||
file_stem,
|
||||
image: GeneratedImageAssetDataUrl {
|
||||
format: normalize_generated_image_asset_mime(content_type.as_str()),
|
||||
bytes: body,
|
||||
},
|
||||
access: OssObjectAccess::Private,
|
||||
metadata: GeneratedImageAssetAdapterMetadata {
|
||||
asset_kind: Some(asset_kind.to_string()),
|
||||
owner_user_id: Some(owner_user_id.to_string()),
|
||||
entity_kind: Some(entity_kind.to_string()),
|
||||
entity_id: Some(entity_id.clone()),
|
||||
slot: Some(slot.to_string()),
|
||||
provider: None,
|
||||
task_id: source_job_id.clone(),
|
||||
},
|
||||
extra_metadata: profile_id
|
||||
.as_ref()
|
||||
.map(|profile_id| BTreeMap::from([("profile_id".to_string(), profile_id.clone())]))
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
.map_err(map_custom_world_generated_image_asset_error)?;
|
||||
let persisted_mime_type = prepared.format.mime_type.clone();
|
||||
let put_result = oss_client
|
||||
.put_object(&http_client, prepared.request)
|
||||
.await
|
||||
.map_err(map_custom_world_asset_oss_error)?;
|
||||
// custom world 图片链正式改为 OSS 真值确认,不再把 put_object 返回值直接当成唯一对象真相。
|
||||
let head = oss_client
|
||||
.head_object(
|
||||
&http_client,
|
||||
OssHeadObjectRequest {
|
||||
object_key: put_result.object_key.clone(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(map_custom_world_asset_oss_error)?;
|
||||
let now_micros = current_utc_micros();
|
||||
let asset_object = state
|
||||
.spacetime_client()
|
||||
.confirm_asset_object(
|
||||
build_asset_object_upsert_input(
|
||||
generate_asset_object_id(now_micros),
|
||||
head.bucket,
|
||||
head.object_key,
|
||||
AssetObjectAccessPolicy::Private,
|
||||
head.content_type.or(Some(persisted_mime_type)),
|
||||
head.content_length,
|
||||
head.etag,
|
||||
asset_kind.to_string(),
|
||||
source_job_id,
|
||||
Some(owner_user_id.to_string()),
|
||||
profile_id.clone(),
|
||||
Some(entity_id.clone()),
|
||||
now_micros,
|
||||
)
|
||||
.map_err(map_asset_object_prepare_error)?,
|
||||
)
|
||||
.await
|
||||
.map_err(map_custom_world_asset_spacetime_error)?;
|
||||
state
|
||||
.spacetime_client()
|
||||
.bind_asset_object_to_entity(
|
||||
build_asset_entity_binding_input(
|
||||
generate_asset_binding_id(now_micros),
|
||||
asset_object.asset_object_id,
|
||||
entity_kind.to_string(),
|
||||
entity_id.clone(),
|
||||
slot.to_string(),
|
||||
asset_kind.to_string(),
|
||||
Some(owner_user_id.to_string()),
|
||||
profile_id,
|
||||
now_micros,
|
||||
)
|
||||
.map_err(map_asset_binding_prepare_error)?,
|
||||
)
|
||||
.await
|
||||
.map_err(map_custom_world_asset_spacetime_error)?;
|
||||
response.image_src = put_result.legacy_public_path;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user