From 0d2f58399c58ac00d47fc3be521e1d3ad15c6ff5 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Jul 2025 00:51:42 +0800 Subject: [PATCH] fix: react hook --- python_core/cli/commands/template.py | 17 ++- test_segment_rename.py | 219 +++++++++++++++++++++++++++ test_segment_rename_debug.md | 140 ----------------- 3 files changed, 232 insertions(+), 144 deletions(-) create mode 100644 test_segment_rename.py delete mode 100644 test_segment_rename_debug.md diff --git a/python_core/cli/commands/template.py b/python_core/cli/commands/template.py index d289171..a205bfa 100644 --- a/python_core/cli/commands/template.py +++ b/python_core/cli/commands/template.py @@ -272,9 +272,12 @@ def get_template_detail( # 确定片段类型和名称 segment_type = 'video' # 默认类型 - segment_name = f'片段 {len(track["segments"]) + 1}' + default_segment_name = f'片段 {len(track["segments"]) + 1}' resource_path = '' + # 优先使用片段自己的名称 + segment_name = segment_data.get('name', default_segment_name) + if material: # 从素材获取信息 material_type = material.get('material_type', material.get('type', 'video')) @@ -291,10 +294,15 @@ def get_template_detail( else: segment_type = material_type - # 获取素材名称和路径 - segment_name = material.get('material_name', material.get('name', segment_name)) + # 获取素材路径,但不覆盖片段名称 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 = { 'id': segment_data.get('id', f'segment_{len(track["segments"])}'), 'type': segment_type, @@ -504,7 +512,8 @@ def update_segment_name( for seg_idx, segment in enumerate(segments): 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') logger.info(f" Segment {seg_idx}: id={seg_id}, name={seg_name}") diff --git a/test_segment_rename.py b/test_segment_rename.py new file mode 100644 index 0000000..dbc3002 --- /dev/null +++ b/test_segment_rename.py @@ -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) diff --git a/test_segment_rename_debug.md b/test_segment_rename_debug.md deleted file mode 100644 index ed6ef0a..0000000 --- a/test_segment_rename_debug.md +++ /dev/null @@ -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 "新名称" --user-id --verbose - -# 测试获取模板详情 -python -m python_core.cli template detail --user-id --verbose -``` - -### 检查数据库状态 - -```sql --- 查看模板的 draft_content -SELECT id, name, draft_content FROM templates WHERE id = ''; - --- 检查片段名称 -SELECT - id, - name, - JSON_EXTRACT(draft_content, '$.tracks[*].segments[*].name') as segment_names -FROM templates -WHERE 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. 验证数据库中的数据是否正确更新 - -通过这些步骤可以准确定位问题所在。