v45 第 45 批:日程「重复到」换最新控件 + CalDAV 双向同步
用户 2026-10-12 两条:
1. 新建日程里「重复到」的那个日历选择框,改成最新控件。
- templates/calendar/_event_fields.php:裸 <input type=date> 换成
.dt-input.dt-antd-single[data-antd-date=1](AntD 纯日期 DatePicker),
复用既有 mountAntdDate,不新写挂载逻辑。
- 值载体仍是 name=rep_until 的原生框(包在 .dt-native 里),
服务端契约与 Repeat::build($_POST) 一字不改。
2. CalDAV 从「只读」改成「双向同步」。
用户给了一台可用的参照服务器(群晖 DAViCal)要求「完全按参照返回」;
抓参照 + 复刻 Thunderbird / SyncCalendar 的真实请求序列后确认:
参照是可写的,而只读会让两个客户端都判「不可用」。
- dav.php:放行 PUT(新建 201+ETag / 更新 204+ETag / If-Match 不符 412)、
DELETE(204)、MKCALENDAR(201+Location),仍逐本判权;
OPTIONS 的 Allow 与 DAV 头照参照补齐(DAV 头两行,注意 PHP header 追加);
current-user-privilege-set 按实际可写性给,并排除系统派生本(农历等)。
- app/CalDav.php:资源名统一用 UID(原自定义本用 id、派生本用 uid 两种混着,
一开写就表现为「客户端 PUT 到 UID 名、服务端 href 是 id 名 ⇒ 写进去读不回」);
补 owner / getctag / getcontenttype / calendar-description;新增 ctagSeedOf。
- app/Ics.php:修一个一直存在的真 bug —— 导出 RRULE 漏了 `RRULE:` 前缀
(库里存的是去前缀的值),导致所有导出/同步出去的重复日程都变成单次。
- templates/home.php:首页红线补 data-now-min(给探针做零容差判据用)。
验证:本地 e2e 1510/0、TB 探针 35/0、DAV 诊断 28/0、
v43 真机 33/0 + 反向 9/0、v44 真机 41/0 + API 63/0 + 反向 19/0、
v45 重复到 10/0 + 反向 2/0、v45 DAV 双向 24/0 + 反向 5/0;
全流水线 PUSH_RC=0(含部署静态断言第 45 批形态)。
This commit is contained in:
@@ -213,8 +213,25 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
|
||||
<?php echo $evRowOpen('', !$evRepeating || (string)$evRp['until'] === ''); ?>
|
||||
<?= $evLab('重复到', 'ev-rep-until') ?>
|
||||
<div id="ev-rep-until-box"<?= ($evRepeating && (string)$evRp['until'] !== '') ? '' : ' hidden' ?>>
|
||||
<input class="input" type="date" id="ev-rep-until" name="rep_until"
|
||||
value="<?= e((string)($evRp['until'] ?? '')) ?>">
|
||||
<?php /* 🔴 v45(用户 2026-10-12 第 1 条):「添加日程这里,当选择了重复,
|
||||
并且选择了重复到某天为止,这时候重复到会出现,有一个日历选择框,
|
||||
这个日历选择框也改为我们最新的控件。」
|
||||
⇒ 把原来那个原生 `<input type="date">` 换成 AntD **纯日期** DatePicker。
|
||||
|
||||
⚠️ 做法与「纪念日 → 日期」完全同一套(v42/v43 已验证):
|
||||
· 外层 `.dt-input` + `data-antd-date="1"` → app.js 的 `mountAntdDate` 接管;
|
||||
· 值载体仍是**同一个** `name="rep_until"` 的 `<input type="date">`,
|
||||
只是被 `.dt-native` 包起来(否则那条"收起原生框"的 CSS 不命中 ⇒
|
||||
会出现"多了一个控件",正是 v43 纪念日踩过的坑);
|
||||
· 服务端契约**一字不改**:`Repeat::build($_POST)` 照旧读 `rep_until`。
|
||||
⚠️ 千万别给这个 `.dt-input` 加 `data-dt="…"`:那是"年/月/日+时/分"那套
|
||||
四字段契约的标记,加上去会被 `upgrade()` 抢走、反而绑错处理器。 */ ?>
|
||||
<div class="dt-input dt-antd-single" data-antd-date="1" id="ev-rep-until-wrap">
|
||||
<span class="dt-native">
|
||||
<input type="date" class="dt-date" id="ev-rep-until" name="rep_until"
|
||||
value="<?= e((string)($evRp['until'] ?? '')) ?>" aria-label="重复到">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+10
-1
@@ -322,7 +322,16 @@ unset($evRef);
|
||||
⚠️ CSS 里那条 `.ag-now-dot` 也一并删(留在那儿是死规则,
|
||||
还会让"红线只有一根"这件事在样式表里看不出结论)。 */ ?>
|
||||
<?php if ($showNow): ?>
|
||||
<div class="ag-now" style="top: <?= number_format($nowPos * 100, 2) ?>%"></div>
|
||||
<?php /* 🔴 v45:把**服务端算红线用的那个分钟数**也写到元素上(`data-now-min`)。
|
||||
为什么:探针原来只能"拿服务端渲染出的 top% 去和浏览器此刻的时间比" ——
|
||||
两者的容差被 0.3% 一道卡着,而"整小时 vs 分钟"的差只等于
|
||||
`分钟/60/跨度`:当分钟数很小时(如第 2 分钟)占比不到 0.3%,
|
||||
**注入旧行为也不会变红** ⇒ 反向验证当场判它"恒真摆设"。
|
||||
写上 data-now-min 之后,探针可以做一个**零容差**的判据:
|
||||
"服务端用的分钟数 == 浏览器此刻的分钟数",整小时注入必然对不上。
|
||||
⚠️ 它只是给测试用的观测点,不影响任何渲染/行为。 */ ?>
|
||||
<div class="ag-now" style="top: <?= number_format($nowPos * 100, 2) ?>%"
|
||||
data-now-min="<?= (int)$nowMinutes ?>"></div>
|
||||
<?php endif; ?>
|
||||
<?php /* 日程块:按"相对第一个刻度的小时数"定位(与日视图同一套比例)---- */ ?>
|
||||
<?php
|
||||
|
||||
Reference in New Issue
Block a user