日历本` / `$evMvStyle = true`)。 * 片段抽走后这些串**只在这个新文件里**,而断言还在查 `calendar/index.php` * ⇒ 正向断言当场中止部署、负向断言恒真没牙齿(v78 原话:"部署当场中止, * 看着像断言写错,其实是目标文件漂移")。 * ⇒ v82 已把这 5 条改成 `_cal_add_src` = 两个文件拼起来一起查。 * * ③ **变量由调用方给全**,片段自己不许偷宿主的变量(本项目重复踩过)。 * 本片段需要的变量见文件末尾那段 `@var` 说明(含兜底逻辑)。 * * ───────────────────────────────────────────────────────────────────────── * @var bool $calCanNew 能不能新建(`Auth::canWrite() && $writable` 非空);片段内自己再兜一次 * @var array $calWritable 可写的日历本清单(含 id/name/color/kind) * @var array $calCtx 上下文:ym / view / anchor / new_at / back / thisYm * `back` 只认 'home' 或 ''('' = 回日程模块),服务端白名单取值 */ /* ---------------------------------------------------------------- 兜底 */ /* 🔴🔴 v82 修正(2026-10-23):片段**自己读进来的变量一律加 `cal` 前缀**。 --------------------------------------------------------------------------- 第一版是照模块页的老变量名写的(`$ym / $view / $anchor / $newAt / $writable`), 想着"沿用模块页的变量名最省事" —— 那是**整页**时代的写法,抽成片段就错了: · require 与宿主**共享一个作用域** ⇒ 片段里那句 `$anchor = (string)($calCtx['anchor'] ?? date('Y-m-d'));` 直接改写了**模块页自己的 `$anchor`**; · 今天两者恰好同值(模块页就是把它自己的值传进 `$calCtx` 的), 所以看不出问题 —— 但只要有一天首页传的 anchor 与模块页不同 (首页固定"今天",模块页是页面锚点),模块页后半页就会静默错位: 页头日期、翻页链接、时间网格的 `.tg-now` top 全跟着变。 · `$newAt` / `$writable` 同理,其中 `$writable` 还被首页 unset 过, 等于在首页里**把宿主的可写本清单干掉**(首页后面别的卡片要用)。 这 5 个名字(anchor / newAt / writable / view / ym)都在 `_tooling/_fb_fragment_scope_check.py` 的"宿主高频名"表里,是那个检查器 2026-10-03 就定下的规则(由来见它文件头:`unset($canWrite)` 把账本页炸成 一片 Warning,`php -l` 与 HTTP 200 全绿,只是页面排版坏了)。 ⇒ 现在片段只碰 `$cal*`,宿主那套名字一个都不写。 ⚠️ 别为了"读起来熟悉"改回去 —— 片段与宿主同名是这类 bug 的唯一入口。 */ $calCanNew = (bool)($calCanNew ?? false); $calWritable = (array)($calWritable ?? []); if (!$calCanNew || !$calWritable) { return; /* 没得写就整块不输出(与模块页那个 if 等价) */ } $calCtx = (array)($calCtx ?? []); $calYm = (string)($calCtx['ym'] ?? date('Y-m')); $calView = (string)($calCtx['view'] ?? 'month'); $calAnchor = (string)($calCtx['anchor'] ?? date('Y-m-d')); $calNewAt = (string)($calCtx['new_at'] ?? ''); $calBack = (string)($calCtx['back'] ?? ''); $calThisYm = date('Y-m'); $calBooks = $calWritable; /* 片段内统一用这个短名遍历可写的本子 */ /* 🔴 v82:通用弹框开关(`assets/js/add_modal.js`)认的是 `data-fb-add-modal`。 ⚠️ 必须**按来源**决定挂不挂: · 首页内嵌(`$calBack === 'home'`)→ 挂上,由 `add_modal.js` 管开合; · 日程模块页 → **不挂**,那页有自己的一套内联 JS(`calAddBtn` 的 onclick + 遮罩/✕/Esc 全在 `calendar/index.php` 底部),挂上会**绑两遍**: 点一次开两次、关两次(`add_modal.js` 的注释里写着同一个坑)。 ⇒ 判据用 `$calBack`(首页那条路才会传 'home'),不要用"页面里有没有别的弹框"。 */ $fbAddModalAttr = ($calBack === 'home'); ?>
`** —— `.cal-modal-panel` 被提前闭合、 跟着又被多关一层,于是 `
` 跑到了 **面板外面**(DOM 上它是 `.cal-modal` 的直接子元素)。 面板 `max-height` 一卡,底栏就被挤到面板下方 → 用户看不到。 另有 CSS 一层:`.cal-modal-panel > form` 原先不是 flex 列, `.cal-modal-body{flex:1 1 auto}` 因此不起作用(两处都已修)。 ⚠️ 提交键用 `form="calAddForm"` **显式关联**:多一层/少一层 DOM 的 意外都不会再让它失效(它本来就在 form 内部,但显式写更稳)。 */ ?>