Files
pengcheng-exam-teacher/TASKID_FIX_DEBUG_GUIDE.md
2025-10-20 15:37:28 +08:00

7.4 KiB
Raw Blame History

TaskId 丢失问题 - 调试指南

问题症状

  • 打开编辑窗口后taskId 为空或 undefined
  • 控制台显示 "5秒内未收到数据显示空界面"
  • 编辑窗口的表单数据为空

最新修复方案2025-10-14

核心问题:窗口通信时序问题

  1. 问题:父窗口创建子窗口后才开始监听 ready 事件,导致错过子窗口的就绪通知
  2. 解决:父窗口在创建子窗口之前就开始监听 ready 事件

通信流程

父窗口                                子窗口
  |                                    |
  |-- 1. 开始监听 ready 事件           |
  |     (BEFORE creating window)       |
  |                                    |
  |-- 2. 创建窗口 ------------------>  |
  |                                    |
  |                                    |-- 3. 窗口创建 (tauri://created)
  |                                    |
  |                                    |-- 4. Vue 组件 mounted
  |                                    |
  |                                    |-- 5. 设置事件监听器
  |                                    |
  |                                    |-- 6. 发送 ready 通知
  |                                    |     emit('xxx-ready')
  |                                    |
  |<-- 7. 收到 ready 通知 -------------|
  |                                    |
  |-- 8. 发送初始化数据 ------------->  |
  |     emit('init-task-edit-xxx')     |
  |                                    |
  |                                    |<-- 9. 收到数据
  |                                    |
  |                                    |-- 10. 填充表单
  |                                    |
  |                                    |-- 11. 显示界面

备用超时机制

如果 2 秒内没收到 ready 通知(可能是通信失败),父窗口会直接发送数据:

setTimeout(async () => {
  if (!readySent) {
    console.log('⏰ 超时备用发送机制触发')
    readySent = true
    await sendInitData()
  }
}, 2000)

调试步骤

1. 打开浏览器控制台

在应用中打开开发者工具F12 或 Ctrl+Shift+I

2. 清空控制台

点击控制台左上角的清空按钮(🚫

3. 触发编辑操作

点击列表中某一行的"编辑"按钮

4. 观察日志输出

正常流程应该看到的日志:

父窗口AI Index

============ AI Index 创建编辑窗口 ============
创建的窗口标签 (windowLabel): task-edit-ai-1728912345678
将要发送的事件名 (eventName): init-task-edit-task-edit-ai-1728912345678
等待就绪事件名 (readyEventName): task-edit-ai-1728912345678-ready
传递的 taskData: {taskId: "123", taskName: "测试任务", ...}
taskData.taskId: 123
[task-edit-ai-1728912345678] 🎧 开始监听就绪事件: task-edit-ai-1728912345678-ready
[task-edit-ai-1728912345678] ✅ 窗口已创建
[task-edit-ai-1728912345678] 📢 收到子窗口就绪通知: {windowLabel: "task-edit-ai-1728912345678", ...}
[task-edit-ai-1728912345678] 📤 发送事件: init-task-edit-task-edit-ai-1728912345678
[task-edit-ai-1728912345678] 📦 payload.data.taskId: 123
[task-edit-ai-1728912345678] ✅ 事件发送成功!

子窗口Task Edit Window

============ AI Task Edit Window onMounted ============
当前窗口标签 (windowLabel): task-edit-ai-1728912345678
初始 form 数据: {taskId: "", ...}
将要监听的事件名: init-task-edit-task-edit-ai-1728912345678
[task-edit-ai-1728912345678] ai - ✅ 事件监听器已设置成功
[task-edit-ai-1728912345678] ai - 📢 已发送就绪通知: task-edit-ai-1728912345678-ready
[task-edit-ai-1728912345678] ai - ✅ 收到事件event.payload: {type: "edit", data: {...}}
[task-edit-ai-1728912345678] ai - 接收到的数据: {taskId: "123", ...}
[task-edit-ai-1728912345678] ai - data.taskId: 123
[task-edit-ai-1728912345678] ai - assignFields 调用后 form: {taskId: "123", ...}
[task-edit-ai-1728912345678] ai - 赋值后 form.taskId: 123
[task-edit-ai-1728912345678] ai - incomingId: 123
[task-edit-ai-1728912345678] ai - resolvedId: 123
[task-edit-ai-1728912345678] ai - 已保存到 localStorage, taskId: 123
[task-edit-ai-1728912345678] ai - nextTick 后 form.taskId: 123

5. 常见问题诊断

问题 A子窗口超时

[task-edit-ai-xxx] ai - ⚠️ 5秒内未收到数据显示空界面

可能原因:

  1. 窗口标签不匹配
  2. 事件名称拼写错误
  3. 父窗口发送数据失败

检查:

  • 确认父窗口和子窗口的 windowLabel 是否一致
  • 确认事件名称是否正确(init-task-edit-${windowLabel}

问题 B父窗口超时发送

[task-edit-ai-xxx] ⏰ 超时备用发送机制触发

可能原因:

  1. 子窗口 ready 事件发送失败
  2. 父窗口监听器设置失败
  3. 子窗口加载太慢

检查:

  • 查看子窗口是否发送了 ready 通知
  • 查看网络是否正常(子窗口资源加载)

问题 CtaskId 为空字符串

[task-edit-ai-xxx] ai - data.taskId: undefined
[task-edit-ai-xxx] ai - incomingId: undefined

可能原因:

  1. 父窗口传递的数据本身就没有 taskId
  2. 字段名不匹配(可能是 taskid 或 id

检查:

  • 查看父窗口日志中的 payload.data.taskId
  • 查看父窗口日志中的 taskData

问题 D重复发送数据

[task-edit-ai-xxx] ⚠️ 已经发送过数据,忽略重复通知

原因:

  • 正常现象,防止重复发送的保护机制生效

检查 localStorage

打开浏览器控制台,输入:

// 查看当前存储的 taskId
localStorage.getItem('taskId')

// 清空 taskId
localStorage.removeItem('taskId')

检查事件监听器

在子窗口控制台输入:

// 查看当前窗口标签
await window.__TAURI__.window.getCurrent().label

// 手动发送就绪通知测试
await window.__TAURI__.event.emit('task-edit-ai-xxx-ready', { test: true })

修复建议

如果问题仍然存在

  1. 增加延迟:将超时时间从 2 秒增加到 3 秒

    }, 3000) // 从 2000 改为 3000
    
  2. 直接发送(临时方案):在 tauri://created 事件中直接发送数据

    webview.once('tauri://created', async () => {
      await new Promise((resolve) => setTimeout(resolve, 1000))
      await sendInitData()
    })
    
  3. 使用全局事件总线:不依赖窗口标签,使用固定的事件名

    // 使用固定的事件名 + taskId
    const eventName = `init-task-edit-${taskData.taskId}`
    

测试清单

  • 从列表打开编辑窗口taskId 正确显示
  • 关闭窗口后重新打开taskId 正确显示
  • 网络慢时打开,超时机制正常工作
  • 快速连续打开多个编辑窗口,互不干扰
  • 编辑窗口刷新后taskId 从 localStorage 恢复
  • 关闭窗口后localStorage 正确清理

性能优化建议

  1. 缓存窗口:不要每次都创建新窗口,复用已有窗口
  2. 预加载:提前创建隐藏窗口,需要时直接显示
  3. 批量操作:如果需要打开多个窗口,使用队列机制

联系与反馈

如果问题仍未解决,请收集以下信息:

  1. 完整的控制台日志(父窗口 + 子窗口)
  2. localStorage 内容快照
  3. 网络请求记录Network 面板)
  4. Tauri 版本号
  5. 操作系统版本