前情回顾

在上一讲中,我们完成了公海池管理功能的开发,实现了客户资源的科学流转。

本节我们将实现商机管理功能,这是CRM系统中承接跟进管理、推动销售转化的核心模块。商机管理帮助销售人员系统性地追踪潜在成交机会,通过销售漏斗分析预测业绩。

本节目标

  • 数据模型设计:创建商机表,关联客户和跟进记录
  • 销售漏斗搭建:实现商机阶段推进功能
  • 页面布局实现:使用低代码组件搭建商机管理界面
  • 核心功能开发:包括商机的新增、编辑、阶段推进、赢单/输单处理

第一步:数据准备

1.1 数据源配置

首先,创建名为MBA_Opportunities的商机表,包含以下核心字段:

字段名称 字段标识 类型 说明
商机名称 name 单行文本 商机标题,如"XX公司MBA培训项目"
关联客户 customer_id 关联关系 关联到MBA_Customers表
负责人 owner_id 关联关系 关联到Users表(当前销售)
商机阶段 stage 枚举 初步接触/需求确认/方案报价/商务谈判/赢单/输单
预计成交金额 amount 数字 预估的成交金额(元)
成交概率 probability 数字 0-100的百分比
预计成交日期 expected_close_date 日期 预计何时成交
商机来源 source 枚举 转介绍/自开拓/渠道/市场活动
竞争情况 competitor 多行文本 竞争对手信息
商机描述 description 多行文本 详细商机描述
输单原因 lost_reason 枚举 价格过高/无需求/选择竞品/其他
创建时间 created_at 日期时间 自动生成
更新时间 updated_at 日期时间 自动更新

在这里插入图片描述


第二步:页面布局搭建

2.1 页面整体布局

点击创建页面的图标
在这里插入图片描述

输入页面的名称"商机管理",布局选择销售布局(因为主要是销售人员使用)
在这里插入图片描述

切换到页面布局,选择销售布局,添加平级菜单,添加商机管理菜单
在这里插入图片描述

2.2 数据表格配置

在销售布局的内容插槽下添加布局组件
在这里插入图片描述

修改标题,改为"商机管理"
在这里插入图片描述

在页面布局中添加数据表格组件,数据模型选择商机表
在这里插入图片描述

2.3 配置查询条件

点击筛选器,给表格配置查询条件
在这里插入图片描述

添加具体的查询条件:

  • 商机名称(模糊搜索)
  • 商机阶段(下拉选择)
  • 预计成交日期范围(日期范围)
  • 负责人(关联选择)

在这里插入图片描述

2.4 配置排序字段

默认按照创建时间的倒序进行排序,最新的商机显示在最前面
在这里插入图片描述

2.5 配置数据筛选

显示表格数据时,默认只显示当前登录销售的商机。配置筛选条件:

  • 负责人等于当前用户对象的数据标识

在这里插入图片描述


第三步:商机功能实现

3.1 创建新增商机弹窗

在商机管理页面添加一个弹窗组件,用于录入新的商机。

从组件库中拖拽弹窗组件到页面,设置弹窗标题为"新增商机"
在这里插入图片描述

在弹窗中添加表单容器组件,数据模型选择商机表
在这里插入图片描述
配置负责人的选中值,设置为currentUser的数据标识
在这里插入图片描述
在表单提交成功后跟一个弹窗关闭和数据表格刷新
在这里插入图片描述
在这里插入图片描述
将全局按钮的删除改为新建
在这里插入图片描述
修改事件,改为打开弹窗
在这里插入图片描述

3.2 阶段推进功能

商机管理的核心是销售漏斗,需要实现阶段推进功能。

在表格操作列添加"推进"按钮,点击后执行阶段推进
在这里插入图片描述

在代码区新增方法advanceStage

export default async function advanceStage({ event, data }) {
  try {
    $w.utils.showLoading({ title: '处理中...' });
    
    const opportunityId = data.target._id;
    const currentStage = data.target.stage;
    
    // 定义阶段流转顺序
    const stageFlow = {
      '1': '2',  // 初步接触 -> 需求确认
      '2': '3',  // 需求确认 -> 方案报价
      '3': '4',  // 方案报价 -> 商务谈判
      '4': '5'   // 商务谈判 -> 赢单
    };
    
    const nextStage = stageFlow[currentStage];
    if (!nextStage) {
      $w.utils.showToast({ title: '当前阶段无法推进', icon: 'error' });
      return;
    }
    
    // 更新商机阶段
    await $w.cloud.callDataSource({
      dataSourceName: 'MBA_Opportunities',
      methodName: 'wedaUpdateV2',
      params: {
        filter: { where: { _id: { $eq: opportunityId } } },
        data: {
          stage: nextStage,
        }
      }
    });
    
    $w.utils.showToast({ title: '阶段推进成功', icon: 'success' });
    $w.table1.refresh();
    
  } catch (error) {
    console.error('阶段推进失败:', error);
    $w.utils.showToast({ title: '操作失败,请稍后重试', icon: 'error' });
  } finally {
    $w.utils.hideLoading();
  }
}

