feat: 多页面UI打磨 — 设置面板、状态反馈与样式升级
Web Quality / verify (pull_request) Has been cancelled

本次更新对多个功能页面进行了系统性的 UI/UX 打磨,统一了交互模式并补充了缺失的状态反馈。

## 新增功能
- WorkbenchPage: 图片提示词案例区域新增加载骨架屏、错误回退、空数据三种状态展示
- CharacterMixPage: 新增左侧设置面板(驱动提示词、图像检测开关、水印开关),支持清除已上传的人物图/参考视频
- DigitalHumanPage: 新增左侧设置面板(提示词输入、去水印/保留原声开关),支持清除已上传的人像/音频,增加取消生成按钮
- ImageWorkbenchPage / ResolutionUpscalePage: 新增参数设置面板和资产清除交互
- MorePage: 新增页面入口

## UI 优化
- 统一 Toggle 开关组件: 所有设置页面采用一致的 .studio-toggle 交互模式
- 资产清除: 各上传区域新增清除按钮,含二次确认和提示反馈
- 生成按钮: 统一为带图标的 .studio-generate-btn,增加 disabled/loading 状态
- ConversationSidebar / ProjectSidebar: 侧边栏交互细节优化

## 样式升级
- image-workbench.css: 大幅扩展样式 (+1900 行),覆盖设置面板、上传区、结果展示等
- workbench.css: 新增 666 行样式,含骨架屏动画、案例卡片网格、状态占位等
- subtitle-removal.css: 补充设置面板样式
This commit is contained in:
2026-06-10 17:54:45 +08:00
parent 77ffd01a50
commit a6626beb32
15 changed files with 2949 additions and 251 deletions
@@ -609,6 +609,20 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
</div>
);
const handleRemoveWorkbenchResult = (index: number) => {
setResultImages((current) => {
const next = current.filter((_, imageIndex) => imageIndex !== index);
if (next.length) {
saveToolTaskState("imagewb", { taskId: taskIdRef.current || "", resultUrl: next[0], status: "完成", progress: 100 });
setStatus(`已移除生成图,剩余 ${next.length}`);
} else {
clearToolTaskState("imagewb");
setStatus("已移除生成图");
}
return next;
});
};
const handleGenerate = async () => {
if (!referenceImages.length && !prompt.trim()) {
setStatus("请先上传参考图或输入提示词");
@@ -797,7 +811,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
aria-label="删除局部重绘素材"
onClick={handleRemoveInpaintImage}
>
×
<DeleteOutlined />
</button>
) : null}
</div>
@@ -830,7 +844,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
</label>
</section>
<section className="image-workbench-control-card">
<section className="image-workbench-control-card image-workbench-inpaint-params-card">
<h3></h3>
<span className="image-workbench-field-label"></span>
<div className="image-workbench-segmented">
@@ -842,7 +856,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
</div>
</section>
<section className="image-workbench-control-card">
<section className="image-workbench-control-card image-workbench-inpaint-prompt-card">
<h3></h3>
<textarea
className="image-workbench-prompt"
@@ -967,7 +981,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
) : activeTool === "camera" ? (
<main className="image-workbench-layout image-workbench-layout--camera">
<aside className="image-workbench-panel image-workbench-panel--left">
<section className="image-workbench-control-card">
<section className="image-workbench-control-card image-workbench-camera-material">
<div className="image-workbench-section-title">
<h3></h3>
<span>{cameraImage ? "已导入" : "待上传"}</span>
@@ -997,7 +1011,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
aria-label="删除镜头参考图"
onClick={handleRemoveCameraImage}
>
×
<DeleteOutlined />
</button>
) : null}
</div>
@@ -1248,7 +1262,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
aria-label={`删除参考图 ${index + 1}`}
onClick={() => handleRemoveReferenceImage(index)}
>
×
<DeleteOutlined />
</button>
</div>
))}
@@ -1282,7 +1296,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
aria-label="删除参考图"
onClick={() => handleRemoveReferenceImage(0)}
>
×
<DeleteOutlined />
</button>
) : null}
</div>
@@ -1300,7 +1314,7 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
</div>
</section>
<section className="image-workbench-control-card">
<section className="image-workbench-control-card image-workbench-output-card">
<h3></h3>
<span className="image-workbench-field-label"></span>
<div className="image-workbench-segmented">
@@ -1365,6 +1379,14 @@ function ImageWorkbenchPage({ initialTool = "workbench", onOpenMore, onSelectVie
<div className="image-workbench-result-grid">
{resultImages.map((url, i) => (
<div key={url} className="image-workbench-result-card">
<button
type="button"
className="image-workbench-result-remove"
aria-label={`移除生成结果 ${i + 1}`}
onClick={() => handleRemoveWorkbenchResult(i)}
>
<DeleteOutlined />
</button>
<a href={url} target="_blank" rel="noopener noreferrer" className="image-workbench-result-item">
<img src={url} alt={`生成结果 ${i + 1}`} />
</a>