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:
@@ -347,3 +347,68 @@ function days_until_birthday(?string $birthday): ?int
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔴 v43(用户 2026-10-11 第 6 条)—— 把一条日历/任务条目编成**详情浮层**能直接渲染的 JSON。
|
||||
*
|
||||
* 用户原话:
|
||||
* 「首页上的日程、首页上的近期任务,以及日程里面的日程,点击它们的时候,
|
||||
* 都会弹出一个框显示更详细的信息。…如果是观影啊、旅程啊,点击详细信息就会
|
||||
* 进入到观影或者旅程的那个相关的页面。如果是日程的话,点击详细信息就进到
|
||||
* 日程的详细页面。当然还可以直接点击编辑,点击编辑不同的来源就进入不同的编辑页面,
|
||||
* 就在当前的页面弹窗…」
|
||||
*
|
||||
* ⇒ 每种来源由这里给出**三样**:
|
||||
* `detail` 「详细信息」跳哪(该来源的详情页)
|
||||
* `edit` 「编辑」取哪份编辑表单片段(`?embed=1` 的那些路由)
|
||||
* `rows` 浮层正文那几行「标签:值」
|
||||
*
|
||||
* ⚠️ 模板里只调这一个函数,不要在各模板里各拼一份 JSON ——
|
||||
* "三个入口三套写法"必然有一天漏改一个(用户第 6 条点名了三处入口)。
|
||||
* ⚠️ 返回**已经 json_encode 好的字符串**,直接写进 `data-fb-entry='…'`;
|
||||
* 模板里用单引号属性包住(JSON 里的双引号不会撞)。
|
||||
* 用 `JSON_HEX_APOS | JSON_HEX_QUOT` 把引号也转成实体,双保险。
|
||||
*
|
||||
* @param array $ev 日历条目(Calendar::month 的形状:kind/ref_id/title/date/time/…)
|
||||
* @param string $detail 详情页地址(没有就不显「详细信息」)
|
||||
* @param string $edit 编辑表单片段地址(没有就不显「编辑」)
|
||||
* @param array $extra 额外要显示的行 [[标签, 值], …]
|
||||
* @return string 可直接放进 data-fb-entry 的 JSON 字符串(已转义)
|
||||
*/
|
||||
function fb_entry_json(array $ev, string $detail = '', string $edit = '', array $extra = []): string
|
||||
{
|
||||
$date = (string)($ev['date'] ?? '');
|
||||
$time = (string)($ev['time'] ?? '');
|
||||
$et = (string)($ev['end_time'] ?? '');
|
||||
if ($date !== '') {
|
||||
$when = $date;
|
||||
if (!empty($ev['all_day'])) {
|
||||
$when .= ' 全天';
|
||||
} elseif ($time !== '') {
|
||||
$when .= ' ' . $time . ($et !== '' ? '–' . $et : '');
|
||||
}
|
||||
} else {
|
||||
$when = '';
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
if ($when !== '') { $rows[] = ['时间', $when]; }
|
||||
if ((string)($ev['calname'] ?? '') !== '') { $rows[] = ['日历本', (string)$ev['calname']]; }
|
||||
if ((string)($ev['location'] ?? '') !== '') { $rows[] = ['地点', (string)$ev['location']]; }
|
||||
if ((string)($ev['status_word'] ?? '') !== '') { $rows[] = ['状态', (string)$ev['status_word']]; }
|
||||
if ((string)($ev['note'] ?? '') !== '') { $rows[] = ['备注', (string)$ev['note']]; }
|
||||
// ⚠️ 扩展行排在"备注"之后、作为补充(调用方按需给,比如任务给「所属看板」)
|
||||
foreach ($extra as $row) {
|
||||
if (is_array($row) && count($row) >= 2 && (string)$row[1] !== '') {
|
||||
$rows[] = [(string)$row[0], (string)$row[1]];
|
||||
}
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'title' => trim((string)($ev['title'] ?? '')),
|
||||
'rows' => $rows,
|
||||
'detail' => $detail,
|
||||
'edit' => $edit,
|
||||
];
|
||||
return json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_HEX_APOS | JSON_HEX_QUOT);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user