Files
FamilyBook/templates/home/_card_tasks.php
T
laoyang 40fd6c501c 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 全过
2026-10-22 12:40:14 +08:00

75 lines
4.5 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
/**
* 首页卡片 · 近期任务(v62 从 templates/home.php 拆出来的)。
*
* 用户原话(v24 第 24 批 第 3 条):「右侧显示任务模块里面的数据,显示当前正在
* 进行当中的所有的任务,除了显示任务的标题之外,还要显示他的状态。比如说正在
* 进行中待确认等等。除了这之外,还要显示他所处的看板的名称。」
*
* 🔴 v53 第 2 条:待办也放进来,放在进行中的**下面**(不是混排)。
* ⚠️ 每行前面有复选框,点了就地完成(AJAX,不跳页);表单与脚本在 home.php 末尾
* 各一份 —— 那份**必须留着**,别跟着卡片一起删。
* ⚠️ 标题的颜色跟着**看板色**(不是任务模块的主题色),见 v32 第 4 条那条注释。
*
* 🔴🔴 v78(用户 2026-10-22):「首页点击一个任务后,除了展示信息,应该有相应的功能,
* 可以修改状态:待办、进行中,可以挪动分组,可以拖动上传附件,可以添加评论,
* 添加子任务等。其目地,是为了让用户不离开首页,就能对任务进行简单的处理。」
* ⇒ 每一行除 `data-fb-entry`(浮层要的基础信息)外,再给一个 `panel` 地址:
* 浮层拿到它就把正文换成**可操作的面板**(`templates/tasks/_panel.php`),
* 地址是 `tasks/panel?id=`,动作全走既有路由(见 helpers.php 的 task_panel_*)。
* 面板取不到(404 / 网络)时,浮层会退回 `rows` 那份只读信息 —— 不会白屏。
*/
?>
<div class="hc-body">
<?php if (!$tasks): ?>
<p class="empty-hint">没有进行中的任务,也没有待办。</p>
<?php else: ?>
<ul class="dash-list tk-list">
<?php foreach ($tasks as $t): ?>
<?php $late = \App\Task::isOverdue($t['due_at'] ?? null); ?>
<?php $tkColor = \App\Task::boardColorById((int)\App\Auth::familyId(),
(int)($t['board_id'] ?? 0) ?: null); ?>
<li class="dash-row tk-row" data-task-row="<?= (int)$t['id'] ?>"
style="--tk-c: <?= e($tkColor) ?>;">
<?php
$tkId = (int)$t['id']; $tkStatus = (string)($t['status'] ?? 'todo');
$tkBack = 'home'; $tkStatic = !\App\Auth::canWrite();
require __DIR__ . '/../_task_check.php';
?>
<span class="dash-dot" style="background: <?= e($late ? 'var(--red)' : 'var(--tk-c)') ?>;"></span>
<a class="dash-what" href="<?= e(url('tasks/show', ['id' => (int)$t['id']])) ?>"
title="<?= e((string)$t['title']) ?>"
data-fb-entry='<?= fb_entry_json([
'title' => (string)$t['title'],
'status_word' => \App\Task::statusWord((string)($t['status'] ?? 'todo')),
'note' => (string)($t['note'] ?? ''),
/* v78:浮层把正文换成这块面板(可就地改状态/看板/子任务/附件/评论) */
'panel' => url('tasks/panel', ['id' => (int)$t['id']]),
], url('tasks/show', ['id' => (int)$t['id']]),
\App\Auth::canWrite() ? url('tasks/edit', ['id' => (int)$t['id']]) : '',
[['截止', ($t['due_at'] ?? '') !== '' ? substr((string)$t['due_at'], 0, 16) : ''],
['看板', trim((string)($t['board_name'] ?? ''))]]) ?>'
style="color: <?= e($late ? 'var(--red)' : $tkColor) ?>;">
<?= e((string)$t['title']) ?>
</a>
<span class="kb-st is-<?= e((string)($t['status'] ?? 'todo')) ?> is-static">
<?= e(\App\Task::statusWord((string)($t['status'] ?? 'todo'))) ?>
</span>
<?php if (trim((string)($t['board_name'] ?? '')) !== ''): ?>
<?php $bColor = \App\Task::boardColor($t['board_color'] ?? null, (string)$t['board_name']); ?>
<span class="tk-board" style="--bc: <?= e($bColor) ?>;">
<i class="tk-board-dot" aria-hidden="true"></i><?= e((string)$t['board_name']) ?>
</span>
<?php endif; ?>
<?php if ((int)($t['child_total'] ?? 0) > 0): ?>
<span class="dash-tag"><?= (int)$t['child_done'] ?>/<?= (int)$t['child_total'] ?></span>
<?php endif; ?>
<?php if (($t['due_at'] ?? '') !== ''): ?>
<span class="tk-due"><?= e(\App\Task::dueWord($t['due_at'] ?? null)) ?></span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>