修改全能创作发现问题

This commit is contained in:
Azmat@qq.com
2026-09-03 19:00:59 +08:00
parent e7122b78fb
commit 3e904479d9
23 changed files with 1325 additions and 433 deletions
@@ -0,0 +1,158 @@
import { useEffect, useRef, useState } from "react";
import { ChevronDown, SlidersHorizontal, Sparkles } from "lucide-react";
import { CustomSelect } from "./custom-select";
export const OMNI_VIDEO_MODELS = ["Seedance 2.5", "Seedance 2.0", "Seedance 2.0 Fast", "Seedance 2.0 Mini"];
export const OMNI_IMAGE_MODELS = ["Seedream5.0", "YQ image2"];
export const OMNI_RESOLUTIONS = ["1080p", "720p", "480p"];
export const OMNI_RATIOS = ["9:16", "16:9", "1:1", "4:3", "3:4"];
export const OMNI_VIDEO_DURATIONS = [
"4 秒", "5 秒", "6 秒", "7 秒", "8 秒", "9 秒", "10 秒",
"11 秒", "12 秒", "13 秒", "14 秒", "15 秒", "30 秒",
];
export const OMNI_IMAGE_COUNTS = ["1 张", "2 张", "4 张", "8 张"];
function toOptions(values: string[]) {
return values.map((value) => ({ value, label: value }));
}
function withCurrent(values: string[], current: string) {
return current && !values.includes(current) ? [current, ...values] : values;
}
export function OmniParamBar({
isVideo,
disabled,
model,
resolution,
ratio,
duration,
onModel,
onResolution,
onRatio,
onDuration,
}: {
isVideo: boolean;
disabled?: boolean;
model: string;
resolution: string;
ratio: string;
duration: string;
onModel: (value: string) => void;
onResolution: (value: string) => void;
onRatio: (value: string) => void;
onDuration: (value: string) => void;
}) {
const [menuOpen, setMenuOpen] = useState(false);
const [customOn, setCustomOn] = useState(isVideo ? duration !== "智能时长" : true);
const wrapRef = useRef<HTMLDivElement>(null);
useEffect(() => {
setCustomOn(isVideo ? duration !== "智能时长" : true);
}, [isVideo, duration]);
useEffect(() => {
if (!menuOpen) return;
const onDown = (event: MouseEvent) => {
if (!wrapRef.current?.contains(event.target as Node)) setMenuOpen(false);
};
document.addEventListener("mousedown", onDown);
return () => document.removeEventListener("mousedown", onDown);
}, [menuOpen]);
const models = withCurrent(isVideo ? OMNI_VIDEO_MODELS : OMNI_IMAGE_MODELS, model);
const durations = isVideo ? OMNI_VIDEO_DURATIONS : OMNI_IMAGE_COUNTS;
return (
<>
<label className="omni-parameter omni-parameter-model">
<CustomSelect
fill
size="sm"
aria-label={isVideo ? "视频模型" : "图片模型"}
disabled={disabled}
value={model}
onChange={onModel}
options={toOptions(models)}
/>
</label>
<label className={`omni-parameter${isVideo ? "" : " is-hidden"}`}>
<CustomSelect
fill
size="sm"
aria-label="分辨率"
disabled={disabled}
value={resolution}
onChange={onResolution}
options={toOptions(withCurrent(OMNI_RESOLUTIONS, resolution))}
/>
</label>
<label className="omni-parameter">
<CustomSelect
fill
size="sm"
aria-label="画面比例"
disabled={disabled}
value={ratio}
onChange={onRatio}
options={toOptions(withCurrent(OMNI_RATIOS, ratio))}
/>
</label>
<div className={`omni-duration-control${isVideo ? "" : " is-image-count"}`} ref={wrapRef}>
<button
type="button"
className="omni-duration-trigger"
aria-expanded={menuOpen}
disabled={disabled}
onClick={() => setMenuOpen((open) => !open)}
>
<span>{duration}</span>
<ChevronDown />
</button>
<div className="omni-duration-menu" hidden={!menuOpen}>
<span className="omni-duration-title">{isVideo ? "时长" : "生成张数"}</span>
{isVideo ? (
<div className="omni-duration-modes">
<button
type="button"
className={!customOn ? "active" : ""}
onClick={() => {
setCustomOn(false);
onDuration("智能时长");
setMenuOpen(false);
}}
>
<Sparkles />
<span>智能时长</span>
</button>
<button
type="button"
className={customOn ? "active" : ""}
onClick={() => setCustomOn(true)}
>
<SlidersHorizontal />
<span>自定义时长</span>
</button>
</div>
) : null}
<div className="omni-duration-values" hidden={isVideo && !customOn}>
{durations.map((value) => (
<button
type="button"
key={value}
className={duration === value ? "active" : ""}
onClick={() => {
onDuration(value);
setCustomOn(true);
setMenuOpen(false);
}}
>
{value}
</button>
))}
</div>
</div>
</div>
</>
);
}