From 56c6e0fecc1e2dffb39040a5a9abf03e1e67a2c6 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Thu, 10 Sep 2026 16:33:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=85=B7=E6=9D=A1?= =?UTF-8?q?=E6=8A=98=E8=A1=8C=E4=B8=8E=E8=B5=84=E6=BA=90=E7=BC=96=E8=BE=91?= =?UTF-8?q?=20400=20=E7=9A=84=E9=94=99=E8=AF=AF=E7=9B=B2=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - resourceCanvasChrome.css:移除我自行添加的 max-width 与 flex-wrap: wrap,按网页端美术画布原始规则改回单行不换行(容器 nowrap + 溢出横向兜底),按钮统一 2.25rem 方块与 0.45rem 圆角,文字键 padding 改回 0 0.62rem,分隔线改回 1.125rem,消除动作变多时折叠成多层与按钮高矮不齐 - resource_editor.rs:新增 editor_api_rejection_reason,在 HTTP 400 分支把服务端响应体的可读原因(兼容 error.message / error 字符串 / details.message / 顶层 message,截断 200 字符)拼进用户可见错误,替换原先只有状态码的笼统提示 --- .../src-tauri/src/project/resource_editor.rs | 34 ++++++++++++++++++- .../resource-canvas/resourceCanvasChrome.css | 33 ++++++++++++++---- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs b/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs index 4af6ed29c..245b3ec82 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs @@ -2457,6 +2457,35 @@ fn is_external_resource_edit_endpoint(endpoint: &str) -> bool { ) } +/// 从服务端 4xx 响应体里取出**可读的失败原因**,让用户看到的不是笼统的 HTTP 状态码。 +/// +/// 平台错误体在不同路由上可能是 `{error:{message}}`、`{error:"文本"}`、`{details:{message}}` +/// 或顶层 `{message}`;这里按这个顺序兼容,并截断到 200 字符,避免把整段响应体塞进用户可见文案。 +async fn editor_api_rejection_reason(response: reqwest::Response) -> Option { + let body = response.text().await.ok()?; + let value: serde_json::Value = serde_json::from_str(body.trim()).ok()?; + let candidate = value + .get("error") + .and_then(|error| { + error + .get("message") + .and_then(|message| message.as_str()) + .or_else(|| error.as_str()) + }) + .or_else(|| { + value + .get("details") + .and_then(|details| details.get("message")) + .and_then(|message| message.as_str()) + }) + .or_else(|| value.get("message").and_then(|message| message.as_str()))?; + let trimmed = candidate.trim(); + if trimmed.is_empty() { + return None; + } + Some(trimmed.chars().take(200).collect()) +} + async fn submit_resource_edit_remote( root: &Path, client: &reqwest::Client, @@ -2527,7 +2556,10 @@ async fn submit_resource_edit_remote( if let Some(error) = post_response_session_error.as_ref() { return Err(error.clone()); } - return Err("remote-terminal-failed: 资源编辑请求被拒绝:HTTP 400".to_string()); + return Err(match editor_api_rejection_reason(response).await { + Some(reason) => format!("remote-terminal-failed: 资源编辑请求被拒绝:HTTP 400({reason})"), + None => "remote-terminal-failed: 资源编辑请求被拒绝:HTTP 400".to_string(), + }); } if !matches!( status, diff --git a/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasChrome.css b/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasChrome.css index de56e491d..fe982d246 100644 --- a/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasChrome.css +++ b/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasChrome.css @@ -30,16 +30,23 @@ --image-canvas-brand-focus-ring: rgba(204, 117, 76, 0.18); } -/* 选中工具条:贴在资源卡正上方浮出,层级高于卡片与画布标题栏。 */ +/* 选中工具条:贴在资源卡正上方浮出,层级高于卡片与画布标题栏。 + * + * 尺寸与排布严格对齐网页端美术画布(`src/index.css`):容器**单行不换行**、 + * 图标键 `2.25rem` 方块、文字键靠同一高度撑开、分隔线 `1.125rem` 高。 + * 早期实现多加了 `max-width` 与 `flex-wrap: wrap`,动作一多就折成两三层, + * 与美术画布不一致,已移除。窄屏用横向滚动兜底,仍然只占一行。 */ .game-resource-canvas-toolbar-host .image-canvas-editor__floating-toolbar { position: absolute; z-index: 60; display: inline-flex; - max-width: min(560px, 92vw); + max-width: min(92vw, 640px); align-items: center; - flex-wrap: wrap; + flex-wrap: nowrap; gap: 0.3rem; + overflow-x: auto; + overscroll-behavior-x: contain; border: 1px solid var(--image-canvas-brand-border-soft); border-radius: 0.5rem; background: #ffffff; @@ -47,6 +54,12 @@ box-shadow: 0 18px 34px rgba(15, 23, 42, 0.18); transform: translate(-50%, -100%); pointer-events: auto; + scrollbar-width: none; +} + +.game-resource-canvas-toolbar-host + .image-canvas-editor__floating-toolbar::-webkit-scrollbar { + display: none; } .game-resource-canvas-toolbar-host @@ -55,8 +68,11 @@ display: inline-flex; align-items: center; justify-content: center; + flex: 0 0 auto; + width: 2.25rem; + height: 2.25rem; border: 1px solid var(--image-canvas-brand-border-soft); - border-radius: 0.375rem; + border-radius: 0.45rem; background: #ffffff; color: #334155; cursor: pointer; @@ -89,7 +105,7 @@ width: auto; min-width: 0; gap: 0.35rem; - padding: 0.34rem 0.62rem; + padding: 0 0.62rem; font-size: 0.74rem; font-weight: 850; white-space: nowrap; @@ -97,9 +113,12 @@ .game-resource-canvas-toolbar-host .image-canvas-editor__floating-toolbar-divider { - display: block; + display: inline-block; + flex: 0 0 auto; + align-self: center; width: 1px; - height: 1.1rem; + height: 1.125rem; + border-radius: 999px; background: var(--image-canvas-brand-border-soft); }