From dda6b3946a4331d8a26866598c7d45de15b3be9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Wed, 9 Sep 2026 00:41:35 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=BB=E6=AD=A2=E8=AF=86=E5=88=AB=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E5=BC=95=E7=94=A8=E6=9C=AA=E6=8E=88=E6=9D=83=E5=AD=97?= =?UTF-8?q?=E4=BD=93=E7=B4=A0=E6=9D=90=20=E8=A1=A5=E9=BD=90=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E9=98=B6=E6=AE=B5=E5=AD=97=E4=BD=93=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=20=E5=A2=9E=E5=8A=A0=E4=BC=AA=E9=80=A0?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E7=BB=91=E5=AE=9A=E5=9B=9E=E5=BD=92=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui_editor/commands/recognition.rs | 67 +++++++++++++++---- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs index ceae0d7ea..bc578daf8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs @@ -348,6 +348,17 @@ fn validate_confidence(nodes: &[RecognitionNode]) -> Result<(), String> { }) { return Err("识别阶段不能返回已绑定的 SpriteAssetId".to_string()); } + if node.components.iter().any(|component| { + matches!( + component, + Component::Text(crate::ui_editor::component::text::TextComponent { + font: crate::ui_editor::component::text::FontSource::Bound(_), + .. + }) + ) + }) { + return Err("识别阶段不能返回已绑定的字体素材".to_string()); + } if let Confidence::UnSure(reason) = &node.confidence { if reason.trim().is_empty() { return Err("UnSure 必须包含审阅原因".to_string()); @@ -464,19 +475,23 @@ mod tests { let oversized = (0..=MAX_RECOGNITION_TREE_NODES) .map(|_| serde_json::json!({"children": []})) .collect::>(); - assert!(validate_recognition_response_shape(&serde_json::json!({ - "trees": [{"children": oversized}] - })) - .is_err()); + assert!( + validate_recognition_response_shape(&serde_json::json!({ + "trees": [{"children": oversized}] + })) + .is_err() + ); let mut nested = serde_json::json!({"children": []}); for _ in 0..MAX_RECOGNITION_TREE_DEPTH { nested = serde_json::json!({"children": [nested]}); } - assert!(validate_recognition_response_shape(&serde_json::json!({ - "trees": [{"children": [nested]}] - })) - .is_err()); + assert!( + validate_recognition_response_shape(&serde_json::json!({ + "trees": [{"children": [nested]}] + })) + .is_err() + ); } #[test] @@ -521,6 +536,30 @@ mod tests { assert!(validate_confidence(&[node]).is_err()); } + #[test] + fn recognition_rejects_bound_font_references() { + let mut text = crate::ui_editor::component::text::TextComponent::default(); + text.font = crate::ui_editor::component::text::FontSource::Bound( + crate::ui_editor::utils::FontAssetId::new("font").expect("valid font id"), + ); + let node = RecognitionNode { + global_pos_x_px: 0, + global_pos_y_px: 0, + width_px: 1, + height_px: 1, + local_anchor: Anchor::Preset(PresetAnchor { + horizontal: HorizontalAnchor::Left, + vertical: VerticalAnchor::Top, + }), + name: "文本".to_string(), + description: String::new(), + children: Vec::new(), + confidence: Confidence::Confident, + components: vec![Component::Text(text)], + }; + assert!(validate_confidence(&[node]).is_err()); + } + #[test] fn conversion_stays_in_the_tree_image_coordinate_system() { let image_id = UIDesignImageId::new("slave").expect("valid image id"); @@ -572,11 +611,13 @@ mod tests { children: Vec::new(), }; - assert!(validate_tree_image_ids( - &[tree(page.clone()), tree(slave.clone())], - &[page.clone(), slave.clone()], - ) - .is_ok()); + assert!( + validate_tree_image_ids( + &[tree(page.clone()), tree(slave.clone())], + &[page.clone(), slave.clone()], + ) + .is_ok() + ); assert!( validate_tree_image_ids(&[tree(page.clone())], &[page.clone(), slave.clone()]).is_err() );