0; /* 分类名:Task::find 不带 join,这里按 id 在清单里找(清单一次查询就够, 比再跑一条 SQL 划算;找不到就当未分类)。 */ $tpCatName = ''; foreach ($tpCats as $tpCat) { if ((int)$tpCat['id'] === (int)($tpT['category_id'] ?? 0)) { $tpCatName = (string)$tpCat['name']; break; } } $tpDue = (string)($tpT['due_at'] ?? ''); /* #78:协作人(共享给)。Task::find 已经带回 `shares`,直接用。 */ $tpShares = (array)($tpT['shares'] ?? []); $tpShareIds = []; foreach ($tpShares as $tpS) { $tpShareIds[] = (int)($tpS['person_id'] ?? 0); } $tpDueWord = \App\Task::dueWord($tpDue !== '' ? $tpDue : null); $tpLate = $tpDue !== '' && $tpStatus !== 'done' && \App\Task::isOverdue($tpDue); ?>
data-tk-url-due="" data-tk-url-save="">
状态
$tpSv): ?>
看板
` 而不是 `_person_picker.php` 的弹窗选人: 面板本身已在浮层里,再弹一层模态 = 两层遮罩,手机上很容易点错; 而且 picker 需要 `fbInitPickers()` 初始化,`loadPanel()` 目前没调它。 家庭成员通常 3~10 人,select 够用。**人多了再换弹窗**,那时记得 把 `fbInitPickers` 也补进 `loadPanel()`。 */ ?>
更多信息
标题
截止
负责人 $tpT['assignee_name'], 'my_nickname' => $tpT['assignee_nick'] ?? ''])) : '不指定' ?>
协作人 (int)($pp['id'] ?? 0) !== $tpMe)); $ppSelected = array_values(array_filter($tpShareIds, fn($sid) => $sid !== $tpMe)); $ppMode = 'multi'; $ppOpenBtn = '+ 添加人'; $ppTitle = '共享给谁'; require __DIR__ . '/../_person_picker.php'; ?> 无
分类
备注
循环
子任务 /

还没有子任务。

附件
'1']; require __DIR__ . '/../_attachments.php'; ?>

还没有附件。

点击或拖动进行上传
讨论

还没有留言。写 @名字 可以点名。

` 必须带 `enctype="multipart/form-data"`, 否则浏览器只提交文件名、文件本体丢失(那种"上传成功但打开是空的"最迷惑)。 ⚠️ 纯附件不写字也允许(把 `required` 从 textarea 上去掉了)—— "只发一张图"是常见用法;服务端在 content 为空时会用一句 占位文案,见 comment_add 的处理。 ⚠️ 用原生 `` 而不是拖拽框:评论是一次性提交, 拖拽框那套(`data-tk-drop-box`)是"点了立刻上传",两者语义不同。 */ ?> `** —— `` 的 `files` 是只读的,得用 `DataTransfer` 重建 一个 FileList 赋回去。这样表单提交时浏览器才会真的带上文件, 否则只是"看起来加上了",提交是空的。 */ ?>
可点击选择,也可把文件拖进来