mxivideo/docs/progress_system_usage.md

350 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🚀 通用进度系统使用指南
一个完全重构的通用进度监听系统,从特定的模板导入功能抽离出来,现在可以用于任何需要进度监控的操作。
## 🎯 系统架构
```
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推荐
```tsx
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
```tsx
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类
```tsx
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
```tsx
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端后端
```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端
```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
```tsx
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
```tsx
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组件示例
### 进度模态框
```tsx
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>
)
}
```
## 🔄 迁移指南
### 从旧的模板导入方式迁移
**旧方式**
```tsx
const [importing, setImporting] = useState(false)
const [progress, setProgress] = useState(null)
const [logs, setLogs] = useState([])
const handleImport = async () => {
setImporting(true)
// ... manual progress handling
}
```
**新方式**
```tsx
const { isExecuting, progress, logs, batchImport } = useTemplateProgress()
const handleImport = async () => {
await batchImport(folderPath)
}
```
## 🎯 最佳实践
1. **优先使用Hook**React Hook提供最佳的状态管理和生命周期处理
2. **合理的进度粒度**:不要过于频繁地报告进度,影响性能
3. **错误处理**:始终处理可能的错误情况
4. **用户反馈**:提供清晰的进度信息和状态反馈
5. **资源清理**:确保在组件卸载时清理监听器
这个通用进度系统现在可以轻松扩展到任何需要进度监控的操作!🚀