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

3.9 KiB
Raw Blame History

金字塔图 (Pyramid)

Content 约束

  • 层级 3-6 个,从底到顶宽度递减
  • 每层一个短标签(如关键词或短语)
  • 长文案外置到金字塔旁边,图形内仅保留核心短文案

Layout 选型

vertical frame + 每层宽度递减。gap 4px 保持紧密。

Layout 规则

  • 外层 frame 使用 layout: "vertical" + alignItems: "center"
  • 所有层必须使用脚本计算宽度,以保证绝对完美的等斜率(直线边缘)。切勿手写拍脑袋的宽度!
  • children 数组中第一个元素是顶层(最窄),最后一个是底层(最宽)。
  • 顶层通常用 triangletopWidth: 0),中间和底层用 trapezoid
  • gap 通常设为 4px 保持紧密的金字塔感。

严格的斜率算法(必须在脚本中实现) 要让金字塔的侧边形成一条完美的直线,宽度的增量必须与高度和 gap 严格挂钩

  1. 设定整体宽度扩张系数 angleK(建议值 1.5 到 2.5表示高度每增加1px总宽度增加的像素数
  2. 当前层的底宽公式:width = topWidth + (height * angleK)
  3. 下一层的顶宽公式(必须考虑 gap 带来的额外外扩):nextTopWidth = width + (gap * angleK)

脚本构建模板

必须使用 node 运行脚本生成 JSON。

const fs = require('fs');

// 1. 配置基础参数
const GAP = 4;
const ANGLE_K = 2; // 斜率系数高度每增加1px宽度增加2px
const LAYER_HEIGHT = 80;

const data = [
  { text: "顶层核心", fillColor: "#1F2329", textColor: "#FFFFFF" },
  { text: "中间层 B", fillColor: "#DFF5E5", textColor: "#1F2329" },
  { text: "中间层 A", fillColor: "#EAE2FE", textColor: "#1F2329" },
  { text: "最底层基础", fillColor: "#F0F4FC", textColor: "#1F2329" }
];

let currentTopWidth = 0; // 顶层如果是尖角,初始为 0
const children = data.map((layer, index) => {
  // 2. 根据公式计算当前层的底宽
  const currentBottomWidth = currentTopWidth + (LAYER_HEIGHT * ANGLE_K);
  
  const node = {
    type: currentTopWidth === 0 ? "triangle" : "trapezoid",
    width: currentBottomWidth,
    topWidth: currentTopWidth,
    height: LAYER_HEIGHT,
    text: layer.text,
    textAlign: "center",
    fillColor: layer.fillColor,
    borderColor: layer.fillColor,
    borderWidth: 2,
    fontSize: 16,
    textColor: layer.textColor
  };

  // 3. 关键:计算下一层的顶宽。必须把 gap 的延伸也算进去!
  currentTopWidth = currentBottomWidth + (GAP * ANGLE_K);
  
  return node;
});

const output = {
  version: 2,
  nodes: [
    {
      type: "frame",
      layout: "vertical",
      alignItems: "center",
      gap: GAP,
      padding: 40,
      children: children
    }
  ]
};

fs.writeFileSync('diagram.json', JSON.stringify(output, null, 2));

陷阱

  • 不要手写随意递增的宽度:这会导致金字塔侧边变成折线,不直。必须严格使用上述 angleK 公式计算。
  • 忘记计算 gap 带来的扩展:如果下一层的 topWidth 只是简单等于上一层的 width,在有 gap 的情况下,衔接处会产生锯齿折角。必须加上 gap * angleK
  • 从上到下排列错误children 数组第一个是顶层(最窄),最后一个是底层(最宽),宽度依次递增。
  • 文字溢出顶层三角形:顶层三角形内部可用空间极小。短文案用 \n 手动换行;长文案外置到金字塔旁边(外层套 horizontal frame金字塔左侧说明文字右侧
  • 倒金字塔误用:如果用户要求"倒金字塔"、"漏斗图"或"自上而下递减的结构"不要使用本文件,切换到 scenes/funnel.md

扩展

  • 辅助说明:需要在旁边添加文字说明时,在最外层套一个 layout: "horizontal" 的 frame金字塔放左侧说明文字vertical 排列的 text 节点)放右侧
  • 配色:各层颜色应从色板中选取不同颜色以示区分(如蓝→紫→绿→黄递进)