This commit is contained in:
2026-05-11 16:15:48 +08:00
parent 0c9254502c
commit e30b733b17
87 changed files with 3527 additions and 1261 deletions

View File

@@ -19,8 +19,9 @@ use shared_contracts::assets::{
AssetBindingPayload, AssetHistoryEntryPayload, AssetHistoryListResponse, AssetHistoryQuery,
AssetObjectPayload, AssetReadUrlPayload, BindAssetObjectRequest, BindAssetObjectResponse,
ConfirmAssetObjectAccessPolicy, ConfirmAssetObjectRequest, ConfirmAssetObjectResponse,
CreateDirectUploadTicketRequest, CreateDirectUploadTicketResponse, DirectUploadTicketPayload,
GetAssetReadUrlResponse, GetReadUrlQuery,
CreateDirectUploadTicketRequest, CreateDirectUploadTicketResponse, DirectUploadObjectAccess,
DirectUploadTicketFormFields, DirectUploadTicketPayload, GetAssetReadUrlResponse,
GetReadUrlQuery,
};
use spacetime_client::SpacetimeClientError;
@@ -44,7 +45,8 @@ const SUPPORTED_ASSET_HISTORY_KINDS: [&str; 7] = [
"square_hole_shape_image",
"square_hole_hole_image",
];
const ASSET_READ_BYTES_MAX_SIZE_BYTES: u64 = 10 * 1024 * 1024;
// 中文注释:同源字节读取同时服务图片转 Data URL 与 Match3D 私有 GLB 预览Rodin GLB 可能明显超过图片上限。
const ASSET_READ_BYTES_MAX_SIZE_BYTES: u64 = 120 * 1024 * 1024;
const ASSET_READ_BYTES_DEFAULT_EXPIRE_SECONDS: u64 = 300;
pub async fn create_direct_upload_ticket(
@@ -73,7 +75,10 @@ pub async fn create_direct_upload_ticket(
path_segments: payload.path_segments,
file_name: payload.file_name,
content_type: payload.content_type,
access: payload.access.unwrap_or(OssObjectAccess::Private),
access: payload
.access
.map(direct_upload_access_to_oss)
.unwrap_or(OssObjectAccess::Private),
metadata: payload.metadata,
max_size_bytes: payload.max_size_bytes,
expire_seconds: payload.expire_seconds,
@@ -85,7 +90,7 @@ pub async fn create_direct_upload_ticket(
"message": error.to_string(),
}))
})?;
let upload = DirectUploadTicketPayload::from(signed);
let upload = direct_upload_ticket_payload_from_oss(signed);
record_asset_tracking_event(
&state,
@@ -149,11 +154,76 @@ pub async fn get_asset_read_url(
Ok(json_success_body(
Some(&request_context),
GetAssetReadUrlResponse {
read: AssetReadUrlPayload::from(signed),
read: asset_read_url_payload_from_oss(signed),
},
))
}
fn direct_upload_access_to_oss(value: DirectUploadObjectAccess) -> OssObjectAccess {
match value {
DirectUploadObjectAccess::Public => OssObjectAccess::Public,
DirectUploadObjectAccess::Private => OssObjectAccess::Private,
}
}
fn direct_upload_access_from_oss(value: OssObjectAccess) -> DirectUploadObjectAccess {
match value {
OssObjectAccess::Public => DirectUploadObjectAccess::Public,
OssObjectAccess::Private => DirectUploadObjectAccess::Private,
}
}
fn direct_upload_ticket_payload_from_oss(
value: platform_oss::OssPostObjectResponse,
) -> DirectUploadTicketPayload {
DirectUploadTicketPayload {
signature_version: value.signature_version.to_string(),
provider: value.provider.to_string(),
bucket: value.bucket,
endpoint: value.endpoint,
host: value.host,
object_key: value.object_key,
legacy_public_path: value.legacy_public_path,
content_type: value.content_type,
access: direct_upload_access_from_oss(value.access),
key_prefix: value.key_prefix,
expires_at: value.expires_at,
max_size_bytes: value.max_size_bytes,
success_action_status: value.success_action_status,
form_fields: direct_upload_ticket_form_fields_from_oss(value.form_fields),
}
}
fn direct_upload_ticket_form_fields_from_oss(
value: platform_oss::OssPostObjectFormFields,
) -> DirectUploadTicketFormFields {
DirectUploadTicketFormFields {
key: value.key,
policy: value.policy,
signature_version: value.signature_version,
credential: value.credential,
date: value.date,
signature: value.signature,
success_action_status: value.success_action_status,
content_type: value.content_type,
metadata: value.metadata,
}
}
fn asset_read_url_payload_from_oss(
value: platform_oss::OssSignedGetObjectUrlResponse,
) -> AssetReadUrlPayload {
AssetReadUrlPayload {
provider: value.provider.to_string(),
bucket: value.bucket,
endpoint: value.endpoint,
host: value.host,
object_key: value.object_key,
expires_at: value.expires_at,
signed_url: value.signed_url,
}
}
pub async fn get_asset_read_bytes(
State(state): State<AppState>,
Query(query): Query<GetReadUrlQuery>,