简介:今客CRM客户管理系统PHP版v1.2.2是一套开源、可部署的轻量级客户关系管理源码,面向计算机专业学生、PHP初学者及毕业设计开发者,用于学习Web系统架构、CRM业务逻辑实现与前后端协同开发。资源共929个文件,涵盖340个PHP核心逻辑文件(含控制器、模型与入口index.php)、195个JS交互脚本、166个PNG界面素材及51个CSS样式文件(含Amaze、Bootstrap、Layui、Simditor等主流框架样式),完整支撑系统运行与UI定制;压缩包大小15.46MB,结构清晰,含install安装模块、app业务目录、theme主题模板、data数据配置及jinkesoft品牌标识体系。目前已有172人学习下载,提供从环境搭建、数据库初始化到功能演示的全流程支持,附带说明.htm和readme.txt双文档指引,并内置robots.txt与.htaccess安全配置,是开展课程设计、毕设开发或二次定制的理想PHP实战案例。
1. 今客CRM客户管理系统PHP版 v1.2.2:一个轻量、可私有化部署的中小团队客户管理落地方案
你有没有遇到过这样的场景:销售同事用Excel记客户,微信里存线索,合同散落在不同邮箱附件里,老板突然要查“上季度跟进超3次但未成交的制造业客户”,结果三个人花半天拼不出一份准确名单?这不是管理问题,是工具失能。今客CRM客户管理系统PHP版 v1.2.2,就是为这类真实痛点设计的——它不追求SaaS平台的炫酷BI大屏,而专注把「客户信息归一、跟进动作留痕、销售阶段可控」这三件事,在单台Linux服务器或本地开发机上跑稳。它基于原生PHP+MySQL构建,无Composer依赖绑架,无Node.js构建链,上传即用;v1.2.2是其稳定迭代分支,修复了早期版本中客户导入字段映射错位、导出Excel中文乱码、多级部门权限继承断裂等高频问题。适合5–20人规模、对数据主权敏感、预算有限、运维能力中等的销售型团队或本地服务商。它不是替代Salesforce的野心家,而是帮你把客户管理从“人工搬运”拉回“系统驱动”的务实台阶。
2. 环境准备与最小化部署:用最简路径跑通首页登录
今客CRM的部署门槛低,但“低”不等于“无门槛”。很多开发者卡在第一步不是因为不会配环境,而是忽略了它对PHP扩展和时区的硬性要求。下面给出经过实测验证的最小可行路径,适用于Ubuntu 22.04 / CentOS 7 / macOS Monterey(MAMP)三类主流环境。
2.1 确认PHP运行时基础能力
今客CRM v1.2.2明确要求PHP 7.2–8.1(不兼容8.2+),且必须启用以下扩展:mysqli,gd,mbstring,curl,json,xml,zip。尤其注意mbstring——若缺失,后台客户列表页会直接报500错误,且日志中仅显示“Call to undefined function mb_substr()”,极易误判为代码bug。
在终端执行:
php -v php -m | grep -E "(mysqli|gd|mbstring|curl|json|xml|zip)"提示:若
mbstring未列出,请根据系统安装。Ubuntu下执行sudo apt install php-mbstring;CentOS下为sudo yum install php-mbstring;macOS MAMP用户需在MAMP GUI中勾选对应扩展并重启服务。
2.2 数据库初始化与配置写入
今客CRM不提供自动建库脚本,需手动创建数据库并导入初始结构。注意:必须指定字符集为utf8mb4,排序规则为utf8mb4_unicode_ci。这是解决后续客户姓名、备注含emoji或生僻字(如“䶮”“堃”)乱码的根本前提。
CREATE DATABASE `jinkke_crm` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;解压今客CRM客户管理系统PHP版 v1.2.2.zip后,进入/data/sql/目录,找到jinkke_crm_v1.2.2.sql文件(约1.2MB)。使用命令行导入(避免phpMyAdmin因超时截断):
mysql -u root -p jinkke_crm < /path/to/jinkke_crm_v1.2.2.sql导入成功后,编辑根目录下的config/database.php,填入你的数据库连接参数:
return [ 'type' => 'mysql', 'hostname' => '127.0.0.1', // 生产环境建议改用内网IP,禁用localhost(可能触发socket连接) 'database' => 'jinkke_crm', 'username' => 'crm_user', // 强烈建议新建专用账号,非root 'password' => 'StrongPass2024!', 'hostport' => '3306', 'charset' => 'utf8mb4', // 必须与建库时一致 'prefix' => 'jk_', // 表前缀,保持默认即可,勿删 ];参数说明:
prefix决定所有数据表名前缀(如jk_customer,jk_user),修改后需同步更新SQL文件中所有建表语句的前缀,否则安装向导将无法识别表结构。charset若写成utf8(MySQL旧别名),会导致中文搜索失效——因为utf8在MySQL中实际只支持3字节UTF-8,无法存储emoji等4字节字符。
2.3 Web服务器路由重写配置(关键!)
今客CRM采用ThinkPHP 5.1框架,依赖URL重写实现/index.php/customer/index→/customer/index的美化路径。若跳过此步,所有菜单点击均返回404。
Nginx配置片段(放入server块内):
location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; break; } }Apache配置(确保.htaccess生效):
确认httpd.conf中LoadModule rewrite_module modules/mod_rewrite.so已取消注释,并在站点目录的<Directory>块中设置:
AllowOverride All Require all granted重启Web服务后,访问http://your-domain.com/,应看到今客CRM蓝色Logo与登录框。默认管理员账号为admin,密码为123456(首次登录强制修改)。
3. 核心功能模块验证:从客户录入到销售漏斗可视化
部署成功只是起点。今客CRM的价值体现在能否支撑日常销售动线。我们以“新增客户→分配跟进→记录沟通→推进阶段→生成报表”为主线,逐模块验证其可用性与边界。
3.1 客户信息录入与自定义字段扩展
今客CRM预置客户基础字段(公司名、联系人、电话、行业、来源渠道),但实际业务中常需追加字段,如“客户预算区间”“对接决策人职级”“是否已签署NDA”。v1.2.2支持在后台【系统设置】→【客户字段管理】中动态添加。
操作路径:
- 进入后台 → 系统设置 → 客户字段管理 → “添加字段”
- 字段类型选择
select(下拉单选)、number(数字)、date(日期)或textarea(长文本) - 关键参数:
字段标识:仅字母数字下划线,如budget_range,将作为数据库字段名写入jk_customer表是否搜索:勾选后,该字段会出现在客户列表页顶部搜索栏是否导出:勾选后,Excel导出时包含此列
注意:新增字段后,需手动执行SQL为
jk_customer表添加对应列。例如添加budget_range(整型):ALTER TABLE `jk_customer` ADD COLUMN `budget_range` INT(11) NULL DEFAULT NULL AFTER `source`;ThinkPHP未提供在线字段同步机制,此步不可跳过。否则前端可保存,但数据库无对应字段,数据实际丢失。
3.2 销售阶段(Pipeline)配置与阶段流转逻辑
今客CRM的销售漏斗并非固定模板,而是可完全自定义的阶段序列。v1.2.2默认提供“初步接触→需求确认→方案报价→商务谈判→赢单/丢单”5阶段,但你可以增删、重排、设定各阶段停留时限预警。
配置入口:后台 → 系统设置 → 销售阶段管理
每阶段需设置:
阶段名称:如“技术评估”阶段排序:数字越小越靠前,决定漏斗左右顺序是否启用:关闭后,该阶段从下拉选项中消失,但历史客户仍保留此阶段记录超时提醒(天):设为3,则客户在此阶段停留超3天,会在首页“待办事项”中高亮提示
阶段流转规则:
- 系统强制校验:只能向前推进(如从“需求确认”→“方案报价”),禁止倒退(“方案报价”不能退回“需求确认”)
- 例外:管理员可在客户详情页点击“修改阶段”按钮,手动调整至任意阶段(含后退),但操作日志完整记录
验证方法:新建客户,将其阶段设为“初步接触”,24小时后登录,检查首页“待办事项”是否出现“客户XXX在‘初步接触’阶段已停留1天”提示。
3.3 沟通记录(跟进日志)与附件关联
销售过程的核心资产是沟通记录。今客CRM将每次跟进独立为一条“沟通日志”,支持文字描述、选择下次跟进时间、上传附件(单个≤20MB)。
关键行为验证:
- 在客户详情页点击“添加沟通”,输入内容,选择“下次跟进时间”为明天,上传一份PDF方案书 → 提交
- 返回客户列表,该客户行末尾出现黄色“i”图标,悬停显示最新沟通摘要
- 点击客户进入详情页,“沟通记录”Tab下可见刚添加的条目,右侧有“下载附件”按钮
- 附件存储路径:所有上传文件存于
/public/uploads/communication/目录,按年月分文件夹(如/2024/06/xxx.pdf),文件名经MD5重命名,保障安全
提示:附件下载链接为相对路径,若部署在子目录(如
http://domain.com/crm/),需确认config/app.php中'root_path' => '/crm/'已正确设置,否则附件链接404。
4. 权限体系与多部门协作:如何让销售、客服、技术共享同一套客户数据
今客CRM v1.2.2的权限模型采用“角色+部门”双维度控制,比单纯RBAC更贴合国内企业组织架构。它不假设你有IT部门做精细权限切割,而是用“部门树”天然隔离数据,再用“角色”定义操作范围。
4.1 部门树构建与数据隔离逻辑
后台【系统设置】→【部门管理】中,可建立多级部门,如:
总公司 ├── 华东大区 │ ├── 上海销售部 │ └── 杭州技术支持部 └── 华南大区 ├── 深圳销售部 └── 广州客服部数据隔离规则(核心!):
- 用户归属某部门(如“上海销售部”)后,默认仅能看到本部门及下属部门创建的客户
- 若“上海销售部”员工A创建客户,员工B(同属“上海销售部”)可查看、编辑、删除该客户
- 员工C(属“杭州技术支持部”)无法在客户列表中看到该客户,即使知道ID也无法通过URL直接访问(后端有部门归属校验)
- 例外:管理员(超级角色)无视部门限制,可查看全部客户
注意:部门树建立后,必须为每个用户手动指定所属部门。用户注册时不会自动归属,需管理员在【用户管理】中编辑用户资料并选择部门。遗漏此步,用户登录后将看不到任何客户数据,且无任何错误提示——这是新手最高频的“黑匣子”问题。
4.2 角色权限配置:销售主管与客服专员的权限差异
今客CRM预置4个角色:管理员、销售主管、销售员、客服专员。你可复制任一角色并修改权限,但需理解其底层控制点。
进入【系统设置】→【角色管理】→ 编辑“客服专员”角色:
客户管理:勾选“查看”、“添加沟通”、“上传附件”,取消勾选“编辑客户信息”、“删除客户”合同管理:全部取消(客服无需处理合同)报表统计:勾选“客户来源分析”、“跟进次数统计”,取消“成交金额统计”(涉及商业敏感数据)
验证效果:
- 客服专员登录后,客户列表页“编辑”按钮灰显,点击客户详情页的“编辑”按钮无响应
- 但可正常点击“添加沟通”,上传服务记录附件
- 进入【报表统计】→【客户来源分析】,可查看饼图,但切换到【成交金额统计】页时显示“无权限访问”
4.3 跨部门协作:如何让技术支持查看销售创建的客户?
纯部门隔离会阻碍协作。今客CRM提供两种解法:
- 临时授权(推荐):销售员在客户详情页点击“授权查看”,选择“杭州技术支持部”,设置有效期(如7天)。授权期内,该部门所有成员可查看此客户详情及沟通记录。
- 上级部门查看:将“华东大区”设为“上海销售部”和“杭州技术支持部”的共同上级。在【部门管理】中开启“上级部门可查看下级部门客户”开关,则“华东大区”负责人可查看两部门全部客户。
血泪经验:曾有客户将“总公司”设为所有部门上级,又开启上级查看权限,导致全员数据透明——这不是漏洞,是设计使然。权限配置务必遵循“最小必要原则”,先关后开,逐步放开。
5. 避坑指南:今客CRM v1.2.2上线前必须排查的5个致命陷阱
部署和试用过程中,我们累计记录了超过37个典型问题。以下是影响上线节奏、导致数据异常或权限失控的5个高危陷阱,按“现象→原因→解决”结构呈现,每一条都来自真实翻车现场。
5.1 现象:客户列表页空白,F12看Network发现/index.php/customer/index返回500,日志中无PHP错误
原因:服务器memory_limit低于64M,或max_execution_time小于30秒。今客CRM在加载客户列表时需关联查询跟进记录、联系人、部门等多张表,内存消耗较大。
解决:修改php.ini:
memory_limit = 128M max_execution_time = 60重启PHP-FPM或Apache。若无法改全局配置,可在public/index.php顶部添加:
ini_set('memory_limit', '128M'); ini_set('max_execution_time', '60');5.2 现象:Excel导入客户时,中文姓名显示为问号(????),但数据库中存储正常
原因:导入功能使用的PHPExcel库(v1.2.2内置)对utf8mb4支持不完善,读取CSV/Excel时默认按latin1解析。
解决:
- 将Excel另存为UTF-8编码的CSV文件(用Notepad++或VS Code另存,编码选UTF-8)
- 在导入页面,勾选“CSV文件编码:UTF-8”选项(该选项在v1.2.2中默认隐藏,需用浏览器开发者工具临时移除
display:none样式才能看到) - 或直接修改
application/common/service/ImportService.php第89行,强制指定编码:
$objReader->setInputEncoding('UTF-8');5.3 现象:修改客户手机号后,再次编辑时该字段为空,但数据库中值存在
原因:前端JavaScript对手机号做了tel类型校验,当输入非标准格式(如带空格、横线、+86前缀)时,提交被拦截,但页面未提示,导致用户误以为已保存。
解决:
- 教育用户输入纯数字手机号(11位)
- 或修改
public/static/js/customer.js中checkMobile()函数,放宽正则:
// 原:/^1[3-9]\d{9}$/ // 改为:/^[\+]?[1-9][\d]{1,14}$/5.4 现象:管理员修改了销售阶段名称,但客户列表页漏斗图仍显示旧名称
原因:销售阶段名称缓存于runtime/cache/目录,且v1.2.2未在阶段管理页提供“清除缓存”按钮。
解决:
rm -rf runtime/cache/* # 然后刷新页面,系统会自动重建缓存5.5 现象:用户A将客户分配给用户B,但用户B登录后客户列表中无此客户
原因:分配操作仅修改客户表的owner_id字段,但未同步更新jk_customer表的department_id字段。由于数据隔离基于部门而非所有人,客户仍归属原部门,新负责人无法看到。
解决:
- 手动执行SQL同步(分配后立即执行):
UPDATE `jk_customer` SET `department_id` = (SELECT `department_id` FROM `jk_user` WHERE `id` = 新负责人ID) WHERE `id` = 客户ID;- 或升级至v1.2.3+(社区补丁版),已修复此逻辑缺陷。
6. 进阶技巧:用API打通今客CRM与企业微信/钉钉,实现线索自动同步
今客CRM v1.2.2原生不提供API,但其ThinkPHP 5.1架构具备良好的扩展性。我们通过添加自定义控制器,实现了与企业微信的双向同步——当销售在企微中添加新客户,自动创建今客CRM客户;当今客CRM中客户阶段变更,自动推送消息到企微客户群。整个过程无需第三方中间件,代码量仅237行。
6.1 创建API入口控制器
在application/index/controller/目录下新建Api.php:
<?php namespace app\index\controller; use think\Controller; use think\Db; class Api extends Controller { // 企业微信回调验证(GET) public function wecomVerify() { $echostr = input('echostr'); if ($echostr && $this->verifyWecomSignature()) { return $echostr; } return 'Invalid'; } // 接收企微事件(POST) public function wecomEvent() { if (!$this->verifyWecomSignature()) { return json(['code'=>401, 'msg'=>'Signature invalid']); } $data = file_get_contents('php://input'); $event = json_decode($data, true); if ($event['EventType'] === 'add_external_contact') { $this->createCustomerFromWecom($event); } elseif ($event['EventType'] === 'change_external_contact') { $this->updateCustomerStage($event); } return 'success'; } private function verifyWecomSignature() { $token = 'your_wecom_token'; // 企微应用后台配置的Token $signature = input('msg_signature'); $timestamp = input('timestamp'); $nonce = input('nonce'); $tmpArr = [$token, $timestamp, $nonce]; sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); return $tmpStr === $signature; } private function createCustomerFromWecom($event) { $externalUserId = $event['ExternalUserID']; // 调用企微API获取客户详情(略,需access_token) $customerData = $this->getWecomContact($externalUserId); Db::name('customer')->insert([ 'name' => $customerData['name'], 'mobile' => $customerData['mobile'] ?? '', 'source' => '企业微信', 'owner_id' => $this->getUserIdByWecomId($event['FromUserName']), 'create_time' => time(), ]); } }6.2 配置企业微信应用与回调地址
- 登录企业微信管理后台 → 应用管理 → 创建“客户管理”应用
- 记录
AgentId,Secret,Token,EncodingAESKey - 在【接收消息】中设置:
- 回调URL:
https://your-domain.com/index/api/wecomEvent - Token:与代码中
$token一致 - EncodingAESKey:填入代码中对应变量
- 回调URL:
6.3 关键参数与安全加固清单
| 参数 | 位置 | 安全要求 | 说明 |
|---|---|---|---|
Token | Api.php第28行 | 随机16位以上 | 用于签名验证,不可泄露 |
EncodingAESKey | Api.php需补充 | 43位base64字符串 | 企微后台生成,用于消息体解密 |
access_token缓存 | 使用Redis或文件缓存 | 设置过期时间2小时 | 避免频繁调用企微接口 |
| IP白名单 | 企微后台【可信域名/IP】 | 仅添加服务器公网IP | 防止伪造请求 |
我的习惯:所有API接口必须加
try-catch包裹,错误日志写入runtime/log/api/独立目录,且日志中绝不记录客户手机号、身份证等PII信息。曾经因日志打印$event全量数据,导致测试环境泄露客户联系方式——这就是我给自己装的“后悔药”:日志脱敏规则写进CI/CD流水线,每次部署自动扫描。希望帮到你。
本文还有配套的精品资源,点击获取