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, },