NocoBase CRM 实战:基于状态联动的线索销售管道(Pipeline)设计与实现
【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase
本文是 NocoBase「如何实现 CRM 的线索转化」系列教程的续篇,聚焦销售管道中最核心的环节——线索的跟进流程与状态管理。通过阅读本文,你可以完整掌握:线索(Leads)集合的字段结构设计、表格区块与详情区块的组合方式、基于记录状态(status)驱动的 10 个操作按钮联动规则,以及利用 Markdown 区块中的 Handlebars 语法($nRecord作用域变量)实现动态文案提示和关联对象跳转链接的技巧,最终在 NocoBase 中搭建出一个状态流转清晰、防误操作的 CRM 线索跟进页面。
本教程承接上一篇关于线索转化的基础内容(创建数据集合、配置数据管理页面、实现线索到公司/联系人/商机的转化),完整系列文档可参考 线索转化基础篇。本节的原始教程文档为 CRM 销售管道可视化。
1. 系列背景与本章目标
在上一篇教程中,我们已经介绍了线索转化的基础知识,包括:
- 创建所需的各数据集合(Leads、Account 公司、Contact 联系人、Opportunity 商机);
- 配置数据管理页面;
- 实现从线索到公司、联系人和商机的转化功能。
本章则重点关注线索的跟进流程和状态管理:以「状态」字段为中枢,驱动页面表单的显示变化、操作按钮的隐藏/激活/禁用,以及转化完成后关联对象的展示与跳转。通过线索跟进和状态管理,你可以提升业务效率,实现对销售过程更精细的控制。
2. Leads 集合结构说明
在线索跟进功能中,status(状态)字段扮演着至关重要的角色:它不仅反映线索的当前进展(未达标、新线索、处理中、跟进中、交易进行中、完成),还驱动整个页面表单的显示与变化。
下表完整给出线索集合(Leads collection)的字段结构:
| Field name | 字段显示名称 | Field interface | Description |
|---|---|---|---|
id | Id | Integer | 主键 |
account_id | account_id | Integer | 公司表 ACCOUNT 外键 |
contact_id | contact_id | Integer | 联系人表 CONTACT 外键 |
opportunity_id | opportunity_id | Integer | 商机表 OPPORTUNITY 外键 |
name | 线索名 | Single line text | 潜在客户的姓名 |
company | 公司名 | Single line text | 潜在客户所在的公司名称 |
email | 电子邮箱 | 潜在客户的电子邮箱地址 | |
phone | 联系电话 | Phone | 联系电话 |
status | 状态 | Single select | 线索当前状态,默认为「未达标」(未达标、新线索、处理中、跟进中、交易进行中、完成) |
Account | 公司 | Many to one | 关联到公司 |
Contact | 联系人 | Many to one | 关联到联系人 |
Opportunity | 商机 | Many to one | 关联到商机 |
设计上值得注意的两个要点:
- 外键字段与关联字段并存:
account_id/contact_id/opportunity_id三个 Integer 外键字段与Account/Contact/Opportunity三个 Many to one 关联字段并存。外键字段用于在转化流程中保存关联记录的 id(后文生成跳转链接时直接引用$nRecord.account_id等),关联字段则用于在表单中展示与维护关联关系。 status使用 Single select(单选)字段:状态值集合固定且有序,后续所有联动规则(按钮显隐、Markdown 文案切换、防修改保护)都以它作为唯一判断依据,这是状态机式页面联动的关键前提。
3. 创建 Leads 表格区块与详情区块
第一步是搭建页面骨架:
- 创建一个"Leads" 的 table block(表格区块),用于展示必要的字段列;
- 在页面右侧配置一个详情区块:当点击某条记录时,右侧会自动显示对应的详细信息。
这种「左侧列表 + 右侧详情」的布局是销售管道类页面的典型形态:销售人员从列表中选中一条线索,右侧即可展开该线索的完整跟进面板(状态提示文案、操作按钮、关联对象等都在详情区块中完成配置)。
4. 配置操作按钮:10 个按钮的状态联动规则
为了满足各种操作需求,本页共创建10 个按钮。每个按钮都依据记录的状态(status)采用不同的显示方式(隐藏、激活或禁用),从而引导用户按照正确的业务流程操作。
4.1 按钮配置总表
| 按钮 | 样式 | 操作 | 联动规则 |
|---|---|---|---|
| 编辑按钮 | 编辑操作 | — | 当记录的 status 为 "Completed"(已完成)时自动禁用,防止不必要的编辑。 |
| 未达标 按钮(激活状态) | "Unqualified >" | 更新记录的 status 为 "Unqualified"。 | 默认展示;若 status 为 "Completed",则按钮被禁用。 |
| 新线索 按钮(未激活) | 更新数据操作,"New >" | 将 status 设置为 "New",更新成功后显示 "New" 的提示。 | 如果记录的 status 不为 "Unqualified" 则隐藏(即记录已处于 "New" 或之后状态,应为激活状态)。 |
| 新线索 按钮(激活状态) | 更新数据操作,"New >" | 更新记录的 status 为 "New"。 | 当 status 为 "Unqualified" 时隐藏;若 status 为 "Completed",则按钮禁用。 |
| 处理中 按钮(未激活) | 更新数据操作,"Working >" | 将 status 更新为 "Working",并显示 "Working" 成功提示。 | 当记录的 status 不为 "Unqualified"、"New" 时隐藏。 |
| 处理中 按钮(激活状态) | 更新数据操作,"Working >" | 更新记录的 status 为 "Working"。 | 当 status 为 "Unqualified"、"New" 时隐藏;若 status 为 "Completed",则按钮禁用。 |
| 跟进中 按钮(未激活) | 更新数据操作,"Nurturing >" | 将 status 设置为 "Nurturing",并显示 "Nurturing" 成功提示。 | 当记录的 status 不为 "Unqualified"、"New"、"Working" 时隐藏。 |
| 跟进中 按钮(激活状态) | 更新数据操作,"Nurturing >" | 更新记录的 status 为 "Nurturing"。 | 当 status 为 "Unqualified"、"New"、"Working" 时隐藏;若 status 为 "Completed",则按钮禁用。 |
| 转化 按钮 | 编辑操作,"transfer",图标为"√" | 弹出转化表单,表单提交时,更新记录的 status 为 "Completed"。 | 当记录的 status 为 "Completed" 时隐藏,以防重复转移。 |
| 转化完成 按钮(激活状态) | 查看操作,"transfered",图标为"√" | 仅用于展示转化完成后的信息,不具备编辑功能。 | 仅在记录的 status 为 "Completed" 时显示;其他状态时隐藏。 |
4.2 联动规则的设计模式
从上面的配置表可以提炼出这套联动规则的通用模式:
- 每个状态迁移都配一对按钮:以「新线索 → 处理中 → 跟进中」为例,每个节点都提供「未激活」(可点击迁移到该状态,成功后给出成功提示)与「激活」(表示记录已处于该状态)两种按钮样式,二者依据 status 显隐互斥切换;
- 终态(Completed)统一禁用/隐藏:一旦线索转化完成,除「转化完成」展示型按钮外,其余按钮全部禁用或隐藏,从 UI 层杜绝回退或重复操作(第 9 节还会再加一层整体保护);
- 迁移按钮即「更新数据操作」:这些按钮本质是预配置了
status字段新值的更新操作,点击即把记录的状态推进到下一个节点,无需二次确认表单,保证销售流程的低摩擦。
4.3 按钮配置总结
- 每项功能均提供未激活和激活状态下的不同按钮样式;
- 利用联动规则,根据记录的 status 动态控制按钮的显示(隐藏或禁用),从而引导销售人员按照正确的工作流程进行操作。
提示:教程中的按钮文案以英文(Unqualified / New / Working / Nurturing / Completed)为准,而状态选项集合在集合定义中以中文展示(未达标、新线索、处理中、跟进中、交易进行中、完成)。实际搭建时,联动规则中比较的字符串必须与 Single select 字段中真实定义的选项值严格一致,否则规则不会命中——这是实施时最容易踩的坑。
5. 表单联动规则设置
按钮之外,表单本身的展示内容也随状态变化:
规则 1:仅展示名称
当记录未确认时,表单只展示名称字段,隐藏其余字段,避免过早暴露尚不确定的信息。
规则 2:「新线索」状态下的显示优化
在 status 为「新线索」时,页面将隐藏公司名,并展示联系方式——新线索阶段往往只有联系人层面的初步信息(邮箱、电话),公司归属尚未确认,因此该阶段优先突出联系渠道。
这两条规则说明:NocoBase 的表单联动能力允许「同一表单、多套视图」,所有切换逻辑仍由 status 单字段驱动,与第 4 节的按钮联动共用同一判断源。
6. 页面 Markdown 动态文案:Handlebars 语法实战
在详情页中,教程使用Handlebars 语法根据记录的状态动态展示不同的跟进提示。$nRecord是当前记录的作用域变量,{{#if (eq ...)}}...{{/if}}是条件块。以下是各状态下的完整示例代码:
当状态为「未达标」时:
{{#if (eq $nRecord.status "未达标")}} **跟踪你那些不合格线索的相关信息。** 如果你的线索对产品不感兴趣或已离开相关公司,则可能是不合格的。 - 记录经验教训以供今后参考 - 保存外联细节和联系方式 {{/if}}当状态为「新线索」时:
{{#if (eq $nRecord.status "新线索")}} **收集更多关于这条线索的信息。** - 了解潜在客户的需求和兴趣点 - 收集基础联系资料和公司背景 - 确定后续跟进的优先级和方式 {{/if}}当状态为「处理中」时:
{{#if (eq $nRecord.status "处理中")}} **主动联系线索并初步评估需求。** - 通过电话/邮件与潜在客户建立联系 - 了解客户面临的问题和挑战 - 初步判断客户的需求与公司产品/服务的匹配度 {{/if}}当状态为「跟进中」时:
{{#if (eq $nRecord.status "跟进中")}} **深入挖掘客户需求,进行线索培育。** - 提供相关产品资料或解决方案建议 - 回答客户的问题,消除顾虑 - 评估线索的转化可能性 {{/if}}当状态为「转化完成」时:
{{#if (eq $nRecord.status "转化完成")}} **线索已成功转化为客户。** - 确认已创建相关的公司和联系人记录 - 创建商机记录,设置跟进计划 - 将相关资料和沟通记录传递给负责的销售人员 {{/if}}6.1 源码视角:Markdown 变量替换是如何工作的
上述$nRecord.xxx插值并非 Markdown 区块私有魔法,而是由 NocoBase 的求值器(evaluators)包统一支撑的。从源码结构看:
- 在 packages/core/evaluators/src/utils/index.ts 中,
evaluate()函数会先用正则{{\s*([\w$.-]+)\s*}}扫描表达式中所有形如{{变量名}}的插值,从传入的 scope(即包含$nRecord等记录作用域变量的上下文)中按路径取值,替换为真实数据后再交给底层求值引擎执行。文中{{$nRecord.account.name}}、{{$nRecord.account_id}}这类写法正是走这条替换路径; - 同一个包中还通过
appendArrayColumn()对数组作用域做了列式展开适配(把数组映射为「同名字段集合」),使得对关联数组的取值也能按点路径解析; - 在 packages/core/evaluators/src/client/index.tsx 中,客户端以 Registry 注册了
formula.js、math.js、string三类求值引擎。Markdown 区块中的条件与比较表达式(如eq $nRecord.status "处理中")即在客户端求值后决定是否渲染对应文本块。
这解释了两个实用细节:插值变量名支持$前缀和作用域点路径(正则字符类为[\w$.-]);而作用域中不存在的变量会被替换为空字符串,因此「状态不匹配时不显示任何内容」是这类条件文案能干净工作的基础。更多 Markdown 变量与技巧可参考系列中的 Markdown 区块技巧 与 Markdown 变量。
7. 展示转化完成后的关联对象及跳转链接
转化完成后,希望直接展示关联对象(公司、联系人、商机),并能从线索详情页一键跳转到对应对象的详情弹窗。
7.1 详情弹窗链接的结构
做法是:打开任一详情弹窗(比如公司),复制其链接。在不同弹窗或页面中,详情链接格式的最后部分(filterbytk之后的数字)代表当前对象的 id,例如:
{Base URL}/admin/{页面token}/popups/{弹窗token}/filterbytk/{id}其中filterbytk/{id}相当于「按主键过滤出一条记录」的定位参数,这是生成跳转链接的关键。
7.2 用 Handlebars 动态拼接关联链接
分别针对公司、联系人、商机三段,在 Markdown 区块中按「状态 = 已完成」的条件渲染带链接的关联对象:
公司:
{{#if (eq $nRecord.status "已完成")}} **公司:** {{$nRecord.account.name}} {{/if}}联系人:
{{#if (eq $nRecord.status "已完成")}} **联系人:** {{$nRecord.contact.name}} {{/if}}商机:
{{#if (eq $nRecord.status "已完成")}} **商机:** {{$nRecord.opportunity.name}} {{/if}}几个要点:
- 链接目标 = 固定弹窗路径 + 动态 id:
popups/xxx/filterbytk/前的 token 是复制详情弹窗链接时得到的固定部分,filterbytk/之后则通过{{$nRecord.account_id}}等外键字段动态注入——这正是第 2 节中外键字段与关联字段并存设计的回报:名称取关联对象($nRecord.account.name),定位取外键 id($nRecord.account_id); - 仅在终态渲染:三段代码都包裹在
eq $nRecord.status "已完成"条件下,未转化的线索不会看到这些链接,避免跳转到尚不存在的记录。
8. 隐藏关联对象但保留值
为确保转化完成后能正常展示关联信息,需要将「公司」「联系人」「商机」三个字段的状态设置为**「隐藏(保留值)」**。
这样,尽管这些字段不在表单中显示,但其值依然会被记录和传递——即前端表单不再编辑这三个关联字段,但$nRecord作用域中仍保有它们的值,供第 7 节的 Handlebars 链接模板读取。若错误地设为完全隐藏(不保留值),跳转链接将取不到名称与 id。
9. 防止转化完成后状态修改
为了防止转化完成后意外更改状态,教程为所有按钮统一添加了一个判断条件:当状态为「已完成」时,所有按钮将被禁用。
这是对第 4 节逐按钮规则的兜底:即使后续新增按钮、或某个按钮遗漏了单条状态判断,全局的「已完成 → 全部禁用」条件也能保证终态记录不可再被流转,形成销售管道的「单向不可逆」保护。
10. 总结:状态驱动型页面上手要点
完成以上步骤后,线索跟进转化功能即告完成。回顾本章,NocoBase 中「状态表单变化联动」的实现可以归纳为四层:
- 数据层:Single select 状态字段 + 外键/关联字段并存的结构(第 2 节);
- 交互层:更新数据操作按钮 + 按状态显隐/启用的联动规则(第 4 节);
- 展示层:表单字段级联动规则 + Markdown 区块中的 Handlebars 条件文案(第 5、6 节);
- 保护层:「隐藏(保留值)」策略 + 终态全局禁用(第 8、9 节)。
这套模式不仅适用于 CRM 线索管道,同样可以迁移到审批流、工单流转、项目阶段管理等任何「有限状态、顺序流转」的业务场景:只要把 status 的选项换成你的业务阶段,按同样的四步配置,就能在 NocoBase 的低代码页面中快速搭出带状态机的业务系统。
【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考