8.3 KiB
8.3 KiB
🚀 通用进度系统使用指南
一个完全重构的通用进度监听系统,从特定的模板导入功能抽离出来,现在可以用于任何需要进度监控的操作。
🎯 系统架构
Frontend (React)
├── useProgressCommand Hook # React Hook for progress management
├── ProgressListener Class # Generic progress listener utility
└── Service Classes # Specialized service classes
Backend (Rust)
├── execute_python_action_with_progress # Generic Python executor
├── PythonCommandBuilder # Command construction helper
└── Progress Callbacks # Flexible callback system
Python
└── JSON-RPC Protocol # Standardized progress reporting
📚 使用方式
1. 使用React Hook(推荐)
import { useTemplateProgress } from '../hooks/useProgressCommand'
function MyComponent() {
const {
isExecuting,
progress,
result,
error,
logs,
batchImport
} = useTemplateProgress({
onSuccess: (result) => {
console.log('Import completed:', result)
},
onError: (error) => {
console.error('Import failed:', error)
}
})
const handleImport = async () => {
try {
await batchImport('/path/to/templates')
} catch (error) {
// Error is already handled by the hook
}
}
return (
<div>
{isExecuting && (
<div>
<div>Progress: {progress?.progress}%</div>
<div>Message: {progress?.message}</div>
</div>
)}
<button onClick={handleImport} disabled={isExecuting}>
{isExecuting ? 'Importing...' : 'Import Templates'}
</button>
{/* Real-time logs */}
<div>
{logs.map((log, index) => (
<div key={index}>{log}</div>
))}
</div>
</div>
)
}
2. 使用通用Hook
import { useProgressCommand } from '../hooks/useProgressCommand'
function DataProcessingComponent() {
const { execute, isExecuting, progress, logs } = useProgressCommand()
const processData = async () => {
await execute(
'process_data_with_progress',
{
request: {
input_file: '/input.csv',
output_file: '/output.json',
processing_type: 'transform'
}
},
'data-processing-progress'
)
}
return (
<div>
<button onClick={processData} disabled={isExecuting}>
Process Data
</button>
{progress && (
<div>
<div>Step: {progress.step}</div>
<div>Progress: {progress.progress}%</div>
<div>Message: {progress.message}</div>
</div>
)}
</div>
)
}
3. 使用Service类
import { AIVideoProgressService, DataProcessingService } from '../services/tauri'
// AI Video Generation
const generateVideo = async () => {
const onProgress = (progress) => {
console.log(`${progress.step}: ${progress.message}`)
updateProgressBar(progress.progress)
}
try {
const result = await AIVideoProgressService.generateVideoWithProgress(
'/path/to/image.jpg',
'A beautiful sunset',
'/path/to/output.mp4',
onProgress
)
console.log('Video generated:', result)
} catch (error) {
console.error('Generation failed:', error)
}
}
// Data Processing
const processFiles = async () => {
const result = await DataProcessingService.batchConvertFilesWithProgress(
['/file1.txt', '/file2.txt'],
'pdf',
(progress) => console.log(progress.message)
)
}
4. 使用底层ProgressListener
import { ProgressListener } from '../services/tauri'
const customOperation = async () => {
const listener = new ProgressListener()
try {
const result = await listener.execute(
'my_custom_command',
{ param1: 'value1' },
'my-progress-event',
(progress) => {
// Custom progress handling
console.log(progress)
}
)
} finally {
listener.cleanup()
}
}
🔧 添加新的进度命令
1. Rust端(后端)
#[tauri::command]
pub async fn my_new_command_with_progress(
app: AppHandle,
my_param: String
) -> Result<String, String> {
let params = &[("--my_param", my_param.as_str())];
execute_python_action_with_progress(
app,
"python_core.my_module",
"my_action",
params,
"my-command-progress",
None,
).await
}
2. Python端
from python_core.utils.jsonrpc import create_response_handler, create_progress_reporter
def my_action():
rpc = create_response_handler("my_action")
progress = create_progress_reporter()
try:
progress.step("start", "开始处理...")
# ... processing ...
progress.report("process", 50.0, "处理中...", {"detail": "info"})
# ... more processing ...
progress.complete("处理完成!")
result = {"status": True, "data": "result"}
rpc.success(result)
except Exception as e:
progress.error(f"处理失败: {str(e)}")
rpc.error(-32603, "处理失败", str(e))
3. 前端Service
export class MyService {
static async myOperationWithProgress(
param: string,
onProgress?: (progress: any) => void
): Promise<any> {
return executeCommandWithProgress(
'my_new_command_with_progress',
{ myParam: param },
'my-command-progress',
onProgress
)
}
}
4. 专用Hook
export function useMyOperationProgress(options = {}) {
const hook = useProgressCommand(options)
const executeOperation = useCallback(async (param: string) => {
return hook.execute(
'my_new_command_with_progress',
{ myParam: param },
'my-command-progress'
)
}, [hook])
return {
...hook,
executeOperation,
}
}
🎨 UI组件示例
进度模态框
function ProgressModal({ isOpen, onClose, progress, logs, isExecuting }) {
return (
<Modal isOpen={isOpen} onClose={!isExecuting ? onClose : undefined}>
<div className="p-6">
<h2 className="text-xl font-bold mb-4">操作进度</h2>
{/* Progress Bar */}
{progress && (
<div className="mb-4">
<div className="flex justify-between mb-2">
<span>{progress.step}</span>
<span>{progress.progress >= 0 ? `${progress.progress}%` : '处理中...'}</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div
className="bg-blue-600 h-2 rounded-full transition-all"
style={{ width: `${Math.max(0, progress.progress)}%` }}
/>
</div>
<p className="text-sm text-gray-600 mt-2">{progress.message}</p>
</div>
)}
{/* Logs */}
<div className="bg-gray-50 rounded p-4 h-64 overflow-y-auto">
{logs.map((log, index) => (
<div key={index} className="text-xs text-gray-600 font-mono">
{log}
</div>
))}
</div>
{/* Actions */}
<div className="flex justify-end mt-4">
{!isExecuting && (
<button onClick={onClose} className="px-4 py-2 bg-gray-200 rounded">
关闭
</button>
)}
</div>
</div>
</Modal>
)
}
🔄 迁移指南
从旧的模板导入方式迁移
旧方式:
const [importing, setImporting] = useState(false)
const [progress, setProgress] = useState(null)
const [logs, setLogs] = useState([])
const handleImport = async () => {
setImporting(true)
// ... manual progress handling
}
新方式:
const { isExecuting, progress, logs, batchImport } = useTemplateProgress()
const handleImport = async () => {
await batchImport(folderPath)
}
🎯 最佳实践
- 优先使用Hook:React Hook提供最佳的状态管理和生命周期处理
- 合理的进度粒度:不要过于频繁地报告进度,影响性能
- 错误处理:始终处理可能的错误情况
- 用户反馈:提供清晰的进度信息和状态反馈
- 资源清理:确保在组件卸载时清理监听器
这个通用进度系统现在可以轻松扩展到任何需要进度监控的操作!🚀