v78 服务端:首页任务改成「就地处理」面板 + 新建任务搬到首页
用户原话: 「网页端,首页点击一个任务后,除了展示信息,应该有相应的功能,可以修改状态: 待办、进行中,可以挪动分组,可以拖动上传附件,可以添加评论,添加子任务等。 其目地,是为了让用户不离开首页,就能对任务进行简单的处理。」 「另外,在全部任务旁边,放一个新建任务的功能,其实就是把任务中的新建和编辑功能, 搬过来,用弹出框来处理。」 一、首页任务浮层由「只读信息」改成「可操作面板」 - 新增 templates/tasks/_panel.php:状态三段 / 看板 chips(带看板色)/ 子任务(复用 _task_check.php)/ 附件拖放框(复用 _attachments.php)/ 讨论 - 新增路由 tasks/panel:只吐一块 HTML(找不到 404) - 既有七个动作路由各加一条 ajax_panel 回包分支(状态 / 挪分组 / 新建子任务 / 评论增删 / 附件增删),没有新开写接口 - helpers.php 新增 task_panel_wanted() / task_panel_json(); fb_entry_json() 的 payload 增加 panel 字段(只有任务会给) - 每次动作回**整块新面板**:一次动作会牵动子任务计数、附件张数、看板选中态, 逐处同步 DOM 必然漏一处 - 拖进来的附件**立刻上传**(任务已存在,不该再让用户点一次保存), 不复用 _stage_drop.php 那套「暂存 + 认领」 二、新建任务搬到首页 - 从 templates/tasks/index.php 抽出公共片段 templates/tasks/_add_modal.php (字段与原来一字未改),首页与任务页共用同一份 - 新增 assets/js/task_add.js 管开关(两页共用,幂等绑定); 打开那一刻才 fbUpgradeRange() + fbBootAntd()(hidden 时宽高为 0,antd 会定位错乱) - App\HomeCards 登记表里加 add => 新建任务,首页卡头与「全部任务」并排 - tasks/create 支持 back=home(白名单),新建完回首页 三、其它 - assets/js/task_panel.js:事件委托;动作后整块换面板; 顺手同步首页那张卡的状态徽标与复选框(关掉浮层不能还是旧状态); 传附件时保住用户写了一半的留言与子任务标题;取不到面板时退回只读信息 - app.css 追加面板样式(含 color-mix 的 @supports 兜底)与卡片窄到宽 2 时允许折行 验证:本地 e2e 1558/0、几何 428/0 + 660/0、v78 反向验证 11/0、 片段作用域体检 35/0、php -l 与 node --check 全过
This commit is contained in:
@@ -443,6 +443,87 @@ function fb_entry_json(array $ev, string $detail = '', string $edit = '', array
|
||||
'info' => $evOwn ? url('calendar/event', ['id' => $evRef, 'embed' => 'detail']) : '',
|
||||
'repeat' => (string)($ev['repeat'] ?? '') !== '',
|
||||
'occ' => (string)($ev['occ'] ?? ''),
|
||||
/* 🔴 v78(用户 2026-10-22):**就地面板**的地址。
|
||||
首页「近期任务」点开时不再只给一行行只读信息,而是直接给出这张
|
||||
面板(状态 / 看板 / 子任务 / 附件 / 评论 都能就地改),用户不必离开首页。
|
||||
⚠️ 只有**任务**会给这个字段(`_card_tasks.php` 里传进来);
|
||||
日程/观影/旅程仍然走原来的"详情 + 编辑/删除"三颗按钮 ——
|
||||
它们没有"在首页上简单处理一下"的诉求,硬塞一个面板只会让浮层变复杂。 */
|
||||
'panel' => (string)($ev['panel'] ?? ''),
|
||||
];
|
||||
return json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_HEX_APOS | JSON_HEX_QUOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 这次请求是不是「首页任务面板」发来的(v78)。
|
||||
*
|
||||
* 面板里的每一个动作都打**既有路由**,只多带一个 `ajax_panel=1`;
|
||||
* 服务端据此把"flash + 302 跳转"换成"一段新面板 + 一句人话"。
|
||||
*
|
||||
* ⚠️ 判据只认 POST 里那个字段,**不要**顺手用 `X-Requested-With` 代替:
|
||||
* `tasks/status` 早就用那个头区分"看板上的就地改(只要状态)"和"表单提交",
|
||||
* 两件事混在一个判据里,改一处必然破坏另一处。
|
||||
*/
|
||||
function task_panel_wanted(): bool
|
||||
{
|
||||
return (string)($_POST['ajax_panel'] ?? '') === '1';
|
||||
}
|
||||
|
||||
/**
|
||||
* 把「这一条任务的最新面板」当 JSON 回给前端(v78)。
|
||||
*
|
||||
* 为什么**每次都重画整块面板**,而不是让前端自己把那一行改掉:
|
||||
* · 一个动作的影响面比看起来大 —— 勾一条子任务会改"2/3"这个计数;
|
||||
* 传一个附件会改附件张数与缩略图墙;挪看板会改上面那排 chip 的选中态。
|
||||
* 逐处同步(本项目在 v55 的状态下拉上已经手写过一次)是"漏一处就自相矛盾"。
|
||||
* · 面板很小(一次 Task::find + 一个片段),重画一次比维护 N 处 DOM 同步便宜。
|
||||
*
|
||||
* ⚠️ `html` 在失败(ok=false)时**也照样给**:失败的典型原因是"权限不够/内容为空",
|
||||
* 这正是最需要让用户看到"现在的真实状态"的时候,回一个空壳反而把旧状态留在屏幕上。
|
||||
*
|
||||
* @param int $taskId 要重画哪一条(子任务新增时传**父任务**,否则会把用户弹到子任务上)
|
||||
* @param string $msg 给用户看的一句话(落在浮层底栏左侧)
|
||||
* @param bool $ok 这次动作成不成功(只影响提示语气与 HTTP 码,不影响 html)
|
||||
*/
|
||||
function task_panel_json(int $taskId, string $msg = '', bool $ok = true): void
|
||||
{
|
||||
$familyId = (int)\App\Auth::familyId();
|
||||
$me = (int)\App\Auth::personId();
|
||||
$t = \App\Task::find($familyId, $taskId, $me);
|
||||
if (!$t) {
|
||||
header('Content-Type: application/json; charset=utf-8', true, 404);
|
||||
echo json_encode(['ok' => false, 'msg' => '找不到这项任务。'], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
$people = \App\Person::roster($familyId, $me, 'member', '');
|
||||
/* @人 高亮的候选名:与 tasks/show.php 同一份口径(真名 + 我的昵称都算),
|
||||
否则同一句话在详情页高亮、在首页面板不高亮。 */
|
||||
$names = [];
|
||||
foreach ($people as $p) {
|
||||
$names[] = person_name($p);
|
||||
$nm = trim((string)($p['name'] ?? ''));
|
||||
if ($nm !== '') {
|
||||
$names[] = $nm;
|
||||
}
|
||||
}
|
||||
$names = array_values(array_unique(array_filter($names)));
|
||||
$html = \App\View::renderPartial('tasks/_panel', [
|
||||
't' => $t,
|
||||
'people' => $people,
|
||||
'names' => $names,
|
||||
'boards' => \App\Task::boards($familyId),
|
||||
'categories' => \App\Task::categories($familyId),
|
||||
'canWrite' => \App\Auth::canWrite() && \App\Task::canWrite($t, $me),
|
||||
'meId' => $me,
|
||||
]);
|
||||
header('Content-Type: application/json; charset=utf-8', true, $ok ? 200 : 422);
|
||||
echo json_encode([
|
||||
'ok' => $ok,
|
||||
'msg' => $msg,
|
||||
'id' => $taskId,
|
||||
'status' => (string)($t['status'] ?? ''),
|
||||
'word' => \App\Task::statusWord((string)($t['status'] ?? 'todo')),
|
||||
'html' => $html,
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user