fix: react hook
This commit is contained in:
@@ -272,9 +272,12 @@ def get_template_detail(
|
|||||||
|
|
||||||
# 确定片段类型和名称
|
# 确定片段类型和名称
|
||||||
segment_type = 'video' # 默认类型
|
segment_type = 'video' # 默认类型
|
||||||
segment_name = f'片段 {len(track["segments"]) + 1}'
|
default_segment_name = f'片段 {len(track["segments"]) + 1}'
|
||||||
resource_path = ''
|
resource_path = ''
|
||||||
|
|
||||||
|
# 优先使用片段自己的名称
|
||||||
|
segment_name = segment_data.get('name', default_segment_name)
|
||||||
|
|
||||||
if material:
|
if material:
|
||||||
# 从素材获取信息
|
# 从素材获取信息
|
||||||
material_type = material.get('material_type', material.get('type', 'video'))
|
material_type = material.get('material_type', material.get('type', 'video'))
|
||||||
@@ -291,10 +294,15 @@ def get_template_detail(
|
|||||||
else:
|
else:
|
||||||
segment_type = material_type
|
segment_type = material_type
|
||||||
|
|
||||||
# 获取素材名称和路径
|
# 获取素材路径,但不覆盖片段名称
|
||||||
segment_name = material.get('material_name', material.get('name', segment_name))
|
|
||||||
resource_path = material.get('path', '')
|
resource_path = material.get('path', '')
|
||||||
|
|
||||||
|
# 只有当片段没有自定义名称时,才使用素材名称
|
||||||
|
if segment_name == default_segment_name:
|
||||||
|
material_name = material.get('material_name', material.get('name'))
|
||||||
|
if material_name:
|
||||||
|
segment_name = material_name
|
||||||
|
|
||||||
segment = {
|
segment = {
|
||||||
'id': segment_data.get('id', f'segment_{len(track["segments"])}'),
|
'id': segment_data.get('id', f'segment_{len(track["segments"])}'),
|
||||||
'type': segment_type,
|
'type': segment_type,
|
||||||
@@ -504,7 +512,8 @@ def update_segment_name(
|
|||||||
|
|
||||||
for seg_idx, segment in enumerate(segments):
|
for seg_idx, segment in enumerate(segments):
|
||||||
if isinstance(segment, dict):
|
if isinstance(segment, dict):
|
||||||
seg_id = segment.get('id')
|
# 使用与 get_template_detail 相同的 ID 生成逻辑
|
||||||
|
seg_id = segment.get('id', f'segment_{seg_idx}')
|
||||||
seg_name = segment.get('name', 'Unknown')
|
seg_name = segment.get('name', 'Unknown')
|
||||||
logger.info(f" Segment {seg_idx}: id={seg_id}, name={seg_name}")
|
logger.info(f" Segment {seg_idx}: id={seg_id}, name={seg_name}")
|
||||||
|
|
||||||
|
|||||||
219
test_segment_rename.py
Normal file
219
test_segment_rename.py
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
测试片段重命名功能
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def parse_jsonrpc_response(stdout):
|
||||||
|
"""解析 JSONRPC 格式的响应"""
|
||||||
|
stdout = stdout.strip()
|
||||||
|
if stdout.startswith("JSONRPC:"):
|
||||||
|
stdout = stdout[8:] # 移除 "JSONRPC:" 前缀
|
||||||
|
|
||||||
|
response = json.loads(stdout)
|
||||||
|
|
||||||
|
# JSONRPC 格式检查
|
||||||
|
if "result" in response:
|
||||||
|
return True, response["result"]
|
||||||
|
elif "error" in response:
|
||||||
|
return False, response["error"]
|
||||||
|
else:
|
||||||
|
return False, response
|
||||||
|
|
||||||
|
def run_cli_command(args):
|
||||||
|
"""运行CLI命令并返回结果"""
|
||||||
|
try:
|
||||||
|
cmd = ["python3", "-m", "python_core.cli"] + args
|
||||||
|
print(f"Running: {' '.join(cmd)}")
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
cmd,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
cwd=Path(__file__).parent
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Return code: {result.returncode}")
|
||||||
|
print(f"STDOUT: {result.stdout}")
|
||||||
|
if result.stderr:
|
||||||
|
print(f"STDERR: {result.stderr}")
|
||||||
|
|
||||||
|
return result
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error running command: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def test_segment_rename():
|
||||||
|
"""测试片段重命名功能"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("测试片段重命名功能")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 1. 首先获取模板列表
|
||||||
|
print("\n1. 获取模板列表...")
|
||||||
|
result = run_cli_command(["template", "list", "--limit", "5", "--json"])
|
||||||
|
|
||||||
|
if not result or result.returncode != 0:
|
||||||
|
print("❌ 获取模板列表失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
success, data = parse_jsonrpc_response(result.stdout)
|
||||||
|
if not success:
|
||||||
|
print(f"❌ 模板列表API返回失败: {data}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
templates = data.get("templates", [])
|
||||||
|
if not templates:
|
||||||
|
print("❌ 没有找到模板")
|
||||||
|
return False
|
||||||
|
|
||||||
|
template = templates[0]
|
||||||
|
template_id = template["id"]
|
||||||
|
print(f"✅ 找到模板: {template['name']} (ID: {template_id})")
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"❌ 解析模板列表响应失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 2. 获取模板详情
|
||||||
|
print(f"\n2. 获取模板详情...")
|
||||||
|
result = run_cli_command(["template", "detail", template_id, "--json"])
|
||||||
|
|
||||||
|
if not result or result.returncode != 0:
|
||||||
|
print("❌ 获取模板详情失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
success, detail = parse_jsonrpc_response(result.stdout)
|
||||||
|
if not success:
|
||||||
|
print(f"❌ 模板详情API返回失败: {detail}")
|
||||||
|
return False
|
||||||
|
tracks = detail.get("tracks", [])
|
||||||
|
|
||||||
|
if not tracks:
|
||||||
|
print("❌ 模板没有轨道")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 找到第一个有片段的轨道
|
||||||
|
segment = None
|
||||||
|
segment_track = None
|
||||||
|
for track in tracks:
|
||||||
|
segments = track.get("segments", [])
|
||||||
|
if segments:
|
||||||
|
segment = segments[0]
|
||||||
|
segment_track = track
|
||||||
|
break
|
||||||
|
|
||||||
|
if not segment:
|
||||||
|
print("❌ 模板没有片段")
|
||||||
|
return False
|
||||||
|
|
||||||
|
segment_id = segment["id"]
|
||||||
|
original_name = segment["name"]
|
||||||
|
print(f"✅ 找到片段: {original_name} (ID: {segment_id})")
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"❌ 解析模板详情响应失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 3. 更新片段名称
|
||||||
|
new_name = f"测试重命名_{original_name}"
|
||||||
|
print(f"\n3. 更新片段名称: '{original_name}' -> '{new_name}'")
|
||||||
|
|
||||||
|
result = run_cli_command([
|
||||||
|
"template", "update-segment",
|
||||||
|
template_id, segment_id, new_name,
|
||||||
|
"--json", "--verbose"
|
||||||
|
])
|
||||||
|
|
||||||
|
if not result or result.returncode != 0:
|
||||||
|
print("❌ 更新片段名称失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
success, update_data = parse_jsonrpc_response(result.stdout)
|
||||||
|
if not success:
|
||||||
|
print(f"❌ 更新片段名称API返回失败: {update_data}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"✅ 更新成功: {update_data}")
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"❌ 解析更新响应失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 4. 验证更新结果
|
||||||
|
print(f"\n4. 验证更新结果...")
|
||||||
|
result = run_cli_command(["template", "detail", template_id, "--json"])
|
||||||
|
|
||||||
|
if not result or result.returncode != 0:
|
||||||
|
print("❌ 重新获取模板详情失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
success, detail = parse_jsonrpc_response(result.stdout)
|
||||||
|
if not success:
|
||||||
|
print(f"❌ 重新获取模板详情API返回失败: {detail}")
|
||||||
|
return False
|
||||||
|
tracks = detail.get("tracks", [])
|
||||||
|
|
||||||
|
# 查找更新后的片段
|
||||||
|
updated_segment = None
|
||||||
|
for track in tracks:
|
||||||
|
for seg in track.get("segments", []):
|
||||||
|
if seg["id"] == segment_id:
|
||||||
|
updated_segment = seg
|
||||||
|
break
|
||||||
|
if updated_segment:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not updated_segment:
|
||||||
|
print("❌ 找不到更新后的片段")
|
||||||
|
return False
|
||||||
|
|
||||||
|
updated_name = updated_segment["name"]
|
||||||
|
print(f"✅ 片段名称已更新: '{updated_name}'")
|
||||||
|
|
||||||
|
if updated_name == new_name:
|
||||||
|
print("✅ 验证成功:片段名称更新正确")
|
||||||
|
else:
|
||||||
|
print(f"❌ 验证失败:期望 '{new_name}',实际 '{updated_name}'")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"❌ 解析验证响应失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 5. 恢复原始名称
|
||||||
|
print(f"\n5. 恢复原始名称...")
|
||||||
|
result = run_cli_command([
|
||||||
|
"template", "update-segment",
|
||||||
|
template_id, segment_id, original_name,
|
||||||
|
"--json"
|
||||||
|
])
|
||||||
|
|
||||||
|
if result and result.returncode == 0:
|
||||||
|
try:
|
||||||
|
success, data = parse_jsonrpc_response(result.stdout)
|
||||||
|
if success:
|
||||||
|
print("✅ 已恢复原始名称")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ 恢复原始名称失败: {data}")
|
||||||
|
except:
|
||||||
|
print("⚠️ 恢复原始名称响应解析失败")
|
||||||
|
else:
|
||||||
|
print("⚠️ 恢复原始名称命令失败")
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("✅ 片段重命名功能测试完成")
|
||||||
|
print("=" * 60)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = test_segment_rename()
|
||||||
|
sys.exit(0 if success else 1)
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
# 片段重命名调试指南
|
|
||||||
|
|
||||||
## 问题诊断步骤
|
|
||||||
|
|
||||||
### 1. 检查前端调用
|
|
||||||
|
|
||||||
在浏览器开发者工具的控制台中查看以下日志:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 当用户重命名片段时,应该看到:
|
|
||||||
"Segment {segmentId} renamed to: {newName} - saved to database"
|
|
||||||
"Template detail reloaded from database"
|
|
||||||
|
|
||||||
// 以及模板详情加载日志:
|
|
||||||
"Template detail loaded: {templateId: ..., tracksCount: ..., segments: [...]}"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 检查后端日志
|
|
||||||
|
|
||||||
在后端日志中查看以下信息:
|
|
||||||
|
|
||||||
```
|
|
||||||
INFO - Searching for segment {segment_id} in {track_count} tracks
|
|
||||||
INFO - Track {track_idx} has {segment_count} segments
|
|
||||||
INFO - Segment {seg_idx}: id={seg_id}, name={seg_name}
|
|
||||||
INFO - Updated segment {segment_id}: '{old_name}' -> '{new_name}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 验证数据库更新
|
|
||||||
|
|
||||||
可以通过以下方式验证:
|
|
||||||
|
|
||||||
1. **前端验证**:
|
|
||||||
- 重命名片段后,刷新页面
|
|
||||||
- 检查片段名称是否保持新名称
|
|
||||||
|
|
||||||
2. **后端验证**:
|
|
||||||
- 查看数据库中的 `draft_content` 字段
|
|
||||||
- 确认片段名称已更新
|
|
||||||
|
|
||||||
### 4. 常见问题排查
|
|
||||||
|
|
||||||
#### 问题1:片段ID不匹配
|
|
||||||
- **症状**:后端日志显示"片段不存在"
|
|
||||||
- **原因**:前端传递的 segmentId 与数据库中的不匹配
|
|
||||||
- **解决**:检查片段ID的生成和传递逻辑
|
|
||||||
|
|
||||||
#### 问题2:权限问题
|
|
||||||
- **症状**:后端返回"无权限修改模板"
|
|
||||||
- **原因**:用户ID不匹配或权限验证失败
|
|
||||||
- **解决**:检查用户认证状态
|
|
||||||
|
|
||||||
#### 问题3:数据库连接问题
|
|
||||||
- **症状**:更新操作失败
|
|
||||||
- **原因**:数据库连接或事务问题
|
|
||||||
- **解决**:检查数据库连接和事务处理
|
|
||||||
|
|
||||||
#### 问题4:前端状态不同步
|
|
||||||
- **症状**:本地显示更新但刷新后恢复
|
|
||||||
- **原因**:后端更新失败但前端没有回滚
|
|
||||||
- **解决**:检查错误处理和状态回滚逻辑
|
|
||||||
|
|
||||||
## 调试命令
|
|
||||||
|
|
||||||
### 手动测试后端API
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 测试更新片段名称
|
|
||||||
python -m python_core.cli template update-segment <template_id> <segment_id> "新名称" --user-id <user_id> --verbose
|
|
||||||
|
|
||||||
# 测试获取模板详情
|
|
||||||
python -m python_core.cli template detail <template_id> --user-id <user_id> --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
### 检查数据库状态
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- 查看模板的 draft_content
|
|
||||||
SELECT id, name, draft_content FROM templates WHERE id = '<template_id>';
|
|
||||||
|
|
||||||
-- 检查片段名称
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
JSON_EXTRACT(draft_content, '$.tracks[*].segments[*].name') as segment_names
|
|
||||||
FROM templates
|
|
||||||
WHERE id = '<template_id>';
|
|
||||||
```
|
|
||||||
|
|
||||||
## 预期行为
|
|
||||||
|
|
||||||
### 正常流程
|
|
||||||
|
|
||||||
1. **用户操作**:双击片段 → 选择分类 → 确认
|
|
||||||
2. **前端处理**:
|
|
||||||
- 立即更新本地状态(UI响应)
|
|
||||||
- 调用后端API保存
|
|
||||||
- 重新加载模板详情
|
|
||||||
3. **后端处理**:
|
|
||||||
- 验证权限和数据
|
|
||||||
- 更新数据库中的 draft_content
|
|
||||||
- 返回成功状态
|
|
||||||
4. **结果验证**:
|
|
||||||
- 页面刷新后名称保持
|
|
||||||
- 控制台显示成功日志
|
|
||||||
|
|
||||||
### 错误处理
|
|
||||||
|
|
||||||
1. **网络错误**:显示错误提示,回滚本地状态
|
|
||||||
2. **权限错误**:显示权限提示
|
|
||||||
3. **数据错误**:显示数据错误提示,回滚状态
|
|
||||||
|
|
||||||
## 修复历史
|
|
||||||
|
|
||||||
### 已修复的问题
|
|
||||||
|
|
||||||
1. ✅ **后端API缺失**:添加了 `update-segment` CLI命令
|
|
||||||
2. ✅ **前端调用缺失**:添加了 `updateSegmentName` 方法
|
|
||||||
3. ✅ **状态同步问题**:添加了重新加载逻辑
|
|
||||||
4. ✅ **错误处理**:添加了完善的错误处理和回滚
|
|
||||||
|
|
||||||
### 当前状态
|
|
||||||
|
|
||||||
- ✅ Python CLI命令:`template update-segment`
|
|
||||||
- ✅ Rust Tauri命令:`update_template_segment_cli`
|
|
||||||
- ✅ TypeScript服务方法:`updateSegmentName`
|
|
||||||
- ✅ 前端处理逻辑:`handleSegmentNameChange`
|
|
||||||
- ✅ 错误处理和状态回滚
|
|
||||||
- ✅ 调试日志和验证
|
|
||||||
|
|
||||||
## 下一步
|
|
||||||
|
|
||||||
如果问题仍然存在,请:
|
|
||||||
|
|
||||||
1. 检查浏览器控制台的日志输出
|
|
||||||
2. 检查后端服务的日志
|
|
||||||
3. 手动测试后端CLI命令
|
|
||||||
4. 验证数据库中的数据是否正确更新
|
|
||||||
|
|
||||||
通过这些步骤可以准确定位问题所在。
|
|
||||||
Reference in New Issue
Block a user