资源模块:新建资源时附件区带着上一次的附件(弹窗复用但暂存清单没复位)
用户原话:「资源模块,新建资源,会把之前的附件带进来,就是说,附件那里不是空的。」
新建资源的弹窗里,「附件」那块不是空的 —— 显示着上一轮/上一条资源上传过的文件缩略图。
因为 #resAddCard 是新建 / 编辑共用同一个弹窗(v42 第 7 条), 而关闭时只清输入框、不清暂存清单,所以:
#resAddCard
templates/resources/index.php 的 resetToCreate()(第 654 行)在点「新建资源」时复位:
templates/resources/index.php
resetToCreate()
function resetToCreate() { ...清 id / action / 标题文字 / rs-title / rs-content / 底栏按钮... setPickerValues('share_ids[]', []); // ← 共享人清了 }
附件(.stage-list)和它里面的隐藏令牌 <input name="stage_token[]"> 一行没清。
.stage-list
<input name="stage_token[]">
而附件令牌是 assets/js/app.js 的 queueDrop() 在上传成功时动态插进 .stage-cell 里的(第 668-670 行):
assets/js/app.js
queueDrop()
.stage-cell
hid.name = box.getAttribute('data-stage-field') || 'stage_token[]'; hid.value = d.stoken; cell.appendChild(hid);
这些节点只在用户点卡片上的「×」时才被移除(第 700 行附近)。 弹窗关闭 / 重新打开都没有任何代码碰它 —— setResOpen(false) 只做 addCard.hidden = true。
setResOpen(false)
addCard.hidden = true
所以 DOM 一直留着 ⇒ 下次打开就看见上一次的附件。
StagedUpload::claim()(app/StagedUpload.php:170)认领后会 rmDir 暂存目录, 第二次认领时 !is_dir($dir) → continue 跳过。
StagedUpload::claim()
rmDir
!is_dir($dir)
continue
⇒ 上一批已经被保存认领过的令牌,残留下来只是视觉噪音(提交了也无害); 但没保存就被关掉的那批(用户点了取消 / 按了 Esc),暂存目录还在, 令牌也还在 DOM 里 ⇒ 下次新建资源点确定,这批文件会被认领到新资源上。 用户会看到"新建的资源里莫名多了照片"。
stage_token[]
e733c4f
#resAddCard 是新建/编辑共用同一个弹窗(v42 第 7 条), 而 resetToCreate() 清了标题、正文、归属人、共享人,唯独漏了附件。
附件的缩略图卡片和隐藏令牌 stage_token[] 是 queueDrop() 上传成功后 动态插进 .stage-list 的(assets/js/app.js:668), 只有点卡片上那个「×」才会移除 —— 关弹窗只做 addCard.hidden = true,DOM 原样留着。
assets/js/app.js:668
上传后没保存就关掉的那批,暂存目录还在(没被认领),令牌残留在表单里 ⇒ 下次点「确定」时被 StagedUpload::claim() 认领到新资源上。
复现脚本实测(_tooling/_b36_res_attach_reset.py 的 D1):
_tooling/_b36_res_attach_reset.py
修复前:新资源 id=3 附件数=1 ← 用户看到"新建的资源莫名多了张照片" 修复后:新资源 id=5 附件数=0
新增 clearStaged(),做三件事:
clearStaged()
input[name="stage_token[]"]
.stage-tip
两处调用:
openEdit()
主判据 _tooling/_b36_res_attach_reset.py(走真实 UI,三条关闭路径 + 数据层)
判"附件区为空"同时看三样:.stage-cell 数量、.stage-list 是否 hidden、 stage_token[] 数量 —— 单看卡片会漏掉"卡片删了但令牌还在"。
判据有牙齿:_tooling/_b36_falsify.py 把 clearStaged() 注入成第一行 return; (等价修复前行为),锚点唯一性断言通过,判据立刻红回7 条,恢复后回到 13/0。
_tooling/_b36_falsify.py
return;
回归 _tooling/_b36_res_regress.py —— 13 通过 / 0 失败,确认没弄坏既有能力:
_tooling/_b36_res_regress.py
[OK] ② 新建+上传+保存,附件真的挂上了(附件数=1) [OK] ④ 标题灌进来了 [OK] ⑤ 正文灌进来了 [OK] ⑥ id 隐藏框填了 A 的 id [OK] ⑦ 底栏「共享」「附件」两颗按钮显示出来 [OK] ⑧ 编辑态附件区为空(不灌历史附件) [OK] ⑩ 编辑 A 后新建:标题清空、id 清空(新建态) [OK] ⑪ 编辑用的附件面板组件仍在(sd-attach-panel)
顺带查了其它用 _stage_drop.php 的模块(books / calendar / movies / people / tasks / trips),都没有"共用弹窗 + 复位函数"这套结构 ⇒ 同一个坑不存在。
_stage_drop.php
git push
fc81347..e733c4f
95a933e2666684623d56e5f1326a6b1c
family
php -l
grep -c clearStaged
本地 fb_test 测试数据已清理:资源 3 → 0,对应 3 张测试图片与 4 个暂存孤儿目录 都移到 _tooling/_fb_trash/20261028-res19/(含库表备份),没有直接删。
fb_test
_tooling/_fb_trash/20261028-res19/
线上登录态的冒烟按分工留给您。
修复已提交(e733c4f)并部署到 family.yangyq.net,线上 md5 与本地一致(95a933e...),clearStaged 线上 4 处。
95a933e...
clearStaged
三组验证:主判据从「通过 6 / 失败 7」变成「13 / 0」;注入回 bug 形态立刻红回 7 条(判据有牙齿);回归 13/0 确认编辑/共享/新建带附件主路径都没坏。
最关键的 D1:修复前新建资源会真的带进上次未保存的附件(附件数=1),修复后 =0。
本地测试数据已清理(资源 3→0),3 张图 + 4 个暂存孤儿目录移到 _tooling/_fb_trash/20261028-res19/。
线上登录态冒烟按分工留给用户。关闭。
No dependencies set.
The note is not visible to the blocked user.
资源模块:新建资源时附件区带着上一次的附件(弹窗复用但暂存清单没复位)
现象
用户原话:「资源模块,新建资源,会把之前的附件带进来,就是说,附件那里不是空的。」
新建资源的弹窗里,「附件」那块不是空的 —— 显示着上一轮/上一条资源上传过的文件缩略图。
影响面(三种表现,严重程度不同)
因为
#resAddCard是新建 / 编辑共用同一个弹窗(v42 第 7 条),而关闭时只清输入框、不清暂存清单,所以:
根因(已读码定位)
templates/resources/index.php的resetToCreate()(第 654 行)在点「新建资源」时复位:附件(
.stage-list)和它里面的隐藏令牌<input name="stage_token[]">一行没清。而附件令牌是
assets/js/app.js的queueDrop()在上传成功时动态插进.stage-cell里的(第 668-670 行):这些节点只在用户点卡片上的「×」时才被移除(第 700 行附近)。
弹窗关闭 / 重新打开都没有任何代码碰它 ——
setResOpen(false)只做addCard.hidden = true。所以 DOM 一直留着 ⇒ 下次打开就看见上一次的附件。
为什么"有时候还会真的带上数据"
StagedUpload::claim()(app/StagedUpload.php:170)认领后会rmDir暂存目录,第二次认领时
!is_dir($dir)→continue跳过。⇒ 上一批已经被保存认领过的令牌,残留下来只是视觉噪音(提交了也无害);
但没保存就被关掉的那批(用户点了取消 / 按了 Esc),暂存目录还在,
令牌也还在 DOM 里 ⇒ 下次新建资源点确定,这批文件会被认领到新资源上。
用户会看到"新建的资源里莫名多了照片"。
验收标准
stage_token[]隐藏字段(否则下次保存会带上旧令牌)已修复并部署(commit
e733c4f)根因
#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):改法
新增
clearStaged(),做三件事:.stage-list里所有.stage-cell卡片;input[name="stage_token[]"]—— 用户看不见令牌,但它才是真正会被提交的东西(DOM 删了、数据还在是 #456 那类坑);
.stage-list/.stage-tip藏回 hidden(与模板初始状态一致)。两处调用:
resetToCreate()openEdit()验证
主判据
_tooling/_b36_res_attach_reset.py(走真实 UI,三条关闭路径 + 数据层)判"附件区为空"同时看三样:
.stage-cell数量、.stage-list是否 hidden、stage_token[]数量 —— 单看卡片会漏掉"卡片删了但令牌还在"。判据有牙齿:
_tooling/_b36_falsify.py把clearStaged()注入成第一行return;(等价修复前行为),锚点唯一性断言通过,判据立刻红回7 条,恢复后回到 13/0。
回归
_tooling/_b36_res_regress.py—— 13 通过 / 0 失败,确认没弄坏既有能力:顺带查了其它用
_stage_drop.php的模块(books / calendar / movies / people /tasks / trips),都没有"共用弹窗 + 复位函数"这套结构 ⇒ 同一个坑不存在。
部署
git push→fc81347..e733c4f95a933e2666684623d56e5f1326a6b1cfamily、mtime 为部署时刻、php -l通过、grep -c clearStaged= 4顺带完成
本地
fb_test测试数据已清理:资源 3 → 0,对应 3 张测试图片与 4 个暂存孤儿目录都移到
_tooling/_fb_trash/20261028-res19/(含库表备份),没有直接删。线上登录态的冒烟按分工留给您。
修复已提交(
e733c4f)并部署到 family.yangyq.net,线上 md5 与本地一致(95a933e...),clearStaged线上 4 处。三组验证:主判据从「通过 6 / 失败 7」变成「13 / 0」;注入回 bug 形态立刻红回 7 条(判据有牙齿);回归 13/0 确认编辑/共享/新建带附件主路径都没坏。
最关键的 D1:修复前新建资源会真的带进上次未保存的附件(附件数=1),修复后 =0。
本地测试数据已清理(资源 3→0),3 张图 + 4 个暂存孤儿目录移到
_tooling/_fb_trash/20261028-res19/。线上登录态冒烟按分工留给用户。关闭。