Files
FamilyBook/templates/tasks/_edit_form.php
T
laoyang 075ac6bbeb v44 第 44 批:界面 5 条 + 移动端 API v1 全量
界面(用户 2026-10-12 第 1~5 条)
1. 新建日程「日历本」并入 .cs 自绘下拉,颜色画进候选项,三字与下拉同行。
2. 新建日程「开始/结束」改「日期范围:」,删旧日期控件;
   重复相关三行仅选重复时出现;删「(含第一次)」与「这段时间算忙碌」。
3. 条目浮层加「地点」、去掉「状态」行;首页红线按分钟定位(原只取整小时);
   去掉左侧红点只留红线。
4. 任务页删掉状态说明提示(STATUS_HINT 三值清空)。
5. 新建任务:标题在前树框在后;截止时间改最新日历控件;负责人默认自己;
   删冗余提示;「上面要做什么」→「任务名称」;清理括号说明。

移动端 API(用户第 6 条:导航模块除外,其余全量)
- 新增 Bearer 令牌鉴权(api_tokens 表,Schema v32),与登录口令 / DAV 口令三套分立。
- Api.php 内核(鉴权/取参/信封/分页/分发 + _method 覆写)+
  ApiHandler.php 17 条资源 + ApiToken.php + api.php 入口。
- 路由:router.php / .htaccess / index.php 三处 /api/ 兜底(部署脚本自动追加线上规则)。
- 个人设置新增「App 接口令牌」卡;docs/API.md 接口文档;
  docs/API-QUESTION-LIST.md 自主决策与待确认缺口清单。

验证:本地 e2e 1510/0、v43 真机 33/0、v43 反向 9/0、
v44 真机 41/0、v44 API 63/0、v44 反向 19/0;全流水线 PUSH_RC=0。
2026-10-12 15:31:03 +08:00

