☰
tpshop多商户源码实战:B2B2C数据隔离与订单拆分
2026/10/10 4:37:05 网站建设 项目流程

简介:这是一套基于ThinkPHP框架开发的tpshop多商户B2B2C商城源码,面向电商开发者、二次开发人员及计算机专业学习者,可支撑多商家入驻、门店管理、商品分销等商业模式,并覆盖PC、H5、微信小程序与APP多端访问。资源包共2000个文件,以948个html模板、447个php业务逻辑、231个js脚本与167个css样式为主,另含sql建表脚本、xml/json配置及md说明文档,压缩包约159.42MB,目录结构清晰,便于按模块检索与调试。目前已有184人学习下载。源码写法简明、接口友好,商家入驻、门店线上线下衔接、分销推广等核心模块完整,适合作为学习参考或二次开发底座,读者可据此理解多商户电商的架构组织与业务实现,并在此基础上定制个性化功能。

1. tpshop多商户源码到底能跑出什么形态:从单店到B2B2C的边界

很多人第一次接触 tpshop 多商户源码,是冲着“一套代码同时支持平台自营、商家入驻、门店提货、分销裂变”这句话去的。真把包解压开、数据库导进去、后台登进去,才发现它和普通单店商城最大的区别不在前端页面,而在角色模型:平台方、商家、门店、分销员四类身份共用一套用户表,却各自挂不同的权限和数据范围。tpshop b2b2c 源码的核心价值就在这里——它把“谁卖货、谁发货、谁分钱、谁核销”拆成了可配置的链路,而不是写死在订单表里。

手机端在这套体系里不是简单套个 H5 模板。多商户场景下,商家要能在手机上看自己店铺的订单,门店要能扫码核销,分销员要能生成带自己标识的推广链接,这三件事对接口鉴权和数据隔离的要求完全不同。如果你只拿它当普通商城改,后面加一个角色就要动一次订单查询逻辑,血泪经验就是:先理清角色和数据的归属关系,再动模板。

这套源码适合谁?适合手里有平台运营需求、需要快速搭出“多商家入驻 + 线下门店 + 分销”雏形的团队,也适合想研究 B2B2C 订单拆分和分账逻辑的开发者。它不适合只想开一个单店、不想碰商家审核和结算的人——那类需求用单商户版本更省事。下面按“环境怎么搭 → 多商户数据怎么隔离 → 手机端和分销怎么接 → 坑在哪 → 怎么验证”推一遍。

2. 把 tpshop 多商户源码在本地跑起来:环境、目录与数据库三件事

2.1 环境选型:PHP 版本和扩展比想象中挑

tpshop 系列常见做法是 PHP 5.6 到 PHP 7.2 之间,多商户版本因为要处理商家上传的图片、门店定位、分销关系链,对 GD、PDO_MySQL、cURL、OpenSSL 这几个扩展是硬依赖。我一般会先用php -m过一遍,缺哪个补哪个,别等装到一半报“Call to undefined function imagecreate”。

本地搭建推荐用 Linux 环境,Windows 下路径分隔符和文件权限容易让商家上传目录出玄学问题。下面是一套最小可用的环境检查脚本,放在项目根目录执行:

#!/bin/bash # 检查 tpshop 多商户运行所需的基础环境 echo "=== PHP 版本 ===" php -v | head -n 1 echo "=== 必需扩展 ===" for ext in pdo_mysql gd curl openssl mbstring fileinfo; do if php -m | grep -qi "^${ext}$"; then echo "[OK] ${ext}" else echo "[缺失] ${ext} <-- 必须安装" fi done echo "=== 目录可写检查 ===" for dir in runtime public/uploads application/common/conf; do if [ -w "$dir" ]; then echo "[可写] $dir" else echo "[不可写] $dir <-- chmod 755 或改属主" fi done

逻辑说明:先确认 PHP 大版本,再逐个核对扩展,最后检查运行目录和上传目录的写权限。参数上,runtime是框架缓存目录,public/uploads是商家和门店图片的落盘位置,这两个目录权限不对,后台会出现“保存成功但图片不显示”的假象。application/common/conf里通常放数据库配置文件,安装向导要往里写内容,所以也得可写。

2.2 目录结构:多商户的“商家”藏在哪个模块

