mcpField
C
cpq-builder

cpq-builder

github.com/customware-ai开发21.2k 次安装1 天前更新
代码仓库

关于 cpq-builder

CPQ Builder 是用于构建原型的技能,帮助工具收集结构化输入、应用业务规则,并生成供审查或审批的交付物。它提供可适配不同领域的产品报价、计算器和信息收集流程模式。

主要功能

  1. 01直接编辑报价明细
  2. 02产品组合与可见约束规则
  3. 03透明展示折扣计算
  4. 04实时汇总与品牌报价输出
  5. 05审批路由与角色视图
  6. 06保存、加载、克隆和管理报价

适用场景

  1. 01替代基于电子表格的报价流程
  2. 02构建产品配置与定价工具
  3. 03制作资格或保险估算器
  4. 04原型化可审查的业务提案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/customware-ai/skills --skill cpq-builder

安装后在 Claude Code 中输入/cpq-builder确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
config-schema.md
example-config.json
vertical-presets.md

详细介绍

CPQ 构建技能

此技能的作用

此技能定义了构建 Configure-Price-Quote(配置、定价、报价)类工具的模式:用户配置输入项,系统应用规则计算结果,最终生成可能需要审核/批准的格式化交付物。

CPQ 并不局限于产品定价。相同的结构模式适用于:

领域“配置”“计算”“输出”
设备销售选择产品、挑选选项应用加价、计算总额销售报价 PDF
法律计算器输入案件详情(收入、期限)应用指导原则公式含估算值的摘要报告
保险估算器输入保障详情应用费率表保费估算文件
贷款资格审核输入财务详情应用贷款标准资格确认函
福利资格审核输入个人详情应用资格规则福利摘要
服务方案选择服务、设定范围应用人工费率服务方案

构建器会读取此技能,读取特定领域的 DOMAIN.md 以了解术语和规则,然后生成可用的原型。DOMAIN.md 决定工具是用于起重机报价还是离婚计算;此技能提供适用的结构模式。

此技能中的模式是默认方案,而非强制要求。 如果实际工作流偏离了标准 CPQ 结构——阶段较少、布局不同或输出不同——请调整这些模式。每个主要章节都会明确说明相应的偏差。


客户背景

Customware 的 CPQ 客户涵盖众多领域:工业设备经销商、定制服装和标牌店、食品/饮料批发商、专业服务公司(法律、咨询、设计)、IT 和托管服务提供商、建筑和工程企业、制造商、分销商。CPQ 模式适用于所有这些领域。

此技能中的示例会轮换使用多个领域——工业设备、服务、消费品、软件、定制商品。这是有意为之。这些模式不依赖特定领域;示例通过类比加以说明。应用此技能时,请忽略任一示例中的具体领域,提炼出其结构模式。构建时,DOMAIN.md 会决定具体的用语、产品、规则和角色。

“单梁起重机需要电机”这一规则,与“定制连帽衫需要选择印刷方式”或“托管服务合同需要选择服务等级”或“狗零食订单需要选择包装规格”的结构相同。这类规则的模式是“父级产品要求选择子级组件”。构建该模式;具体措辞由 DOMAIN.md 提供。

客户画像

Customware 的 CPQ 客户通常是成长中遇到瓶颈的中小型企业(5-50 名员工)。他们不是从其他 CPQ 系统迁移而来,而是从以下方式迁移:

  • 已经变得难以管理的 Excel 电子表格(多个选项卡、复制粘贴错误、公式失效)
  • 每次都要针对客户手动编辑的 Word 文档报价模板
  • 基于电子邮件的审批工作流:老板在回复所有人的邮件线程中批准报价
  • 关于哪些产品需要搭配哪些配件的经验知识,这些知识只存在于资深销售代表的脑海中
  • 手动输入价格,折扣不一致导致利润率不断缩水

原型的任务是让用户感觉比电子表格好得多,同时又不会复杂得像企业级软件。一个 5 年来一直用 Excel 报价的小团队看到原型后,应该立刻觉得“这快多了”,而不是“这看起来好复杂”。

这一定位会影响本技能中的每项设计决策:

  • 行内编辑明细行是主要比较点。Excel 用户希望能直接编辑表格。
  • 实时总计很重要。客户一直用公式计算,因此希望看到数字随着输入内容的变化而更新。
  • 角色权限限制令人印象深刻。客户从未见过通过软件强制执行“只有所有者才能批准超过 50K 的金额”这类规则——过去这只是口头规定,而且经常被违反。
  • 品牌化 PDF 输出令人印象深刻。客户以前一直在 Word 文档中手动调整格式。
  • 面向客户的门户、AI 建议、电子签名集成在这个阶段并不令人印象深刻。它们属于企业级复杂功能,解决的是客户目前尚未遇到的问题。

服务于那些厌倦了 Excel 公式失效的客户,而不是从 Salesforce 迁移来的客户。


这真的算 CPQ 吗?

在应用本技能中的任何模式之前,请先确认工作流确实符合 CPQ 特征。只有以下四项全部成立时,CPQ 模式才适用:

  1. 用户收集结构化输入,这些输入决定最终结果(配置选项、客户详情、需求、财务数据、案例详情)。
  2. 业务规则或计算逻辑会转换这些输入,生成交付物(加价公式、准则计算、费率表、资格规则)。
  3. 输入与最终确定之间存在审核或审批关卡,或者交付物需要经过某种利益相关方审核(准备者/审核者模式)。
  4. 工作成果看起来需要移交给他人——客户、内部利益相关方、监管机构或下游系统。

缺少标准 1 → 这是仪表板或展示工具,不是 CPQ。停止。 缺少标准 2 → 这是数据录入表单,不是 CPQ。停止。 缺少标准 3 → 这是“收集后交付”流程——应用 CPQ 模式,但跳过“审批”部分。 缺少标准 4 → 这是个人计算器/实用工具,不是 CPQ。停止。

常见误判:

  • “股票报价查看器”——虽然名称中有“报价”,但它是展示工具(缺少标准 1)
  • 没有审核步骤的“税务计算器”——这是实用工具,不是 CPQ(缺少标准 3 和 4)
  • 带有价格的“产品目录”——这是展示工具,不是 CPQ(缺少标准 2 和 3)
  • “反馈表单”——这是数据录入工具,不是 CPQ(缺少标准 2)

如果不满足这四项标准,请勿强行套用以下模式。请根据任务描述和 DOMAIN.md,改用 frontend-design 的原则进行构建。


领域类型

大多数 CPQ 工作流分为两种领域类型。应用模式之前,先确定构建属于哪种类型:

产品领域。 用户配置可销售的产品/服务。定价是核心计算。输出为报价文档,其中包含行项目、总计、税费和条款。示例:设备销售、定制服装订单、食品/消费品批发、服务方案(咨询投标、托管服务)、软件许可、定制包装。

计算器/信息采集领域。 用户输入案例/申请人详情。计算会应用指南/规则/费率表。输出为摘要报告,其中包含输入项、计算值和免责声明。示例:配偶赡养费计算器(Clarity Legal)、保险估算器、贷款资格评估、福利资格评估。

本技能中的模式适用于这两种领域。当某个章节或规则仅适用于特定领域时,本技能会明确说明。


最低标准

每个 CPQ 构建都必须符合 Tier 1 标准。当 DOMAIN.md 表明有此需求时,再构建 Tier 2 标准。Tier 3 功能会在完成摘要中作为未来工作提及,但不会在原型中构建。

Tier 1 — 不可妥协(适用于每个 CPQ 构建)

这些功能能让原型显著优于 Excel + Word。如果缺少任何一项,无论 UI 看起来多么整洁,构建都不完整。

1. 直接内联编辑行项目。 提供类似电子表格的表格,让用户添加行、编辑任意单元格,并实时查看总计更新。不能采用“配置表单 → 添加到报价 → 构建报价表格 → 编辑”的往返流程。行项目表格本身就是工作区。规范实现请参见下方的“章节模式”。