134 lines
6.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 🔴 v43(用户 2026-10-11 第 6 条)—— 任务的「编辑」表单,**独立一份**。
*
* 为什么要独立出来:
* 原来它内联在 `tasks/show.php` 的 `<details>` 里。而条目详情浮层点「编辑」时,
* 需要**单独取这份表单**(`tasks/edit?embed=1`)—— 不可能去详情页里抠。
* 抽成一份后,详情页与浮层用的是**同一张表单**,不会出现"两处字段不一致"。
*
* ⚠️ 字段名 / 服务端契约与原来**一字未改**(tasks/update 收的就是这些)。
* ⚠️ 「状态」不在这里改:状态由专门的 `tasks/status` 路由管(它还要处理循环任务),
* 文案里也说明了这一点(与 v24 第 14 批的口径一致)。
*
* 🔴🔴 **本片段一律用带前缀的局部变量(`$tk*`),绝不碰入参的名字。**
* 第一版写的是 `$t = is_array($t ?? null) ? $t : [];` —— 看似无害,其实是在
* **覆盖宿主模板的 `$t`**(那是"这条任务"本身)。只读一次没问题,
* 但下一个人只要把某个 `$tk*` 改回 `$t`(很自然)就会让详情页后半段的
* `$t['children']` / 评论区全是 null —— **而且是静默的**。
* 项目的"片段体检"(`_fb_frag_guard`)当场抓到了这处裸赋值,是对的。
* ⇒ 入参先**收进 `$tkT`**,后面全用它。
*
* 用法(include 前设好):
* $t 任务(Task::find 的形状)
* $people 名册
* $parents 可选父任务候选
* $categories / $boards 分类与看板
* $tkEditEmbed 是否"浮层形态"(true = 不输出自己的「保存」,由浮层底栏给)
*/
$tkT = is_array($t ?? null) ? $t : [];
$tkPeople = (array)($people ?? []);
$tkParents = (array)($parents ?? []);
$tkCats = (array)($categories ?? []);
$tkBoards = (array)($boards ?? []);
$tkEmbed = !empty($tkEditEmbed);
?>
<form method="post" action="<?= e(url('tasks/update')) ?>" class="node-form" id="tkEditForm">
<?= csrf_field() ?>
<input type="hidden" name="id" value="<?= (int)($tkT['id'] ?? 0) ?>">
<?php /* 🔴 v44(用户 2026-10-12 第 5 条):编辑表单也统一成观影式排版 +
最新时间控件 + 文案精简(与「新建任务」弹框一致)——
同一件事在两个入口长得不一样,用户会以为"进了别的页面"。 */ ?>
<div class="mv-grid">
<div class="mv-row">
<span class="mv-lb">任务名称<i>*</i></span>
<input class="input" id="tk-title" name="title" required value="<?= e((string)($tkT['title'] ?? '')) ?>">
</div>
<div class="mv-row">
<span class="mv-lb">截止时间</span>
<?php /* 🔴 v44:截止时间用 AntD 单点控件(与新建同一套);括号去掉。 */ ?>
<?php $dtName = 'due_at'; $dtValue = $tkT['due_at'] ?? null;
$dtRequired = false; $dtPlugin = 'antd-single';
require __DIR__ . '/../_datetime.php'; ?>
</div>
<div class="mv-row">
<span class="mv-lb">负责人</span>
<?php /* 第 8 条同一诉求:负责人也是「选人」,人多时用弹窗 + 首字母更快。
保留原下拉的「不指定」(pp-item-none + value=0)。 */ ?>
<?php
$ppName = 'assignee_id';
$ppPeople = $tkPeople;
$ppSelected = [(int)($tkT['assignee_id'] ?? 0)];
$ppMode = 'single';
$ppOpenBtn = '更换负责人';
$ppTitle = '谁负责这件事';
$ppEmptyText = '不指定';
$ppAllowEmpty = true;
require __DIR__ . '/../_person_picker.php';
?>
</div>
<div class="mv-row">
<span class="mv-lb">循环</span>
<select class="select" name="repeat_rule">
<?php foreach (\App\Task::REPEAT as $rk => $rv): ?>
<option value="<?= e($rk) ?>"<?= (string)($tkT['repeat_rule'] ?? '') === (string)$rk ? ' selected' : '' ?>>
<?= e($rv) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mv-row">
<span class="mv-lb">父任务</span>
<select class="select" name="parent_id">
<option value="0">(这是一项独立的任务)</option>
<?php foreach ($tkParents as $p): ?>
<option value="<?= (int)$p['id'] ?>"<?= (int)($tkT['parent_id'] ?? 0) === (int)$p['id'] ? ' selected' : '' ?>>
<?= e((string)$p['title']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<?php /* v24 第 9、10 条:分类与看板(看板把任务放到哪一块,分类是标签) */ ?>
<div class="mv-row">
<span class="mv-lb">分类</span>
<select class="select" name="category_id">
<option value="0">未分类</option>
<?php foreach ($tkCats as $c): ?>
<option value="<?= (int)$c['id'] ?>"<?= (int)($tkT['category_id'] ?? 0) === (int)$c['id'] ? ' selected' : '' ?>>
<?= e((string)$c['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mv-row">
<span class="mv-lb">看板</span>
<select class="select" name="board_id">
<?php foreach ($tkBoards as $b): ?>
<option value="<?= (int)$b['id'] ?>"<?= (int)($tkT['board_id'] ?? 0) === (int)$b['id'] ? ' selected' : '' ?>>
<?= e((string)$b['name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mv-row">
<span class="mv-lb">备注</span>
<textarea class="input" id="tk-note" name="note" rows="3"><?= e((string)($tkT['note'] ?? '')) ?></textarea>
</div>
</div>
<?php /* ⚠️ 「状态」不在这里改(由 tasks/status 路由管,它还要处理循环任务)。
浮层形态下由它的底栏给「保存」;整页详情页里带自己的按钮。 */ ?>
<?php if (!$tkEmbed): ?>
<div class="btn-row"><button class="btn btn-sm" type="submit">保存</button></div>
<?php endif; ?>
</form>
<?php /* 🔴🔴 —— **千万不要 unset 入参变量**!
这几种是宿主模板的"大局变量"(`$t` = 这条任务、`$people` = 名册…),
include 之后宿主还要继续用它们(`$t['children']`、评论、子任务…)。
我第一版照抄了 `_datetime.php` 那种"用完即清"的写法,把 `$t` 一并 unset ——
结果 `tasks/show.php` 后半段全部拿不到 `$t`,**子任务列表与评论区静默消失**
(e2e 当场抓到 2 条:子任务没了、@高亮没了)。
⇒ 这里只清**本片段自己造的**临时变量(`$tk*` 与 `$dt*` / `$pp*` 那几组)。 */
unset($tkT, $tkPeople, $tkParents, $tkCats, $tkBoards, $tkEmbed,
$dtName, $dtValue, $dtRequired,
$ppName, $ppPeople, $ppSelected, $ppMode, $ppOpenBtn, $ppTitle,
$ppEmptyText, $ppAllowEmpty); ?>