解压后不要急着点安装。先看application下的模块划分,常见结构是admin(平台后台)、seller(商家后台)、home(前台)、mobile(手机端)、api(接口)。多商户和单商户最明显的区别就是多了一个seller模块,门店相关逻辑一般挂在seller或独立的store控制器里。

用一条命令快速确认模块是否齐全:

ls -d application/*/ | sed 's#application/##;s#/##'

如果输出里没有seller,那这套包大概率是单商户改的,或者多商户模块被裁剪过。这时候不要硬着头皮往下装,先确认包来源。正常的多商户包,seller目录下会有controller、model、view三层,view里还能看到商家订单、门店管理、分销明细这些模板文件。

数据库方面,安装向导会导入一份基础 SQL。导入前建议先建一个空库,字符集选utf8mb4,排序规则utf8mb4_general_ci。多商户场景下商家名称、门店地址、分销备注都可能出现特殊字符,utf8三字节版本会在某些生僻字上翻车。

2.3 安装向导与后台入口:别把平台后台和商家后台搞混

安装流程本身不复杂:访问域名进入安装页,填数据库信息,设管理员账号,等它跑完。真正容易出错的是装完之后进哪个后台。平台后台一般是/index.php/admin,商家后台是/index.php/seller,手机端是/index.php/mobile或独立域名。三个入口的登录态是分开的,平台管理员账号不能直接登商家后台。

装完后先做一次最小验证:平台后台能登录、商家后台能登录、前台能打开、手机端能打开。四个都通,再往下配商家入驻和分销。如果商家后台登录后空白,先看runtime/log里的错误日志,八成是seller模块的权限节点没初始化,或者数据库里商家表为空导致查询直接返回异常。

提示:安装完成后立刻把application/common/conf下的数据库配置备份一份,后面调分销和门店参数时改崩了能快速回滚。

3. 多商户数据隔离与订单拆分:商家、门店、分销员怎么各看各的

3.1 商家数据隔离靠什么字段

多商户系统里,几乎每张业务表都会带一个store_id或seller_id。订单表、商品表、优惠券表、分销记录表,查询时都要带上这个条件。tpshop b2b2c 源码常见做法是在模型层做全局作用域,或者在控制器里手动拼where('store_id', $sellerId)。两种方式各有代价:全局作用域省事,但平台后台查全量数据时要临时关掉;手动拼灵活,但容易漏。

我一般会先确认订单表结构里有没有store_id,以及商家后台的订单列表是不是按这个字段过滤。可以用一条 SQL 快速验证:

-- 查看订单表中与多商户相关的关键字段 SHOW COLUMNS FROM tp_order LIKE '%store%'; SHOW COLUMNS FROM tp_order LIKE '%seller%'; SHOW COLUMNS FROM tp_order LIKE '%distrib%'; -- 统计每个商家的订单量,确认隔离是否生效 SELECT store_id, COUNT(*) AS order_count FROM tp_order GROUP BY store_id ORDER BY order_count DESC;

逻辑说明:第一条确认字段命名,不同版本可能用store_id也可能用seller_id。第二条按商家分组统计订单量,如果所有订单都挂在同一个store_id下,说明下单时没有正确写入商家标识,后面分账和结算全错。参数上,tp_是默认表前缀,实际以安装时填的为准。

3.2 订单拆分:一个购物车跨店下单怎么处理

多商户最典型的场景是用户在一个购物车里加了 A 店和 B 店的商品,提交后系统必须拆成两笔订单,分别归属两个商家。tpshop 多商户源码通常在下单逻辑里按store_id分组,每组生成一个主订单号,再挂子订单。分账、发货、退款都按子订单走。

这里的关键参数是订单分组依据和主从订单号生成规则。常见做法是主订单号用时间戳加随机数,子订单号在主订单号后加商家序号。如果拆单逻辑写错,会出现“A 店商家能看到 B 店商品”的严重问题。验证方法是下一笔跨店订单,然后分别登录两个商家后台看订单列表,各自只能看到自己的商品和金额。

分销员的数据隔离是另一层。分销员一般绑定在用户表上,通过distributor_id关联订单。分销佣金记录表里通常有order_id、distributor_id、commission三个核心字段。查佣金时既要按分销员过滤,也要按订单状态过滤——未完成订单的佣金是冻结状态,完成后才可提现。

3.3 门店核销:线上买、线下取的链路怎么接

门店模块的核心是核销码。用户下单后生成一个核销码,门店店员在手机端输入或扫码,系统校验后把订单状态改成“已核销”。tpshop 多商户源码里,门店通常挂在商家下面,一个商家可以有多个门店,每个门店有独立的核销权限。

核销链路要确认三件事:核销码存在哪张表、核销接口有没有校验门店归属、核销后订单状态怎么流转。常见表是tp_store存门店信息,tp_order_writeoff或类似表存核销记录。接口一般在api模块下,手机端调用。如果核销接口只校验了核销码没校验门店,A 店店员就能核销 B 店的订单,这是典型的越权漏洞。

注意:门店核销接口一定要同时校验核销码、门店 ID、商家 ID 三者归属,只校验核销码等于没校验。

4. 手机端与分销接入:接口鉴权、推广链接和佣金结算

4.1 手机端接口鉴权:token 怎么发、怎么验

tpshop 手机端一般走 API 接口,登录后返回 token,后续请求带 token 换用户身份。多商户场景下,token 里除了用户 ID,最好还带上当前角色和商家 ID(如果用户同时是商家)。常见做法是 JWT 或数据库存 token 映射。

下面是一个典型的手机端登录接口调用示例,用 curl 模拟:

# 手机端登录,获取 token curl -X POST "http://your-domain/index.php/api/user/login" \ -H "Content-Type: application/json" \ -d '{"mobile":"13800000000","password":"your_password"}' # 用 token 请求商家订单列表 curl -X GET "http://your-domain/index.php/api/seller/order/list" \ -H "Authorization: Bearer <上一步返回的token>" \ -H "Content-Type: application/json"

逻辑说明:登录接口返回 token 后,后续请求放在Authorization头里。参数上,mobile和password是登录凭据,商家订单接口会从 token 解析出用户 ID,再查这个用户绑定的商家,最后按store_id过滤订单。如果 token 里没带商家信息,接口内部就要多查一次用户-商家绑定表,性能差但逻辑简单;带了则快,但 token 泄露后商家数据风险更大。

4.2 分销推广链接:标识怎么带、关系怎么绑

分销员生成推广链接时,链接里通常带distributor_id或加密后的邀请码。用户点链接进站,系统在 cookie 或 session 里记下这个标识,下单时写入订单表的分销字段。tpshop 多商户源码里,分销关系一般分两级或三级,具体层级在后台分销设置里配。

关键参数有三个:绑定时机、分佣比例、结算周期。绑定时机常见是“首次点击绑定”或“首次下单绑定”,前者容易被人刷,后者更稳。分佣比例按商品或按商家配,多商户下每个商家可以设不同比例。结算周期一般是订单完成后 T+N 天,防止退款后佣金已提现。

验证分销是否生效,可以自己生成一个推广链接,用另一个账号点进去下单,然后看分销记录表里有没有生成对应记录。如果没生成,先查链接里的标识有没有被正确解析,再查下单逻辑有没有读这个标识。

4.3 佣金结算与提现:钱从哪扣、什么时候能提

分销佣金本质是平台或商家让利。多商户下,佣金通常从商家结算金额里扣,平台只做记账。佣金记录表里会有状态字段:冻结、可提现、已提现、已取消。订单完成前是冻结,完成后转可提现,退款则取消。

提现流程要确认打款方式。常见是分销员发起提现申请,平台后台审核,线下打款后标记已提现。如果系统接了支付接口自动打款,要额外注意并发和幂等,避免重复打款。这块我踩过的坑是:提现审核通过后直接改了余额,但没写提现流水,对账时完全查不清。

提示:佣金结算相关表一定要有流水记录,余额字段可以算出来,但流水丢了就再也补不回来。

5. 部署 tpshop 多商户时最容易翻车的 5 个点

5.1 商家后台登录后一片空白

现象:平台后台正常,商家后台登录成功但页面空白,浏览器控制台无报错,PHP 日志有“Call to a member function on null”。

原因:商家表里没有对应记录,或者当前用户没有绑定任何商家,seller模块初始化时拿不到商家信息直接抛异常。

解决:先查tp_seller或类似表里有没有这个用户对应的商家记录,没有就手动补一条,或者走平台后台的“商家入驻审核”流程正常创建。再检查seller模块的基类控制器有没有对空商家做兜底。

5.2 手机端接口返回 401 但 token 明明带了

现象:用 Postman 调手机端接口,token 放在 header 里,返回 401 未授权。

原因:token 的 header 名称不对,或者 token 过期时间设得太短,或者接口用的是 session 而不是 token 鉴权。

解决:先确认接口文档里 header 名称是Authorization还是token,再看 token 生成时有没有设过期时间。如果是 session 鉴权,手机端要带 cookie,这就不适合 App 场景,需要改成 token 模式。

5.3 跨店下单后商家看到别人的订单

现象:用户在一个购物车里买了 A、B 两店商品,下单后 A 店商家后台能看到 B 店商品。

原因:拆单逻辑没生效,或者订单列表查询没按store_id过滤。

解决:查订单表里这笔订单的store_id是不是只有一个值,如果是,说明拆单没执行。再查商家后台订单列表的查询条件,确认有没有where('store_id', $sellerId)。两个都正常还出问题,就看模型层有没有全局作用域把条件覆盖了。

5.4 门店核销后订单状态没变

现象:手机端提示核销成功,但订单状态还是“待核销”。

原因:核销接口只写了核销记录,没更新订单状态,或者更新了但事务没提交。

解决:查核销接口代码,确认有没有update订单状态的操作,以及这个操作和核销记录写入是否在同一个事务里。如果分开写,中间出错就会不一致。建议核销记录和订单状态更新放在一个事务里,要么都成功要么都回滚。

5.5 分销佣金算出来是负数或翻倍

现象:分销记录里佣金金额不对,有的负数,有的比订单金额还高。

原因:分佣比例配置错误,或者退款后佣金没回滚,或者同一订单被多个分销员重复绑定。

解决:先查后台分佣比例是不是设成了大于 1 的数,再查退款逻辑有没有把对应佣金记录置为取消。重复绑定一般是绑定逻辑没做唯一性校验,同一订单同一分销员应该只有一条有效记录。

6. 用一笔跨店分销订单验证整套链路是否真的通了

前面拆了环境、隔离、手机端、分销和坑,最后落到一个具体验证方法:自己造一笔“跨店 + 分销 + 门店核销”的订单,看整条链路的数据流转。这是我认为最值得养成的习惯——不要只看后台页面能不能打开,要看数据表里的记录对不对。

具体操作:用分销员 A 的推广链接,用买家账号 B 下单,购物车里放商家甲和商家乙各一件商品,收货方式选门店自提。下单后依次检查:

检查点预期结果对应表/位置
订单是否拆成两笔两个子订单,分别归属甲、乙订单表 store_id 字段
分销记录是否生成一条冻结状态佣金记录,绑定分销员 A分销记录表
门店核销码是否生成每个子订单一个核销码核销码表
手机端商家甲能否看到订单只能看到甲的子订单商家后台/手机端接口
核销后佣金状态订单完成后佣金转可提现分销记录表状态字段

如果这张表里每一项都对,说明多商户隔离、分销绑定、门店核销三条链路都通了。有一项不对,就回到对应章节查字段和查询条件。

进阶一点的做法是写一个简单的校验脚本,直接查数据库比对:

-- 验证最近一笔跨店订单的拆分和分销绑定 SELECT o.order_id, o.store_id, o.order_status, d.distributor_id, d.commission, d.status AS commission_status FROM tp_order o LEFT JOIN tp_distributor_record d ON d.order_id = o.order_id WHERE o.order_sn = '你的主订单号';

逻辑说明:这条 SQL 把订单和分销记录关联起来,一次看清订单归属哪个商家、绑定了哪个分销员、佣金多少、什么状态。参数上,order_sn换成你实际下单的主订单号。如果store_id只有一个值,拆单没生效;如果distributor_id为空,分销绑定没生效;如果commission_status一直是冻结,结算逻辑没跑。

我自己的习惯是每次改完分销或门店相关代码,都跑一遍这个验证,比点后台快得多,也不容易漏。这套 tpshop 多商户源码的复杂度主要在角色和数据关系上,页面反而是最不容易出问题的部分。把数据链路盯住,后面加商家、加门店、调分佣比例都只是改配置。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询