开源CRM3.0系统部署与二次开发实战:从环境配置到权限模型 简介一款基于PHP开发的开源客户管理CRM系统源码定位为可自由扩展的中小企业客户关系管理解决方案适合需要私有化部署或深度定制CRM的开发者与企业运营人员。代码无加密支持无限二次开发降低功能改造门槛。系统功能覆盖线索全生命周期管理支持线索导入、转移、来源/状态维护客户模块包含公海、客户列表、成交客户、行业类别等并内置订单管理、订单审核、业绩查看等销售协同能力同时提供权限管理、管理员与用户组设置、邮箱配置等后台工具整体界面简洁大气能够直接部署或作为基础框架迭代。压缩包约32.55MB具体文件结构与数量暂未完整展示。已有273人学习下载适合需要快速搭建CRM系统或想研究PHP后台开发架构的读者。系统还涵盖公海类型、客户级别、地区列表等细分配置便于不同行业灵活调整。1. 开源客户管理php系统crm3.0无加密源码是入手的好理由但不是全部我接过好几个“客户管理靠Excel”的项目最麻烦的不是表格本身而是销售一离职客户线索全断。后来我都是直接部署一套开源客户管理php系统crm3.0管理系统源码无加密、能无限二次开发当天部署完当天就能录客户、记跟进、转商机、走合同。这套系统最值得说的不是功能有多少而是它能改、敢让用户改。数据表结构、路由规则、权限模型全部摊在眼前适合中小团队自用也适合外包交付后继续按客户要求做定制。想拿它当二次开发底子的人后面几章的部署细节和坑你得看清楚。2. 摸清CRM3.0的家底业务链路、权限模型与数据表三件套在你动手部署之前先花二十分钟把它的代码结构看一遍。多数人翻车都是因为上来就装装完发现业务逻辑和自己想的不一样。这套CRM3.0的代码组织不算复杂入口文件加模块控制器的结构后台模块和前台模块分离模板文件直接可改属于能快速上手的类型。下面三个点是我每次接手项目都会先看的能省掉后面大量返工。2.1 业务主线从客户到回款的六个状态节点CRM3.0的核心不是“存客户”而是让客户记录在业务流转中不断改变状态。整个流程可以压缩成六个节点潜在客户、跟进中、商机确认、报价审批、合同签订、回款完成。每个节点对应一张表或一个状态字段字段值用数字表示不写字符串因为数字枚举在统计和索引效率上都更稳。客户状态字段常规做法是这样的SELECT id, name, mobile, status, owner_id, next_follow_at FROM customer WHERE status 1 AND owner_id 7 ORDER BY next_follow_at ASC LIMIT 20;这段查询拉出当前归属人为ID 7的销售当天需要跟进的客户列表status 1表示跟进中next_follow_at存的是下一次跟进时间。销售每天上班第一件事就是执行这条逻辑说是CRM系统的“今日待办”也不为过。参数owner_id在多人共用账号时不靠谱务必保证一个销售一个账号否则跟进记录会串。商机阶段表更细一点stage字段区分需求确认、方案报价、商务谈判和成交。这套逻辑在CRM3.0里已经内置后台菜单里“商机管理”点进去就能看到每个阶段的数量统计。需要注意它没有做复杂的销售漏斗预测只做了阶段计数够用但别指望BI级别的分析。2.2 权限模型角色、部门、菜单的三层结构CRM3.0的权限设计比很多自研系统规整没有把按钮权限写死在代码里而是拆成三张核心表admin_role存角色名和标识admin_menu存菜单路由和图标admin_role_menu存角色和菜单的关联关系。再通过admin_user表里的role_id字段把用户挂到角色下。判定逻辑是这样的用户登录后取出所属角色再查出该角色可见的菜单ID集合生成一个权限数组存到会话里。后续每次请求后台URL时框架拿当前控制器和方法名去权限数组里比对不在集合内就直接拒绝。这套做法的好处是新增菜单后只要往关联表里插一条记录就能授给整个角色不用改代码逻辑。部门和角色的关系要注意CRM3.0里的部门是独立字段挂在用户档案上权限控制主要走角色部门仅做数据筛选。也就是说你没法通过“设置部门可见范围”来控制数据权限只能控制“看到哪个菜单”。如果业务上要求销售只能看自己的客户、主管能看整个部门的客户需要自己在查询条件里追加owner_id或dept_id过滤这也是二次开发最常改的地方。2.3 数据表设计客户表、跟进记录、商机表的关键字段我挑三张使用频率最高的表给新手做个速览避免一上来就迷路。客户表customer字段名 | 类型 | 说明 id | int | 主键 name | varchar | 客户名称 mobile | varchar | 手机号 source | varchar | 客户来源 status | tinyint | 0潜在 1跟进中 2已成交 3已流失 owner_id | int | 归属销售ID next_follow_at | datetime | 下次跟进时间 created_at | datetime | 创建时间跟进记录表follow_log字段名 | 类型 | 说明 id | int | 主键 customer_id | int | 关联客户ID content | text | 跟进内容 next_time | datetime | 计划下次跟进时间 create_time | datetime | 记录时间商机表business字段名 | 类型 | 说明 id | int | 主键 customer_id | int | 关联客户ID name | varchar | 商机名称 amount | decimal | 预计金额 stage | tinyint | 阶段编号看到source字段就要明白这套系统默认是允许自定义客户来源的只是后台界面没做专门维护直接改数据字典就行。上次有个同事把status 0当“正常”用结果所有新客户都不出现在待跟进列表里查了半天才发现是他自己二次开发时改了枚举含义。这个字段的取值前后端约定死了别乱动。3. 部署一台能跑的CRM3.0环境版本、导入顺序与目录权限都要注意这一章是落地重点。很多人下载完源码直接往宝塔面板一扔结果要么白屏要么数据库导入失败。我先说环境选型逻辑再给一套我反复用的部署顺序跟着做能避开大部分安装期问题。3.1 环境选型PHP 7.4配MySQL 5.7别急着上PHP 8这套CRM3.0写的时间比较早代码里有些老式语法比如用类名当构造函数、依赖一些PHP 7时代才规范化但PHP 8严格模式下会报错的写法。最稳的组合是PHP 7.4加MySQL 5.7或MariaDB 10.3以上版本。PHP 8.0之后的严格类型检查会把某些隐式转换当致命错误你看到的不是运行日志里的报错而是登录后直接白屏。部署前先在命令行确认环境版本php -v php -m | grep -E pdo_mysql|mysqli|gdpdo_mysql和gd必须出现。gd库缺失会导致验证码不显示和图片裁剪功能不可用。没有就装上apt install php7.4-gd php7.4-mysql systemctl restart apache2有些精简镜像默认没装zip扩展而CRM3.0后台有数据导出功能没有zip扩展导出Excel会一直转圈。顺手把php7.4-zip也装掉省得后面踩坑。3.2 数据库导入建库、导库、验证三连源码包里通常有一个.sql文件这就是初始数据库备份。不要直接在phpMyAdmin里复制粘贴整个文件文件一大会超时。用命令行导入是最稳的mysql -uroot -p -e CREATE DATABASE crm3 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; mysql -uroot -p crm3 crm3.sql mysql -uroot -p -e SELECT COUNT(*) AS tbl_count FROM information_schema.tables WHERE table_schemacrm3;第三行验证导入是否完整正常情况下会输出一个数字比如40或55。如果这个数字和你解压包里的说明文档对不上说明导入过程有表丢失别继续配置重来一次。导入时最常见的报错是ERROR 1064 (42000)后面跟着一句near ‘TYPEMyISAM’。老版本的MySQL导出文件会带TYPEMyISAMMySQL 8.0不再识别这个关键字。第4章我会给具体处理命令这里先记住遇到别慌。3.3 目录权限能写的目录越小越好别chmod 777这套CRM3.0运行时要写的目录不多核心就三个runtime缓存目录、upload上传目录、config下的配置文件安装时改数据库连接用。给整个项目赋777权限是新手最常见的错误后患极大后面做权限控制时会被绕过去因为文件权限全放开了。按最小权限给推荐下面的做法cd /var/www/crm3 chown -R www-data:www-data . find . -type d -exec chmod 755 {} \; chmod -R 770 runtime upload chmod 640 config/database.php第一行把项目所属改成Web服务用户保证PHP进程能写runtime和upload。第二行把全部目录设为755排除掉Web服务用户之外的写权限。第三行单独给需要写文件的目录放开组写权限。config/database.php只保留读权限防止线上环境配置被意外篡改。如果你用的是宝塔面板默认用户是www把命令里的www-data替换成www即可。面板里右键目录可视化设置权限本质和命令一样但要注意勾选“应用到子目录”时会把文件也改掉权限出现诡异的500错误时先回来检查。3.4 伪静态与URL重写Apache和Nginx两套写法这套系统的URL默认带入口文件和参数类似index.php?madmincindexalogin能用但不美观而且部分环境会对这类URL的静态资源加载有干扰。后台设置里把URL模式改为重写模式后需要服务器配合伪静态规则。Apache环境很简单项目public目录下放.htaccessIfModule mod_rewrite.c RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?/$1 [L] /IfModuleNginx环境则要在server块里加location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?/$1 last; } }两者的逻辑都是“请求的文件不存在时交给index.php处理”。区别在于Apache的规则写在项目目录里跟着代码走Nginx的规则写在站点配置里。改完伪静态后记得清一下runtime缓存不然老URL会一直生效。4. 避坑实录部署和二次开发最常见的五个翻车点这一章是我自己踩出来的清单每条都包含了现象、原因和解决方式。遇到类似问题不用怀疑按下面处理基本能救回来。4.1 数据库导入到一半报错SQL语法不完全兼容MySQL 8现象mysql命令行导入sql文件执行到几十行时弹出ERROR 1064 (42000)后面导入终止。查看文件对应位置发现是CREATE TABLE语句里写了TYPEMyISAM。原因这个sql文件是老版本mysqldump导出的MyISAM已经是历史写法MySQL 8.0的建表语法只识别ENGINE关键字老文件直接导入必挂。解决导入前全局替换掉这个关键字sed -i s/TYPEMyISAM/ENGINEInnoDB/g crm3.sql替换后再执行导入命令。如果你不想改源文件也可以在mysql客户端里先关闭严格模式再导入但那样后续表引擎可能不统一。我是建议直接改文件内容一步到位。4.2 登录后台白屏PHP版本过高与老式构造函数冲突现象部署完成后访问前台首页正常输账号密码点登录直接白屏浏览器网络面板显示HTTP 200但响应体为空PHP错误日志也没记录。原因这套CRM3.0的基础类里有两个类用了“与类名同名的方法”当构造函数PHP 7.0时代只是E_DEPRECATED警告PHP 8.0直接判定为致命错误。框架开启错误显示的话页面会报错没开启的话就是白屏。解决切换PHP到7.4版本。如果你坚持在PHP 8下运行需要找到这两个类文件并把老构造函数改成__construct// 修改前 function UserBase() { $this-db new PDO(...); } // 修改后 function __construct() { $this-db new PDO(...); }改完再清缓存测试。我的建议是直接换PHP 7.4省得改完这个冒出下一个兼容问题。4.3 上传图片不显示或提示文件不存在现象后台新增客户时头像上传成功文件也确实写入了服务器磁盘但页面上img标签访问URL返回404或提示文件不存在。原因默认上传配置写的是绝对路径比如/var/www/crm3/storage/upload而Web根目录指向public/子目录两者没对上。文件在磁盘上但不在Web可访问目录下等于黑匣子。解决把上传目录软链接到public下ln -s /var/www/crm3/storage/upload /var/www/crm3/public/upload如果你已经部署上线修改后再去后台把上传路径配置改成相对路径例如./upload让所有环境不再依赖服务器绝对路径。这个处理对后续迁移服务器也很重要。4.4 改完角色权限不生效会话缓存作祟现象管理员在后台给某角色新增了一个菜单权限销售账号退出重新登录还是看不到新菜单甚至旧菜单也时好时坏。原因这套系统的权限数组在登录时一次写入会话并且会话有效期设置为一周。修改角色权限后已登录用户的会话里还是旧权限集合必须等会话过期或强制重新登录。解决改权限后顺便清理runtime下的会话文件或者把会话有效期调短// 配置文件里 expire 86400,86400表示一天这样即使忘了让人重新登录第二天也会强制退出。紧急情况下直接删除runtime/session目录下所有文件全部人重新登录即可。4.5 二次开发新增模块访问404入口文件白名单拦截现象你想加一个“售后回访”模块复制了一个现有控制器改名后台菜单也加了但访问url时404。原因这套系统入口文件对模块名和控制器名做了白名单校验你复制出来的新控制器不在白名单里被当作非法请求拦截了。解决打开入口文件或对应的路由配置文件找到控制器列表数组把新增的控制器名补进去allow_module_list [Index, Admin, Api, AfterSale],注意Linux环境下类名大小写敏感AfterSale和aftersale是两个名字务必保持一致。这类白名单机制本身是好事防止越权访问后台控制器但二次开发时确实容易忽略它出现404先往这个方向查。5. 二次开发不必动核心加字段、写独立模块的回滚技巧给你一个最常用的二次开发例子给客户表加一个“客户来源”下拉字段。这需求常见到几乎每个客户都提过。操作顺序是改表、改控制器、改模板最后走一遍回滚验证。先加字段ALTER TABLE customer ADD COLUMN source varchar(50) DEFAULT manual COMMENT 客户来源;然后在控制器对应的方法里读取和保存这个字段。老代码用的是数组形式接收请求数据不是实体类反而简单// save方法里 $data[source] $this-input-post(source, manual);模板文件里加下拉框value值和SQL字段保持一致select namesource option valuemanual手动录入/option option valuead广告咨询/option option valuefriend朋友推荐/option /select这三点动完功能就上了。真正的技巧在最后一步——回滚验证。我吃过一次亏新字段上线后销售录入报错查了半天是下拉框有一个值的长度超过了varchar(50)。从那以后我每次改表前都强制走一遍完整流程先mysqldump导出该表备份再执行ALTER然后改代码最后在测试环境录一条完整数据。测试环境有任何异常一条命令就能把表恢复回去。替换表的时候注意先备份原表数据再重建别直接覆盖。这套CRM3.0底子不差适合拿来即用也适合改造成自己的客户管理平台。希望你部署顺利希望帮到你。本文还有配套的精品资源点击获取