2. 套装/必需子产品采用合适的配置器模式。 当父产品需要子组件时(例如,“工业设备需要选择电机”“定制连帽衫需要选择印花方式”“托管服务合同需要选择等级”“狗零食订单需要选择包装规格”),配置父产品时就应包含子产品选择。行项目应将父产品和所选子产品显示为一个完整条目。绝不能拆成两个独立行项目,以免用户忘记选择子产品。对于包含 4 项以上配置属性或存在级联依赖的产品(典型的工业设备、定制商品和分级服务通常会深入 3-4 层),应采用合适的配置器模式——关于内联展开、侧边抽屉或整页的选择,请参见下方的“产品配置器模式”。

3. 明确展示约束规则。 DOMAIN.md 中的必需/排除/推荐规则必须向用户清晰可见,不能只在后台静默执行。用户添加起重机时,UI 应在用户保存之前显示“必须选择电机(BR-001)”。用户尝试添加不允许的组合时,UI 应显示相关规则及其原因。习惯使用 Excel 的客户从未经历过规则强制执行——让规则清晰可见,就体现了产品的一半价值。

4. 清晰展示折扣叠加计算。 应用折扣时,展示分层计算:

List Price:                  $15,000.00
Volume Discount (5%):           -$750.00
Promotional Discount (3%):      -$427.50
─────────────────────────────────────
Net Price:                   $13,822.50

每项折扣都应单独列出,计算过程一目了然。过去在没有审计记录的电子邮件往来中协商折扣的客户,需要清楚了解价格的具体计算过程。

5. 实时报价摘要。 用户编辑行项目时,小计、税费和总计等累计金额应实时更新。不应设置“点击计算”按钮。这是从 Excel 转来的客户感受最强烈的“惊艳时刻”——总计会自动更新。

6. 品牌化报价文档。 生成的 PDF/打印视图应包含客户徽标、行项目表、总计、条款及任何必需的免责声明。该文档取代手动排版的 Word 文档。质量标准:外观应达到真实企业会发送的报价水平。 7. 多层审批路由。 大多数中小企业工作流至少有 2 个审批级别(销售代表配置 → 经理审核 → 所有者批准)。即使是简单情况,也至少有一位审批人和一位最终签字人。原型必须展示基于角色的路由,并遵循 DOMAIN.md 的利益相关者关系图。路由通常会根据请求类型分支,例如,一家公司可能会将“自定义配置交由高级审核人审批,检查交由服务经理审批,维护交由运营经理审批,而所有路径的最终审批人都是所有者”。这种条件式多层路由是必备功能。

8. 多报价管理。 用户会同时处理多个报价。原型必须展示带状态指示器的报价列表,支持筛选和排序,并允许用户点击任意报价进行编辑。不能只有一个报价工作区,再加上一个“已保存报价”的侧边栏列表。

9. 保存/加载/克隆报价。 基于 localStorage 实现。用户可以创建新报价、保存报价、加载已保存的报价,并克隆现有报价以此为基础创建类似报价。Excel 用户会通过复制工作表来实现这一点;原型则提供“克隆”按钮。

10. 按角色控制视图和操作权限。 不同角色看到的内容不同。审批人可以看到“批准”按钮;准备人员看不到。非审批人看不到敏感数字(利润率、成本)。这就是“只有老板才能看到利润率”的模式,客户对此直观易懂,但过去从未真正落实过。

第 2 级 — 仅在 DOMAIN.md 有依据时构建

这些能力很有价值,但只有在 DOMAIN.md 提供明确信号时才值得构建。

  • 引导式销售(针对复杂配置的分步问答)——当 DOMAIN.md 描述了与客户进行的需求发现流程时
  • 批量/阶梯定价——当 DOMAIN.md 提及批量折扣、数量阶梯或批量优惠时
  • 面向客户的只读报价链接——当 DOMAIN.md 提及通过电子邮件向客户发送报价或与客户分享报价时
  • 订阅/续约处理——当领域类似 SaaS 且具有经常性收入时
  • 在一次构建中支持多种定价模式(成本加成 + 目录定价 + 自定义定价)——当 DOMAIN.md 描述了混合定价策略时
  • 按客户类型区分的报价文档模板——当 DOMAIN.md 描述了面向不同受众的不同输出格式时
第 3 级 — 后续工作(在完成摘要中提及,不要构建)

这些功能属于生产级构建,而非原型。完成摘要应列出这些功能,让客户了解接下来会有哪些内容。

  • 根据 CRM/电子邮件/通话上下文由 AI 推荐报价
  • 报价版本管理和修订跟踪
  • 订阅计费逻辑和按比例计费
  • CRM/ERP 集成(在全栈阶段处理)
  • 电子签名集成(DocuSign、HelloSign 等)
  • 税务引擎集成(Avalara、Vertex)
  • 支持动态外汇汇率的多币种功能
  • 客户自助配置门户
  • 交易室/品牌化提案微型网站
  • 原生移动应用
完成摘要模板

每个 CPQ 构建的完成摘要必须包含:

## What this prototype includes

**Tier 1 (always built):**
- [confirm each Tier 1 capability is present, or note why a specific one was omitted]

**Tier 2 (built for this domain):**
- [list any Tier 2 capabilities that were built and why]

## What this prototype does NOT include

This is a frontend prototype demonstrating the core CPQ workflow. The following capabilities
would come in production:

- [list relevant Tier 3 items based on the customer's likely future needs]

To move from prototype to production, add: real authentication, CRM/ERP integration,
e-signature, real PDF generation, and any Tier 3 capabilities listed above.

这样既能让客户清楚了解已交付的内容,又能坦诚说明还有更多功能即将推出。


何时使用此技能

当“这算 CPQ 吗?”中的四项标准均满足,且客户的 DOMAIN.md 包含以下内容时:

经典 CPQ 信号:

  • 面向客户报价或定价的产品或服务
  • 配置选项(尺寸、型号、变体、材料)
  • 产品之间的依赖关系(必需、推荐、排除)
  • 基于加价或利润率的定价(成本加成、供应商价目表 + 百分比)
  • 报价或提案工作流(草拟 → 审核 → 批准 → 发送)

更广泛的“配置-计算-输出”信号:

  • 带有审核/交接步骤的计算器、估算工具或评估工具
  • 输入项会影响计算结果的引导式信息收集表单
  • 应用规则以生成结果的多步骤数据收集
  • 输出文档(报告、摘要、估算、提案)
  • 填写者/审核者工作流(客户填写 → 专业人员审核)

**以下情况请勿使用此技能:**如果该领域主要涉及库存跟踪(使用 ERP 技能)、带有现场跟踪和付款的持续项目执行(使用 trades-builder)、在线产品销售(使用电商技能)或客户关系管理(使用 CRM 技能)。


模板约定

开始构建前,请先了解模板提供的内容,以及此技能会补充的内容:

模板(app/layouts/MainLayout.tsx)自带:

  • SidebarProvider、Sidebar、SidebarContent、SidebarInset、SidebarTrigger — 均已完成接线
  • SidebarContent 为空 — 这是你的工作区域
  • 页眉中的一个品牌栏位(徽标占位符 + 公司名称)
  • 页眉右侧区域中的 ModeToggle 和用户菜单

此技能负责填充:

  • SidebarContent — 根据所选布局填充相应的分区导航
  • 品牌栏位 — 使用 DOMAIN.md 中的客户徽标和公司名称
  • 页眉右侧区域 — 当工作流包含多个角色时,在现有用户菜单前添加角色切换器 DropdownMenu
  • <main> 中的 <Outlet /> — 通过各分区的路由组件进行填充

此技能不会:

  • 添加第二个 Sidebar 组件。整个应用只有一个侧边栏。
  • 在 SidebarContent 中放置品牌标识块。品牌标识只放在页眉中。
  • 在路由组件中挂载 MainLayout。路由会在 <Outlet /> 中渲染;布局是父级。在路由中挂载 MainLayout 会导致侧边栏/页眉重复。
  • 重新接线 SidebarProvider 或替换其可折叠行为。

如果工作流不适合侧边栏布局(见下文的布局模式替代方案),构建时可以使用其他外壳。请在完成摘要中说明这一偏差。


分区模式

默认的 CPQ 工作流包含三个逻辑阶段:配置输入、审核/批准、交付文档。默认 UI 会将这些阶段映射到三个或四个分区,具体取决于用户是否需要单独的“审核/编辑明细行”阶段。

默认分区结构(SMB 直接编辑模式)

对于 SMB CPQ,如果同一角色负责从创建到批准整个报价流程(这是最常见的情况),默认设置为三个分区:

  1. 编辑报价 — 直接内联编辑所有明细行和客户详情。这是主要工作区,用户约 90% 的时间都会在这里度过。明细行可直接内联添加、编辑和删除。客户信息、条款和备注也都在此内联编辑。实时总额显示在右侧或下方。
  2. 批准 — 审核并批准。展示最终状态、执行审批前检查,并提供批准操作。如果报价此前已获批准或经过修订,也可以显示变更历史。
  3. 报价文档 — 最终交付物。只读、可打印,并采用品牌格式。

这将 v4.3 中“配置 → 构建报价”的往返流程合并为一个直接编辑界面。大多数 SMB CPQ 构建都应采用这一三分区模式。

四部分结构(存在角色交接时)

当配置和明细项组装由不同人员完成时(例如:工程师配置 → 销售代表定价 → 经理审批),适合采用四个部分:

  1. 配置 — 工程师或技术岗位指定产品
  2. 构建报价 — 销售岗位添加价格、条款和客户信息
  3. 审批 — 经理审批
  4. 报价文档 — 最终交付物

仅当 DOMAIN.md 描述了各阶段角色之间真实的交接时,才采用此结构。大多数中小企业的 CPQ 不需要这样做——一个人就能完成配置、构建和审批。使用三个部分。

计算器领域的部分结构

对于计算器/信息收集领域(Clarity Legal 模式):

  1. 提交详情 — 信息收集表单(面向客户)
  2. 计算 — 计算得出的结果(根据输入自动生成)
  3. 律师审核 — 面向审核者的审批(面向律师)
  4. 最终报告 — 交付的输出

结构模式相同;标签和组件会根据领域进行调整。

偏离情况

当工作流没有审核关卡时,跳过“审批”(自助服务流程)。编辑报价 → 文档。 当交付物不是文档时,跳过“报价文档”(推送到系统、内嵌结果、确认页面)。 当工作流在配置之前有探索阶段时,在“编辑报价”之前添加“探索/信息收集”。 选择与实际工作流相符的部分数量。 不要凑成四个,也不要为了迁就数量而删减。

编辑报价部分 — 直接内联编辑(第 1 级必需)

编辑报价部分以类似 Excel 的行项目表格作为主要工作区。这是产品 CPQ 的硬性要求。

必需行为:

  • 每个行项目都是表格中的一行
  • 单元格支持内联编辑——点击单元格、编辑数值,总计随之更新
  • 通过表格下方的“+ Add Line”按钮添加新行(或在用户点击空白占位行时自动添加)
  • 通过行操作菜单(垃圾桶图标、“Remove”选项)删除行
  • 通过行操作菜单(“Duplicate”选项)克隆行
  • 每行计算总额(数量 × 单价 - 折扣)
  • 页脚行计算所有行项目的小计
  • 折扣明细显示在小计下方(如适用)
  • 税费行显示在折扣下方(如果 DOMAIN.md 提及税费)
  • 底部以粗体显示总计

必需列(产品领域):

#描述配置数量标价折扣净价行总额操作

“描述”列显示产品名称。“配置”列显示所选选项(例如“高级套餐 — 50 位用户”或“三色混纺,DTG 印花”)。对于需要配置的产品(捆绑/必需子项模式),点击行会打开配置器抽屉/弹出框,供用户选择选项,然后再提交该行。选定后,配置会内联显示,再次点击即可编辑。

捆绑/必需子项产品的必需行为:

当 DOMAIN.md 描述需要子组件的父产品时——例如“工业设备需要选择电机”、“定制连帽衫需要选择印花方式”、“托管服务合同需要选择套餐”或“狗狗零食订单需要选择包装尺寸”:

  • 添加父产品时自动提示用户选择必需的子项
  • 行项目显示为一个完整条目:“[Parent Product] — [Required Child] — [Variant]”
  • 价格合计为父产品基础价格 + 子项附加费用
  • 选择必需子项之前,用户无法保存该行
  • 显示可见的规则指示:“[Component name] selection required (BR-001)”

约束规则的必需行为:

当 DOMAIN.md 中存在 requires / excludes / recommends 规则时:

  • “Requires”规则会阻止保存,直到满足条件;内联显示“Required: [explanation]”
  • “Excludes”规则会阻止无效组合;内联显示“Cannot combine X with Y because [rationale]”
  • “Recommends”规则会显示为非强制建议;显示“Customers often add Z with this. Add?”
  • 每条规则都显示其规则 ID(BR-001、BR-002),方便用户追溯来源

这种直观的规则执行方式,是从 Excel 切换而来的客户最能感受到“惊艳”的体验之一。请突出展示。

产品配置器模式

当一个产品具有多个配置属性(需要做出 3 个或更多选择),或配置选项会逐级联动(第 1 级选择决定第 2 级选项,第 2 级再决定第 3 级选项,依此类推)时,仅使用单元格内联下拉菜单模式并不足够。用户需要一个真正的配置器。

在许多领域,实际的产品配置通常有 3–4 个层级:

  • 工业设备:类型 → 容量 → 电机 → 起重机 → 控制装置
  • 定制服装:服装款式 → 面料 → 尺码组合 → 印花/刺绣方式 → 后整理
  • IT 服务:服务层级 → 用户数量 → 模块 → SLA 级别 → 集成
  • 食品/CPG 批发:产品系列 → 口味或变体 → 包装规格 → 箱装数量 → 冷链/常温配送
  • 专业服务:合作类型 → 范围级别 → 团队组成 → 时长 → 交付物格式
  • 定制标牌/包装:基材 → 尺寸 → 表面处理 → 印刷方式 → 安装五金件

每个层级都会限制下一级的选项。选择一台 5 吨的工业设备 → 只有某些电机适用 → 只有某些控制装置匹配。选择三混纺连帽衫面料 → 只有某些印花方式兼容 → 只有某些后整理选项。选择 Premium 服务层级 → 解锁某些模块 → 需要更高级别的 SLA。其结构相同。DOMAIN.md 会告诉 Agent 实际配置的内容。

对于这类深度的配置,可根据配置复杂度选择以下三种模式:

模式 A — 内联展开行(2–4 个属性,无级联)

当产品只有少量相互独立的属性(例如数量、颜色、尺寸或一个配置选项)时,行项目会在行内展开以显示这些属性。点击该行 → 展开并显示属性选择器 → 填写属性 → 行收起,并在“配置”列中显示配置摘要。

┌─────────────────────────────────────────────────────────────┐
│ 1  [Product Name]    [Variant ▾]    1   $X,XXX.XX  ...     │  ← collapsed
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 1  [Product Name]    [Variant ▾]    1   $X,XXX.XX  ...     │
│    ┌───────────────────────────────────────────────────┐    │  ← expanded
│    │ Variant:      ( ) Option A    ( ) Option B        │    │
│    │ Quantity:     [  1  ]                             │    │
│    │ Description:  [                              ]    │    │
│    └───────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

适用于:

  • 总共 2–4 个属性
  • 属性相互独立(无级联依赖)
  • 展开后所有属性在视觉上都能放入约 200px 的垂直空间内

适合模式 A 的产品示例:包含尺码和颜色的 T 恤、包含工时和费率的服务附加项、软件许可证席位数量、批发箱装数量选择、包含一个后整理选项的印刷横幅。

模式 B — 带垂直步骤指示器的侧边抽屉(4-7 个属性,可包含级联依赖)

当配置存在级联依赖,或包含 4-7 个属性时,点击行后,侧边抽屉会从右侧滑入并覆盖约 40% 的屏幕。抽屉左侧设有垂直步骤指示器,显示各个配置级别。

                           ┌────────────────────────────────┐
                           │ Configure [Product]            │
                           │                                │
                           │ ●━━━ Step 1: Foundation         │
                           │ │    [Selected value]           │
                           │ │                              │
                           │ ●━━━ Step 2: Sizing             │
                           │ │    [Selected value]           │
                           │ │                              │
                           │ ◉━━━ Step 3: Core Component     │
                           │ │    [ Option A ]  [ Option B ] │
                           │ │                              │
                           │ ○━━━ Step 4: Dependent Choice   │
                           │ │    (Complete Step 3 first)    │
                           │ │                              │
                           │ ○━━━ Step 5: Finishing           │
                           │                                │
                           │           [Cancel]  [Save]     │
                           └────────────────────────────────┘

抽屉行为:

  • 抽屉内左侧显示垂直步骤指示器(不在主应用侧边栏中)
  • 满足依赖条件后,步骤即可点击;未满足时则显示为灰色
  • 每个步骤的内容显示在抽屉内步骤指示器的右侧
  • 级联依赖:更改上游选项会使下游选项失效并清空(同时显示确认提示:“更改 [上游] 将重置 [下游] 选项”)
  • “Save” 会将配置应用到行项目;“Cancel” 会放弃更改
  • 行项目会在 Configuration 列中显示组合后的配置摘要

对于确实存在级联依赖的配置,应使用此模式。适合模式 B 的示例:包含类型/容量/电机/控制系统的工业设备,包含服装/面料/印刷方式/后整理的定制服装,包含套餐等级/用户数/模块/SLA 的 IT 服务,以及包含基材/尺寸/印刷/安装方式的定制标牌。抽屉为配置器提供了充足空间,同时不会让用户离开报价工作区。抽屉内的垂直步骤指示器让级联关系一目了然,同时不会占用应用级导航空间。

为什么使用抽屉而非模态框:

  • 与模态框相比,抽屉对用户的干扰更小
  • 用户仍可将左侧的行项目表作为上下文参考
  • 点击外部即可关闭抽屉(避免模态框式的“关闭前先保存”操作阻碍)
  • 抽屉与 React Router 配合良好——可作为路由打开,关闭后返回上一级
模式 C — 全页配置器(8 个以上属性,复杂级联)

当配置确实十分复杂——包含 8 个以上属性、多阶段级联,或需要图表、可视化内容时,配置器应使用独立页面。点击“Configure” → 跳转到 /quotes/{id}/lines/{lineId}/configure → 打开全页界面,顶部显示水平步骤指示器,中间为配置主体,右侧为摘要/预览栏。

┌──────────────────────────────────────────────────────────────────┐
│ ← Back to Quote                                                  │
│                                                                  │
│ ●━━━━━━●━━━━━━●━━━━━━◉━━━━━━○━━━━━━○                            │
│ Step 1  Step 2  Step 3  Step 4  Step 5  Review                   │
│                                                                  │
│ ┌─────────────────────────────────────┬──────────────────────┐  │
│ │                                     │ Selected so far:     │  │
│ │  Configuration content for          │                      │  │
│ │  current step                       │ Step 1: [value]      │  │
│ │                                     │ Step 2: [value]      │  │
│ │                                     │ Step 3: [value]      │  │
│ │                                     │ Step 4: (selecting)  │  │
│ │                                     │                      │  │
│ │                                     │ Running price:       │  │
│ │                                     │ $X,XXX.XX            │  │
│ └─────────────────────────────────────┴──────────────────────┘  │
│                                                                  │
│                          [Back]  [Continue →]                    │
└──────────────────────────────────────────────────────────────────┘

对于真正复杂的配置,只有全页模式适用。顶部的水平步骤指示器适用于这里(专用的向导式流程),但不适用于报价详情层级——因为在这里,用户确实会一次完成一个步骤,再进入下一步。

适用场景:

  • 8 个以上属性
  • 配置涉及可视元素(图表、尺寸、照片、色样、布局预览)
  • 配置耗时超过 30 秒,值得提供专门的操作界面,让用户专注处理
  • 配置结果足够重要,值得设置“确认前审核”步骤

适合模式 C 的示例:包含数十项橱柜、台面、电器和饰面选择的定制厨房;可配置车架、传动系统、车轮、刹车、配件和颜色的自行车;包含模块、用户套餐、集成、支持级别和合同期限的企业软件合同;包含基材、尺寸、结构设计、印刷、后整理、数量和运输方式的定制包装订单。

选择模式
IF product has 2-4 independent attributes, no cascading:
  → Pattern A: Inline expandable row

IF product has 4-7 attributes, cascading dependencies, configuration takes <30s:
  → Pattern B: Side drawer with vertical stepper

IF product has 8+ attributes, visual/diagram component, takes >30s:
  → Pattern C: Full-page configurator with horizontal step indicator

WHEN IN DOUBT:
  → Pattern A for simple-looking products
  → Pattern B for industrial equipment, services with options
  → Pattern C reserved for genuinely complex configurators
级联依赖规则

对于模式 B 和 C,在配置级联时:

  1. 将下游步骤显示为禁用状态,直到完成上游选择。第 2 步为空时,不要让用户进入第 4 步。
  2. 当上游选择发生变化时,清除下游选择并显示确认提示:“将产能从 5 吨改为 10 吨会重置电机和起重机的选择。是否继续?”
  3. 在每一步显示规则依据:“可选电机会根据您选择的 5 吨产能进行筛选(BR-007)。”让筛选规则清晰可见。
  4. 仅有一个选项时自动选择:如果级联筛选后只剩一个有效选项,则预先选中该选项,并注明“(根据先前选择,这是唯一可用选项)”。

这样能让级联配置显得智能,而不令人困惑。习惯使用 Excel 的客户往往会在心里记着这些规则——“尺寸更大时,就不能使用基础组件”,“选择高级服务层级时,会包含嵌入式支持”,“使用食品级基材时,只能使用水性油墨”——明确展示规则,比默默强制执行更令人印象深刻。

行项目中的配置摘要

配置器完成提交后(抽屉保存、整页确认),行项目会在“配置”列中显示已组装的配置。对于深度为 3–4 层的配置,内容可能很长:

[Industrial equipment example]
Industrial Lift — 5 ton, 40ft span
└─ Standard motor, Type 2 hoist, 480V controls, festoon system

[Custom apparel example]
Premium Hoodie — Tri-blend, M-XL run
└─ DTG print, 4-color front, sleeve embroidery, polybag

[IT services example]
Managed Services — Premium Tier, 50 users
└─ Security module, Backup module, 4-hr SLA, Slack integration

将其显示为简洁的摘要文本,并提供“编辑配置”链接,以重新打开配置器。不要尝试在行项目表格中将每个属性都列为单独的列——属性超过 2–3 个时,这种方式就无法扩展。

参考实现模式:

<table>
  <thead>
    <tr>
      <th>#</th>
      <th>Description</th>
      <th>Configuration</th>
      <th>Qty</th>
      <th className="text-right">List Price</th>
      <th className="text-right">Discount</th>
      <th className="text-right">Net Price</th>
      <th className="text-right">Line Total</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    {lineItems.map((item, i) => (
      <tr key={item.id}>
        <td>{i + 1}</td>
        <td>
          <ProductPicker value={item.productId} onChange={(p) => updateItem(item.id, { productId: p })} />
        </td>
        <td>
          <ConfigurationCell item={item} onChange={(config) => updateItem(item.id, { configuration: config })} />
          {item.requiredRules.map(rule => (
            <RuleIndicator key={rule.id} rule={rule} satisfied={item.satisfiedRules.includes(rule.id)} />
          ))}
        </td>
        <td>
          <Input type="number" value={item.qty} onChange={(e) => updateItem(item.id, { qty: e.target.value })} />
        </td>
        <td className="text-right">{formatCurrency(item.listPrice)}</td>
        <td className="text-right">
          <DiscountCell item={item} onChange={(d) => updateItem(item.id, { discount: d })} />
        </td>
        <td className="text-right">{formatCurrency(item.netPrice)}</td>
        <td className="text-right font-medium">{formatCurrency(item.lineTotal)}</td>
        <td>
          <RowActions onClone={() => cloneItem(item.id)} onRemove={() => removeItem(item.id)} />
        </td>
      </tr>
    ))}
  </tbody>
  <tfoot>
    <tr><td colSpan={7} className="text-right">Subtotal:</td><td className="text-right">{formatCurrency(subtotal)}</td><td /></tr>
    {discountRows.map(d => (
      <tr key={d.id}><td colSpan={7} className="text-right text-muted-foreground">{d.label}:</td><td className="text-right">-{formatCurrency(d.amount)}</td><td /></tr>
    ))}
    {taxRate > 0 && (
      <tr><td colSpan={7} className="text-right">{taxName} ({taxRate}%):</td><td className="text-right">{formatCurrency(taxAmount)}</td><td /></tr>
    )}
    <tr className="font-bold text-lg"><td colSpan={7} className="text-right">Total:</td><td className="text-right">{formatCurrency(grandTotal)} {currency}</td><td /></tr>
  </tfoot>
</table>

<Button onClick={addNewLine}>+ Add Line</Button>

客户信息、付款条款、有效期和备注显示在行项目表格下方的一个区域中——直接显示在同一页面上,而不是作为单独的路由或步骤。


折扣叠加模式(应用折扣时 Tier 1 必须支持)

当 DOMAIN.md 提及任何形式的折扣(批量、促销、手动、协商)时,构建的原型必须将折扣显示为分层且透明的计算结果。

必须显示的计算:

List Price (5 × $15,000):       $75,000.00
─────────────────────────────────────────
Volume Discount (5%):              -$3,750.00
Promotional Discount (3%):         -$2,137.50
Manual Discount ($1,000):          -$1,000.00
─────────────────────────────────────────
Net Price:                       $68,112.50
HST (13%):                         $8,854.63
─────────────────────────────────────────
Total:                           $76,967.13 CAD

必须实现的行为:

  • 汇总区域中的每项折扣单独占一行
  • 每行显示:折扣类型、百分比或金额、扣除的金额
  • 折扣按叠加顺序应用(批量 → 促销 → 手动)
  • 手动折扣超过 DOMAIN.md 中的阈值时,触发审批流程
  • 用户可以看到扣除了什么以及原因;公式中不得隐藏任何信息

折扣审批阈值:

当 DOMAIN.md 描述折扣审批规则(“超过 15% 的折扣需要经理审批”)时,原型必须强制执行这些规则:

  • 折扣低于阈值 → 用户可以直接应用,无需审批
  • 折扣达到或超过阈值 → 用户可以应用,但报价状态会变为“待审批”
  • 审批流程会将请求发送给有权审批该折扣级别的角色

这是 SMB 企业最常见的“我们利润率下降了”抱怨。在界面中展示规则能带来很高的价值。


多级审批链模式(Tier 1 必须支持)

大多数 SMB CPQ 工作流有 2 个或更多审批级别。原型必须体现这一点。

审批链定义

DOMAIN.md 会在利益相关者映射中描述审批人。原型根据该映射得出审批链:

  • 单个审批人 → 简单关卡(“等待 [Owner] 审批”)
  • 顺序审批人 → 审批链(“等待 [Sales Manager] 审批,然后等待 [Owner] 审批”)
  • 条件审批人 → 根据报价属性进行路由(“标准配置路由至 [Reviewer A],服务请求路由至 [Reviewer B],维护请求路由至 [Reviewer C]”)
审批链 UI

清晰展示审批链,让用户了解报价目前处于哪个环节,以及接下来会发生什么:

Quote Status: Pending Approval
─────────────────────────────────────────
✓ Submitted by [Sales Rep]              (May 5, 2:30 PM)
✓ Approved by [Sales Manager]            (May 5, 3:15 PM)
○ Pending approval from [Finance Lead]
○ Pending final signoff from [Owner]

每位审批人:

  • 都能在自己的队列中看到报价(筛选列表视图:“等待我审批”)
  • 可以批准、拒绝或请求修改
  • 其操作会推进或中止审批链
  • 被拒绝或要求修改的报价会连同备注一起返回给上一位审批人

构建时的要求:

  • 审批链根据 DOMAIN.md 的 Stakeholder Map 自动生成
  • 角色切换器允许用户切换为任意审批人,查看其队列
  • 多报价列表中的“等待我审批”筛选器会显示待当前角色审批的报价
  • 审批操作会更新审批链状态,并触发 Toast 确认提示
  • 拒绝或要求修改时,需要填写评论,且下一位或上一位角色可以看到该评论
审批路由规则

如果 DOMAIN.md 描述了路由规则——例如,“将维护请求路由给服务经理,将巡检请求路由给现场主管”——原型就应实现这些路由。逻辑示例(DOMAIN.md 会替换占位名称):

// Example routing logic derived from DOMAIN.md stakeholder map:
// - Standard quotes: route to [Sales Manager]
// - Inspection requests: route to [Field Supervisor]
// - Maintenance requests: route to [Service Manager]
// - All quotes finalized by [Owner]

function getApprovalChain(quote) {
  const chain = [];
  
  if (quote.requestType === 'inspection') {
    chain.push({ role: 'inspection-reviewer', name: '[Field Supervisor]' });
  } else if (quote.requestType === 'maintenance') {
    chain.push({ role: 'maintenance-reviewer', name: '[Service Manager]' });
  } else {
    chain.push({ role: 'sales-reviewer', name: '[Sales Manager]' });
  }
  
  chain.push({ role: 'final-approver', name: '[Owner]' }); // Always final-signoff at end
  return chain;
}

在实际构建中,请将占位名称替换为 DOMAIN.md 的 Stakeholder Map 中的真实名称。原型会在“审批”部分明确显示审批链,让用户了解路由逻辑。这是对 SMB 客户最有价值的功能之一——他们此前从未使用过自动路由。


布局模式

默认布局为列表/详情,因为 SMB CPQ 用户通常会同时处理多个报价。他们需要查看队列并深入查看单个报价。

默认:列表/详情布局
+----------+--------------------------------+
|          | [List of quotes]               |
| Filters  | row (status badge)             |
| Quick    | row                            |
| filters  | row                            |
|          |                                 |
|          | + New Quote                     |
+----------+--------------------------------+

用户点击某个报价后,会跳转到详情路由:

+--------------------------------------------------------------+
| Header: [Company Name] | Q-2026-0001 | Status: Draft         |
| ← All Quotes                                                  |
+--------------------------------------------------------------+
| [Edit Quote] [Approve] [Quote Document]   tabs               |
| ──────────────────────────────────────────────────────────── |
|                                                               |
| [Active section content — line items table by default]        |
|                                                               |
| [Live totals on right or below — collapsible]                |
+--------------------------------------------------------------+

列表/详情布局为何是默认选择:

  • 客户使用 Excel 时,会为不同报价创建多个工作表/文件
  • 他们需要一目了然地查看所有正在处理的报价(队列视图)
  • 他们需要按状态、客户、审批人和日期筛选
  • 深入查看某个报价时不应丢失队列上下文(返回按钮始终可用)
  • 审批队列本质上就是列表(“显示所有等待我审批的项目”)

**列表视图中的侧边栏:**筛选器、角色切换器、已保存报价的快捷入口,以及“+ 新建报价”链接。不要放入工作流步骤指示器(此时尚未打开任何报价)。

**详情视图中的侧边栏:**四部分/三部分导航(编辑报价 / 审批 / 报价文档)。也可以在详情视图中使用顶部标签页代替侧边栏——两种方式都可以;根据视觉密度选择。

**右侧栏/实时摘要:**可折叠。在“编辑报价”中默认展开(总额是重要的上下文信息)。在“报价文档”中默认折叠(文档本身就是摘要)。

备选:单报价布局

当 DOMAIN.md 描述的工作流中,用户始终一次只处理一个报价时(CPQ 中较少见,但某些计算器场景适用),使用不含列表视图的单页布局。报价本身就是页面。

备选:计算器式布局(计算器领域)

对于以计算为主要功能的计算器/信息收集领域:

+--------------------------------------------------------------+
|  [Single-column form]                                         |
|                                                               |
|  Personal details                                             |
|    [field rows]                                               |
|                                                               |
|  Financial details                                            |
|    [field rows]                                               |
|                                                               |
|  ─────────────────────────────────────                       |
|                                                               |
|  Calculated result                                            |
|    [inline output panel — updates as user types]              |
|                                                               |
|  [Submit for review]                                          |
+--------------------------------------------------------------+

Clarity Legal 面向客户的流程采用此布局。面向律师的审核流程采用列表/详情布局。

布局决策规则
IF the user manages multiple in-flight workflows in parallel (almost all CPQ):
  → List/Detail layout (DEFAULT)

IF the calculation is the primary feature AND can be shown inline with inputs:
  → Calculator-Style layout

IF the user only ever works on one item at a time (rare):
  → Single-Page layout

IF in doubt:
  → List/Detail layout
侧边栏行为

使用列表/详情布局时,侧边栏会根据用户当前处于列表视图还是详情视图而变化:

**列表视图:**筛选器、角色切换器、“+ 新建报价”按钮,以及可选的已保存筛选器快捷入口。

**详情视图:**分区导航(编辑报价 → 审批 → 报价文档),顶部提供返回列表的链接。

两种视图都使用 SidebarContent——根据路由切换内容,不要添加第二个侧边栏。这是常见的实现错误:Agent 在详情路由中挂载 MainLayout,导致侧边栏重复。不要这样做。

右侧栏可折叠

报价摘要面板是可折叠的右侧边栏,而不是固定面板。使用 shadcn 的 Sidebar 组件并设置 side="right",或使用 Sheet 实现画布外行为。

各区域的默认状态:

  • 编辑报价:展开(总计金额至关重要)
  • 审批:展开(最终审核需要上下文)
  • 报价文档:折叠(文档就是摘要)

用户可以随时通过标题栏中的触发按钮切换状态。


报价生命周期指示器

用户进入报价详情视图后,需要了解当前报价处于生命周期的哪个阶段,以及如何在不同视图(编辑、文档、审批)之间切换。

这是两个不同的问题,需要分别提供两种交互方式。

问题 1 — 工作流状态(“这份报价处于生命周期的哪个阶段?”)

报价会经历以下状态:草稿 → 等待审批 → 已批准 → 已发送(或已拒绝)。用户需要始终看到当前状态。

默认模式:在页面标题附近显示状态徽章。

在报价编号旁放置一个 Badge,显示当前状态。根据状态使用不同颜色:

  • 草稿 → 轮廓样式 / 灰色
  • 等待审批 → 默认样式 / 琥珀色
  • 已批准 → 次要样式 / 绿色
  • 已拒绝 → destructive / 红色
  • 已发送 / 已定稿 → 次要样式 / 蓝色

这是最低要求。v4.5 版本中已包含此功能,且效果良好。

可选增强:水平状态流程。

对于包含 4 个或更多可见状态,且客户能从一目了然的进度中受益的工作流,可在页面标题下方添加水平状态行:

●━━━━━━━━━━━━━●━━━━━━━━━━━━━◉━━━━━━━━━━━━━○━━━━━━━━━━━━━○
Draft         [Reviewer]     [Approver]     Approved      Sent
(complete)    (complete)     (current)

已完成的状态使用实心圆表示,当前状态使用带填充的空心圆表示,未来状态使用空心圆表示。在等待审批的阶段显示审批人姓名,让用户知道报价目前由谁处理。

如果生命周期较简单(不超过 3 个状态),则无需采用此方式,状态徽章已足够。添加 3 步状态流程只是装饰,并没有提供更多信息。

问题 2 — 视图导航(“如何在编辑视图和文档视图之间切换?”)

用户需要在可编辑的工作区、只读的客户文档视图以及其他视图(审批队列、历史记录)之间切换。这些是同一份报价的并列视图,而非连续阶段。

默认模式:在详情页顶部放置标签页。

将 Tabs 放在页面标题下方和主要内容区域上方:

[Edit Quote]  [Document]  [Approval]  [History]
═══════════

当前标签页使用下划线或填充样式。未选中的标签页可以点击。这种模式最合适,因为:

  • 标签页表示“并列视图”——不会暗示先后顺序
  • 只需单击即可切换,无需弹出模态框或跳转页面
  • 每个标签页都可以显示数量或状态徽章(“审批(1 项待处理)”、“历史记录(5 项)”)
  • 禁用状态有明确含义——在存在明细项之前,可以禁用“文档”
  • 可以轻松扩展至 6 个标签页;如果超过 6 个,说明工作流可能包含过多阶段

标签页可用性规则:

  • 编辑 — 始终可用
  • 文档 — 至少存在一个明细项后才可用(否则文档为空)
  • 审批 — 仅当报价处于审批状态或存在审批历史时显示
  • 历史记录 — 报价发生过任何状态变更(编辑、批准、拒绝)时显示

不要显示空标签页。不要显示“即将推出”的标签页。

何时不使用选项卡——改用垂直步骤条

适合使用垂直步骤条(左侧栏中的编号步骤,类似 v4.3 构建版本)的情况:

  • 工作流包含 4 个或更多真正按顺序执行的步骤,不能跳过顺序
  • 用户会 逐一完成每个步骤,再进入下一步(这是向导,而不是工作区)
  • 工作流 有明确的结束点——用户完成第 N 步后,报价即告完成

大多数 CPQ 都不符合这些条件。报价是工作区——用户会反复查看、编辑,也会稍后再回来。选项卡符合这种心智模型。在应用级别使用垂直步骤条,会把向导式心智模型强加给工作区工作流,还会产生视觉问题(步骤标签被挤压、侧边栏空间利用不当)。此技能的早期版本曾犯过这个错误;当前模式将垂直步骤条仅用于配置器抽屉,而不用于应用外壳。

垂直步骤条应留给真正的向导:入门流程、一次性设置,或由不同人员负责各阶段的企业多阶段交易。

何时既不使用选项卡,也不使用步骤条——只用面包屑

面包屑显示层级和位置,而不是工作流阶段。用户沿着 树形结构向下导航(Quotes › Q-2026-0007 › Line Items)时使用面包屑,但不要用它代替阶段导航。

实际上,两者可以共存:最顶部的面包屑显示当前位置,下方的选项卡显示当前项目的同级视图。

工作流简单到不需要这些模式时

有些工作流只有一个界面(计算器式单页布局)。不需要选项卡。页面本身就是工作区。仅靠状态徽章即可传达状态。用户需要时,报价文档会在单独的路由或模态框中打开。

不要为了填满布局而添加选项卡栏。如果只有一个选项卡,那就没有选项卡。

总结
工作流形态模式
多视图工作区(Edit/Document/Approval)详情页顶部使用 选项卡 + 标题附近的状态徽章
多视图工作区 + 复杂生命周期(4 个或更多状态)选项卡 + 状态徽章 + 水平状态流程行
按顺序执行步骤的真正向导左侧栏中的 垂直步骤条
层级导航面包屑(如果也存在同级视图,则与选项卡搭配使用)
单页工作流仅使用 状态徽章

大多数产品类 CPQ 使用第 1 行模式——多视图工作区。Edit/Document/Approval 使用选项卡,标题附近显示状态徽章。


报价文档(最终输出)

这是交付成果。对于产品领域,这是面向客户的报价 PDF;对于计算器领域,这是汇总报告。

应将其视为真正的文档,而不是摘要卡片。**质量标准:**如果你会不好意思把它作为“报价/报告”发给客户,那它就还没有完成。

布局(从上到下)

1. 文档页眉 — 两列:

  • 左侧:品牌徽标(发生错误时回退到带色调的首字母方块 — 切勿使用裸露的 img 标签)。公司名称。公司地址。
  • 右侧:文档标题(“报价单”“估算单”“汇总报告”等)。参考编号(自动生成,例如“Q-2026-0001”)。文档日期。适用时填写有效期。

2. 接收方信息块 — 接收方姓名、联系邮箱、客户公司。突出显示。

3. 内容块:

产品领域:行项目表格。 | # | 描述 | 配置 | 数量 | 单价 | 行总计 |

计算器领域:输入表格 + 结果表格。(参见 Clarity Legal 模式。)

4. 总计/摘要块:

产品领域 — 右对齐的总计项,并完整展示折扣计算:

Subtotal:                         $75,000.00
Volume Discount (5%):              -$3,750.00
Promotional Discount (3%):         -$2,137.50
─────────────────────────────────────
Net Subtotal:                     $69,112.50
HST (13%):                         $8,984.63
─────────────────────────────────────
Total:                            $78,097.13 CAD

计算器领域 — 突出显示主要计算值或数值范围。对于范围,三卡片布局(低/中/高)并突出主要数值效果很好。

5. 条款/免责声明块:

产品:付款条款、币种、有效期。 计算器:DOMAIN.md 中的强制法律/监管免责声明。

6. 审批流程块 — 显示审批历史:

Approved by:
  ✓ [Reviewer Name] (Sales Manager) — May 5, 2026
  ✓ [Reviewer Name] (Finance) — May 6, 2026
  ✓ [Reviewer Name] (Owner) — May 6, 2026

这会让客户印象深刻 — 证明报价单经过了适当的审批流程。

7. 状态徽标 — 草稿 / 等待审核 / 已批准 / 已定稿。清晰可见。

8. 页脚 — 小字说明、联系信息,以及领域要求的签名栏。

只读

文档视图中不提供编辑控件。仅可执行以下操作:“返回编辑报价单”、“打印”、“下载 PDF”(原型中为带提示消息的占位操作)。


RBAC 行为

当工作流包含多个角色时:

  • 使用 DOMAIN.md 的“用户角色”或“利益相关方映射”中的角色填充 localStorage
  • 角色切换器是页眉中的单个 DropdownMenu。触发器中显示当前角色 + 徽标
  • 视图限制: 不同角色默认看到不同的列表筛选条件(审批者看到“待我审批”;准备者看到“我的草稿”)
  • 操作限制: 只有获授权的角色才会看到审批按钮
  • 字段限制: 非审批者角色看不到敏感数字(成本、利润率)
  • 路由可见性: 当某个角色负责特定工作类型时,在该角色处于活动状态时显示相关路由信息

当 DOMAIN.md 仅描述一个角色或未描述角色时,省略角色切换器。不要为了填充 UI 而编造角色。

角色无权操作时,应采用以操作为导向的提示:

  • ❌ 禁用按钮(令人困惑 — 用户不知道原因)
  • ✓ “切换到[审批者角色]角色以[执行操作]”(用于带角色切换器的原型)
  • ✓ “此操作需要[审批者角色]权限。请联系[name]以获取批准。”(用于生产环境)

shadcn/ui 组件映射

使用这些 shadcn/ui 组件。从 ~/components/ui/* 导入。卡片应视为例外,而非默认选择——视觉质量标准请参阅 frontend-design skill。

CPQ 元素组件备注
行项目表格带有 TableHeader、TableBody、TableFooter 的 Table单元格可内联编辑。TableFooter 用于汇总金额。
可编辑单元格(数字)Input type="number"在单元格内占满宽度。失焦或值变更时更新。
可编辑单元格(选择项)Select用于表格单元格中的下拉菜单。
配置单元格自定义弹出框/抽屉点击打开配置器,并在单元格内显示摘要。
行操作DropdownMenu以垃圾桶图标为触发按钮,选项:编辑 / 复制 / 移除。
添加行按钮Button variant="outline"位于表格下方。添加空白行或打开选择器。
状态徽标Badgeoutline 表示草稿,default 表示待处理,secondary 表示已批准。
角色切换器DropdownMenu位于页眉。显示当前角色和徽标。
右侧边栏(可折叠)Sidebar side="right"也可使用 Sheet 实现画布外面板。从页眉切换。
审批链展示带状态图标的自定义列表逐步展示,并使用勾选标记/待处理圆圈。
报价列表Table 或行列表在上方显示状态筛选标签。点击行 → 详情路由。
筛选器标签组 / Select位于报价列表上方。按状态、客户、审批人筛选。
确认对话框AlertDialog用于破坏性操作(删除、拒绝)。
Toast 通知Sonner / toast()保存、批准、拒绝、克隆后显示。
报价文档打印样式文章print:border-0,品牌页眉,汇总金额。
汇总中的折扣行内联标签/值折扣行使用弱化颜色。

配置架构

完整的 TypeScript 接口请参阅 references/config-schema.md。摘要:

config
├── app                    ← Branding, theme
├── sections[]             ← Sections (3 default for SMB direct-editing)
├── layout                 ← list-detail | calculator-style | single-page
├── data
│   ├── products[]         ← Catalog with options, required-children
│   ├── inputSections[]    ← Calculator domain inputs
│   ├── quotes[]           ← All quotes (multi-quote management)
│   └── quoteSettings      ← Currency, tax, terms, markup
├── rules[]                ← Constraint rules + business rules + discount rules
├── approvalChain          ← Multi-tier approval routing
└── roles[]                ← Roles with permissions and view filters

确定性映射规则

领域类型检测
INSPECT DOMAIN.md:
  IF Entity Registry has products with prices/options/accessories:
    → DOMAIN TYPE: product
  ELSE IF Entity Registry has input fields with rules and DOMAIN.md has guidelines/formulas:
    → DOMAIN TYPE: calculator
  ELSE IF both:
    → DOMAIN TYPE: hybrid (rare — pick dominant)
  ELSE:
    → AMBIGUOUS — note in completion summary, default to product
区块数量决策
EVALUATE workflow handoffs:
  IF same role does configure + line management + approval:
    → 3 sections: Edit Quote, Approve, Quote Document (DEFAULT for SMB)
  IF different roles for configure vs line management:
    → 4 sections: Configure, Build Quote, Approve, Quote Document
  IF no review gate exists:
    → Skip Approve section
  IF deliverable isn't a document:
    → Replace Quote Document with appropriate output (confirmation, push-to-system, inline result)
布局决策
PICK based on workflow:
  IF user manages multiple quotes in parallel (almost all CPQ):
    → List/Detail layout (DEFAULT)
  IF calculation is primary feature, simple inputs/outputs:
    → Calculator-Style layout
  IF single-item workflow (rare):
    → Single-Page layout
实体 → 可配置项目映射
FOR EACH entity in DOMAIN.md Entity Registry:

  PRODUCT DOMAIN:
  WHERE entity is sellable product/service/part:
    → CREATE config.data.products[] entry
    → SET id, name, category, basePrice, pricingSource
    → SET options[] from entity's "what varies" attributes
    → SET requiredChildren[] from "must include" relationships (e.g., crane requires motor)
    → SET optionalChildren[] from "may include" relationships

  CALCULATOR DOMAIN:
  WHERE entity is input field/parameter:
    → CREATE config.data.inputSections[] entry
    → GROUP related inputs into sections
    → SET field id, label, type, required, validation
关系 → 规则映射
FOR EACH relationship:
  "requires" → config.rules[] (type: requires, severity: error, surface visibly)
  "recommends" → config.rules[] (type: recommends, severity: info, surface as suggestion)
  "excludes" → config.rules[] (type: excludes, severity: error, block invalid combo)
  "includes child" → config.products[].requiredChildren[] (bundle pattern)
折扣汇总映射
FOR EACH discount type in DOMAIN.md:
  → CREATE config.data.discountTypes[] entry
  → SET id, label, type (percentage|amount), rate, conditions
  → IF discount has approval threshold:
      → CREATE config.rules[] entry (type: approval-required, threshold: X)

EXAMPLES:
  "5% volume discount over 10 units" → percentage discount with quantity condition
  "Promotional 3% in Q4" → percentage discount with date condition  
  "Discounts over 15% require manager approval" → approval-required rule, threshold 0.15
审批链映射
FROM DOMAIN.md Stakeholder Map and routing rules:
  → CREATE config.approvalChain entry per quote type
  → IF routing rules exist (e.g., "inspections to Dre, maintenance to Manish"):
      → CREATE conditional routing in approvalChain
  → ALWAYS append final approver if DOMAIN.md describes one
  → SURFACE the chain visually in the Approve section
状态模型 → 工作流映射
IF DOMAIN.md State Models contain workflow statuses:
  → MAP to quote.status enum (Draft, Awaiting Approval, Approved, Rejected, Finalized)
  → MAP transitions to action availability
品牌 → 主题映射
→ SET config.app.companyName from DOMAIN.md Project Overview
→ SET config.app.theme.primaryColor from brandfetch
→ SET config.app.theme.accentColor from brandfetch
→ SET config.app.theme.logoUrl from brandfetch (with onError fallback in BrandMark)
→ SET config.app.theme.mode = "light"
报价设置映射
Product domain:
→ SET currency, taxEnabled (only if DOMAIN.md mentions tax), taxLabel, taxRate
→ SET defaultTerms, markup, quoteFormat

Calculator domain:
→ SET formulas from DOMAIN.md guidelines
→ SET outputFormat per deliverable type
→ SET disclaimers from DOMAIN.md mandatory text
角色映射
FOR EACH role in DOMAIN.md User Roles:
  → CREATE config.roles[] entry
  → SET id, label, permissions, viewFilters, fieldVisibility
  → IF role appears in approval chain → mark as approver
  → IF only one role or no roles → omit role switcher in UI
边缘情况
→ IF entity has no price → SET pricingSource = "tbd", ADD to openQuestions
→ IF relationship rationale missing → SET message = "[source] [rel] [target] — rationale not captured"
→ IF entity unclassifiable → SKIP, ADD to openQuestions
→ IF DOMAIN.md has Open Questions → COPY to config.metadata.openQuestions
→ IF only one role → CREATE default role, OMIT role switcher
→ IF no pricing AND domain is product → SET markup = 0, ADD to openQuestions
→ IF no calculation formulas AND domain is calculator → BUILD with placeholder formulas, ADD to openQuestions
→ IF DOMAIN.md mentions discounts but no approval thresholds → use 15% default for "requires approval"

业务规则模板

产品依赖(硬性要求)
{
  "id": "BR-XXX",
  "type": "requires",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "suggest": "[target_product_id]", "matchField": "[matching_attribute]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "error",
  "surfaceVisibly": true
}
产品推荐(软性建议)
{
  "id": "BR-XXX",
  "type": "recommends",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "suggest": "[target_product_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "info",
  "surfaceVisibly": true
}
产品排除
{
  "id": "BR-XXX",
  "type": "excludes",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "block": "[target_product_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "error",
  "surfaceVisibly": true
}
套装 / 必选子项
{
  "id": "BR-XXX",
  "type": "requires-child",
  "parent": "[parent_product_id]",
  "child": "[child_product_id_or_category]",
  "selectionMode": "required-one-of",
  "message": "[rationale]",
  "severity": "error"
}
折扣阈值审批关卡
{
  "id": "BR-XXX",
  "type": "approval-required",
  "trigger": "discountApplied",
  "condition": { "discount.percentage": { "$gte": 0.15 } },
  "action": { "requireApproval": "[approver_role_id]" },
  "message": "Discounts over 15% require [approver name] approval",
  "severity": "warning"
}
多级审批链
{
  "id": "BR-XXX",
  "type": "approval-chain",
  "trigger": "submitForApproval",
  "chain": [
    { "role": "sales-reviewer", "name": "[Sales Manager]", "condition": { "quote.requestType": "standard" } },
    { "role": "inspection-reviewer", "name": "[Field Supervisor]", "condition": { "quote.requestType": "inspection" } },
    { "role": "maintenance-reviewer", "name": "[Service Manager]", "condition": { "quote.requestType": "maintenance" } },
    { "role": "final-approver", "name": "[Owner]" }
  ],
  "message": "Routed through reviewer based on request type, finalized by [Owner]"
}

在实际配置中,将占位名称替换为 DOMAIN.md 的 Stakeholder Map 中的真实名称。

计算器公式
{
  "id": "BR-XXX",
  "type": "computes",
  "trigger": "inputChange",
  "condition": { "fields": ["incomeA", "incomeB", "duration"] },
  "action": { "compute": "supportLow = (incomeB - incomeA) * 0.015 * yearsOfMarriage" },
  "message": "[formula basis from DOMAIN.md]",
  "severity": "info"
}

垂直行业预设

垂直行业领域类型常见布局关键 Tier 1 功能
制造业 / BOM产品列表/详情套装(父项 + 配件)、折扣汇总、多级审批
批发 / 分销产品列表/详情数量阶梯(Tier 2)、折扣汇总、客户定价
服务 / 集成商产品列表/详情设备 + 人工 + 材料套装、审批链
法律 / 合规计算器计算器样式 + 列表/详情公式计算、强制免责声明、律师审核队列
金融 / 保险计算器计算器样式 + 列表/详情费率表、资格规则、范围输出
评估 / 资格判定计算器计算器样式评分模型、阈值规则、建议输出

完成前验证

完成构建前,请确认满足所有 Tier 1 标准:

[ ] Direct inline editing — line items table with editable cells, no Configure-then-Build round trip
[ ] Bundle / required-child — parent products with required children handled in single line; configurator pattern matches complexity (inline / drawer / full-page)
[ ] Constraint rules visible — requires/excludes/recommends surfaced with rationale and rule IDs
[ ] Discount stack — visible math, layered calculation, no hidden formulas
[ ] Live quote summary — totals update in real-time as user edits
[ ] Branded quote document — logo, line items, totals, terms, approval chain, professional print layout
[ ] Multi-tier approval routing — chain derived from DOMAIN.md, surfaced visually
[ ] Multi-quote management — list view with filters, drill into detail
[ ] Save / load / clone — all persisted to localStorage
[ ] Role-based gating — view filters, action gating, sensitive field hiding
[ ] Quote lifecycle indicator — tabs for view navigation + status badge for state; horizontal status flow when 4+ states

如果缺少任何 Tier 1 标准,则构建尚未完成。请先修复再完成。

[ ] No duplicate sidebars — verify by routing through to detail view, count Sidebar components (should be 1)
[ ] No mounted MainLayout inside route — routes render in <Outlet />
[ ] Light mode set in BOTH app.css AND ThemeProvider default
[ ] BrandMark component used everywhere a logo appears (no bare <img>)
[ ] Currency uses Intl.NumberFormat with thousands separators
[ ] Footer text appears once, not duplicated by layout nesting

这些是常见的实现错误,虽然能通过 npm run build,却会破坏用户体验。


映射日志

执行映射规则后,生成映射日志:

## Mapping Log

**Skill:** cpq-builder v4.7
**DOMAIN.md:** [company name]
**Domain type:** [product / calculator / hybrid / ambiguous]
**Vertical preset:** [manufacturing / wholesale / services / legal / financial / assessment / none]
**Section count:** [3 / 4 / 5] (deviations: [list])
**Layout:** [list-detail / calculator-style / single-page]

### Tier 1 standards: [all met / list any gaps]
- [confirm or note gap]

### Tier 2 capabilities built: [N]
- [list with rationale]

### Tier 3 capabilities mentioned in completion summary: [N]
- [list]

### Items mapped: [N]
- [entity name] → config.data.products[0] (with [N] required children, [N] options)

### Rules mapped: [N]
- BR-001: [source] [rel] [target] → [severity, action]

### Approval chain configured:
- [chain description]

### Discount stack configured:
- [list discount types and thresholds]

### Configurator pattern used:
- [inline-expand / drawer-with-stepper / full-page] — [rationale based on attribute count and cascading]

### Lifecycle indicator pattern:
- Tabs: [Edit / Document / Approval / History — list which are present]
- Status flow: [included / omitted — rationale]

### Skipped entities: [N]
- [entity name] — [reason]

### Open questions carried forward: [N]
- [question from DOMAIN.md]

参考文件

  • references/config-schema.md — CPQ 配置结构的完整 TypeScript 接口
  • references/vertical-presets.md — 产品和计算器领域的详细预设
  • references/example-config.json — 完整填充的示例配置

评论

支持 Markdown