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

252 lines
7.4 KiB
Markdown
Raw 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.

# 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 通知(可能是通信失败),父窗口会直接发送数据:
```typescript
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
打开浏览器控制台,输入:
```javascript
// 查看当前存储的 taskId
localStorage.getItem('taskId')
// 清空 taskId
localStorage.removeItem('taskId')
```
## 检查事件监听器
在子窗口控制台输入:
```javascript
// 查看当前窗口标签
await window.__TAURI__.window.getCurrent().label
// 手动发送就绪通知测试
await window.__TAURI__.event.emit('task-edit-ai-xxx-ready', { test: true })
```
## 修复建议
### 如果问题仍然存在
1. **增加延迟**:将超时时间从 2 秒增加到 3 秒
```typescript
}, 3000) // 从 2000 改为 3000
```
2. **直接发送(临时方案)**:在 `tauri://created` 事件中直接发送数据
```typescript
webview.once('tauri://created', async () => {
await new Promise((resolve) => setTimeout(resolve, 1000))
await sendInitData()
})
```
3. **使用全局事件总线**:不依赖窗口标签,使用固定的事件名
```typescript
// 使用固定的事件名 + taskId
const eventName = `init-task-edit-${taskData.taskId}`
```
## 测试清单
- [ ] 从列表打开编辑窗口taskId 正确显示
- [ ] 关闭窗口后重新打开taskId 正确显示
- [ ] 网络慢时打开,超时机制正常工作
- [ ] 快速连续打开多个编辑窗口,互不干扰
- [ ] 编辑窗口刷新后taskId 从 localStorage 恢复
- [ ] 关闭窗口后localStorage 正确清理
## 性能优化建议
1. **缓存窗口**:不要每次都创建新窗口,复用已有窗口
2. **预加载**:提前创建隐藏窗口,需要时直接显示
3. **批量操作**:如果需要打开多个窗口,使用队列机制
## 联系与反馈
如果问题仍未解决,请收集以下信息:
1. 完整的控制台日志(父窗口 + 子窗口)
2. localStorage 内容快照
3. 网络请求记录Network 面板)
4. Tauri 版本号
5. 操作系统版本