OpenProject 组合管理(Portfolio Management)实战指南:从战略分组到领导层汇报
【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject
本指南基于 OpenProject 官方使用案例文档(docs/use-cases/portfolio-management/README.md)整理并补充源码级实现细节,帮助你在多项目并行时建立跨项目、跨计划的战略级视图,用结构化数据汇报替代手工汇总的电子表格。
导读
当组织内同时运行数十个甚至上百个项目时,项目状态分散在各处,管理者很难看清全局。OpenProject 的组合管理(Portfolio Management)通过 Portfolios 模块将相关的**计划(Program)与项目(Project)**聚合到顶层工作区中,提供聚合状态、进度与风险的宏观视图。读完本文,你将掌握:如何启用并导航 Portfolios 模块、如何构建组合层级、如何利用过滤器和保存视图进行汇报,以及如何用项目列表、甘特图、Wiki 等互补功能完善你的汇报体系。
[!NOTE] 本指南假定你使用的是启用了 Portfolios 企业版插件(Enterprise add-on)的 OpenProject(Enterprise Cloud 或 Enterprise on-premises),并且拥有查看和管理组合的权限。
一、为什么需要组合管理:从混乱到战略清晰
当多个项目同时运行时,通常会遇到三类典型问题:
- 缺乏单一事实来源:状态和进度分散在各自的看板、表格或邮件中,没有统一口径;
- 汇报手工化、不一致且滞后:执行层汇报靠人工汇总电子表格,耗时且容易过期;
- 难以聚焦战略信号:管理者真正关心的是风险、时间线和整体进展等战略信号,而非具体操作细节。
OpenProject 的组合管理正是针对这些问题设计:把相关的计划与项目分组到顶层工作区(Portfolio)中,提供高层级概览。组合是特殊的 workspace,具备以下能力:
- 将多个计划与项目组合进一个战略层级结构;
- 跨工作区追踪聚合状态与进度;
- 使用过滤器和可自定义视图进行汇报;
- 在需要时,用项目级列表与导出功能进行补充。
二、分步指南:四步搭建你的组合管理体系
1. 导航到组合总览页
从左侧菜单或全局模块菜单中点击Portfolios进入组合总览页。
总览页会列出你有权访问的全部组合。页面核心元素包括:
- 左侧的预定义组合过滤器(见下文"过滤器"小节);
- 居中的搜索栏,可按名称快速查找组合;
- 搜索栏旁的Filters按钮,可基于状态、项目属性、项目生命周期阶段等属性进一步过滤;
- 右上角的More options(三个点)菜单,内含Zen mode(专注模式)开关;
- + Portfolio按钮,用于创建新组合;
- 组合列表,每个组合以独立卡片展示。
每个组合卡片包含以下信息:
- 组合名称
- 组合状态(可直接编辑)
- 组合描述
- 状态条(Status bar):聚合展示子项(计划与项目)的状态分布:
- 子项按状态分组并可视化在状态条中;
- 悬停状态条可查看详细的状态分布明细;
- 若组合没有子项或子项均未设置状态,状态条显示为空;
- 收藏指示器(星标图标),可标记/取消收藏;
- 计划与项目数量:统计以该组合为根节点的整个层级中的全部计划与项目。例如在
Portfolio A → Program B → Project C → Project D → Project E结构中,计数为1 个计划、3 个项目; - 最后更新时间。
2. 结构化你的组合:计划、项目与层级规则
进入组合后,你可以添加两种子项:
- 计划(Program):按共同战略目标或业务目标聚合相关项目的工作区,可以独立存在,也可以包含项目;
- 项目(Project):团队在其中规划、跟踪和执行日常工作的工作区。
一个组合可以只包含计划、只包含项目,或者两者混合,具体结构应反映你的战略优先级。下面是一个"组合包含计划、计划再包含项目"的典型示例:
组合、计划、项目:workspace 三种类型的定位
在 OpenProject 中,项目、计划和组合都属于workspace(工作区),共享成员、权限、状态、描述等公共属性,但定位不同:
| 类型 | 定位 |
|---|---|
| 项目(Project) | 用于执行日常工作 |
| 计划(Program) | 聚合相关项目 |
| 组合(Portfolio) | 跨多个计划与项目提供高层级概览 |
在源码层面,这一设计体现在 app/models/project.rb 的workspace_type枚举与父级约束中:
enum :workspace_type, { project: "project", program: "program", portfolio: "portfolio" }, validate: true ALLOWED_PARENT_WORKSPACE_TYPES = { project: %i[portfolio program project], program: %i[portfolio], portfolio: %i[] }.with_indifferent_access层级与组合规则
为防止出现无效或混乱的工作区结构,OpenProject 对父子关系做了如下硬性约束(与上述源码常量一一对应):
- 组合不能有父级,始终位于最顶层;
- 计划可以以组合为父级,也可以没有父级——这支持"自下而上"的组合管理:先有计划,之后再定义组合;
- 项目可以以组合、计划或另一个项目为父级;
- 计划与项目可以处于组合内的同一层级;
- 计划可以包含项目,但不强制;
- 一个组合可以:只包含计划、只包含项目、或两者混合。
一个组合在技术上也可以为空、作为独立 workspace 存在,但文档建议:若无需聚合子项,直接用项目即可满足需求。
四种常见组合结构示例
- 示例 1:含多个计划与项目的组合:Portfolio A 下挂 Program A.1(内含 Project A.1.1、A.1.2…)、Program A.2、Program A.3;
- 示例 2:计划与独立项目混合:Portfolio X 下挂 Program Y(含 Project Y.1)、Program Z(含 Project Z.1),以及独立项目 Project O、Project I;
- 示例 3:只含计划的组合:Portfolio D 下挂 Program D1、D2、D3;
- 示例 4:只含项目的组合:Portfolio 123 下挂 Project 1、2、3。
更多层级细节可阅读 用户指南:组合(Portfolios)。
3. 管理组合子项:Subitems 组件
组合首页的Subitems(子项)组件用于维护组合中包含的计划与项目。它与项目页的同类组件最大的区别在于:可以同时添加计划(program)和项目(project)两种子项。
在实现层面,子项管理由 app/controllers/projects/settings/subitems_controller.rb 支撑:更新操作会分别处理project_template与program_template两类参数(对应子项的"项目模板"与"计划模板"指派),保存后跳回子项设置页。建议定期审视并调整组合结构,确保战略概览与组织变化保持同步。
4. 使用过滤器与保存视图
为聚焦相关信息,你可以在组合总览上配置视图并应用过滤器,常见维度包括:
- 状态(Status)
- 干系人(Stakeholders)
- 时间线指标(Timeline indicators)
- 自定义属性(Custom attributes)
预定义过滤器的源码实现
组合总览左侧的预定义过滤器由 app/models/project_queries/static.rb 定义,四类组合专属过滤器为:
| 过滤器 | 常量 | 底层查询 |
|---|---|---|
| Active portfolios(进行中的组合) | ACTIVE_PORTFOLIOS | active = true |
| My portfolios(我的组合) | MY_PORTFOLIOS | member_of = true(你是成员) |
| Favorite portfolios(收藏的组合) | FAVORITED_PORTFOLIOS | favorited = true |
| Archived portfolios(已归档的组合) | ARCHIVED_PORTFOLIOS | active = false |
默认视图为"进行中的组合"。所有静态查询都基于ProjectQuery构建,并按层级字段lft升序排列,以保证树形结构的展示顺序。
聚合状态条的源码原理
组合卡片上的状态条并非手工填报,而是实时聚合计算而来。相关逻辑位于 app/components/portfolios/details_component.rb:
def all_descendants @all_descendants ||= portfolio .descendants .where(workspace_type: %w[project program]) .visible end def sub_statuses @sub_statuses ||= all_descendants .reorder(:status_code) .pluck(:status_code) .tally end即:取组合的全部后代(仅project与program类型且当前用户可见),按status_code统计计数,再计算各状态占比(count.fdiv(total) * 100,见 details_component.rb)。若没有任何子项设置状态,状态条会以not_set占满 100%。组合总览页则通过 app/components/portfolios/index_component.rb 将查询结果与用户收藏状态(with_favorited_by_user)合并渲染。
三、互补的组合管理功能:让汇报体系更完整
除了 Portfolios 模块本身,OpenProject 还提供一系列可增强组合管理与汇报的能力:
- 项目列表(Project lists):创建全组织范围、可过滤的项目总览,调整列、按状态或负责人排序、保存视图,并可共享或导出用于干系人汇报;
- 甘特图(Gantt charts):在共享时间轴上打开多个项目,可视化里程碑、重叠与依赖关系,支撑跨项目时间线讨论;
- 导出选项:将工作包表格或甘特图导出为 PDF、XLS 或 CSV 用于正式汇报,参见导出工作包与打印甘特图;
- Wiki 模块:构建结构化组合报告,嵌入工作包表格、宏与动态计算,可为不同举措创建汇报中枢或仪表盘;
- 全局工作包视图:跨项目分析工作包,识别逾期的里程碑、高优先级事项或影响组合的跨项目风险。
从代码结构看,组合功能的后端由 app/controllers/portfolios_controller.rb 承载——它继承自ProjectsController(组合多数行为与项目一致),但通过before_action设置默认查询并渲染全局布局(layout: "global"),同时以 Turbo Stream 响应过滤器变更、侧边菜单刷新与页面状态更新;组合的菜单入口则定义于 app/menus/portfolios/menu.rb。
四、成果:把战略讨论从"收集数据"拉回"聚焦优先级"
将 Portfolios 模块与结构化汇报能力结合后,你就在操作层项目之上建立了一层清晰的治理层(governance layer):
- 不再手工汇总信息,而是依赖实时的组合数据、一致的状态结构和可复用的汇报视图;
- 战略讨论聚焦于优先级与风险,而非数据收集;
- 能够支撑增长管理、确保举措与组织目标对齐,并在整个项目全景中保持透明。
组合本身支持像项目一样编辑、复制、设为公开、用作模板和删除(详见项目指南);唯一的差异是组合首页的Subitems组件可以同时添加计划与项目。若你想深入了解组合的结构规则、示例层级与过滤器细节,可继续阅读 用户指南:组合(Portfolios) 以及本使用案例的完整文档 docs/use-cases/portfolio-management/README.md。
【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考