fix: add template track
This commit is contained in:
349
docs/progress_system_usage.md
Normal file
349
docs/progress_system_usage.md
Normal file
@@ -0,0 +1,349 @@
|
||||
# 🚀 通用进度系统使用指南
|
||||
|
||||
一个完全重构的通用进度监听系统,从特定的模板导入功能抽离出来,现在可以用于任何需要进度监控的操作。
|
||||
|
||||
## 🎯 系统架构
|
||||
|
||||
```
|
||||
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. **资源清理**:确保在组件卸载时清理监听器
|
||||
|
||||
这个通用进度系统现在可以轻松扩展到任何需要进度监控的操作!🚀
|
||||
Reference in New Issue
Block a user