v43 第 43 批:六条反馈(界面 5 + 条目详情浮层)
用户 2026-10-11 反馈六条,逐条定位真根因后修复: ① 纪念日「日期」多出一个控件 —— 只保留最新的那个 两层根因:(a)原生 `input[type=date]` 当初没包在 `.dt-native` 里, v42 那条"AntD 挂上后收起原生框"的选择器根本不命中;(b)更要命的是 `.dt-native` 基类写着 `display: contents` —— 该元素**没有盒子**, 给它 position/width 完全无效 ⇒ 必须把 display 显式改回 block 才收得起来。 ② 编辑纪念日把底层列表页弄没 —— 「修改」原来是整页跳 `days/edit` (套 layout = 一张只有弹框的空白页)。改为 `?embed=1` 只吐弹框那一块, 列表页 JS 取回来替换 `#anNewCard` 并打开 —— 与「新建」同一观感。 内嵌形态标 `$anModalOnly` 以免打 standalone 标记(关闭时不再跳页)。 ③ 拖图裁剪的层被弹框盖住 —— `.crop-overlay` 是 z-index:100 而 `.cal-modal` 是 200 ⇒ 裁剪层被整块盖住。提到 260(与 v41 的 .cn-modal 同一处理)。 ④ 行程弹框里"参与的人"弹不出选人框 —— person_picker.js 只绑定一次, 而弹框表单是 AJAX 片段 ⇒ 里面的 `.pp` 从未被 init。三件事一起: 暴露 `window.fbInitPickers()`(幂等)+ layout 暴露 `window.fbLoadPicker()` (脚本是按需加载的)+ 塞完片段后补调初始化。 ⑤ 日程新建排版/控件/文案 —— 改走观影式 `.mv-grid`(标签对齐 + 冒号); 起止补上 `$dtPlugin='antd'`(试点正式推广到日程);标签「时间范围」→「开始 / 结束」; 删三句提示(结束留空 / 多选提醒 / 全天)。 ⑥ 条目详情浮层(首页日程 / 首页近期任务 / 日程页条目)—— 点条目不再直接跳页,弹浮层显示详情;「详细信息」跳该来源详情页; 「编辑」就地换成该来源的编辑表单(四处 `?embed=1` 片段)。 新增 `templates/_entry_popup.php` + `assets/js/entry_popup.js` + `fb_entry_json()`(三个入口共用一个编码函数)。 验证:php -l 157 文件全过;div 深度 33 组合全配平;片段体检 20 片段无越界; 本地 e2e 1510/0;v43 真机 33/0;v43 反向验证 8/0;v38 36/0;v42 33/0; b31/b32 反向验证 8/0 与 5/0;部署断言本地空跑 RC=0;完整流水线 PUSH_RC=0。
This commit is contained in:
@@ -17,31 +17,54 @@
|
||||
* 用法(include 前设好):
|
||||
* $evFields 正在编辑的日程(新建时传空数组)
|
||||
* $evAllDay 全天的默认值(新建默认**不勾**,用户 2026-10-02 第 6 条)
|
||||
* $evMvStyle 🔴 v43:「标签 62px 右对齐 + 冒号 + 控件」的**观影式**排版开关。
|
||||
* 新建日程那个弹框要它(用户:日程新建页排版和观影/行程一样);
|
||||
* 编辑页(`calendar/event.php`)继续用原来的 `.form-grid` 两列。
|
||||
*/
|
||||
$evF = is_array($evFields ?? null) ? $evFields : [];
|
||||
$evAllDayDefault = (bool)($evAllDay ?? false);
|
||||
$evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evAllDayDefault;
|
||||
/* 🔴 v43(用户 2026-10-11 第 5 条):观影式排版开关。 */
|
||||
$evMv = !empty($evMvStyle);
|
||||
/* 标签包装:观影式用 `.mv-row` + `.mv-lb`(冒号由 CSS ::after 给);
|
||||
否则用原来的 `.field` + `<label>`。
|
||||
⚠️ 抽成闭包是为了**不在下面每处 if/else 手抄两遍结构** ——
|
||||
抄两遍必然有一天两边不同步(v37 那种"改了 A 忘了 B"的坑)。
|
||||
⚠️ 「必填星号」作为**参数**传(不要用 `use` 捕获 —— 闭包定义时那个变量还没赋值,
|
||||
捕获到的是 null,星号永远不出现)。 */
|
||||
$evRowOpen = static function (string $full = '') use ($evMv): string {
|
||||
return '<div class="' . ($evMv ? 'mv-row' : 'field') . ($full !== '' ? ' ' . $full : '') . '">';
|
||||
};
|
||||
$evLab = static function (string $text, string $for = '', bool $star = false) use ($evMv): string {
|
||||
if ($evMv) {
|
||||
// 观影式:标签是 <span class="mv-lb">,冒号由 CSS ::after 给
|
||||
return '<span class="mv-lb">' . $text . ($star ? '<i>*</i>' : '') . '</span>';
|
||||
}
|
||||
return '<label' . ($for !== '' ? ' for="' . e($for) . '"' : '') . '>' . $text . ($star ? ' *' : '') . '</label>';
|
||||
};
|
||||
?>
|
||||
<div class="field full">
|
||||
<label for="ev-title">标题 *</label>
|
||||
<?php echo $evRowOpen('full'); ?>
|
||||
<?= $evLab('标题', 'ev-title', true) ?>
|
||||
<input class="input" id="ev-title" name="title" required
|
||||
value="<?= e((string)($evF['title'] ?? '')) ?>" placeholder="如:家长会">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="ev-location">地点</label>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('地点', 'ev-location') ?>
|
||||
<input class="input" id="ev-location" name="location"
|
||||
value="<?= e((string)($evF['location'] ?? '')) ?>" placeholder="如:学校三楼会议室">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>提醒</label>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('提醒') ?>
|
||||
<?php /* v24 第 20 批 第 8 条:**多选**(用户原话:「一个日程,我可以选择让它
|
||||
5分钟提醒,10分钟提醒等等。」)。
|
||||
⚠️ 用 checkbox 而不是 `<select multiple>`:后者在手机上要"按住再点",
|
||||
几乎没法用(任务共享那个 multiple 下拉就是因此被换掉的)。
|
||||
⚠️ 字段名必须是 `reminder_minutes[]` —— Calendar::reminderMinutes() 认得数组。
|
||||
写成 `reminder_minutes`(不带 [])会让 PHP 只留最后一个勾选。 */
|
||||
写成 `reminder_minutes`(不带 [])会让 PHP 只留最后一个勾选。
|
||||
🔴 v43(用户第 5 条):他要求把这一栏底下那句「多选与不提醒」的说明去掉
|
||||
⇒ 这里删掉那个 `.tip`(多选语义由复选框本身表达)。 */
|
||||
$curReminders = \App\Calendar::reminderList($evF['reminder_minutes'] ?? null); ?>
|
||||
<div class="rem-picks">
|
||||
<?php foreach (\App\Calendar::REMINDERS as $mins => $word): ?>
|
||||
@@ -52,7 +75,6 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<span class="tip">可以选多个(到点各响一次);一个都不选就是不提醒。</span>
|
||||
</div>
|
||||
|
||||
<?php /* v24 第 5、6 条:起止各一个「日期 + 时分秒」合在一起的控件(全局统一),
|
||||
@@ -74,43 +96,58 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
修法:**结束那一端不再默认藏起来**,范围控件一次性就挂上。
|
||||
起止成对本来就该一起填。想表达"只有一个时刻"的话,范围控件 clear 一下即可。
|
||||
⚠️ 顺带删掉「+ 添加结束时间 / 去掉结束时间」那套开关:
|
||||
它切换显隐会让范围控件反复重挂;范围控件自己就能表达"没有结束"。 */ ?>
|
||||
<div class="dt-range">
|
||||
它切换显隐会让范围控件反复重挂;范围控件自己就能表达"没有结束"。
|
||||
|
||||
🔴🔴 v43(用户 2026-10-11 第 5 条):「开始和结束时间也没有用我们最新的控件,
|
||||
直接就是四个字"时间范围"。」
|
||||
—— 两处真缺陷一起修:
|
||||
① 这个字段块**没传 `$dtPlugin='antd'`** ⇒ 用户看到的还是年/月/日 + 时/分
|
||||
五个原生下拉,而不是他点名要的 Ant Design 控件;
|
||||
② 标签写的是「时间范围」四个字,没告诉人"这是开始 / 结束"。
|
||||
⇒ `$dtPlugin='antd'`(与观影/行程同一套:面板有可点的时/分列、中文「确定」),
|
||||
标签改「开始 / 结束」(并去掉那颗必填星号的位置歧义 —— 只标在开始上)。
|
||||
⚠️ 契约一字未改:隐藏字段仍是 `*_date/_hour/_minute`;antd 拉不动时
|
||||
自动退回自建下拉(渐进增强)。 */ ?>
|
||||
<div class="dt-range<?= $evMv ? ' mv-row' : '' ?>">
|
||||
<?php /* ⚠️ 标签只有**一个**,挂在范围容器上(不是各挂各的):
|
||||
升级成一个范围控件之后,"开始"与"结束"就是同一个控件的两个端点,
|
||||
两个标签会变成"看着像两个字段、其实是一个"的错觉。 */ ?>
|
||||
<span class="dt-range-label">开始 / 结束 *</span>
|
||||
<?php if ($evMv): ?>
|
||||
<span class="mv-lb dt-range-label">开始 / 结束<i>*</i></span>
|
||||
<?php else: ?>
|
||||
<span class="dt-range-label">开始 / 结束 *</span>
|
||||
<?php endif; ?>
|
||||
<div class="field ev-dt" data-dt>
|
||||
<?php $dtName = 'starts_at'; $dtId = 'ev-start';
|
||||
$dtValue = $evF['starts_at'] ?? null; $dtRequired = true;
|
||||
$dtRange = 'start';
|
||||
$dtRange = 'start'; $dtPlugin = 'antd';
|
||||
require __DIR__ . '/../_datetime.php'; ?>
|
||||
</div>
|
||||
<div class="field ev-dt" data-dt id="ev-end-field">
|
||||
<?php $dtName = 'ends_at'; $dtId = 'ev-end';
|
||||
$dtValue = $evF['ends_at'] ?? null; $dtRequired = false;
|
||||
$dtRange = 'end';
|
||||
$dtRange = 'end'; $dtPlugin = 'antd';
|
||||
require __DIR__ . '/../_datetime.php'; ?>
|
||||
</div>
|
||||
</div><?php /* /dt-range */ ?>
|
||||
<span class="field-hint" style="display:block;margin:-4px 0 10px">
|
||||
结束留空就表示没有明确的结束(只占开始那一刻/那一天)。
|
||||
</span>
|
||||
<?php /* 🔴 v43(用户第 5 条):他要求把「结束留空即无明确结束」的那条提示去掉
|
||||
⇒ 那句 `.field-hint` 整块删除(不再输出)。 */ ?>
|
||||
|
||||
<div class="field">
|
||||
<label>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<label class="chk-inline">
|
||||
<input type="checkbox" id="ev-allday" name="all_day" value="1"
|
||||
<?= $evIsAllDay ? 'checked' : '' ?>>
|
||||
全天
|
||||
<span>全天</span>
|
||||
</label>
|
||||
<span class="field-hint">勾上就不管具体几点,只占这一天</span>
|
||||
<?php /* 🔴 v43(用户第 5 条):他要求把「全天只管日期、不管几点」的说明也去掉
|
||||
⇒ 那句 `.field-hint` 整块删除。 */ ?>
|
||||
</div>
|
||||
|
||||
<?php /* 用户 2026-10-03 第 5、6 条:重复日程。
|
||||
放在「全天」之后的自然位置:先定"哪一天/几点",再定"要不要重复"。
|
||||
周期用 FREQ 记号,结束条件三档(一直 / N 次 / 到某天),另加"工作日"。 */ ?>
|
||||
<div class="field">
|
||||
<label for="ev-freq">重复</label>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('重复', 'ev-freq') ?>
|
||||
<select class="select" id="ev-freq" name="freq">
|
||||
<?php $rp = \App\Repeat::parse((string)($evF['rrule'] ?? '')); ?>
|
||||
<?php foreach (\App\Repeat::FREQS as $k => $w): ?>
|
||||
@@ -119,29 +156,35 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field" id="ev-rep-end-box" hidden>
|
||||
<label for="ev-rep-end">结束条件</label>
|
||||
<select class="select" id="ev-rep-end" name="rep_end">
|
||||
<?php foreach (\App\Repeat::ENDS as $k => $w): ?>
|
||||
<option value="<?= e($k) ?>"<?= $rp['count'] > 0 ? '' : '' ?>><?= e($w) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('结束条件', 'ev-rep-end') ?>
|
||||
<div id="ev-rep-end-box" hidden>
|
||||
<select class="select" id="ev-rep-end" name="rep_end">
|
||||
<?php foreach (\App\Repeat::ENDS as $k => $w): ?>
|
||||
<option value="<?= e($k) ?>"><?= e($w) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" id="ev-rep-count-box" hidden>
|
||||
<label for="ev-rep-count">重复次数(含第一次)</label>
|
||||
<input class="input" type="number" min="1" max="2000" id="ev-rep-count" name="rep_count"
|
||||
value="<?= (int)($rp['count'] ?: 10) ?>">
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('重复次数(含第一次)', 'ev-rep-count') ?>
|
||||
<div id="ev-rep-count-box" hidden>
|
||||
<input class="input" type="number" min="1" max="2000" id="ev-rep-count" name="rep_count"
|
||||
value="<?= (int)($rp['count'] ?: 10) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" id="ev-rep-until-box" hidden>
|
||||
<label for="ev-rep-until">重复到</label>
|
||||
<input class="input" type="date" id="ev-rep-until" name="rep_until"
|
||||
value="<?= e((string)($rp['until'] ?? '')) ?>">
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('重复到', 'ev-rep-until') ?>
|
||||
<div id="ev-rep-until-box" hidden>
|
||||
<input class="input" type="date" id="ev-rep-until" name="rep_until"
|
||||
value="<?= e((string)($rp['until'] ?? '')) ?>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="ev-status">状态</label>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('状态', 'ev-status') ?>
|
||||
<select class="select" id="ev-status" name="status">
|
||||
<?php $st = (string)($evF['status'] ?? 'confirmed'); ?>
|
||||
<option value="confirmed"<?= $st === 'confirmed' ? ' selected' : '' ?>>确定</option>
|
||||
@@ -150,8 +193,8 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label for="ev-transp">这段时间算</label>
|
||||
<?php echo $evRowOpen(); ?>
|
||||
<?= $evLab('这段时间算', 'ev-transp') ?>
|
||||
<select class="select" id="ev-transp" name="transp">
|
||||
<?php $tp = (int)($evF['transp'] ?? 0); ?>
|
||||
<option value="0"<?= $tp === 0 ? ' selected' : '' ?>>忙碌</option>
|
||||
@@ -159,14 +202,14 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field full">
|
||||
<label for="ev-note">备注</label>
|
||||
<?php echo $evRowOpen('full'); ?>
|
||||
<?= $evLab('备注', 'ev-note') ?>
|
||||
<textarea class="input" id="ev-note" name="note" rows="3"
|
||||
placeholder="要带什么、跟谁一起…"><?= e((string)($evF['note'] ?? '')) ?></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field full">
|
||||
<label>附件(可多选)</label>
|
||||
<?php echo $evRowOpen('full'); ?>
|
||||
<?= $evLab('附件(可多选)') ?>
|
||||
<?php /* v24 第 21 批 第 7 条:统一成「点击或拖动进行上传」的框。
|
||||
⚠️ 文件框的 id 保持 `ev-attach`(原来就叫这个)—— e2e 与部署断言里
|
||||
有按 id 定位的写法,改名会把它们静默打成假红。 */
|
||||
@@ -189,7 +232,7 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
sync();
|
||||
|
||||
/* ⚠️ v24 第 21 批 第 7 条:原来这里有一整段「结束时间显隐 + 跟着开始时间走」的 JS。
|
||||
现在起止两端**始终可见**,并且由 Semi 的范围控件统一接管(一次选完两端),
|
||||
现在起止两端**始终可见**,并且由范围控件统一接管(一次选完两端),
|
||||
所以那段"同步两端"的逻辑整个删掉 —— 留着不但没用,还会和范围控件抢着改那两个
|
||||
原生字段(两处都写 → 值互相覆盖)。范围控件选完会自己把两端分别写回原生字段
|
||||
(见 app.js 的 onRange → writeDT),服务端契约不变。 */
|
||||
@@ -233,4 +276,5 @@ $evIsAllDay = array_key_exists('all_day', $evF) ? !empty($evF['all_day']) : $evA
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<?php unset($evF, $evAllDayDefault, $evIsAllDay, $evFields, $evAllDay); ?>
|
||||
<?php unset($evF, $evAllDayDefault, $evIsAllDay, $evFields, $evAllDay, $evMv, $evMvStyle,
|
||||
$evRowOpen, $evLab, $evLabelStar); ?>
|
||||
|
||||
Reference in New Issue
Block a user