v41 第 41 批:流水线提速 + 12 项界面/交互开发 + DAV 彻底修复

DAV(用户「务必彻底解决」):
- 真根因是 home-set 层级错:CalDav::HOME_PATH 原为 /dav/calendars/、
  CardDav 原为 /carddav/addressbooks/,而日历本/通讯录的 href 在
  /dav/N.ics/ 与 /carddav/N.vcf/ —— home-set 下面一本都没有。
  Thunderbird 按 home-set 前缀认成员,于是「找不到日历本 / 找不到联系人」。
  改为 /dav/ 与 /carddav/(所有既有 URL 一字不变,老配置不作废)。
- 又发现并修掉 Depth:0 违反 RFC 4918:原实现无论 depth 都列出全部子集合,
  且第一条 response 是日历本(不含 current-user-principal)。改为按 depth 分流,
  Depth:0 只回资源自身、Depth:1 才列出子集合。

界面与交互:
- 观影:新建影院弹窗层级修正 + 详细地址;照片左右按钮悬停不再位移;
  弹框底栏改「确定 / 取消」。
- 旅程:新建旅程改弹窗并按观影式排版;详情页四个动作按钮按用户指定顺序与配色;
  编辑与新增行程弹窗化(单容器 + AJAX);行程时间控件改 AntD(精确到分);
  参与人默认带上自己;车次号/车牌号紧跟交通方式词。
- 资源:新建/编辑改弹窗 + 观影式排版 + 新建时即定共享人。
- 纪念日:新建改弹框 + 观影式排版。

验证:
- e2e 1510/0;v41 十二项真机 48/0;DAV 反向验证 8/0;
  部署断言空跑 337/0;模板 div 深度三形态穷举 33 组全配平。
- 线上 DAV 终验(--resolve 真实入口 + 真 DAV 口令)12/0;
  线上确认 Depth:0 恰好 1 个 response。
This commit is contained in:
2026-10-11 10:12:11 +08:00
parent f9e30bd7d8
commit 7544fb9f6a
19 changed files with 1616 additions and 342 deletions
+31 -3
View File
@@ -386,20 +386,39 @@ $mDelForms = []; // 收集起来,在表单**外面**统一渲染
以后动这里只要保证:**开的数量 = 关的数量,且顺序一致**。 */ ?>
<?php if ($mvModal): ?>
</div><?php /* /.cal-modal-body(仅弹框形态) */ ?>
<?php /* 🔴 v41(用户 2026-10-10):「观影模块弹出的框下面的按钮也是确定和取消。」
两处变化:① 提交按钮文案 保存/记下这场电影 → **「确定」**(统一口径);
② **顺序改成「确定」在前、「取消」在后**(用户明确"下面的按钮就是确定和取消
两个",与旅程那边同一口径)。id 保持不变(详情页的 AJAX 主路挂的是
`#mvAddSubmit`,改文案不影响)。 */ ?>
<div class="cal-modal-foot">
<span class="cal-modal-tip" id="mvAddTip"></span>
<button class="btn btn-sm" type="submit" form="mvForm" id="mvAddSubmit"><?= $isEdit ? '保存' : '记下这场电影' ?></button>
<button class="btn btn-sm" type="submit" form="mvForm" id="mvAddSubmit">确定</button>
<button class="btn btn-ghost btn-sm" type="button" id="mvAddCancel">取消</button>
</div>
</div><?php /* /.cal-modal-panel(仅弹框形态) */ ?>
<?php else: ?>
<div class="btn-row">
<button type="submit" class="btn">保存</button>
<?php /* ⚠️ 整页形态的提交按钮**也要 id**:两种形态的按钮语义完全相同,
给同一个 id 让"按 id 定位"对两种形态都成立(同一时刻只渲染其一,不会冲突)。
v41 实测:探针原来按**文案**("保存")找按钮,用户要求改成「确定」后
探针找不到按钮 ⇒ 三条落库断言全 NULL(看着像功能坏了)。⇒ id 才是契约。 */ ?>
<button type="submit" class="btn" id="mvAddSubmit">确定</button>
<a class="btn btn-ghost"
href="<?= e(url('movies/show', ['id' => (int)$m['id']])) ?>">取消</a>
</div>
<?php endif; ?>
</div><?php /* /.mv-form-inner 或 .card.card-pad(编辑态) */ ?>
<?php /* 🔴🔴 v41:**这一层只在整页形态存在**。
弹框形态下 `.mv-form-inner` 已经在上面(`</div><!-- /.mv-form-inner -->`)
关掉了 —— 原来这里**无条件**又关一次 ⇒ 弹框形态**多一个 `</div>`**,
把 `</form>` 挤到了容器外面(`_fb_divdepth.py` 当场抓到:
"深度结束时 -1,首个负深度在 `</div></form>`")。
⚠️ 这与 v37 那次"保存按钮被甩到 form 外面"是**同一个结构性坑**,
而 v40 那轮只跑了 `php -l`(它对此完全无感)所以没发现
—— 这一轮补上"按形态逐一量 div 深度"才暴露出来。 */ ?>
<?php if (!$mvModal): ?>
</div><?php /* /.card.card-pad(整页形态) */ ?>
<?php endif; ?>
</form>
<?php if ($mvModal): ?>
</div><?php /* /.cal-modal(弹框壳) */ ?>
@@ -455,6 +474,15 @@ $mDelForms = []; // 收集起来,在表单**外面**统一渲染
<label>影院名称 *</label>
<input class="input" name="name" required placeholder="如:万象城 CGV" maxlength="100">
</div>
<?php /* 🔴 v41(用户 2026-10-10):「这里新建影院这个地方好像没有详细地址啊。
应该把详细地址加上。」—— 影院管理页的表单一直有 address 字段,
但这个**快捷弹框**漏了它 ⇒ 从这里新建的影院永远没有详细地址。
字段名与影院管理页保持一致(`address`),服务端 Cinema::save 已经收它。 */ ?>
<div class="field">
<label>详细地址(可不填)</label>
<input class="input" name="address" placeholder="如:香港中路 10 号万象城 4 层"
maxlength="200">
</div>
<div class="field">
<label>主题颜色</label>
<div class="color-row">