From deb60065a5676bfdc38ef72f4b98509698f6e3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sat, 5 Sep 2026 12:58:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E8=81=94=E5=90=88=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E7=B4=A0=E6=9D=90=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 拒绝不存在的图片素材组件引用 拒绝不存在的字体绑定引用 --- .../commands/recognition_and_binding.rs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition_and_binding.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition_and_binding.rs index dee6b9573..396107949 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition_and_binding.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition_and_binding.rs @@ -4,6 +4,7 @@ use crate::ui_editor::commands::utils::{ parse_limited_llm_tool_arguments, read_ui_reference_image_data_url, request_ui_editor_llm, strict_json_schema, }; +use crate::ui_editor::component::text::FontSource; use crate::ui_editor::component::Component; use crate::ui_editor::layout::children_display_mode::ChildrenDisplayMode; use crate::ui_editor::layout::control_layout::ControlLayout; @@ -348,6 +349,37 @@ fn validate_confidence(nodes: &[RecognitionNode]) -> Result<(), String> { Ok(()) } +fn validate_component_references( + nodes: &[RecognitionNode], + known_sprite_ids: &HashSet, + known_font_ids: &HashSet, +) -> Result<(), String> { + for node in nodes { + for component in node.components.as_deref().unwrap_or_default() { + match component { + Component::Image(image) => { + if image + .target_graphic + .as_ref() + .is_some_and(|id| !known_sprite_ids.contains(id)) + { + return Err("联合识别绑定引用了不存在的独立素材".to_string()); + } + } + Component::Text(text) => { + if let FontSource::Bound(id) = &text.font { + if !known_font_ids.contains(id) { + return Err("联合识别绑定引用了不存在的字体素材".to_string()); + } + } + } + } + } + validate_component_references(&node.children, known_sprite_ids, known_font_ids)?; + } + Ok(()) +} + fn validate_tree_image_ids( trees: &[RecognitionTree], allowed_ids: &[UIDesignImageId], @@ -694,6 +726,11 @@ pub(crate) async fn recognition_and_binding_impl_with_provider( let parsed = serde_json::from_value::(arguments) .map_err(|error| format!("联合结果参数无效:{error}"))?; validate_tree_image_ids(&parsed.trees, &context_ids)?; + let known_sprite_ids = state.sprite_assets.keys().cloned().collect::>(); + let known_font_ids = state.font_assets.keys().cloned().collect::>(); + for tree in &parsed.trees { + validate_component_references(&tree.children, &known_sprite_ids, &known_font_ids)?; + } let mut ui_trees = Vec::with_capacity(parsed.trees.len()); for tree in parsed.trees { let image = state