v28 第 28 批(12 条):名册分组改标签 / 资源合并为两按钮 / 首页定位与主题色 / 笔记富文本双模式
其中 4 条是**上批遗漏的真 bug**(1/4/8/9),根因已逐条定位:
1. 首页日程没定位到红线 —— 真根因:刻度区间**不含当前时刻** → $showNow=false
→ 红线**整个不渲染**,而定位脚本用同一个越界比例算目标,被 clamp 到底部。
修:把当前小时并进区间端点(现在必然落在区间内)。
2. 「看整月」→「更多日程」+ 日程主题色;3. 「手头在做」→「近期任务」、
「任务看板」→「全部任务」+ 任务主题色(注入 --hd-c,不再写死白底)。
4. 任务复选框提示还在 —— 真根因:**JS 在点击后**给状态徽标挂 title
(`badge.setAttribute('title',…)`),上批只去了静态渲染,静态断言永远抓不到。
5. 名册「分组」→「标签」(用户:一个人可能既是小学同学又是初中同学,没法分组):
新增 person_tags(每人一份、一人多标签),名册改**平铺 + 顶部标签筛选**;
🔴 迁移用**一次性哨兵**(第一版用 NOT EXISTS,实测被"用户清空标签"绕过 → 旧分组名被灌回)。
6. 名册卡片按钮加语义底色。
7. 资源四按钮 → **编辑 / 删除**两颗:三块内容进一个带页签的弹框(信息/附件/共享)。
8. 财务多选数字不变 —— 真根因:前端发 `kinds=a,b`(逗号串),服务端 `(array)` 收成
单元素 → 求交为空 → **静默回落整本账**。修:两种形状都收。
9. 微信读书偶发很慢 —— 真根因:syncNow 扫 60 本 × 每本 1~3 次网关调用(单次超时 20s),
全同步阻塞在列表页请求里。修:总时长预算 + 单次超时 8s + 自动/手动分批。
10. 新增全局可见的联想接口库(6 个实测可用来源)+ 三种新解析类型。
11. 导航右上角「设置」:默认进"添加网址 + 全部网址",四类设置收进 ?set=1 视图。
12. 笔记:段落/清单支持 Markdown(自研渲染器,**不允许原始 HTML**),
实时预览走服务端(前后端只一份规则);底部附件上传;清单多级;
列表改**定尺寸卡片网格**(溢出显示摘要、图片缩放下方);按用户要求**去掉标签侧栏**。
This commit is contained in:
+29
-6
@@ -153,6 +153,20 @@ final class PersonRoster
|
||||
* @param array $columns [['g' => 分组id(0=未分类), 'ids' => [personId, ...]], ...]
|
||||
* @return int 实际写入的条数
|
||||
*/
|
||||
/**
|
||||
* 保存名册布局(拖动排序/改栏)。返回真正写了几条。
|
||||
*
|
||||
* 🔴 v28 用户第 5 条:名册**平铺**之后不再有"改栏"这回事(一个人挂多个标签,
|
||||
* 分栏会让他在多栏重复出现)。前端会把整个平铺列表当成"唯一一栏"(`g=0`)报上来。
|
||||
* ⚠️ 这时**绝对不能写 group_id**:
|
||||
* · `g=0` 按下面那条规则会被落成 NULL —— 拖一次就把所有人原有的分组清空了;
|
||||
* · 而 `person_roster.group_id` 正是"旧分组→同名标签"迁移的数据来源
|
||||
* (见 Schema 的迁移步骤),也不能被随手抹掉;
|
||||
* · 它同时还是 vCard CATEGORIES 的读点(导出通讯录要用)。
|
||||
* ⇒ 判据:`g` 缺省(前端没报这一栏的组号)时**只更新 sort_order**,
|
||||
* 完全不碰 group_id。这样"拖动只改顺序"这个新语义是结构上保证的,
|
||||
* 而不是靠调用方记得别传错值。
|
||||
*/
|
||||
public static function applyLayout(int $familyId, int $ownerId, array $columns): int
|
||||
{
|
||||
$mine = self::mine($familyId, $ownerId);
|
||||
@@ -161,7 +175,11 @@ final class PersonRoster
|
||||
}
|
||||
$okGroups = PersonGroup::visibleIds($familyId, $ownerId);
|
||||
$db = Database::get();
|
||||
$up = $db->prepare(
|
||||
$upSort = $db->prepare(
|
||||
'UPDATE person_roster SET sort_order = ?
|
||||
WHERE family_id = ? AND owner_id = ? AND person_id = ?'
|
||||
);
|
||||
$upBoth = $db->prepare(
|
||||
'UPDATE person_roster SET group_id = ?, sort_order = ?
|
||||
WHERE family_id = ? AND owner_id = ? AND person_id = ?'
|
||||
);
|
||||
@@ -171,10 +189,11 @@ final class PersonRoster
|
||||
if (!is_array($col)) {
|
||||
continue;
|
||||
}
|
||||
$gid = (int)($col['g'] ?? 0);
|
||||
// 分组不合法(别人家的私自分组 / 已删掉的分组)→ 落成未分类,绝不静默挂错
|
||||
if ($gid !== 0 && !isset($okGroups[$gid])) {
|
||||
$gid = 0;
|
||||
// 只有**显式带了组号**的栏才去动 group_id(见方法注释)
|
||||
$hasG = array_key_exists('g', $col);
|
||||
$gid = (int)($col['g'] ?? 0);
|
||||
if ($hasG && $gid !== 0 && !isset($okGroups[$gid])) {
|
||||
$gid = 0; // 别人家的私自分组 / 已删的分组 → 未分类,绝不静默挂错
|
||||
}
|
||||
foreach ((array)($col['ids'] ?? []) as $pid) {
|
||||
$pid = (int)$pid;
|
||||
@@ -182,7 +201,11 @@ final class PersonRoster
|
||||
continue; // 不在我名册里的人,忽略
|
||||
}
|
||||
$sort += 10;
|
||||
$up->execute([$gid ?: null, $sort, $familyId, $ownerId, $pid]);
|
||||
if ($hasG) {
|
||||
$upBoth->execute([$gid ?: null, $sort, $familyId, $ownerId, $pid]);
|
||||
} else {
|
||||
$upSort->execute([$sort, $familyId, $ownerId, $pid]);
|
||||
}
|
||||
$written++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user