客户关系管理 (CRM) 是一个系统,它管理客户与公司之间跨不同渠道的整个客户生命周期中的客户交互和数据。在本教程中,我们将构建一个自定义 CRM 使用 PHP,销售团队可以使用它在整个销售周期中跟踪客户。
我们将为销售人员创建一个简单的 CRM 系统 以
- 访问他们的任务
- 查看他们的潜在客户
- 为每个潜在客户创建新的任务
- 创建新的商机
- 失去销售
销售经理将能够
- 管理所有客户
- 管理销售团队
- 查看当前的销售活动
CRM 的构建模块
以下是 CRM 的基本组件列表
- 潜在客户:初始联系人
- 帐户:有关您与之进行业务往来的公司的信息
- 联系人:有关您认识和与之合作的人员的信息。 通常,一个帐户有多个联系人
- 商机:合格的潜在客户
- 活动:任务、会议、电话、电子邮件以及任何其他允许您与客户互动的活动
- 销售:您的销售团队
- 仪表板:CRM 仪表板不仅仅是漂亮的界面。 它们应该一目了然地提供关键信息,并提供链接以深入了解更多详细信息。
- 登录:销售人员和经理在系统中具有不同的角色。 经理可以访问报告和销售管道信息。

系统要求
- PHP 5.3+,
- MySQL 或 MariaDB
- phpGrid
创建 CRM 数据库
我们将从创建自定义 CRM 数据库开始。 我们将使用的主要表是
- 联系 – 包含基本客户数据
- 备注 – 保存销售人员从联系人处收集的信息。
- 用户 – 有关销售人员的信息

联系 表包含基本客户信息,包括姓名、公司地址、项目信息等。
备注 表用于存储所有销售活动信息,例如会议和电话。
用户 表保存有关系统用户(例如用户名和密码)的登录信息。 用户还可以具有角色,可以是销售人员或经理。
所有其他表都是简单的 查找表,用于连接到上述三个主要关系数据库表。
- contact_status – 包含联系状态,例如潜在客户和商机,每个状态都表示典型销售周期中的不同阶段
- task_status – 任务状态可以是待处理或已完成
- user_status – 销售人员可以是活跃的或非活跃的
- todo_type – 一种任务类型,可以是任务或会议
- todo_desc – 任务的描述,例如跟进电子邮件、电话和会议等。
- 角色 – 用户可以是销售代表或经理
完整的数据库模式图
数据库模式是代表整个数据库的逻辑视图(表、视图、主键和外键)的结构。 数据库模式包括实体及其之间的关系。
在关系数据库中,每个表都应该有一个主键是一个很好的做法。 主键是每条记录的唯一标识符。 它可以是社会安全号码 (SSN)、车辆识别号码 (VIN),或者只是自动递增的数字(在向表中插入新记录时生成的唯一数字)。
以下是我们简单 CRM 的数据库图。 每个表中的关键符号代表表的 PRIMARY KEY。 放大镜表示连接到数据库中另一个表的 FOREIGN KEY。 有时我们称之为“查找”表。

install.sql
一旦您了解了数据库表结构,请在 db 文件夹中找到 install.sql
脚本,并使用 MySQL 工具(例如 MySQL Workbench 或 Sequel Pro)来运行 SQL 脚本。 它应该创建一个名为 custom_crm
的新关系数据库及其数据库表。
设置 phpGrid
我们简单的 CRM 包含许多数据网格。 数据网格是一个类似电子表格的数据表,它显示表示数据库表中记录和字段的行和列。 数据网格使最终用户能够在网页上读取和写入数据库表。
我们选择来自 phpGrid 的数据网格工具来创建数据网格。 使用工具而不是从头开始构建的原因是,开发数据网格通常非常繁琐且容易出错。 数据网格库将为我们处理所有内部数据库 CRUD(创建、删除、更新和删除)操作,并以更少代码实现更好更快的结果。
要安装 phpGrid,请按照以下步骤操作
- 解压缩 phpGrid 下载文件
- 将 phpGrid 文件夹上传到
phpGrid
文件夹 - 通过配置
conf.php
文件来完成安装
在我们开始编码之前,必须在 conf.php
(phpGrid 配置文件)中指定数据库信息。 以下是一些数据库连接设置示例
define('PHPGRID_DB_HOSTNAME', 'localhost');
define('PHPGRID_DB_USERNAME', 'root');
define('PHPGRID_DB_PASSWORD', '');
define('PHPGRID_DB_NAME', 'custom_crm');
define('PHPGRID_DB_TYPE', 'mysql');
define('PHPGRID_DB_CHARSET','utf8');
- PHPGRID_DB_HOSTNAME – Web 服务器 IP 或主机名
- PHPGRID_DB_USERNAME – 数据库用户名
- PHPGRID_DB_PASSWORD – 数据库密码
- PHPGRID_DB_NAME – 我们 CRM 的数据库名称
- PHPGRID_DB_TYPE – 数据库类型
- PHPGRID_DB_CHARSET – 在 MySQL 中始终为“utf8”
页面模板

