From 09f214d9414ea9a4e4e32c9c91946ceb282accca Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 30 Jul 2026 14:05:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(#1195):=20CloneVoiceSection=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=AF=95=E5=90=AC=E6=92=AD=E6=94=BE=E6=8C=89=E9=92=AE?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=85=8B=E9=9A=86=E9=9F=B3=E8=89=B2?= =?UTF-8?q?=E8=AF=95=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/voice/CloneVoiceSection.tsx | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/apps/web/src/pages/generate/components/voice/CloneVoiceSection.tsx b/apps/web/src/pages/generate/components/voice/CloneVoiceSection.tsx index 37947529d..761bafce5 100644 --- a/apps/web/src/pages/generate/components/voice/CloneVoiceSection.tsx +++ b/apps/web/src/pages/generate/components/voice/CloneVoiceSection.tsx @@ -1,10 +1,18 @@ /** * 克隆声音展开区域 * 克隆按钮、轮询提示、已克隆列表、空状态 + * 支持克隆音色试听播放 + * TODO: 后端克隆音色试听接口出来后,替换 sample_url 为接口返回的试听音频 */ import React from "react" import { Typography } from "antd" -import { ThunderboltOutlined, AudioOutlined, CheckCircleFilled } from "@ant-design/icons" +import { + ThunderboltOutlined, + AudioOutlined, + CheckCircleFilled, + PlayCircleOutlined, + PauseCircleOutlined, +} from "@ant-design/icons" import type { VoiceClone } from "@/api/voice-clone" const { Text } = Typography @@ -15,6 +23,10 @@ interface CloneVoiceSectionProps { selectedClonedVoice: string onSelect: (voiceId: string) => void onOpenCloneModal: () => void + /** 当前正在播放的音色ID */ + playingVoiceId: string | null + /** 播放/暂停试听 */ + onPlaySample: (voiceId: VoiceClone) => void CLONE_STATUS_CONFIG: Record formatDuration: (seconds: number) => string } @@ -25,6 +37,8 @@ const CloneVoiceSection: React.FC = ({ selectedClonedVoice, onSelect, onOpenCloneModal, + playingVoiceId, + onPlaySample, CLONE_STATUS_CONFIG, formatDuration, }) => { @@ -60,6 +74,7 @@ const CloneVoiceSection: React.FC = ({ const statusCfg = CLONE_STATUS_CONFIG[cv.status] const isReady = cv.status === "ready" const selected = selectedClonedVoice === cv.id + const isPlaying = playingVoiceId === cv.id return (
= ({ )}
- {selected && isReady && ( + + {/* 试听播放按钮 */} + {isReady && ( + + )} + + {selected && isReady && !isPlaying && ( )}