Merge branch 'master' into codex/puzzle-clear-template-runtime-fixes
# Conflicts: # .hermes/shared-memory/decision-log.md # .hermes/shared-memory/project-overview.md # docs/【开发运维】本地开发验证与生产运维-2026-05-15.md # scripts/dev.test.ts # server-rs/crates/api-server/src/creation_entry_config.rs # server-rs/crates/api-server/src/wooden_fish.rs # server-rs/crates/module-auth/src/lib.rs # server-rs/crates/spacetime-client/src/wooden_fish.rs # server-rs/crates/spacetime-module/src/auth/procedures.rs # src/components/custom-world-home/creationWorkShelf.ts # src/components/platform-entry/PlatformEntryFlowShellImpl.tsx # src/components/rpg-entry/rpgEntryWorldPresentation.ts # src/services/miniGameDraftGenerationProgress.test.ts # src/services/miniGameDraftGenerationProgress.ts
This commit is contained in:
@@ -14,6 +14,18 @@ impl From<module_runtime::CreationEntryTypeAdminUpsertInput> for CreationEntryTy
|
||||
category_id: input.category_id,
|
||||
category_label: input.category_label,
|
||||
category_sort_order: input.category_sort_order,
|
||||
unified_creation_spec_json: input.unified_creation_spec_json,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 将业务层 banner JSON 保存输入转换为 SpacetimeDB 生成绑定类型。
|
||||
impl From<module_runtime::CreationEntryEventBannersAdminUpsertInput>
|
||||
for CreationEntryEventBannersAdminUpsertInput
|
||||
{
|
||||
fn from(input: module_runtime::CreationEntryEventBannersAdminUpsertInput) -> Self {
|
||||
Self {
|
||||
event_banners_json: input.event_banners_json,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,6 +244,7 @@ fn map_admin_work_visibility_snapshot(
|
||||
}
|
||||
}
|
||||
|
||||
/// 从本地订阅表行组装创作入口配置响应,兼容旧单条 banner 字段。
|
||||
pub(crate) fn build_creation_entry_config_record_from_rows(
|
||||
header: CreationEntryConfig,
|
||||
mut creation_types: Vec<CreationEntryTypeConfig>,
|
||||
@@ -277,7 +290,10 @@ pub(crate) fn build_creation_entry_config_record_from_rows(
|
||||
header.event_ends_at_text,
|
||||
module_runtime::DEFAULT_CREATION_ENTRY_EVENT_ENDS_AT_TEXT,
|
||||
),
|
||||
render_mode: "structured".to_string(),
|
||||
html_code: None,
|
||||
},
|
||||
event_banners_json: header.event_banners_json,
|
||||
creation_types: creation_types
|
||||
.into_iter()
|
||||
.map(|item| module_runtime::CreationEntryTypeSnapshot {
|
||||
@@ -299,6 +315,7 @@ pub(crate) fn build_creation_entry_config_record_from_rows(
|
||||
),
|
||||
category_sort_order: item.category_sort_order,
|
||||
updated_at_micros: item.updated_at.to_micros_since_unix_epoch(),
|
||||
unified_creation_spec_json: item.unified_creation_spec_json,
|
||||
})
|
||||
.collect(),
|
||||
updated_at_micros: header.updated_at.to_micros_since_unix_epoch(),
|
||||
@@ -306,6 +323,7 @@ pub(crate) fn build_creation_entry_config_record_from_rows(
|
||||
)
|
||||
}
|
||||
|
||||
/// 将 SpacetimeDB procedure 快照映射为 module-runtime 领域快照。
|
||||
fn map_creation_entry_config_snapshot(
|
||||
snapshot: CreationEntryConfigSnapshot,
|
||||
) -> module_runtime::CreationEntryConfigSnapshot {
|
||||
@@ -328,7 +346,10 @@ fn map_creation_entry_config_snapshot(
|
||||
prize_pool_mud_points: snapshot.event_banner.prize_pool_mud_points,
|
||||
starts_at_text: snapshot.event_banner.starts_at_text,
|
||||
ends_at_text: snapshot.event_banner.ends_at_text,
|
||||
render_mode: snapshot.event_banner.render_mode,
|
||||
html_code: snapshot.event_banner.html_code,
|
||||
},
|
||||
event_banners_json: snapshot.event_banners_json,
|
||||
creation_types: snapshot
|
||||
.creation_types
|
||||
.into_iter()
|
||||
@@ -345,6 +366,7 @@ fn map_creation_entry_config_snapshot(
|
||||
category_label: item.category_label,
|
||||
category_sort_order: item.category_sort_order,
|
||||
updated_at_micros: item.updated_at_micros,
|
||||
unified_creation_spec_json: item.unified_creation_spec_json,
|
||||
})
|
||||
.collect(),
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
|
||||
@@ -100,6 +100,7 @@ fn map_wooden_fish_session_snapshot(
|
||||
fn map_wooden_fish_work_snapshot(
|
||||
snapshot: WoodenFishWorkSnapshot,
|
||||
) -> Result<WoodenFishWorkProfileResponse, SpacetimeClientError> {
|
||||
let generation_status = parse_generation_status(&snapshot.generation_status);
|
||||
let draft = WoodenFishDraftResponse {
|
||||
template_id: "wooden-fish".to_string(),
|
||||
template_name: "敲木鱼".to_string(),
|
||||
@@ -116,15 +117,23 @@ fn map_wooden_fish_work_snapshot(
|
||||
back_button_asset: snapshot.back_button_asset.clone().map(map_image_asset),
|
||||
hit_sound_asset: snapshot.hit_sound_asset.clone().map(map_audio_asset),
|
||||
cover_image_src: empty_string_to_none(snapshot.cover_image_src.clone()),
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
generation_status: generation_status.clone(),
|
||||
};
|
||||
let hit_object_asset = draft
|
||||
.hit_object_asset
|
||||
.clone()
|
||||
.or_else(|| {
|
||||
matches!(generation_status, WoodenFishGenerationStatus::Failed)
|
||||
.then(default_failed_hit_object_asset)
|
||||
})
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish hit object asset"))?;
|
||||
let hit_sound_asset = draft
|
||||
.hit_sound_asset
|
||||
.clone()
|
||||
.or_else(|| {
|
||||
matches!(generation_status, WoodenFishGenerationStatus::Failed)
|
||||
.then(default_failed_hit_sound_asset)
|
||||
})
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish hit sound asset"))?;
|
||||
Ok(WoodenFishWorkProfileResponse {
|
||||
summary: WoodenFishWorkSummaryResponse {
|
||||
@@ -143,7 +152,7 @@ fn map_wooden_fish_work_snapshot(
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
|
||||
publish_ready: snapshot.publish_ready,
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
generation_status,
|
||||
},
|
||||
draft,
|
||||
hit_object_asset,
|
||||
@@ -154,6 +163,31 @@ fn map_wooden_fish_work_snapshot(
|
||||
})
|
||||
}
|
||||
|
||||
fn default_failed_hit_object_asset() -> WoodenFishImageAsset {
|
||||
WoodenFishImageAsset {
|
||||
asset_id: "wooden-fish-failed-hit-object".to_string(),
|
||||
image_src: "/wooden-fish/default-hit-object.png".to_string(),
|
||||
image_object_key: "public/wooden-fish/default-hit-object.png".to_string(),
|
||||
asset_object_id: "wooden-fish-failed-hit-object".to_string(),
|
||||
generation_provider: "failed-fallback".to_string(),
|
||||
prompt: "生成失败占位图".to_string(),
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_failed_hit_sound_asset() -> WoodenFishAudioAsset {
|
||||
WoodenFishAudioAsset {
|
||||
asset_id: "wooden-fish-failed-hit-sound".to_string(),
|
||||
audio_src: "/wooden-fish/default-hit-sound.mp3".to_string(),
|
||||
audio_object_key: "public/wooden-fish/default-hit-sound.mp3".to_string(),
|
||||
asset_object_id: "wooden-fish-failed-hit-sound".to_string(),
|
||||
source: "failed-fallback".to_string(),
|
||||
prompt: Some("生成失败占位音效".to_string()),
|
||||
duration_ms: Some(3_000),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_wooden_fish_draft_snapshot(snapshot: WoodenFishDraftSnapshot) -> WoodenFishDraftResponse {
|
||||
WoodenFishDraftResponse {
|
||||
template_id: snapshot.template_id,
|
||||
|
||||
Reference in New Issue
Block a user