在我们开始构建 CRM 的第一页之前,最好使页面项(例如页眉和页脚)可重复使用。
页面将包含页眉、菜单、正文和页脚。 我们将从创建一个可重复使用的页面模板开始。
head.php
这是一个基本的 HTML5 模板页眉。 它包含一个指向自定义样式表的链接,该样式表将在后面的步骤中创建。
menu.php

请注意 $_GET['currentPage']
的使用。 每个页面都将设置一个值,该值将突出显示顶部菜单栏中当前页面的名称。
在 style.css
中包含以下代码以进行菜单样式设置。 它将把上面的无序列表转换为菜单。
#menu ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #1590C2;
}
#menu ul li {
float: left;
}
#menu ul li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
#menu ul li a:hover,
#menu .active {
background-color: #ddd;
color: black;
}
footer.php
我们在头部打开的元素的结束标签
我们完整的可复用页面模板
这是完整的页面模板。主要内容将在Section Title
之后。
我的自定义 CRM
标题
CRM 主页
你还在吗?很好!现在我们可以最终开发 CRM 中的第一个页面了。
我们的销售团队成员 CRM 有四个页面
- 任务
- 潜在客户
- 商机
- 客户/已赢得
每个页面都表示典型销售周期中的不同阶段。
设计样机
这是我们为销售人员提供的 CRM 设计样机。

任务
当销售团队成员登录时,他看到的第一个页面是当前任务列表。
您可能还记得,我们的notes
表格包含所有销售活动信息。我们可以使用phpGrid创建一个数据网格,并使用它从Notes表格中填充数据。
任务页面主要内容是一个数据网格。以下两行将为我们提供当前销售人员的任务列表。
display();
?>
- 第一行通过传递SELECT SQL 语句、它的主键 -
ID
,以及数据库表名 -notes
来创建一个phpGrid对象。 - 第二行也是最后一行调用 display() 函数以在屏幕上呈现数据网格。查看 基本数据网格演示以获取更多详细信息。
潜在客户
潜在客户页面包含销售人员负责的当前潜在客户列表。每个潜在客户可以有一个或多个笔记。我们将为此使用 phpGrid 子网格 功能。
我们还需要使用 set_query_filter()
来仅显示潜在客户,Status = 1
,并且仅针对当前销售人员。
联系人状态表

set_query_filter(" Status = 1 && sales_rep = 1 ");
// the detail grid displays notes about a lead
$sdg = new C_DataGrid("SELECT * FROM notes", "id", "notes");
$sdg->set_query_filter(" Sales_Rep = 1 ");
$sdg->enable_edit();
$dg->set_subgrid($sdg, 'Contact', 'id');
$dg -> display();
?>
商机
一旦潜在客户获得资格,它就会成为商机。商机页面类似于潜在客户页面。唯一的区别是set_query_filter
中过滤的 状态代码是Status = 2
。
set_query_filter(" Status = 2 && sales_rep = 1 ");
$sdg = new C_DataGrid("SELECT * FROM notes", "id", "notes");
$sdg->set_query_filter(" Sales_Rep = 1 ");
$sdg->enable_edit();
$dg->set_subgrid($sdg, 'Contact', 'id');
$dg -> display();
?>
客户/已赢得
客户/已赢得的Status = 3
。与潜在客户和商机类似,客户/已赢得也可以有笔记。
set_query_filter(" Status = 3 && sales_rep = 1 ");
$sdg = new C_DataGrid("SELECT * FROM notes", "id", "notes");
$sdg->set_query_filter(" Sales_Rep = 1 ");
$sdg->enable_edit();
$dg->set_subgrid($sdg, 'Contact', 'id');
$dg -> display();
?>
这就是我们简单 CRM 中销售人员需要了解的全部内容。
经理仪表板
销售经理可以访问销售管道中的所有记录,以及管理销售团队和客户数据的权限。
以下是设计样机

菜单
经理仪表板有三个菜单项。

