laoyang
aac7dd5974
修截止时间时/分保存不上:保存前替用户点 antd 的「确定」(#77)
用户给的方法很对:「看一下数据库里有没有记时和分。如果没有记,
就说明是修改它的时候出了问题。」查库结果:
tasks #15 [台式机采购]
due_at = 2026-11-07 00:00:00
updated = 2026-11-05 18:04:05 ← 正是用户操作的时间点
⇒ 时分在**写入时**就丢了,不是显示问题。
用 Playwright + 站点真实 antd 5 逐帧实测,找到决定性证据:
选完日期/时间(不点弹层里的「确定」):
vis="2026-11-16 20:34" onChange 次数 = 0
点面板的「保存」(这一下同时把弹层关掉):
50ms 后 readDue = "2026-11-07 00:00:00" ← **弹回原值!**
onChange 次数仍然是 0
根因:antd 的 DatePicker(showTime) **只有点它内部的「确定」才提交**。
点别处(包括点我们的保存按钮)会被当成取消,值弹回上一次确认的值。
「台式机采购」原本就是 2026-11-07 00:00:00,用户改完时间直接点保存,
antd 把修改丢了,于是存进去的还是原来的 00:00:00。
修法(三步,缺一不可):
① app.js 的 writeBack():把 onChange 拿到的字符串写到
box[data-fb-dt-value]。这是"控件刚确认的值",不经镜像、不受弹层影响。
② task_panel.js 新增 commitAntd():保存前主动点掉弹层「确定」。
只在弹层真开着时点(:not(.ant-picker-dropdown-hidden))。
③ 读值改为**异步**:commitAntd() 之后等 60ms 再 readDue()。
antd 的 onChange → setState → 重渲染落在微任务/下一帧,
同步读拿到的是提交前那一帧(实测差几分钟,或干脆是旧值)。
readDue 的优先级也理顺了:
① data-fb-dt-value(onChange 直挂,最可靠)
② antd 可见框(降级兜底)
③ 原生隐藏字段(antd 没挂上时)
④ 都没有 → 空(清掉截止时间)
实测(复刻完整流程:选日期+20时+30分,不点确定,直接点保存):
保存读到 = "2026-11-16 20:30:00" ✅
onChange 次数 = 1
dataset="2026-11-16 20:30" h=20 m=30 vis="2026-11-16 20:30"
服务端侧确认无需改动:Task::dtOrNull() 对
YYYY-MM-DD HH:mm[:ss] / YYYY-MM-DD 都能正确补全,
只有带 T 分隔的会返回 null(那是整条清空,不是时分丢失)。
2026-11-05 18:19:46 +08:00
..
2026-11-05 18:07:17 +08:00
2026-10-04 08:56:40 +08:00
2026-09-29 23:48:45 +08:00
2026-11-05 18:19:46 +08:00
2026-10-10 12:42:43 +08:00
2026-09-30 00:49:53 +08:00