diff --git a/src/assets/images/subscribe_banner3.png b/src/assets/images/subscribe_banner3.png
index ba317ba..0382423 100644
Binary files a/src/assets/images/subscribe_banner3.png and b/src/assets/images/subscribe_banner3.png differ
diff --git a/src/layouts/Layout/Layout.tsx b/src/layouts/Layout/Layout.tsx
index 53e760d..5495da1 100644
--- a/src/layouts/Layout/Layout.tsx
+++ b/src/layouts/Layout/Layout.tsx
@@ -666,7 +666,7 @@ export function Layout({ children }: LayoutProps) {
diff --git a/src/layouts/globalPromptPanel/globalPromptPanel.tsx b/src/layouts/globalPromptPanel/globalPromptPanel.tsx
index 04892d4..d9fc7ed 100644
--- a/src/layouts/globalPromptPanel/globalPromptPanel.tsx
+++ b/src/layouts/globalPromptPanel/globalPromptPanel.tsx
@@ -46,6 +46,8 @@ import { useHorizontalWheelScroll } from "./useHorizontalWheelScroll";
import {
OTHER_CATEGORY,
buildPreferredParamValues,
+ buildComposerTaskParamPayload,
+ buildSeedanceVideoPricePayload,
buildSelectedParamsFromTaskInfo,
buildGenTaskModelPayload,
collectTaskInfoMedia,
@@ -135,12 +137,11 @@ function useGenerateCost(params: {
activeModelItem: AiModelItem | null;
selectedParamValues: Record;
activeTaskSubType: number | null;
- ratioSizePreview: AspectRatioItem | null;
inputVideoDurationSeconds: number;
isActionMimicTask: boolean;
selectedActionMimicItem: ActionMimicSelectedItem | null;
}) {
- const { activeModelItem, selectedParamValues, activeTaskSubType, ratioSizePreview, inputVideoDurationSeconds, isActionMimicTask, selectedActionMimicItem } = params;
+ const { activeModelItem, selectedParamValues, activeTaskSubType, inputVideoDurationSeconds, isActionMimicTask, selectedActionMimicItem } = params;
const [generateCost, setGenerateCost] = useState(0);
const debounceTimerRef = useRef(null);
const requestSeqRef = useRef(0);
@@ -161,22 +162,27 @@ function useGenerateCost(params: {
return;
}
+ const modelParamFields = getComposerParamFieldsForModel(activeModelItem);
+ const resolvedParamValues = buildComposerTaskParamPayload(modelParamFields, selectedParamValues);
+
// token计费 从服务端拿积分
if (activeModelItem?.billingMethod === 2) {
- if (!Object.keys(selectedParamValues).length) return;
+ const seedanceParams = buildSeedanceVideoPricePayload(modelParamFields, selectedParamValues);
+ if (!seedanceParams) {
+ if (!cancelled) setGenerateCost(0);
+ return;
+ }
const currentSeq = ++requestSeqRef.current;
const res: any = await getAiModelPrice({
modelName: activeModelItem?.aiModelCodeAlias,
estimationType: "seedance_video",
seedanceVideo: {
input_video_duration_seconds: inputVideoDurationSeconds,
- output_video_duration_seconds: selectedParamValues.duration,
- resolution: selectedParamValues.resolution,
- aspect_ratio: selectedParamValues.ratio,
+ ...seedanceParams,
},
});
const points = res?.data?.estimated_points ?? 0;
- const batchSize = Number(selectedParamValues.batchSize ?? 1);
+ const batchSize = Number(resolvedParamValues.batchSize ?? 1);
if (!cancelled && currentSeq === requestSeqRef.current) {
setGenerateCost(Math.ceil(points * batchSize));
}
@@ -198,8 +204,7 @@ function useGenerateCost(params: {
aiModelCode: activeModelItem?.code,
aiModelCodeAlias: activeModelItem?.aiModelCodeAlias,
type: getTaskSubTypeRow(activeTaskSubType)?.type,
- ...selectedParamValues,
- ...dimensionPayloadFromPreview(selectedParamValues.resolution, ratioSizePreview),
+ ...resolvedParamValues,
});
const taskPrice = Number(res?.data?.taskPrice ?? 0);
if (!cancelled && currentSeq === requestSeqRef.current) {
@@ -224,7 +229,7 @@ function useGenerateCost(params: {
debounceTimerRef.current = null;
}
};
- }, [activeModelItem, activeTaskSubType, inputVideoDurationSeconds, isActionMimicTask, ratioSizePreview, selectedActionMimicItem, selectedParamValues]);
+ }, [activeModelItem, activeTaskSubType, inputVideoDurationSeconds, isActionMimicTask, selectedActionMimicItem, selectedParamValues]);
return generateCost;
}
@@ -865,8 +870,9 @@ export function GlobalPromptPanel({
const applyAiModelsList = useCallback((list: AiModelItem[]) => {
setAiModels(list);
- setActiveModelItem(list[0] ?? null);
- setSelectedParamValues({});
+ const firstModel = list[0] ?? null;
+ setActiveModelItem(firstModel);
+ setSelectedParamValues(buildPreferredParamValues(getComposerParamFieldsForModel(firstModel), {}));
}, []);
/** 拉模型并写状态;制作同款可选择只取列表不落地,避免中间态覆盖。 */
@@ -1241,7 +1247,6 @@ export function GlobalPromptPanel({
activeModelItem,
selectedParamValues,
activeTaskSubType,
- ratioSizePreview,
inputVideoDurationSeconds,
isActionMimicTask,
selectedActionMimicItem,
@@ -1754,7 +1759,9 @@ export function GlobalPromptPanel({
onClick={() => {
setActiveModelItem(item);
setModelMenuOpen(false);
- setSelectedParamValues({});
+ setSelectedParamValues(
+ buildPreferredParamValues(getComposerParamFieldsForModel(item), {}),
+ );
}}
>
,
+): {
+ output_video_duration_seconds: string | number;
+ resolution: string | number;
+ aspect_ratio: string;
+} | null {
+ const params = buildPreferredParamValues(fields, selected);
+ const durationField = fields.find((field) => {
+ const key = field.key.trim().toLowerCase();
+ return key === "duration" || key === "output_video_duration_seconds";
+ });
+ const resolutionField = fields.find(
+ (field) =>
+ field.key.toLowerCase().includes("resolution") ||
+ (field.name ?? "").toLowerCase().includes("resolution"),
+ );
+ const ratioField = fields.find((field) => isRatioField(field.key, field.name));
+
+ const duration = durationField != null ? params[durationField.key] : params.duration;
+ const resolution = resolutionField != null ? params[resolutionField.key] : params.resolution;
+ const aspectRatio = ratioField != null ? params[ratioField.key] : params.ratio;
+
+ if (
+ duration == null ||
+ duration === "" ||
+ resolution == null ||
+ resolution === "" ||
+ aspectRatio == null ||
+ aspectRatio === ""
+ ) {
+ return null;
+ }
+
+ return {
+ output_video_duration_seconds: duration,
+ resolution,
+ aspect_ratio: String(aspectRatio),
+ };
+}
+
/**
* 生成任务请求体中的模型参数:补齐默认值、推导 width/height,并保证写入接口约定的 `ratio` 字段。
*/
diff --git a/vite.config.mts b/vite.config.mts
index 6fa40ac..02683f0 100644
--- a/vite.config.mts
+++ b/vite.config.mts
@@ -39,9 +39,9 @@ export default defineConfig(({ mode }) => {
proxy: isDev
? {
"/api_client": {
- // target: "http://192.168.77.111:8080/",
+ target: "http://192.168.77.111:8080/",
// target: "https://wwwtest.popi.art/",
- target: "https://www.popi.art/",
+ // target: "https://www.popi.art/",
secure: false,
changeOrigin: true,
},