主要内容
每个菜单项代表 CRM 数据库中的一个表。$_GET['gn']
将存储表名。它根据传递的表名动态生成数据网格。
set_subgrid($sdg, 'sales_rep', 'id');
break;
case "notes":
$dg = new C_DataGrid("SELECT * FROM notes", "id", "notes");
break;
case "contact":
$dg = new C_DataGrid("SELECT * FROM contact", "id", "contact");
$sdg = new C_DataGrid("SELECT * FROM notes", "id", "notes");
$sdg->enable_edit();
$dg->set_subgrid($sdg, 'Contact', 'id');
break;
}
$dg->enable_edit();
$dg->display();
?>
我的销售代表
由于销售经理需要快速了解销售人员正在与谁合作,因此我们添加了一个从联系人表填充并与父网格链接的详细信息网格$sdg
。
$sdg = new C_DataGrid("SELECT * FROM contact", "id", "contact");
$dg->set_subgrid($sdg, 'sales_rep', 'id');
sales_rep
是contact
表中连接到id
的键,而id
是users
表中的外键。请记住,users
存储了我们所有销售人员的信息。
屏幕截图


您使用什么应用程序创建了数据库图表?我使用的是 Visio,似乎每次修订都会变得更糟。很棒的文章!
谢谢!数据库图表是使用 DBSchema 从 dbschema.com 创建的。它太棒了!
… 我不知道,伙计。
现在,在没有像 Symfony、Laravel 等等这样的结构化框架的情况下构建 PHP 应用程序,对我来说感觉只是不对。我可以忍受没有 ORM,但我们已经从痛苦的经验中吸取教训,将 HTML 和 PHP 语句混合在同一个文件中 - 实际上使用 PHP 作为模板引擎 - 很容易导致最混乱的意大利面条代码。
此外,如果我们是在教初学者,我建议他们从一开始就使用 PHP 7。
另外,PSR-0 作为一种编码风格在 PHP 社区中被广泛采用。我不是教条式 CS 的粉丝,但对于 PHP,我会坚持使用它。
感谢您的反馈。CRM 不是一个简单的系统,需要从头开始实现。但是,本教程的目的是尽可能简单,以便初学者学习。它当然可以与 Laravel 或 CodeIgniter 等框架集成。并不难。在未来的教程中,比如第二部分,它肯定可以得到进一步探索。
我同意。现在,没有至少像 Slim 这样的框架支持的 PHP 应用程序几乎没有用武之地,更不用说没有像 Twig 或 Blade 这样的模板引擎支持的 PHP 应用程序了。
另外,一个小提醒:PSR-0 已被弃用,应改用 PSR-4 作为自动加载标准。如果您指的是编码风格指南,您可能将 PSR-0 与 PSR-1 和 PSR-2 混淆了;-)
@Sven Luijten 请查看这里:http://phpgrid.com/example/phpgrid-laravel-5-and-bootstrap-3-part-ii-improved-version/
我已经尝试了几个小时,但没有任何进展。我不能代表所有人说话,但作为一名初学者,我对 phpmyadmin 最熟悉。您建议“例如,使用 MySQL Workbench 或 Sequel Pro 来运行 SQL 脚本”。也许这是可行的,但我无法让它与 WAMP 一起运行。当我尝试导入安装脚本时,它会显示不同的错误。这是最新的 - #1100 - 表“pma__column_info”没有使用 LOCK TABLES 锁定
确保您以 MySQL 管理员身份登录,并且具有
LOCK TABLES
权限查看这里:phpMyAdmin 锁定表
我发现您必须先创建数据库。
虽然这是一个不错的教程,但现在带有 CRUD 编辑支持的 phpGrid 被锁定在 phpGrid PRO 后面。虽然我相信您可以完成本教程(如果您使用的是 PHP 7,可以注释掉 use phpGrid\C_DataGrid;),但最好向人们展示如何使用 jqgrid for PHP(因为 phpGrid 是 jqgrid 的一个包装器)来完成。
很棒的观察。不幸的是,这将不是“初学者”指南。本教程的目的是轻松创建 CRM,而无需读者费力地了解 jqGrid 的内部工作原理。它只会使他们不堪重负,并让他们迷失在细枝末节中。在现阶段,开发人员不应该为此担心。这可以在未来的教程中得到更好的解释。
警告:include_once(../phpGrid_Lite/conf.php) [function.include-once]:无法打开流:C:\wamp\www\project\phpgrid-custom-crm-master\sales\tasks.php 第 2 行中不存在此文件或目录
警告:include_once() [function.include]:无法打开“../phpGrid_Lite/conf.php”以进行包含(include_path='.;C:\php\pear')在 C:\wamp\www\project\phpgrid-custom-crm-master\sales\tasks.php 第 2 行中
我在每个菜单任务、潜在客户、机会、客户/获胜中都遇到了错误。
我还可以问一下,您在哪个地方编辑 phpGrid 数据库?
PS。我刚接触这个。
看起来缺少 php 数据网格库。您可以从这里获取免费库,然后将文件解压缩到文件夹
phpGrid_Lite
中。确保设置 phpGrid 数据库信息。用于创建设计模型的工具是什么?
它被称为 Balsamiq。URL:https://balsamiq.com/