feat: 完善敲木鱼玩法模板链路

This commit is contained in:
2026-05-24 02:49:13 +08:00
parent 2ba4691bc0
commit 8638397faa
402 changed files with 2329 additions and 1781 deletions

View File

@@ -1271,6 +1271,10 @@ fn normalize_migration_row(table_name: &str, value: &serde_json::Value) -> serde
object
.entry("background_asset_json".to_string())
.or_insert(serde_json::Value::Null);
// 中文注释:敲木鱼返回按钮图晚于首版作品表加入,旧迁移包按未生成返回按钮兼容。
object
.entry("back_button_asset_json".to_string())
.or_insert(serde_json::Value::Null);
}
}
next_value

View File

@@ -82,6 +82,7 @@ pub struct WoodenFishGalleryViewRow {
pub hit_sound_prompt: Option<String>,
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
pub background_asset: Option<WoodenFishImageAssetSnapshot>,
pub back_button_asset: Option<WoodenFishImageAssetSnapshot>,
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
pub floating_words: Vec<String>,
pub cover_image_src: String,
@@ -333,6 +334,11 @@ fn compile_wooden_fish_draft_tx(
.as_deref()
.map(parse_json)
.transpose()?;
let back_button_asset = input
.back_button_asset_json
.as_deref()
.map(parse_json)
.transpose()?;
let cover_image_src = input
.cover_image_src
.as_deref()
@@ -361,6 +367,7 @@ fn compile_wooden_fish_draft_tx(
floating_words: floating_words.clone(),
hit_object_asset: hit_object_asset.clone(),
background_asset: background_asset.clone(),
back_button_asset: back_button_asset.clone(),
hit_sound_asset: hit_sound_asset.clone(),
cover_image_src: cover_image_src.clone(),
generation_status: input
@@ -400,6 +407,7 @@ fn compile_wooden_fish_draft_tx(
updated_at: compiled_at,
published_at: None,
background_asset_json: background_asset.as_ref().map(to_json_string),
back_button_asset_json: back_button_asset.as_ref().map(to_json_string),
};
upsert_work(ctx, row);
let config = config_from_draft(&draft);
@@ -485,6 +493,14 @@ fn update_wooden_fish_work_tx(
let asset = parse_json::<WoodenFishImageAssetSnapshot>(&value)?;
next.background_asset_json = Some(to_json_string(&asset));
}
if let Some(value) = input
.back_button_asset_json
.as_deref()
.and_then(clean_optional)
{
let asset = parse_json::<WoodenFishImageAssetSnapshot>(&value)?;
next.back_button_asset_json = Some(to_json_string(&asset));
}
if let Some(value) = input
.floating_words_json
.as_deref()
@@ -512,7 +528,7 @@ fn publish_wooden_fish_work_tx(
) -> Result<WoodenFishWorkSnapshot, String> {
let row = find_owned_work(ctx, &input.profile_id, &input.owner_user_id)?;
if !is_publish_ready(&row) {
return Err("发布需要完整的敲击物图案、敲击音效和飘字配置".to_string());
return Err("发布需要完整的敲击物图案、背景、返回按钮、敲击音效和飘字配置".to_string());
}
let published_at = Timestamp::from_micros_since_unix_epoch(input.published_at_micros);
replace_work(
@@ -691,6 +707,7 @@ fn build_gallery_view_row(
hit_sound_prompt: work.hit_sound_prompt,
hit_object_asset: work.hit_object_asset,
background_asset: work.background_asset,
back_button_asset: work.back_button_asset,
hit_sound_asset: work.hit_sound_asset,
floating_words: work.floating_words,
cover_image_src: work.cover_image_src,
@@ -744,6 +761,12 @@ fn build_work_snapshot(row: &WoodenFishWorkProfileRow) -> Result<WoodenFishWorkS
.and_then(clean_optional)
.map(|value| parse_json(&value))
.transpose()?,
back_button_asset: row
.back_button_asset_json
.as_deref()
.and_then(clean_optional)
.map(|value| parse_json(&value))
.transpose()?,
hit_sound_asset: clean_optional(&row.hit_sound_asset_json)
.map(|value| parse_json(&value))
.transpose()?,
@@ -993,6 +1016,11 @@ fn is_publish_ready(row: &WoodenFishWorkProfileRow) -> bool {
.as_deref()
.and_then(clean_optional)
.is_some()
&& row
.back_button_asset_json
.as_deref()
.and_then(clean_optional)
.is_some()
&& !row.hit_sound_asset_json.trim().is_empty()
&& !row.floating_words_json.trim().is_empty()
&& row.generation_status == WOODEN_FISH_GENERATION_READY
@@ -1031,6 +1059,7 @@ fn draft_from_config(
floating_words: normalize_floating_words(&config.floating_words),
hit_object_asset: None,
background_asset: None,
back_button_asset: None,
hit_sound_asset: None,
cover_image_src: None,
generation_status: generation_status.to_string(),
@@ -1051,6 +1080,7 @@ fn draft_from_work_snapshot(work: &WoodenFishWorkSnapshot) -> WoodenFishDraftSna
floating_words: work.floating_words.clone(),
hit_object_asset: work.hit_object_asset.clone(),
background_asset: work.background_asset.clone(),
back_button_asset: work.back_button_asset.clone(),
hit_sound_asset: work.hit_sound_asset.clone(),
cover_image_src: clean_optional(&work.cover_image_src),
generation_status: work.generation_status.clone(),
@@ -1231,6 +1261,7 @@ fn clone_work(row: &WoodenFishWorkProfileRow) -> WoodenFishWorkProfileRow {
hit_object_asset_json: row.hit_object_asset_json.clone(),
background_asset_json: row.background_asset_json.clone(),
hit_sound_asset_json: row.hit_sound_asset_json.clone(),
back_button_asset_json: row.back_button_asset_json.clone(),
floating_words_json: row.floating_words_json.clone(),
cover_image_src: row.cover_image_src.clone(),
generation_status: row.generation_status.clone(),

View File

@@ -47,6 +47,8 @@ pub struct WoodenFishWorkProfileRow {
pub(crate) published_at: Option<Timestamp>,
#[default(None::<String>)]
pub(crate) background_asset_json: Option<String>,
#[default(None::<String>)]
pub(crate) back_button_asset_json: Option<String>,
}
#[spacetimedb::table(

View File

@@ -47,6 +47,7 @@ pub struct WoodenFishDraftCompileInput {
pub hit_object_asset_json: Option<String>,
pub background_asset_json: Option<String>,
pub hit_sound_asset_json: Option<String>,
pub back_button_asset_json: Option<String>,
pub floating_words_json: Option<String>,
pub cover_image_src: Option<String>,
pub generation_status: Option<String>,
@@ -66,6 +67,7 @@ pub struct WoodenFishWorkUpdateInput {
pub hit_object_asset_json: Option<String>,
pub background_asset_json: Option<String>,
pub hit_sound_asset_json: Option<String>,
pub back_button_asset_json: Option<String>,
pub floating_words_json: Option<String>,
pub cover_image_src: Option<String>,
pub generation_status: Option<String>,
@@ -210,6 +212,7 @@ pub struct WoodenFishDraftSnapshot {
pub floating_words: Vec<String>,
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
pub background_asset: Option<WoodenFishImageAssetSnapshot>,
pub back_button_asset: Option<WoodenFishImageAssetSnapshot>,
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
pub cover_image_src: Option<String>,
pub generation_status: String,
@@ -246,6 +249,7 @@ pub struct WoodenFishWorkSnapshot {
pub hit_sound_prompt: Option<String>,
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
pub background_asset: Option<WoodenFishImageAssetSnapshot>,
pub back_button_asset: Option<WoodenFishImageAssetSnapshot>,
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
pub floating_words: Vec<String>,
pub cover_image_src: String,