sf-industry-commoncore-flexcard:OmniStudio FlexCard 创建与验证
专注于 Salesforce Industries FlexCard UI 组件的 OmniStudio 专家。生成可用于生产环境的 FlexCard 定义,通过声明式数据绑定、Integration Procedure 数据源、条件渲染和恰当的 SLDS 样式,展示一目了然的信息。所有 FlexCard 均依据涵盖 7 个类别的 130 分评分标准进行验证。
核心职责
- FlexCard 编写:设计并构建 FlexCard 定义,设置恰当的布局、状态和字段映射
- 数据源绑定:配置 Integration Procedure 数据源,确保字段映射正确并妥善处理错误
- 测试生成:针对多种数据状态(已填充、空、错误、多条记录)验证卡片
- 文档编写:提供可用于部署的文档,说明数据源沿袭和操作映射
文档索引
关键:编排顺序
FlexCard 位于 OmniStudio 技术栈的展示层。构建依赖上游组件的 FlexCard 之前,请确保这些组件已存在。
sf-industry-commoncore-omnistudio-analyze → sf-industry-commoncore-datamapper → sf-industry-commoncore-integration-procedure → sf-industry-commoncore-omniscript → sf-industry-commoncore-flexcard (you are here)
FlexCard 使用 Integration Procedure 中的数据,并可启动 OmniScript。请先构建数据层,再构建展示层。
重要见解
| 见解 | 详情 |
|---|
| 配置字段 | OmniUiCard 使用 DataSourceConfig 绑定数据源,并使用 PropertySetConfig 配置卡片布局、状态和操作。Core 命名空间中的 OmniUiCard 没有 Definition 字段。 |
| 数据源绑定 | 数据源绑定到 Integration Procedure 以获取实时数据;FlexCard 获取数据前,IP 必须处于激活状态并已部署 |
| 嵌入子卡片 | FlexCard 可将其他 FlexCard 嵌入为子卡片,从而创建采用共享或独立数据源的复合布局 |
| 启动 OmniScript | FlexCard 可通过操作按钮启动 OmniScript,并将卡片数据源中的上下文数据传递到 OmniScript 的输入中 |
| Designer 虚拟对象 | FlexCard Designer 使用 OmniFlexCardView 作为虚拟列表对象(/lightning/o/OmniFlexCardView/home),与存储卡片记录的 OmniUiCard sObject 分开。通过 API 创建的卡片,在 Designer 中打开之前可能不会显示在“最近查看”中。 |
工作流(5 阶段模式)
阶段 1:收集需求
开始构建之前,请与相关方确认以下事项:
| 问题 | 重要性 |
|---|
| 卡片的用途是什么? | 决定布局类型和数据密度 |
| 需要哪些数据源? | 确定所需的 Integration Procedure |
| 卡片在哪种对象上下文中运行? | 决定是按记录还是按列表显示 |
| 卡片应提供哪些操作? | 决定按钮/链接配置和 OmniScript 集成方式 |
| 哪种布局最适合此用例? | 单卡片、列表、选项卡式卡片或弹出卡片 |
| 是否有条件显示规则? | 哪些字段或区块会根据数据值显示或隐藏 |
阶段 2:设计与布局
卡片布局选项
| 布局类型 | 用例 | 描述 |
|---|
| 单卡片 | 记录摘要 | 显示单条记录字段的卡片 |
| 卡片列表 | 相关记录 | 绑定到数组数据源的重复卡片 |
| 选项卡式卡片 | 多上下文 | 在一张卡片中以选项卡形式显示多个状态 |
| 弹出卡片 | 按需查看详情 | 从摘要卡片触发的可展开详情面板 |
数据源配置
每个 FlexCard 数据源都会连接到一个 Integration Procedure(或其他源类型),并将响应字段映射到显示元素。
FlexCard → Data Source (type: IntegrationProcedure)
→ IP Name + Input Mapping
→ Response Field Mapping → Card Elements
- 使用
{datasource.fieldName} 合并语法,将 IP 响应字段映射到卡片显示元素
- 配置输入参数,将记录上下文(例如
{recordId})传递给 IP
- 多个数据源为同一张卡片提供数据时,设置数据源顺序
操作按钮设计
| 操作类型 | 用途 | 配置 |
|---|
| 启动 OmniScript | 启动引导流程 | OmniScript 类型 + 子类型,传递上下文参数 |
| 导航 | 前往记录或 URL | 记录 ID 或带合并字段的 URL 模板 |
| 自定义操作 | 平台事件、LWC 等 | 自定义操作处理程序及载荷映射 |
条件可见性
- 使用可见性条件,根据数据值显示或隐藏字段
- 根据数据源结果显示或隐藏整个卡片状态
- 数据源未返回记录时,显示空状态提示信息
第 3 阶段:生成与验证
- 生成 FlexCard 定义 JSON
- 验证所有数据源引用都指向有效的 Integration Procedure
- 执行 130 项评分标准检查(见下方“评分”部分)
- 验证合并字段语法与 IP 响应结构相符
- 检查所有交互元素的无障碍属性
第 4 阶段:部署
- 确保所有上游 Integration Procedure 均已部署并处于有效状态
- 部署 FlexCard 元数据(
OmniUiCard)
- 在目标 org 中激活 FlexCard
- 将 FlexCard 嵌入目标 Lightning 页面、OmniScript 或父 FlexCard 中
第 5 阶段:测试
针对多种数据场景测试每个 FlexCard:
| 场景 | 验证内容 |
|---|
| 数据已填充 | 所有字段均正确呈现,合并字段均已解析 |
| 数据为空 | 显示空状态提示信息,不出现无法解析的合并字段 |
| 错误状态 | IP 返回错误或超时时能妥善处理 |
| 多条记录 | 卡片列表呈现正确数量的项目,分页正常工作 |
| 操作按钮 | OmniScript 启动时包含正确的预填充数据 |
| 条件字段 | 可见性规则根据数据值正确切换 |
| 移动设备 | 卡片布局适应较小的视口宽度 |
生成规范
生成 FlexCard 定义时,避免以下模式:
| 反模式 | 错误原因 | 正确做法 |
|---|
| 引用不存在的 IP 数据源 | 卡片在运行时无法加载数据 | 绑定前确认 IP 存在且处于有效状态 |
| 在样式中硬编码颜色 | 破坏 SLDS 主题和深色模式 | 使用 SLDS 设计令牌和 CSS 自定义属性 |
| 缺少无障碍属性 | 不符合 WCAG 标准 | 添加 aria-label、role 和键盘处理程序 |
| 子卡片嵌套过多 | 深层嵌套会降低性能 | 嵌套最多保持 2 层;尽可能扁平化 |
| 忽略空状态 | 数据源未返回记录时 UI 会出现问题 | 配置明确的空状态提示信息 |
| 硬编码记录 ID | 卡片无法在不同环境中正常使用 | 使用合并字段和上下文驱动的参数 |
评分标准(130 分)
所有 FlexCards 均根据 7 个类别进行验证。阈值:✅ 90+(部署) | ⚠️ 67-89(审核) | ❌ <67(阻止 - 必须修复)
| 类别 | 分值 | 标准 |
|---|
| 设计与布局 | 25 | 布局类型合适、字段分组合理、响应式设计、间距一致、视觉层次清晰 |
| 数据绑定 | 20 | IP 引用正确、合并字段语法正确、输入参数映射、多数据源协调 |
| 操作与导航 | 20 | 操作按钮配置正确、OmniScript 启动参数已映射、导航目标有效、操作标签描述清晰 |
| 样式 | 20 | 使用 SLDS 令牌(不硬编码颜色)、字体排版一致、正确使用卡片/磁贴模式、兼容深色模式 |
| 无障碍访问 | 15 | 交互元素带有 aria-label、操作可通过键盘导航、颜色对比度充足、字段标签便于屏幕阅读器识别 |
| 测试 | 15 | 已使用有数据、空状态、错误状态、多记录场景和移动视口进行验证 |
| 性能 | 15 | 尽量减少数据源调用、限制子卡片嵌套(最多 2 层)、无冗余 IP 调用、对不可见状态使用延迟加载 |
评分明细
设计与布局(25 分)
| 标准 | 分值 | 说明 |
|---|
| 布局类型符合使用场景 | 5 | 根据实际情况选择单项、列表、选项卡式或弹出式布局 |
| 字段分组合理 | 5 | 相关字段在视觉上归为一组 |
| 响应式行为 | 5 | 卡片可适应不同的视口宽度 |
| 间距一致 | 5 | 边距和内边距遵循 SLDS 间距比例 |
| 视觉层次 | 5 | 突出显示主要信息,弱化次要信息 |
数据绑定(20 分)
| 标准 | 分值 | 说明 |
|---|
| IP 引用有效 | 5 | 所有引用的 IP 均存在且处于活动状态 |
| 合并字段语法正确 | 5 | {datasource.field} 路径可解析为实际 IP 响应字段 |
| 输入参数已映射 | 5 | 记录上下文已正确传递到 IP 输入参数 |
| 多数据源协调 | 5 | 多个数据源按正确顺序加载,且不会发生冲突 |
操作与导航(20 分)
| 标准 | 分值 | 说明 |
|---|
| 操作按钮正常运行 | 5 | 所有按钮均会触发配置的操作 |
| OmniScript 参数已映射 | 5 | 上下文数据可正确传递到启动的 OmniScript |
| 导航目标有效 | 5 | 记录和 URL 导航均可正确解析 |
| 标签描述清晰 | 5 | 操作标签能清楚说明操作内容 |
样式(20 分)
| 标准 | 分值 | 说明 |
|---|
| 使用 SLDS 令牌 | 5 | 通过设计令牌设置颜色、字体和间距 |
| 字体排版一致 | 5 | 文本大小遵循 SLDS 字体比例 |
| 符合卡片模式规范 | 5 | 使用标准 SLDS 卡片或磁贴模式 |
| 兼容深色模式 | 5 | 不硬编码颜色;兼容 SLDS 深色主题 |
无障碍访问(15 分)
| 标准 | 分值 | 说明 |
|---|
| 交互元素带有 ARIA 标签 | 5 | 按钮、链接和输入框均具有无障碍名称 |
| 支持键盘导航 | 5 | 所有操作均可通过 Tab 键访问,并通过 Enter/Space 键触发 |
| 颜色对比度充足 | 5 | 符合 WCAG 2.1 AA 对比度要求(文本为 4.5:1) |
测试(15 分)
| 标准 | 分值 | 说明 |
|---|
| 已验证有数据的情况 | 3 | 卡片在数据完整时可正确呈现 |
| 已验证空状态 | 3 | 空状态消息可正常显示 |
| 已验证错误状态 | 3 | 可妥善处理 IP 错误 |
| 已验证多记录情况 | 3 | 卡片列表可正确呈现各项 |
| 已验证移动视口 | 3 | 布局可适应小屏幕 |
性能(15 分)
| 标准 | 分值 | 说明 |
|---|
| 尽量减少数据源调用 | 5 | 不重复或冗余调用 IP |
| 限制子卡片嵌套 | 5 | 子卡片最多嵌套 2 层 |
| 隐藏状态下延迟加载 | 5 | 不可见的选项卡/弹出层按需加载 |
CLI 命令
# Query active FlexCards in the org
sf data query -q "SELECT Id,Name,DataSourceConfig,PropertySetConfig,IsActive FROM OmniUiCard WHERE IsActive=true" -o <org>
# Retrieve a specific FlexCard by name
sf project retrieve start -m OmniUiCard:<Name> -o <org>
# Deploy a FlexCard to the target org
sf project deploy start -m OmniUiCard:<Name> -o <org>
# Retrieve all FlexCards
sf project retrieve start -m OmniUiCard -o <org>
# Deploy all OmniStudio metadata (FlexCards + dependencies)
sf project deploy start -m OmniUiCard -m OmniIntegrationProcedure -m OmniScript -o <org>
数据源绑定
FlexCard 数据源配置
OmniUiCard 上的 DataSourceConfig 字段以 JSON 格式包含数据源绑定。PropertySetConfig 字段包含卡片布局、状态和字段定义。
IMPORTANT:Core 命名空间中的 OmniUiCard 没有 Definition 字段。数据源请使用 DataSourceConfig,布局请使用 PropertySetConfig。
{
"dataSource": {
"type": "IntegrationProcedures",
"value": {
"ipMethod": "Type_SubType",
"vlocityAsync": false,
"inputMap": {
"recordId": "{recordId}"
},
"resultVar": ""
},
"orderBy": {
"name": "",
"isReverse": ""
},
"contextVariables": []
}
}
数据源类型
| 类型 | dataSource.type | 使用场景 |
|---|
| Integration Procedure | IntegrationProcedures(复数形式,P 大写) | 主要模式;调用 IP 获取实时数据 |
| SOQL | SOQL | 直接查询(谨慎使用;优先使用 IP 以实现抽象) |
| Apex Remote | ApexRemote | 调用自定义 Apex 类 |
| REST | REST | 通过 Named Credential 调用外部 API |
| Custom | Custom | 自定义数据提供程序(直接传递 JSON 请求体) |
IP 响应的字段映射
使用合并字段语法,将 IP 响应字段映射到卡片显示元素:
IP Response: FlexCard Merge Field:
───────────── ─────────────────────
{ "Name": "Acme Corp" } → {Name}
{ "Account": { → {Account.Name}
"Name": "Acme Corp"
}
}
{ "records": [ → {records[0].Name} (single)
{ "Name": "Acme" } or iterate with Card List layout
]
}
输入参数映射
将托管页面的上下文传递到 IP 数据源:
| 上下文变量 | 来源 | 示例 |
|---|
{recordId} | 当前记录页面 | 传递给 IP,以查询相关数据 |
{userId} | 当前运行用户 | 按当前用户筛选数据 |
{param.customKey} | URL 参数或父卡片 | 从父 FlexCard 或 URL 传递 |
跨技能集成
| 技能 | 与 sf-industry-commoncore-flexcard 的关系 |
|---|
| sf-industry-commoncore-integration-procedure | 构建 FlexCard 使用的 IP 数据源 |
| sf-industry-commoncore-omniscript | 构建由 FlexCard 操作按钮启动的 OmniScripts |
| sf-industry-commoncore-datamapper | 构建 IP 在底层使用的 DataRaptors/DataMappers |
| sf-industry-commoncore-omnistudio-analyze | 分析 FlexCard、IP 和 OmniScripts 之间的依赖链 |
| sf-deploy | 连同上游依赖项一起部署 FlexCard 元数据 |
| sf-lwc | 构建嵌入 FlexCard 的自定义 LWC 组件 |
边缘情况
| 场景 | 处理方式 |
|---|
| 数据为空 | 配置明确的空状态并显示友好提示;不要显示原始的“无数据”或空白卡片 |
| 错误状态 | IP 数据源失败时显示有意义的错误消息;记录错误以便调试 |
| 移动端响应式布局 | 移动端使用单列布局;避免水平滚动;在 320px 视口宽度下测试 |
| 长文本值 | 使用省略号截断,并提供弹出层或工具提示以显示完整文本 |
| 大型记录集 | 使用带分页的卡片列表;初始加载限制为 10-25 条记录 |
| 字段值为空 | 使用条件可见性隐藏值为空的字段,而不是显示空标签 |
| 数据新鲜度不一致 | 多个数据源的刷新频率不同时,显示“上次更新”指示器 |
FlexCard 与 LWC 决策指南
| 因素 | FlexCard | LWC |
|---|
| 构建方式 | 声明式(拖放) | 代码(JS、HTML、CSS) |
| 数据绑定 | Integration Procedure 合并字段 | Wire 服务、Apex、GraphQL |
| 最适合 | 一目了然的信息展示 | 复杂的交互式 UI |
| 测试 | 手动测试 + 数据状态验证 | Jest 单元测试 + 手动测试 |
| 自定义 | 受限于 OmniStudio 框架 | 充分利用平台灵活性 |
| 复用 | 嵌入为子卡片 | 导入为子组件 |
| 何时选择 | 使用 IP 数据的标准卡片布局 | 自定义行为、动画、复杂状态 |
依赖项
必需:目标组织拥有 OmniStudio(Industries Cloud)许可证,且 sf CLI 已完成身份验证
数据源:已部署到目标组织的有效 Integration Procedures
操作:已部署的有效 OmniScripts(如果操作按钮会启动 OmniScripts)
评分:如果评分 < 67,则阻止部署
以编程方式创建 FlexCards:使用 REST API(sf api request rest --method POST --body @file.json)。必填字段:Name、VersionNumber、OmniUiCardType(例如,Child)。设置 DataSourceConfig(JSON 字符串)以绑定数据源,设置 PropertySetConfig(JSON 字符串)以配置卡片布局。sf data create record --values 标志无法处理 textarea 字段中的 JSON。创建后,将 IsActive=true 以激活。
外部参考
许可证
MIT 许可证。
版权所有 (c) 2026 David Ryan (weytani)