简介CRMEB开源商城系统是一套全开源可商用的电商解决方案基于ThinkPHP6MySQLelementUIuniapp开发前后端分离覆盖小程序、公众号、H5、APP、PC端适合有二次开发需求的个人开发者、电商运营者及企业快速搭建在线商城。系统内置分销、拼团、砍价、秒杀、优惠券、积分、抽奖、会员等级、小程序直播、页面DIY等完整营销能力同时支持风格切换与多语言可满足不同行业与运营场景的定制需要。压缩包共2000个文件以js和vue源码文件为主辅以json配置、css样式、md文档及少量doc/docx说明整体约126.99MB目录结构清晰便于按前后端模块检索与学习。已有96人学习下载适合具备一定PHP或前端基础、希望获得完整可商用商城系统并深入理解其架构与二开流程的开发者参考使用。1. 前后端分离的开源商城我为什么拿它当二开底子做电商系统选型时我第一反应不是去对比付费商业源码而是先看 CRMEB 这类全开源、可商用的方案。它的定位很直接一套代码覆盖小程序、H5、公众号、App、PC 端后端用 Tp6前端是 elementUI 和 uniapp全部源码开源没有加密文件没有授权锁。这意味着你拿到手的不是一个黑匣子而是可以改、可以拆、可以换肤的完整工程。我实际拆过几套商城源码CRMEB 的文档体系在开源项目里算是比较完整的使用文档、接口文档、数据字典、代码生成、二开视频都有。对想快速上线又不想被商业授权绑死的团队来说这套东西能省下从零搭建后台管理、会员体系、支付闭环的大把时间。它的功能面覆盖了分销、拼团、砍价、秒杀、优惠券、积分、抽奖、会员等级、小程序直播、页面 DIY基本把新零售场景下的主流营销玩法都包进去了。这篇文章就按我复现 CRMEB 的实际路线来写先拆技术选型的理由再走一遍部署和小程序端联调然后逐个讲功能模块的配置链路最后把我踩过的坑和二次开发的技巧交代清楚。如果你正准备拿一套开源商城做二开或是搭建自己的电商项目这份笔记能帮你少走不少弯路。2. 技术选型拆解Tp6 和 uniapp 这套组合的边界在哪2.1 Tp6 做后端为什么是它而不是 Laravel 或 ThinkPHP 5CRMEB 后端选的是 ThinkPHP 6这个选择在国内开源商城项目里很常见。Tp6 对比 Tp5 最大的变化是底层架构重写采用更规范的容器管理依赖注入和中间件机制都有明显提升。对于商城这种需要频繁加模块、改逻辑的业务场景Tp6 的路由分组、验证器、模型关联这些特性能让你在写接口时少掉不少头发。我一般在本地环境直接跑 PHP 7.4 来配合 Tp6原因很简单Tp6 官方对 PHP 7.1 都支持但 7.4 的 JIT 和语法兼容性在跑 CRMEB 自带代码生成器时最稳。如果你手里是 PHP 8.0 以上的环境反而得注意一些老扩展的兼容问题这个坑我后面专门讲。后端入口结构上CRMEB 按app目录下的模块划分api模块对外提供接口admin模块管后台crontab模块处理定时任务。你二开时新增业务基本就是在这几个模块里加控制器和数据表然后配合系统自带的数据字典和菜单权限去注册。它的管理员权限是基于 RBAC 做的角色、菜单、按钮三级控制这个粒度在给运营配权限时很实用。2.2 uniapp 前端一套代码跑五个端的得与失CRMEB 的前端是用 uniapp 写的编译目标覆盖微信小程序、H5、App、公众号。说句公道话uniapp 的优势在于开发效率你只需要维护一套 Vue 语法的代码条件编译处理平台差异就能同时产出多端产物。但代价也很明确当某个端需要深度定制原生能力时你得写条件编译甚至去改对应的原生工程。拿小程序直播来说微信那边的直播组件只能在原生小程序里调用uniapp 提供的是封装好的live-player组件包装。CRMEB 的做法是在小程序端做了一个原生插件桥接把微信直播的推流和播放能力接入到 uniapp 的页面里。这个设计思路值得你二开时复刻——核心逻辑放 uniapp平台差异能力走条件编译和大前端插件。H5 端和 PC 端是两个独立的前端工程PC 管理后台用的是 elementUIH5 商城页面也是 Vue 生态。这样的拆分意味着页面风格切换不是靠 CSS 换肤那么简单而是整套 UI 组件体系的替换。CRMEB 后台的「风格切换」功能实际上是提前内置了几套可选的商城模板切换时只换数据不换代码结构。2.3 数据库设计订单、商品、会员这三张核心表的联动逻辑CRMEB 的数据库表有上百张新手容易被表数量吓住但其实核心链路看三块商品、订单、会员。商品表eb_product承载 SKU 和规格通过eb_store_product_attr_value关联具体规格的库存和价格订单表eb_store_order记录主单子订单和退款单都有独立表会员体系则是eb_user加等级表、积分流水表。商品到订单的链路是用户下单时系统先生成订单主记录再锁库存同时扣减对应规格的库存字段。这套逻辑如果你要加「预约购买」或「预售」这类场景改动的重点就是下单时的库存校验和支付后的状态流转。我一般会在eb_store_order的status字段旁加一个自定义状态用注释标注业务含义避免后续维护误判。数据库字符集建议建表时直接utf8mb4原因是商城商品名、用户昵称里经常出现 emoji 表情utf8会直接报错或存成乱码。CRMEB 的安装包默认 SQL 是 utf8mb4但如果你拿的是老版本的备份数据导入时要留意建表语句里的字符集。3. 本地部署跑通从下载源码到小程序端联调3.1 环境准备PHP、MySQL、Nginx 的版本红线部署 CRMEB 之前先把环境版本对齐。我用的是 PHP 7.4 MySQL 5.7 Nginx 1.18这套组合跑 CRMEB 最新版没有兼容问题。PHP 需要开启的扩展包括fileinfo、redis如果用缓存、bcmath价格计算精度、openssl。少了fileinfo的话后台图片上传会直接报错这个是新手经常忽视的。# 检查 PHP 扩展 php -m | grep -E fileinfo|redis|bcmath|openssl|pdo_mysql # 如果没有 fileinfo以 Ubuntu 为例 sudo apt-get install php7.4-fileinfo sudo systemctl restart php7.4-fpm参数说明bcmath在商城系统里用于金额计算PHP 的浮点运算在涉及分账、优惠拆分时容易丢精度开启 bcmath 后可以用bcadd、bccomp这类函数做精确运算。fileinfo是上传文件时校验文件 MIME 类型用的CRMEB 的商品图片和用户头像上传都依赖它。Redis 扩展看你的部署模式如果打算用 Redis 做缓存队列和验证码存储就必须装纯文件缓存模式也可以跑但高并发下撑不住。3.2 后端部署伪静态配置和安装向导源码下载解压后把项目根目录指向public目录。这一步很关键TP6 的入口在public/index.php如果你把站点根目录指到项目根目录前端会找不到路由。Nginx 的伪静态规则用 thinkphp 通用的那一套location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s/$1 last; } }逻辑说明这个配置的作用是把所有不存在的文件请求重写到index.php由 Tp6 的路由解析器接管。商城前端的页面链接、接口地址都是伪静态形式不配这条规则会导致访问任意页面都 404。需要注意的是Nginx 的if指令在这里是安全的因为只做文件存在性判断不涉及复杂的正则回溯。配置好虚拟主机后访问域名会进入 CRMEB 的安装向导。安装过程就是填数据库连接信息和管理员账号向导会自动导入 SQL 并生成.env文件。.env里的APP_DEBUG建议线上设为false否则异常堆栈会直接抛给用户既难看又泄露路径。3.3 前端跑起来uniapp 的 H5 和微信小程序编译CRMEB 的商城前端在template目录下是 uniapp 工程。想先在浏览器里看效果直接编译 H5 端最快cd template npm install npm run serve:h5参数说明serve:h5是 package.json 里预先定义好的脚本实际执行的是uniapp-cli的 H5 模式。第一次npm install会拉取大量依赖如果你网络状况一般建议设置镜像源为国内 npm 镜像。跑起来后访问localhost:8080默认会请求localhost:80的接口如果你后端跑在别的端口需要改template/.env里的VUE_APP_BASE_URL配置。微信小程序端需要先npm run build:mp-weixin生成dist/build/mp-weixin目录然后用微信开发者工具导入这个目录。这里有个常见问题开发者工具里打开后页面白屏大部分原因是后台接口域名没有在「详情 → 本地设置」里勾选「不校验合法域名」。调试阶段可以临时勾上上线前还是得在小程序后台配 request 合法域名。npm run build:mp-weixin逻辑说明编译产物是原生小程序代码CRMEB 的 uniapp 工程会在编译阶段把 Vue 语法转成微信小程序的 WXML 和 JS。这个过程会自动处理组件转换但如果你直接改了template里的原生小程序插件目录编译会被覆盖所以原生自定义部分要放在插件目录里独立维护。3.4 后台首次登录菜单权限和基础配置要点安装完成后访问后台域名默认路径是/admin。首次登录用安装时创建的管理员账号。进去后先做三件事配置站点信息、配置支付方式、创建角色和菜单权限。站点信息里的 URL 地址会影响前端接口请求和生成分享海报时的域名拼接填错会导致前端图片加载不出来。支付方式默认是关闭的需要先在「设置 → 支付方式」里配置微信支付和支付宝的商户参数。开发阶段可以用测试密钥但注意 CRMEB 存在缓存机制改完支付参数后需要清理runtime/cache目录下的缓存否则前端支付时还是走旧配置。菜单权限那边如果你只想让运营人员看订单和商品就不要勾选系统设置相关的权限节点权限树是异步加载的保存后需要重新登录才能生效。4. 功能模块怎么落地分销、拼团、秒杀和页面 DIY 的配置链路4.1 分销体系配置三级分销的分佣规则和结算时机CRMEB 的分销功能内置了三级分佣关系链通过用户表的spread_uid字段记录上下级关系。后台配置路径是「应用 → 分销」主要设置几个参数分销模式指定人分销还是人人分销、佣金比例、提现门槛。系统默认只有推广订单完成后才生成佣金账单而不是支付成功立即结算这样做的好处是降低了退款操作带来的佣金追回成本。实际业务中你需要设计分销等级和升级条件。CRMEB 支持根据累计佣金或订单数自动升级分销等级等级不同佣金比例不同。我的建议是分销比例先在后台跑通默认值再根据商品毛利调整不要一上来就设 30% 佣金很容易亏本。4.2 营销玩法差异拼团、砍价、秒杀的规则引擎对比拼团、砍价、秒杀这三个模块在 CRMEB 里是独立的表结构但都复用了商品 SKU 和订单流程。拼团的规则是「N 人成团成团后发货」核心表eb_store_pink记录团状态砍价是「帮砍人数越多价格越低」价格由eb_store_bargain表里的起始价和最低价决定秒杀是「限时、限量、限价」秒杀商品挂在eb_store_seckill下。模块核心参数状态变更依据与普通订单的关系拼团成团人数、限购数量参团人数达到阈值先占库存成团失败自动退款砍价起始价、底价、帮砍人数砍价金额累计达到底价砍价完成生成待支付订单秒杀秒杀时段、秒杀库存库存扣减到零独立店铺商品单独限制购买这三个模块二开时最容易出问题的地方是库存一致性。CRMEB 的秒杀库存是单独字段seckill_stock不占用普通库存所以你要在商品上下架时同步维护这两个库存值。我曾经在对接 ERP 时只同步了普通库存导致秒杀库存卖超这是一个很典型的坑。4.3 促销工具联动优惠券、积分、抽奖的组合使用策略优惠券模块支持满减券和折扣券创建时可以限制品类、金额门槛和使用时段。积分体系则是「消费得积分、积分抵现金」的闭环。抽奖功能是典型的拉活跃工具支持转盘和刮刮卡两种形式奖品池可以放积分、优惠券、实物。运营策略上我建议把优惠券和积分设计成联动用户抽奖得到大额优惠券但设置了使用门槛促使他继续凑单消费积分抵现比例控制在 5% 以内避免利润被积分的抵现金额吃掉。CRMEB 后台的「优惠券发放记录」和「积分流水」都能在「数据 → 财务报表」里对账核心操作是定期核对优惠券核销金额和实际收款金额的差值。4.4 页面 DIY可视化装修的实际边界页面 DIY 是 CRMEB 的差异化功能后台拖拽组件生成商城首页、活动专题页。它的实现原理是可视化编辑器生成 JSON 结构前端根据 JSON 渲染组件。这意味着 DIY 出来的页面灵活度很高但也意味着如果你要新增一个组件类型需要前端和后端配合在组件库里加配置项和渲染器。我用这个功能时一般按两个方向来一是首页用来承载品牌宣传和核心入口做组件拼装二是活动页交给运营自己拖拽搭建减少 UI 排期。注意 DIY 组件里的数据源有两种一种是系统固定的商品列表、分类列表另一种是自定义接口数据后者需要开发人员配置数据源地址。运营如果不懂接口配置就会把页面搭出来但显示空白所以我通常给运营配一个只读的角色限制他们只能使用预设的数据源。5. 避坑记录定时任务、伪静态、字符集和小程序校验那些事5.1 订单状态不自动流转秒杀结束还是「进行中」现象后台秒杀活动到点后状态仍是进行中订单超时未支付也不会自动关闭。原因CRMEB 的订单超时关闭、秒杀活动结束、拼团超时退款全部依赖定时任务。crontab模块有一个Crontab命令官方文档要求配到系统计划任务里。如果只是配置了php think timer但没设置好时间间隔或者是像宝塔面板这种环境没有正确识别 PHP 路径定时任务就静默失效了。解决在系统 crontab 里加上*/1 * * * * php /你的网站路径/think timer参数说明timer是 Tp6 命令空间的入口系统每分钟执行一次内部会去扫所有到期任务包括订单超时节点、拼团状态检测、秒杀开始前预热、分销佣金结算。注意这里的间隔是 1 分钟如果你改成 5 分钟用户下单后订单关闭时间会延迟最多 5 分钟这在秒杀场景里会造成库存无法及时释放。5.2 前端点击链接变 404刷新页面也白屏现象H5 商城在页面内跳转正常但复制链接到新窗口打开或者刷新当前页面直接 404。原因这是典型的 Vue History 路由问题Nginx 只配置了根路径的重写没有覆盖所有子路径的 fallback。如果伪静态规则只写在location /里而你的 Nginx 里还有别的 location 优先级高的配置请求会落到错误路由。解决把伪静态规则覆盖到整个站点根目录location / { try_files $uri $uri/ /index.php?s$uri$args; }注意这套规则同时适用于后端接口和前端页面但public目录下的静态资源图片、JS、CSS不需要重写Nginx 会优先判断文件是否存在。如果资源也得走重写说明root路径指错了检查站点根目录是否指向public。5.3 后台保存商品带表情符号的文本直接报错现象商品详情里加了 emoji 表情保存时提示数据库错误或者保存成功后前端读出乱码。原因数据表字符集不是 utf8mb4。utf8在 MySQL 里最多存 3 字节emoji 是 4 字节所以直接报Incorrect string value。很多老 SQL 备份文件里建表语句是DEFAULT CHARSETutf8你导入后如果没改踩坑是必然的。解决全局替换字符集并转表ALTER TABLE eb_product CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;参数说明CONVERT TO会改变表中既有字段的字符集对已有数据做转换。有一个坑是转换后字段的默认值可能被改动建议先全库备份。商城核心的表如eb_product、eb_store_order、eb_user、eb_store_product_attr_value都需要执行其他表也建议都转不然后续加字段时还是有问题。5.4 微信小程序白屏request 合法域名校验失败现象开发者工具里已经完全编译成功但小程序打开后页面白屏Console 报request:fail url not in domain list。原因微信小程序的网络请求被限制为必须使用 HTTPS而且域名需要在小程序管理后台配置request 合法域名。开发调试阶段如果没勾选「不校验合法域名」所有 API 请求都会被拦截。解决开发阶段在微信开发者工具里勾选详情 → 本地设置 → 不校验合法域名上线前把后端域名配置到小程序后台的 request 合法域名里且必须备案、必须 HTTPS。如果你用的证书是自签的也会同样白屏微信不认自签证书需要换正规 CA。5.5 管理后台接口 500日志里全是「Class not found」现象登录后台后部分功能打开报 500查看runtime/log里的日志发现是某个类不存在。原因PHP 版本和扩展不匹配导致的 Composer 依赖问题。比如topthink/think-orm在某些 PHP 8.0 版本下会有兼容问题而 CRMEB 源码包里自带的 vendor 是按 PHP 7.4 生成的。换了 PHP 版本后 autoload 失效就会出现类找不到。解决重新执行依赖安装并强制刷新rm -rf vendor composer install --no-dev参数说明--no-dev跳过开发依赖生产环境不需要 Debug 工具包。如果你没有修改过 CRMEB 的 composer.json这个操作不会影响系统功能。执行完后清理runtime缓存重新登录后台就正常了。6. 二次开发的三个快速上手技巧二开 CRMEB最忌讳的是直接钻进代码里逐行读。我的做法是先跑通一个最小的二开链路加数据表 → 注册菜单 → 写接口 → 前端调用。第一个技巧是使用代码生成器。CRMEB 后台的代码生成器可以基于你新建的数据表反向生成控制器、模型、验证器和前端页面。我用它生成过一个「供应商结算单」模块从表设计到后台可管理页面耗时不到半小时。生成后需要手动调整的是关联关系比如结算单要关联用户表和订单表这些关联关系生成器不会自动识别需要你自己在模型里补上belongsTo方法。第二个技巧是用好数据字典。数据字典里记录了每张表的字段含义和枚举值二开前先查字典能省去猜字段的功夫。我改订单模块时发现pay_type字段的枚举值有weixin、alipay、offline但字典里没写offline是什么场景触发的。后来翻了代码才知道是后台管理员手动标记付款。所以数据字典不是完全可信但它是探索代码的索引图。第三个技巧是留意template目录下的页面组件缓存。uniapp 编译后的产物在dist目录很多人改完页面后发现没生效是因为改的是template下的源码忘了重新编译。我一般会在发布脚本里加一步强制重新构建npm run build:mp-weixin cd ../ php think clear逻辑说明php think clear是 Tp6 的缓存清理命令同时会清掉模板缓存和日志缓存。微信小程序端的 API 请求如果遇到 404 或数据变化不刷新大多是这个缓存没清。从那以后我每次二开都强制走一遍「改代码 → 重新编译 → 清缓存 → 真机预览」的流程这个顺序救了我无数次。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?