1
This commit is contained in:
@@ -15,7 +15,8 @@ use module_puzzle::{
|
||||
PuzzleRecommendedNextWork, PuzzleResultDraft, PuzzleRunDragInput, PuzzleRunGetInput,
|
||||
PuzzleRunNextLevelInput, PuzzleRunPauseInput, PuzzleRunProcedureResult, PuzzleRunPropInput,
|
||||
PuzzleRunSnapshot, PuzzleRunStartInput, PuzzleRunSwapInput, PuzzleRuntimeLevelStatus,
|
||||
PuzzleSelectCoverImageInput, PuzzleWorkDeleteInput, PuzzleWorkGetInput,
|
||||
PuzzleSelectCoverImageInput, PuzzleUiBackgroundSaveInput, PuzzleWorkDeleteInput,
|
||||
PuzzleWorkGetInput,
|
||||
PuzzleWorkLikeRecordInput as PuzzleWorkLikeInput, PuzzleWorkPointIncentiveClaimInput,
|
||||
PuzzleWorkProcedureResult, PuzzleWorkProfile, PuzzleWorkRemixInput, PuzzleWorkUpsertInput,
|
||||
PuzzleWorksListInput, PuzzleWorksProcedureResult, apply_publish_overrides_to_draft,
|
||||
@@ -313,6 +314,25 @@ pub fn save_puzzle_generated_images(
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn save_puzzle_ui_background(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: PuzzleUiBackgroundSaveInput,
|
||||
) -> PuzzleAgentSessionProcedureResult {
|
||||
match ctx.try_with_tx(|tx| save_puzzle_ui_background_tx(tx, input.clone())) {
|
||||
Ok(session) => PuzzleAgentSessionProcedureResult {
|
||||
ok: true,
|
||||
session_json: Some(serialize_json(&session)),
|
||||
error_message: None,
|
||||
},
|
||||
Err(message) => PuzzleAgentSessionProcedureResult {
|
||||
ok: false,
|
||||
session_json: None,
|
||||
error_message: Some(message),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn select_puzzle_cover_image(
|
||||
ctx: &mut ProcedureContext,
|
||||
@@ -1025,6 +1045,70 @@ fn save_puzzle_generated_images_tx(
|
||||
)
|
||||
}
|
||||
|
||||
fn save_puzzle_ui_background_tx(
|
||||
ctx: &TxContext,
|
||||
input: PuzzleUiBackgroundSaveInput,
|
||||
) -> Result<PuzzleAgentSessionSnapshot, String> {
|
||||
let row = get_owned_session_row(ctx, &input.session_id, &input.owner_user_id)?;
|
||||
let mut draft = deserialize_draft_required(&row.draft_json)?;
|
||||
if let Some(levels) = deserialize_optional_levels_input(input.levels_json.as_deref())? {
|
||||
// 中文注释:UI 背景可以在自动保存前立即生成,写回前优先使用本次 action 携带的关卡快照。
|
||||
draft.levels = levels;
|
||||
module_puzzle::sync_primary_level_fields(&mut draft);
|
||||
}
|
||||
let target_level = selected_puzzle_level(&draft, input.level_id.as_deref())
|
||||
.ok_or_else(|| "拼图关卡不存在".to_string())?;
|
||||
let mut next_level = target_level;
|
||||
next_level.ui_background_prompt = Some(input.prompt.trim().to_string());
|
||||
next_level.ui_background_image_src = Some(input.image_src.trim().to_string());
|
||||
next_level.ui_background_image_object_key = input
|
||||
.image_object_key
|
||||
.and_then(|value| {
|
||||
let trimmed = value.trim().to_string();
|
||||
(!trimmed.is_empty()).then_some(trimmed)
|
||||
});
|
||||
let draft = replace_puzzle_level(&draft, next_level).map_err(|error| error.to_string())?;
|
||||
|
||||
let saved_at = Timestamp::from_micros_since_unix_epoch(input.saved_at_micros);
|
||||
let next_stage = if build_result_preview(&draft, Some("百梦主")).publish_ready {
|
||||
PuzzleAgentStage::ReadyToPublish
|
||||
} else {
|
||||
PuzzleAgentStage::ImageRefining
|
||||
};
|
||||
upsert_puzzle_draft_work_profile(
|
||||
ctx,
|
||||
&row.session_id,
|
||||
&row.owner_user_id,
|
||||
&draft,
|
||||
input.saved_at_micros,
|
||||
)?;
|
||||
replace_puzzle_agent_session(
|
||||
ctx,
|
||||
&row,
|
||||
PuzzleAgentSessionRow {
|
||||
session_id: row.session_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
seed_text: row.seed_text.clone(),
|
||||
current_turn: row.current_turn,
|
||||
progress_percent: row.progress_percent.max(96),
|
||||
stage: next_stage,
|
||||
anchor_pack_json: row.anchor_pack_json.clone(),
|
||||
draft_json: Some(serialize_json(&draft)),
|
||||
last_assistant_reply: Some("拼图 UI 背景图已生成。".to_string()),
|
||||
published_profile_id: row.published_profile_id.clone(),
|
||||
created_at: row.created_at,
|
||||
updated_at: saved_at,
|
||||
},
|
||||
);
|
||||
get_puzzle_agent_session_tx(
|
||||
ctx,
|
||||
PuzzleAgentSessionGetInput {
|
||||
session_id: input.session_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn sync_generated_primary_level_name_as_default_work_title(
|
||||
draft: &mut PuzzleResultDraft,
|
||||
previous_work_title: &str,
|
||||
@@ -1069,6 +1153,9 @@ fn select_puzzle_cover_image_tx(
|
||||
level_name: target_level.level_name,
|
||||
picture_description: target_level.picture_description,
|
||||
picture_reference: target_level.picture_reference,
|
||||
ui_background_prompt: target_level.ui_background_prompt,
|
||||
ui_background_image_src: target_level.ui_background_image_src,
|
||||
ui_background_image_object_key: target_level.ui_background_image_object_key,
|
||||
background_music: target_level.background_music,
|
||||
candidates: selected_level_draft.candidates,
|
||||
selected_candidate_id: selected_level_draft.selected_candidate_id,
|
||||
@@ -2322,6 +2409,9 @@ fn build_profile_levels_from_row(
|
||||
level_name: row.level_name.clone(),
|
||||
picture_description: row.summary.clone(),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
@@ -3337,6 +3427,9 @@ mod tests {
|
||||
.map(|level| level.picture_description.clone())
|
||||
.unwrap_or_default(),
|
||||
picture_reference: None,
|
||||
ui_background_prompt: None,
|
||||
ui_background_image_src: None,
|
||||
ui_background_image_object_key: None,
|
||||
background_music: None,
|
||||
candidates: candidates.clone(),
|
||||
selected_candidate_id: None,
|
||||
|
||||
Reference in New Issue
Block a user