laoyang
|
870a63df5a
|
首页任务浮层:补 ref_id,修复「编辑」按钮不显示 (#72)
用户 Console 提供决定性线索:
AntD 日期控件已挂上 5 处
⇒ 前端控件、资源加载全部正常,问题不在那里。
真根因:
entry_popup.js 的 paintDetail() 里
ed.hidden = !(isEvent && data.edit);
「编辑」按钮要求 data.source === event。
而 fb_entry_json() 算 source:
$evKind = $ev[\x27kind\x27] ?? \x27custom\x27; // 任务卡没传,默认 custom
$evRef = (int)($ev[\x27ref_id\x27] ?? 0); // 任务卡没传 ⇒ 0
$evOwn = ($evKind === \x27custom\x27 && $evRef > 0); // ⇒ false
\x27source\x27 => $evOwn ? \x27event\x27 : \x27derived\x27, // ⇒ derived
⇒ 编辑按钮恒不显示 ⇒ 用户点开任务只能看到只读面板
⇒ 压根没有进 _edit_form.php 的入口
⇒ 永远看不到「截止时间」(那控件只在那张表里)
讽刺的是:_card_tasks.php 是唯一给 panel 的卡片(注释还强调"只有任务会给"),
却也是唯一没给 ref_id 的调用方。
修法:第一个参数补 \x27ref_id\x27 => (int)$t[\x27id\x27]
不补 kind 的理由:fb_entry_json 的 kind 判据只用来区分
「日历里真正属于某本日历的条目」vs「从别的模块派生的」。
对任务来说它只关心"能不能在这里改",答案是能(有 tasks/edit),
走默认 \x27custom\x27 就对了。
副作用检查:del 仍为空(任务没有 calendar/event_del 那种路由,
面板里另有删除入口),所以「删除」按钮不显示 —— 这是正确的。
「编辑」只要 isEvent && data.edit 两者都满足就显示。
实测:
改后(带 ref_id):source = event ✅ 编辑显示 ref=49
改前(不带) :source = derived ❌ 编辑不显示(即 bug)
|
2026-11-05 17:35:54 +08:00 |
|
laoyang
|
4941e9db9c
|
fix(home): 从浮层把任务标成完成时该行不消失(只修了复选框那条路)(#20)
用户第二次提同一条需求。核了线上代码:4 文件 md5 与本地一致、mtime 18:14,
部署没问题;复跑原判据仍 20/0 全绿。判据绿 + 用户能复现 ⇒ 判据有盲区。
盲区:首页把任务标成完成有**两个入口**
① 每行前面那颗复选框 —— home.php 末尾的脚本(上一版已修)
② 点整行弹浮层 → 面板里「状态」三段按钮 → assets/js/task_panel.js 的 syncRow()
上一版只改了 ①。syncRow() 只改徽章与复选框的 aria 状态,**从不删行**,
所以从面板点「已完成」后行留在原地,只把徽标换成「已完成」。
用户点的就是 ②,而原判据 grep 全文没有 panel / 浮层 / data-fb-entry —— 完全没测这条路。
改法:
- 把删行逻辑抽成 window.fbHomeTaskDrop(row, wasStatus) 放 assets/js/app.js,
两个入口共用一份。作用域限定 [data-tk-home-host]:任务**看板**页的行也带
data-task-row,那里勾完成只改状态、**必须保留该行**(看板按状态分栏,删了就没处看)。
- task_panel.js 的 syncRow() 在 d.status === 'done' 时调它;
wasStatus 必须在改写 data-tk-status **之前**读,否则概述卡不知道该减「在做」还是「待办」。
- home.php 原来那份本地实现改成薄转发,避免两份实现改一处忘一处。
- 顺带修掉一条说谎的注释:原注释写"补偿了一个可撤回的提示",但代码里从来没有
撤回按钮,只有一句 3.2 秒自动消失的 say()。
- _card_tasks.php 补记"两个入口"这件事。
子任务安全:task_panel_json() 用 panel_of 找**父任务**,回的 status 是父任务的,
所以面板里勾子任务不会把父任务那一行删掉(判据 ⑱ 专门守这条)。
判据:
- 新增 _b38_panel_done_drop.py(21 条,走真实浮层点击):
修复前 **16 通过 / 5 失败**(⑥⑦⑧⑬⑭)→ 修复后 **21 / 0**
- 注入反证 _b38_falsify.py:把删行那两行用 if(false) 挡掉,锚点断言 count==1,
立刻红回同样的 5 条、关键条目 ⑥⑧⑬⑭ 命中 4/4,副本自动还原
- 原 _b37_home_task_drop.py(复选框路径)仍 **20 / 0**
- _b37_regress.py **11 / 0**:看板仍改状态且**不删行**、详情页子任务复选框正常、
空态 display 真的是 none
- home.php 内联 JS 0 块坏;app.js / task_panel.js node --check 全过
|
2026-10-28 18:29:59 +08:00 |
|
laoyang
|
ea6e42c27f
|
fix(home): 近期任务勾选完成后该行不消失(连概述卡计数也不减)(#20)
用户原话:「首页,近期任务,如果勾选了完成,应该刷新一下这个列表,把完成的删掉。」
## 原来的行为
首页那段复选框脚本 AJAX 成功后只改徽章文字(`kb-st` → 「已完成」),
**没有任何"移除这一行"的逻辑**。而且 templates/home.php:160 那条注释还写着
这是**当年的刻意设计**:
> ⚠️ 改完**不摘掉这一行**:用户点完正想看自己刚完成什么,立刻消失会让人怀疑
> "是不是点到删除了"。刷新时由服务端决定它还在不在。
用户现在明确推翻这条:完成的就该从列表里删掉。
## 服务端本身是对的
首页路由只取 `doing` + `todo`(index.php:839),`done` 本来就不在列表里
⇒ 手动刷新这一行确实会消失,问题纯粹在"AJAX 完成后前端没同步"。
所以这次一行服务端代码都不用改。
## 改法
新增 `dropTaskRow(row, wasStatus)`,AJAX 成功后(**按服务端返回的 `d.status` 判断**,
不是拿点击前的 `next`)做三件事:
1. **删掉这一行**;
2. **同步「概述」卡右下的「N 件在做 / N 件待办」** —— 那两个数字与这份列表
**同源**(同一个 `$tasks`,见 _card_brief.php:53),只删行不减去数字
⇒ 列表 2 条、概述说 3 件在做,自相矛盾;
3. **一条不剩时把空态提示露出来**(服务端渲染的 `[data-tk-empty]` 原来一直 hidden)
—— 否则卡片变成一片空白,用户以为加载坏了。
配套的小改动:
- `_card_tasks.php`:空态提示改成**一直渲染、靠 `hidden` 切换**,加 `data-tk-empty`
钩子(不靠匹配文案 —— 文案改一个字就失效)。外层加 `data-tk-home-host`。
- `_card_brief.php`:两个统计 `<a>` 加 `data-hbs="doing|todo"` 钩子,
同样**不靠中文文案定位**(这是 JS 要读的东西,不能把展示文案变成接口)。
- `app.css`:补 `.empty-hint[hidden] { display: none !important; }` ——
浏览器默认的 `[hidden]{display:none}` 优先级最低,哪天有人给它加 `display:flex`
这句提示就会在"有任务时"也冒出来(与 app.css:601 那条注释是同一约定)。
## 几个判据上的讲究
- **按 `d.status` 判断而不是 `next`**:`tasks/status` 是幂等接口,
拿服务端返回的状态才不会"手快连点两下,第二下把行删了"。
- **`wasStatus` 要在改 `data-tk-status` 之前存**:删行时要靠它决定减「在做」还是「待办」。
第一版直接在删行时读 `data-tk-status`,读到的已经是 `done` —— 自己写的时候就踩了。
- **提示文案补一句"已从近期任务移出,去「全部」里能看到"**:
删行的原罪是"用户以为点到删除了",所以必须**明说它去哪了**,
而不是沿用服务端那句「已标成「已完成」」(那会让人以为行还在,下一眼发现没了更慌)。
## 验证
**主判据 `_tooling/_b37_home_task_drop.py` —— 20 通过 / 0 失败**
夹具:把库里历史 doing/todo 任务临时改状态腾空卡片(**不能靠 `deleted_at`** ——
`Task::byStatus()` 的 SQL 里根本没有 `deleted_at IS NULL`,软删对首页无效,实测过),
造 2 条 doing + 1 条 todo,跑完逐个恢复。
覆盖:勾「进行中」→ 行移除 + 「件在做」2→1 + 「件待办」不误减;
勾「待办」→ 行移除 + 「件待办」1→0 且链接藏起;
删到最后一条 → 0 行 + 空态露出;刷新后与服务端事实一致;库里状态真的是 done。
**注入反证 `_tooling/_b37_falsify.py` —— 三次独立注入,各自红在对应处**
| 注入 | 结果 | 命中的判据 |
|---|---|---|
| ① 不删行(原始 bug) | 通过 12 / **失败 8** | ③④⑤⑪⑭⑮ |
| ② 删行但不减概述卡计数 | 通过 17 / **失败 3** | ⑤⑫⑯ |
| ③ 不限空态(删完一片空白) | 通过 19 / **失败 1** | ⑮ |
每次注入前断言锚点唯一(#474),恢复后回到 20/0。
**回归 `_tooling/_b37_regress.py` —— 11 通过 / 0 失败**
看板勾选仍能改状态且**不删行**(与首页行为不同是有意的)、
详情页子任务复选框仍能改状态、`[hidden]` 的 `display` 真的是 `none`、
`data-hbs` 钩子在、卡片「全部」入口仍指向 tasks。
⚠️ 回归里踩了一个判据假设错:我一开始按"详情页也该有父任务复选框"写,
直接 FAIL。真实情况是详情页的复选框**只给子任务**(show.php:181 在子任务循环里),
父任务没有 —— 是判据错了不是产品坏了(#429 同族)。
**内联 JS 校验 `_tooling/_b37_inline_js_check.py`**:把渲染后 HTML 的 `<script>`
抽出来逐个 `node --check`(`php -l` 不看 HTML 里的 JS)。
并做了反证:喂一段坏 JS,它确实报 1 块坏,不是恒绿。
工单 #20
|
2026-10-28 18:13:49 +08:00 |
|
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 |
|
laoyang
|
9a66068c33
|
v62:纪念日列表修正 / 分类图标与设置菜单 / 首页卡片体系
- 纪念日列表:display:flex 从 td 移到内层 div(写在 td 上会破坏表格列算法,
表现为关联人列与其它列高度不一致);行内列序按表头对齐;
改完再点「新建」不再带出上次修改的数据;文案改为「与我相关」「来自名册」;
别人记的、把我挂成关联人的条目一并显示(split() 返回 hiddenIds,
路由层据此过滤「接下来的日子」,与两张表同一套可见性)
- 分类图标:新增 app/AnnivIcon.php(17 个行内 SVG 图标 + 同 key 的 emoji
供日历纯文本处使用,内网无 CDN 不用 FontAwesome);去掉「看日历」按钮;
设置按钮改为菜单,第一项进 days/settings 独立页;分类可自选图标,
列表徽标与日历条目都按分类显示
- 首页卡片:新增 app/HomeCards.php 与 templates/home_cards.php;
8 格宽 × 高 2/4/6/8;首页拆成 templates/home/_card_*.php 共 8 个片段;
home/cards 可改尺寸、调顺序、开关
|
2026-10-19 12:51:17 +08:00 |
|