import React, { useState, useEffect, useRef } from 'react'; import { Button, Form, Spinner, Card, Container, Row, Col, Alert } from 'react-bootstrap'; import { toast } from 'react-toastify'; import { textToSpeech, speechToText, translateText, summarizeText, cozeService } from '../utils/cozeExample'; /** * Coze工作流演示组件 */ const CozeWorkflowDemo = () => { // 状态管理 const [loading, setLoading] = useState(false); const [audioUrl, setAudioUrl] = useState(null); const [inputText, setInputText] = useState(''); const [outputText, setOutputText] = useState(''); const [targetLanguage, setTargetLanguage] = useState('en'); const [audioFile, setAudioFile] = useState(null); const [errorMessage, setErrorMessage] = useState(''); const [workflowId, setWorkflowId] = useState(''); const [activeTab, setActiveTab] = useState('tts'); // tts, stt, translate, summarize const audioRef = useRef(null); useEffect(() => { // 在组件卸载时清理音频URL return () => { if (audioUrl) { URL.revokeObjectURL(audioUrl); } }; }, [audioUrl]); // 处理文本转语音 const handleTextToSpeech = async () => { if (!inputText.trim()) { setErrorMessage('请输入要转换的文本'); return; } setLoading(true); setErrorMessage(''); try { if (audioUrl) { URL.revokeObjectURL(audioUrl); setAudioUrl(null); } const response = await textToSpeech(inputText, { voice: 'female', // 可以是不同的声音选项 speed: 1.0 // 语速 }); // 处理流式响应 if (response && response.audio) { // 假设返回的是Base64格式的音频数据 const blob = base64ToBlob(response.audio, 'audio/mp3'); const url = URL.createObjectURL(blob); setAudioUrl(url); // 设置输出文本为成功消息 setOutputText('语音合成成功,可点击播放按钮收听'); } else { throw new Error('未接收到有效的音频数据'); } } catch (error) { console.error('文本转语音失败:', error); setErrorMessage(`文本转语音失败: ${error.message}`); toast.error(`文本转语音失败: ${error.message}`); } finally { setLoading(false); } }; // 处理语音转文本 const handleSpeechToText = async () => { if (!audioFile) { setErrorMessage('请先选择音频文件'); return; } setLoading(true); setErrorMessage(''); try { const response = await speechToText(audioFile); if (response && response.text) { setOutputText(response.text); } else { throw new Error('未接收到有效的识别结果'); } } catch (error) { console.error('语音识别失败:', error); setErrorMessage(`语音识别失败: ${error.message}`); toast.error(`语音识别失败: ${error.message}`); } finally { setLoading(false); } }; // 处理文本翻译 const handleTextTranslation = async () => { if (!inputText.trim()) { setErrorMessage('请输入要翻译的文本'); return; } setLoading(true); setErrorMessage(''); try { const response = await translateText(inputText, targetLanguage); if (response && response.translated_text) { setOutputText(response.translated_text); } else { throw new Error('未接收到有效的翻译结果'); } } catch (error) { console.error('文本翻译失败:', error); setErrorMessage(`文本翻译失败: ${error.message}`); toast.error(`文本翻译失败: ${error.message}`); } finally { setLoading(false); } }; // 处理文本摘要 const handleTextSummarization = async () => { if (!inputText.trim()) { setErrorMessage('请输入要摘要的文本'); return; } setLoading(true); setErrorMessage(''); try { const response = await summarizeText(inputText); if (response && response.summary) { setOutputText(response.summary); } else { throw new Error('未接收到有效的摘要结果'); } } catch (error) { console.error('文本摘要失败:', error); setErrorMessage(`文本摘要失败: ${error.message}`); toast.error(`文本摘要失败: ${error.message}`); } finally { setLoading(false); } }; // 直接调用工作流 const handleRunWorkflow = async () => { if (!workflowId.trim()) { setErrorMessage('请输入工作流ID'); return; } if (!inputText.trim()) { setErrorMessage('请输入参数'); return; } setLoading(true); setErrorMessage(''); try { // 解析JSON参数 let parameters = {}; try { parameters = JSON.parse(inputText); } catch (e) { // 如果不是有效的JSON,则作为text参数传递 parameters = { text: inputText }; } const response = await cozeService.runWorkflow(workflowId, parameters); // 在实际应用中,您可能需要根据工作流的不同输出格式进行不同的处理 setOutputText(JSON.stringify(response, null, 2)); } catch (error) { console.error('运行工作流失败:', error); setErrorMessage(`运行工作流失败: ${error.message}`); toast.error(`运行工作流失败: ${error.message}`); } finally { setLoading(false); } }; // 处理音频文件选择 const handleFileChange = (e) => { const file = e.target.files[0]; if (file) { setAudioFile(file); // 创建本地URL以便预览 if (audioUrl) { URL.revokeObjectURL(audioUrl); } const url = URL.createObjectURL(file); setAudioUrl(url); } }; // 辅助函数:将Base64字符串转换为Blob对象 const base64ToBlob = (base64, mimeType) => { const byteString = atob(base64); const ab = new ArrayBuffer(byteString.length); const ia = new Uint8Array(ab); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ab], { type: mimeType }); }; // 渲染不同的功能面板 const renderPanel = () => { switch (activeTab) { case 'tts': return ( <>