个人 OKR 与执行进度可视化设计
目标
修复“我的 OKR”和“执行进度”无法稳定继承当前周期、执行进度页在缺少 periodId 时完全不调用接口的问题,并按 Open Design 参考图实现个人 OKR 的核心进度可视化。
范围边界
- “我的 OKR”和“执行进度”只展示当前登录人的全部 Objective 与 KR。
- 团队成员的 OKR 和执行进度继续从“团队 OKR”进入,不混入个人执行页。
admin 等没有参与周期或没有个人 OKR 的系统账号显示明确空态,不伪造演示数据。
- 不改变现有 OKR 创建、审核、进度更新和团队查看权限模型。
根因
- 侧边栏使用固定路径
/okr/my 与 /okr/execution,没有携带顶部当前周期。
OkrExecutionView.fetchData() 仅在 route.query.periodId 存在时请求数据;缺少参数时直接结束,所以没有网络请求。
- “我的 OKR”自行选择周期,与工作台顶部当前周期不是同一数据源,并把请求异常转换为空数组。
- 执行图受
timelineItems.length 控制,数据链路未启动时整个核心区域消失。
- 当前 execution-timeline 后端会混入直属下属 OKR,不符合已确认的个人页面范围。
数据流设计
workspace.periodId 是当前周期的唯一来源,URL 查询参数是可分享、可刷新恢复的外部表示。
- 侧边栏导航到周期相关页面时自动附加当前
periodId。
- 页面优先读取 URL
periodId;缺失时等待工作台加载推荐周期并补写 URL,然后加载数据。
- 周期切换后页面监听
periodId 变化并重新请求,防止只在 onMounted 调用一次。
- “我的 OKR”调用
getMyOkrSet(periodId);“执行进度”调用 getMyOkrSet(periodId) 和个人版 execution-timeline。
- 页面分别呈现加载、接口错误、未选周期、当前账号无 OKR 四种状态,不再静默吞错。
接口设计
- 保留
GET /api/okr/period/{periodId}/my-set,返回当前用户的全部 Objective。
- 调整
GET /api/okr/period/{periodId}/execution-timeline 为仅返回当前用户的 KR 时间线。
- 时间线每条 KR 至少返回:Objective 信息、KR 标识与标题、当前值、目标值、单位、状态、开始日期、截止日期、进度更新历史。
- 前端统一使用
src/api/index.js 的 okrApi,避免两个 axios 客户端造成返回结构认知不一致。
页面设计
我的 OKR
- 按 Objective 分组展示,支持多个目标。
- Objective 卡片使用医梦深紫主边和浅青强调边,标题、说明、权重建立清晰层级。
- 每条 KR 显示编号、标题、当前值、目标值、单位、状态与横向进度条。
- 延迟或阻塞使用危险色,正常执行使用深紫或浅青;不使用深色容器嵌套浅色容器。
执行进度
- 顶部显示当前周期及整体完成度摘要。
- 主视图按 Objective 渲染复杂进度卡片,与参考图保持一致的信息密度和布局:Objective 标题与权重、KR 行、当前值、目标值、状态标签、彩色进度条。
- 每条 KR 提供“更新进度”入口,沿用现有
newValue/status/remark 契约。
- 第二层时间线展示计划区间、历史更新节点和阻塞/延期标记;没有历史记录时仍显示计划区间和当前进度,不隐藏整个视图。
测试与验收
- 前端契约测试:无 URL 周期时使用 workspace 周期;周期变化会重新加载;个人页调用
getMyOkrSet 与 getExecutionTimeline。
- API 客户端测试:返回结构统一解包。
- 后端服务测试:execution-timeline 不包含直属下属,只包含当前用户全部 Objective 的 KR。
- 集成测试:有 OKR 的用户返回非空 Objective 和时间线;无 OKR 的用户返回空集合而非异常。
- 浏览器验收:桌面端与用户截图并排比较,验证 Objective 卡片、KR 进度条、状态颜色、排版与更新入口;同时检查移动端无横向溢出。