给按钮配置点击事件,调用我们的方法,传入所在行的数据
在这里插入图片描述

3.3 赢单处理

在表格操作列添加"赢单"和"输单"按钮
在这里插入图片描述

编写赢单处理方法:

export default async function winOpportunity({ event, data }) {
  try {
    $w.utils.showModal({
      title: '确认赢单',
      content: `确定将商机【${data.target.name}】标记为赢单吗?`,
      success: async (res) => {
        if (res.confirm) {
          await $w.utils.showLoading({ title: '处理中...' });
          
          // 更新商机状态为赢单
          await $w.cloud.callDataSource({
            dataSourceName: 'MBA_Opportunities',
            methodName: 'wedaUpdateV2',
            params: {
              filter: { where: { _id: { $eq: data.target._id } } },
              data: {
                stage: '5',  // 赢单
                probability: 100,
              }
            }
          });
          
          // 更新客户状态为已成交
          await $w.cloud.callDataSource({
            dataSourceName: 'MBA_Customers',
            methodName: 'wedaUpdateV2',
            params: {
              filter: { where: { _id: { $eq: data.target.customer_id._id } } },
              data: {
                status: '3',  // 已成交
              }
            }
          });
          
          $w.utils.showToast({ title: '恭喜赢单!', icon: 'success' });
          $w.table1.refresh();
        }
      }
    });
  } catch (error) {
    console.error('赢单处理失败:', error);
    $w.utils.showToast({ title: '操作失败', icon: 'error' });
  }
}

给按钮设置事件,调用方法,传入所在行数据
在这里插入图片描述

3.4 输单处理

编写输单处理方法:

export default async function confirmLose({ event, data }) {
  try {
    const opportunityId = $w.modal2.openInfo._id;
    const lostReason = $w.textarea3.value;
    
    if (!lostReason) {
      $w.utils.showToast({ title: '请选择输单原因', icon: 'error' });
      return;
    }
    
    await $w.utils.showLoading({ title: '处理中...' });
    
    await $w.cloud.callDataSource({
      dataSourceName: 'MBA_Opportunities',
      methodName: 'wedaUpdateV2',
      params: {
        filter: { where: { _id: { $eq: opportunityId } } },
        data: {
          stage: '6',  // 输单
          lost_reason: lostReason,
          probability: 0
        }
      }
    });
    
    $w.utils.showToast({ title: '已标记为输单', icon: 'success' });
    $w.modal2.close({});
    $w.table1.refresh();
    
  } catch (error) {
    console.error('输单确认失败:', error);
    $w.utils.showToast({ title: '操作失败', icon: 'error' });
  } finally {
    $w.utils.hideLoading();
  }
}

输单的时候需要输入原因,增加一个弹窗
在这里插入图片描述
添加多行输入组件
在这里插入图片描述
配置输单按钮的点击事件,打开弹窗,传入所在行数据
在这里插入图片描述
给弹窗的确认按钮配置点击事件,调用我们的输单方法
在这里插入图片描述


最终效果

销售打开商机管理模块,可以录入商机,点击推进阶段自动往下流转,点击赢单标记状态,点击输单需要录入输单原因
在这里插入图片描述
在这里插入图片描述


总结

本节我们完成了商机管理功能的开发,实现了销售过程的可视化管理:

  1. 数据模型设计

    • 创建了MBA_Opportunities商机表,记录商机基本信息、阶段、金额等
    • 扩展了客户表,增加商机数量和预计成交总额字段
  2. 核心功能实现

    • 商机的新增、编辑、查询功能
    • 商机阶段推进功能(初步接触→需求确认→方案报价→商务谈判→赢单)
    • 赢单/输单处理,自动更新客户状态

通过本讲的实现,我们构建了完整的商机管理体系,实现了销售过程的可视化管理。

下一步,我们将继续完善CRM系统的报表功能,实现销售业绩统计、客户分析等模块。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