ooodc a7883dbed9 refactor(todo): 重构待办事项管理逻辑及更新状态规则
- 移除 TodoItem 中的 priority、created_at 和 updated_at 字段
- 强制每个任务都必须有唯一 id,且由用户负责生成
- 修改合并模式逻辑,merge=true 下保留未提及的旧任务
- 支持已完成和已取消任务重新激活(状态改回 pending 或 in_progress)
- 禁止 in_progress 状态退回到 pending,必须标记为 completed 或 cancelled
- 优化状态转换校验,允许特定状态间合法切换
- 简化任务变更消息,移除详细的新增/更新/移除统计
- 更新文档和示例,明确 id 必须由用户生成和使用
- 修复和补充测试,增强状态转换和合并模式验证
- 调整任务时间戳生成逻辑,统一使用当前时间及索引
- 该变更提供更合理的任务状态机械及管理模式,提升稳定性和易用性
2026-06-13 09:22:33 +08:00

136 lines
7.4 KiB
Markdown
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.

# 对比图 / 矩阵图
适用于:方案对比、功能矩阵、技术选型等多选项按多维度比较的场景。
## Content 约束
- **每格内容要充实**:不要只写一个关键词,给出具体说明(如"MVCC 多版本并发控制,支持行级锁"而非仅"支持"
- 单格内容不同格子允许不同长度,但每格不超过 5 行
- 长文本(超过 15 字)用 `textAlign: "left"`(不要居中)
- 第一行是标题行(对象名称),第一列是维度标签列
- 维度数量至少 4 个,充分展开对比维度
## Layout 选型
| 模式 | 适用条件 | 特征 |
|------|---------|------|
| **严格 grid默认** | 所有对比场景 | 表头行 + 数据行,每行 horizontal frame行内 rect 等分 |
| **卡片式对比(替代)** | 维度较少2-3 个) | 每个对象做一张独立卡片,卡片内纵向列出各维度。卡片横向等分:外层 `layout: "horizontal"`,每张卡片 `width: "fill-container"` |
## Layout 规则
- 最外层 frame`layout: "vertical"`,固定 `width`(如 1000`height: "fit-content"`
- 每行horizontal frame`width: "fill-container"``alignItems: "stretch"`
- 行内单元格全部 `width: "fill-container"` 等分列宽
- 行间 `gap >= 12`(不要 8太紧
- 行内列间 `gap: 8-12`
- 标题行:深色底白字(由 style 控制具体颜色)
- 每列同色边框保持视觉一致性
- 单元格 `height: "fit-content"`,不要写固定 height
## 骨架示例
### 3 列 4 行表格
```json
{
"version": 2,
"nodes": [
{
"type": "frame",
"width": 1000,
"height": "fit-content",
"layout": "vertical",
"gap": 12,
"padding": 0,
"children": [
{
"type": "text",
"id": "title",
"width": "fill-container",
"height": "fit-content",
"text": "[对比图标题]",
"fontSize": 24,
"textAlign": "center",
"verticalAlign": "middle"
},
{
"type": "frame",
"id": "header-row",
"width": "fill-container",
"height": "fit-content",
"layout": "horizontal",
"gap": 8,
"padding": 0,
"alignItems": "stretch",
"children": [
{ "type": "rect", "id": "h-dim", "width": "fill-container", "height": "fit-content", "text": "[维度]", "fontSize": 15, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 0, "borderWidth": 2 },
{ "type": "rect", "id": "h-col-1", "width": "fill-container", "height": "fit-content", "text": "[对象A]", "fontSize": 15, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "h-col-2", "width": "fill-container", "height": "fit-content", "text": "[对象B]", "fontSize": 15, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "h-col-3", "width": "fill-container", "height": "fit-content", "text": "[对象C]", "fontSize": 15, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 }
]
},
{
"type": "frame",
"id": "data-row-1",
"width": "fill-container",
"height": "fit-content",
"layout": "horizontal",
"gap": 8,
"padding": 0,
"alignItems": "stretch",
"children": [
{ "type": "rect", "id": "d1-dim", "width": "fill-container", "height": "fit-content", "text": "[维度1]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d1-c1", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d1-c2", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d1-c3", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 }
]
},
{
"type": "frame",
"id": "data-row-2",
"width": "fill-container",
"height": "fit-content",
"layout": "horizontal",
"gap": 8,
"padding": 0,
"alignItems": "stretch",
"children": [
{ "type": "rect", "id": "d2-dim", "width": "fill-container", "height": "fit-content", "text": "[维度2]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d2-c1", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d2-c2", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d2-c3", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 }
]
},
{
"type": "frame",
"id": "data-row-3",
"width": "fill-container",
"height": "fit-content",
"layout": "horizontal",
"gap": 8,
"padding": 0,
"alignItems": "stretch",
"children": [
{ "type": "rect", "id": "d3-dim", "width": "fill-container", "height": "fit-content", "text": "[维度3]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d3-c1", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d3-c2", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 },
{ "type": "rect", "id": "d3-c3", "width": "fill-container", "height": "fit-content", "text": "[...]", "fontSize": 14, "textAlign": "center", "verticalAlign": "middle", "borderRadius": 8, "borderWidth": 2 }
]
}
]
}
]
}
```
## 陷阱
- **行间距 8px 太紧**:行间 gap 至少 128 会让行与行视觉粘连。
- **长文本居中对齐**:超过一行的文本应改为 `textAlign: "left"`,居中多行文本可读性差。
- **列数太多导致每列太窄**:对比对象建议 ≤ 5 列(含维度列),超过时合并维度或拆分为多张表。
- **列宽不等**:所有数据列必须用 `width: "fill-container"` 等分,不要给某列写固定宽度。
- **行高不等**:每行 frame 必须 `alignItems: "stretch"`,否则同行单元格因文字行数不同高矮不齐。
- **忘记维度标签列**:第一列放维度名称,标题行(维度列)用与数据列不同的视觉处理。
- **单元格用固定 height**:单元格必须 `height: "fit-content"`,固定高度会导致文字截断。