笔记附件:修好拖放、传完回编辑态、选中即上传 #21

用户原话:「网页端,笔记应该可以同时上传多个附件。」

诊断后确认「多选」本来就是好的(multiple + name=file[] + 后端数组分支,
一次选 3 个混合类型真的存了 3 行)。真正坏的是另外两件事:

1) 拖放是假承诺。界面写「把文件拖到这里」,但没有任何 drop 监听器:
   拖完 input.files 仍是 0、POST 0 个文件。更糟的是 dragover 没有
   preventDefault ⇒ 浏览器按默认行为直接打开那个文件,正在写的笔记
   连未保存正文一起丢。
   修法:给框加 data-sd-for="noteAttInput",复用 app.js 里既有的
   bindInput() → bindZone()。一行属性,不另写一套拖放。
   踩过的坑:data-sd-for 写的是**裸 id**,第一版带了个 `#`,选择器
   变成 [data-sd-for="#noteAttInput"],一个都匹配不上,拖放照样没人接。

2) 传完跳回阅读态(redirect 不带 edit=1),附件区在 $editMode 分支里
   根本不渲染 ⇒ 用户看到的是"没传上"。attach_add / attach_del 两处
   都补 edit => 1。

另外补了即时反馈:change 一来就把提示换成「已选择 N 个文件:…,正在
上传…」并自动提交。用 requestSubmit(btn) 而不是 form.submit() ——
后者绕过 submit 事件、也不带按钮的 formaction/formenctype,提交会跑去
notes/save 且非 multipart,文件直接丢。

判据:
- _b40_note_multi_attach.py  16/0(点选多选 / 拖放 / 回编辑态 / 单选回归 / 提示文案)
- _b40_falsify21.py  三处注入各自红在预期编号(data-sd-for 带# → ③④a-d;
  requestSubmit→submit → ①-b;去掉 edit=1 → ③-a/b)
- _b40_regress21.py  20/0(删除生效且回编辑态 / 越权删除被拒 / 公共绑定器
  未受影响 / MAX_PER_HOST=60 端到端仍生效)
- _b40_regress21_falsify.py  关掉上限与归属校验各自变红
This commit is contained in:
2026-10-28 20:13:22 +08:00
parent 4941e9db9c
commit 7c86859ab9
2 changed files with 115 additions and 5 deletions
+10 -2
View File
@@ -8111,7 +8111,12 @@ $want = array_keys($want);
$warns = attach_save_files($familyId, Note::ATTACH, $id, 'file', $me);
flash($warns ? 'err' : 'ok',
$warns ? '有附件没有保存:' . implode(';', $warns) : '附件已上传。');
redirect('notes/form', ['id' => $id]);
/* 🔴 工单 #21:回**编辑态**(`edit=1`),不是阅读态。
`notes/form` 的 `$editMode = $id <= 0 || !empty($_GET['edit'])` ⇒
原来这里不带 edit 参数,id>0 就落到阅读态,附件区(在 $editMode 分支里)
根本不渲染。用户上传完看到的是"附件没传上"——体感就是功能坏了,
实际只是跳错了态。 */
redirect('notes/form', ['id' => $id, 'edit' => 1]);
break;
case 'notes/attach_del':
@@ -8134,7 +8139,10 @@ $want = array_keys($want);
}
\App\Attachment::remove($aid);
flash('ok', '附件已删除。');
redirect('notes/form', ['id' => $nid]);
/* 🔴 工单 #21:删完同样回**编辑态** —— 与 attach_add 保持一致的道理:
回阅读态的话,用户点「✕」删掉一个,跳转后看不见附件列表,
不知道删成功了没有,也找不到继续删/继续传的入口。 */
redirect('notes/form', ['id' => $nid, 'edit' => 1]);
break;
/* 段落 Markdown 的**实时预览**(v28 用户第 12 条:"允许所见即所得编辑")。