fix(resources): 新建资源时带着上一次的附件(暂存清单从不复位)(#19)
用户原话:「资源模块,新建资源,会把之前的附件带进来,就是说,附件那里不是空的。」 ## 根因 `#resAddCard` 是新建/编辑**共用**同一个弹窗(v42 第 7 条), 复位函数 `resetToCreate()` 清了标题/正文/归属人/共享人,**唯独漏了附件**: - 缩略图卡片与隐藏令牌 `stage_token[]` 是 queueDrop() 上传成功后 **动态插进 `.stage-list`** 的(assets/js/app.js:668),只有点卡片上的「×」才移除; - 关弹窗只做 `addCard.hidden = true`,DOM 原样留着 ⇒ 下次打开就看见上一次的附件。 ## 不只是"看着脏" 上传后**没保存就关掉**的那批,暂存目录还在(没被认领),令牌残留在表单里 ⇒ 下次点「确定」时被 `StagedUpload::claim()` 认领到**新资源**上。 实测(`_tooling/_b36_res_attach_reset.py` 的 D1): 修复前新建的资源 id=3 附件数 **=1** —— 用户会看到"新建的资源莫名多了张照片"。 修复后同一路径附件数 **=0**。 ## 改法 新增 `clearStaged()`:清 `.stage-cell` 卡片 + 兜底清 `input[name="stage_token[]"]` + 把 `.stage-list` 藏回 hidden(与模板初始状态一致)。 两处调用: - `resetToCreate()` —— 点「新建资源」时 - `openEdit()` —— 点「编辑」时(openEdit 并不灌附件,已有附件走列表里独立的 「附件」弹窗,所以此刻表单里的卡片一定是"上一次没做完的残留") ⚠️ 兜底清令牌这步不能省:用户看不见令牌,但它才是真正会被提交的东西 (DOM 删了、数据还在 —— #456 同族)。 ## 验证 `_tooling/_b36_res_attach_reset.py`(走真实 UI,三条关闭路径 A/B/C + 数据层 D): | | 修复前 | 修复后 | |---|---|---| | A 取消后再新建(卡片/令牌) | 1 / 1 | **0 / 0** | | B 保存成功后再新建 | 1 / 1 | **0 / 0** | | C Esc 关闭后再新建 | 1 / 1 | **0 / 0** | | D 新建资源的实际附件数 | **1**(带进来了) | **0** | | 合计 | 通过 6 / **失败 7** | **通过 13 / 失败 0** | **判据有牙齿**:`_tooling/_b36_falsify.py` 把 `clearStaged()` 注入成第一行 `return;` (等价修复前),判据立刻红回 7 条,恢复后 13/0。锚点命中数断言 =1。 `_tooling/_b36_res_regress.py` —— 回归 13/0,确认没弄坏既有能力: 编辑仍能灌入标题/正文/id、底栏「共享」「附件」两颗按钮仍显示、 「新建+上传+保存」附件照旧真的挂上(附件数=1)、 列表里独立的附件面板组件(`sd-attach-panel`)仍在。 顺带查了其它用 `_stage_drop.php` 的模块(books/calendar/movies/people/tasks/trips), 都没有"共用弹窗 + 复位"这套结构,同一个坑不存在。 工单 #19
This commit is contained in:
@@ -532,6 +532,47 @@ $myPerson = (int)\App\Auth::personId();
|
||||
会丢掉滚动位置;既然列表页已经有 `#resListHost` 这样的容器就顺手接上。 */
|
||||
var addBtn = document.getElementById('resAddBtn');
|
||||
var addCard = document.getElementById('resAddCard');
|
||||
|
||||
/* 🔴 工单 #19(用户 2026-10-28):「资源模块,新建资源,会把之前的附件带进来,
|
||||
就是说,附件那里不是空的。」
|
||||
【根因】`#resAddCard` 是新建/编辑**共用**同一个弹窗(v42 第 7 条),
|
||||
但附件区**从来没被复位过**:
|
||||
· 缩略图卡片与隐藏令牌 `stage_token[]` 是 queueDrop() 上传成功后
|
||||
**动态插进 `.stage-list`** 的(assets/js/app.js:668),
|
||||
只有点卡片上那个「×」才会移除;
|
||||
· 关弹窗只做 `addCard.hidden = true`,DOM 原样留着 ⇒ 下次打开就看见上一次的附件。
|
||||
⇒ 复位函数 `resetToCreate()` 清了标题/正文/归属人/共享人,**唯独漏了附件**。
|
||||
|
||||
⚠️ 这不只是"看着脏":上传后**没保存就关掉**的那批,暂存目录还在(没被认领),
|
||||
令牌残留在表单里 ⇒ 下次点「确定」时会被 `StagedUpload::claim()` 认领到
|
||||
**新资源**上 —— 实测「新建的资源莫名多了 1 张照片」
|
||||
(见 `_tooling/_b36_res_attach_reset.py` 的 D1)。
|
||||
⚠️ 编辑态**也要清**:`openEdit()` 并不灌附件(已有附件走列表里独立的「附件」弹窗),
|
||||
所以编辑时看到的任何附件都是"上一次没做完的残留" ⇒ 保存时会被挂到这条资源上。
|
||||
⚠️ 为什么"只清 DOM"就够了:卡片在**拖入时**就已经 append 进 `.stage-list`
|
||||
(app.js:600,同步执行),上传完成的回调是在那个**已脱离文档**的节点上
|
||||
改样式、塞令牌,不会再回到表单里 ⇒ 不需要额外加"代/epoch"计数器。
|
||||
⚠️ 除了卡片,还要兜底清 `input[name="stage_token[]"]`:
|
||||
用户看不见令牌,但它才是真正会被提交的东西(#456 同族:DOM 删了、数据还在)。 */
|
||||
function clearStaged() {
|
||||
var form = document.getElementById('resForm');
|
||||
if (!form) { return; }
|
||||
var list = form.querySelector('[data-stage-list]');
|
||||
if (list) {
|
||||
Array.prototype.forEach.call(list.querySelectorAll('.stage-cell'), function (c) {
|
||||
if (c.parentNode) { c.parentNode.removeChild(c); }
|
||||
});
|
||||
// 一张不剩就藏回去(模板初始就 hidden,别留一条空边框)
|
||||
list.hidden = true;
|
||||
}
|
||||
Array.prototype.forEach.call(form.querySelectorAll('input[name="stage_token[]"]'),
|
||||
function (i) {
|
||||
if (i.parentNode) { i.parentNode.removeChild(i); }
|
||||
});
|
||||
var tip = form.querySelector('[data-stage-tip]');
|
||||
if (tip) { tip.textContent = ''; tip.hidden = true; }
|
||||
}
|
||||
|
||||
function setResOpen(on) {
|
||||
if (!addCard) { return; }
|
||||
addCard.hidden = !on;
|
||||
@@ -611,6 +652,10 @@ $myPerson = (int)\App\Auth::personId();
|
||||
ids = arr.map(function (o) { return o.id; });
|
||||
} catch (e) { ids = []; }
|
||||
setPickerValues('share_ids[]', ids);
|
||||
/* 🔴 工单 #19:编辑态**也要清**暂存区 —— openEdit 并不灌附件(已有附件走
|
||||
列表里独立的「附件」弹窗,见下面的 openPane),所以此刻表单里若还有卡片/令牌,
|
||||
那一定是"上一次拖进来没保存"的残留 ⇒ 不清的话会被挂到**这条资源**上。 */
|
||||
clearStaged();
|
||||
setResOpen(true);
|
||||
/* 🔴 v42:编辑态才显示底栏的「共享」「附件」两颗按钮(新建时资源还不存在,
|
||||
没有"共享给谁/挂哪些附件"可说)。 */
|
||||
@@ -666,6 +711,8 @@ $myPerson = (int)\App\Auth::personId();
|
||||
if (el) { el.hidden = true; el.removeAttribute('data-res-id'); }
|
||||
});
|
||||
setPickerValues('share_ids[]', []);
|
||||
/* 🔴 工单 #19:附件也要清 —— 否则新建时带着上一次的附件,见 clearStaged 的注释 */
|
||||
clearStaged();
|
||||
}
|
||||
|
||||
/* 事件委托:列表里的「编辑」按钮(AJAX 换过列表后仍然有效) */
|
||||
|
||||
Reference in New Issue
Block a user