拓客小程序源码1.0.16实战:从用户绑定到佣金归因的核心设计
发布时间:2026/9/14 2:49:31来源:尧图网络
简介江湖拓客小程序源码1.0.16是一套面向商家与企业客户拓展场景的微信小程序完整代码包用于通过地图定位、数据采集与用户行为分析等方式精准挖掘潜在客户并支持按业务需求进行二次开发适合有PHP或小程序开发基础的技术人员、以及需要快速搭建拓客工具的企业技术团队。资源共2000个文件压缩包约25.21MB主体为php与js前者对应后端服务、接口与数据库逻辑后者负责小程序前端交互同时包含大量png/gif图标素材、css样式、md说明及xlsx数据样例目录结构覆盖代码、文档、配置和示例数据便于对照研究。已有631人学习下载。开发者可基于源码梳理完整项目链路掌握从用户授权、位置服务到客户线索沉淀的实现思路也可直接修改页面逻辑与接口配置快速构建适用于本地生活、营销推广等行业的拓客工具并根据1.0.16版本的迭代特点继续扩展新功能。1. 江湖拓客小程序源码不是营销页是一套客户归因系统江湖拓客小程序源码 1.0.16 面向「强销售、弱品牌」场景典型使用者是装修、教培、保险、企业服务这类靠业务员和兼职推广员拉客户的公司。核心问题永远是一个客户从哪个渠道进来、算谁的业绩、成交后佣金怎么分。源码价值不在前台营销页而在绑定关系、线索归因、佣金结算这条链路。1.0.16 是迭代到正式阶段的版本交付通常是前端、后台、数据库脚本。运营装上就能配开发的活主要在二次改造换白标、对接产品库、把线索同步给现有 CRM。下文按接手源码的顺序讲模块与数据、本地跑通、关键参数、上线细节代码和参数可直接抄。2. 拓客源码 1.0.16 的模块边界与两张核心数据表2.1 一个标准拓客源码包通常拆成哪五块拿到包先别急着跑先把目录和服务端代码捋一遍。1.0.16 这类面向商业交付的源码通常按用户、内容、海报、线索、佣金五个子模块组织对应关系大致如下子模块小程序端形态管理后台对应一句话职责用户与绑定微信登录、扫码进入用户列表、上下级关系记录身份和推荐人内容展示名片、案例库、产品图文内容发布与管理给推广员提供弹药海报与分享保存海报、转发卡片海报模板配置生成带参小程序码线索与订单留资表单、在线下单线索池、订单管理做转化和业绩归因佣金与提现我的收益、提现申请结算设置、提现审核分钱并把账记清楚我一般会先对着这五列打勾验收缺线索池或砍掉提现审核的包后台运营日常会非常难受这两个模块恰恰是最不能省的部分。五块完整的源码包在行情里价格也明显高出一截阉割版的包改起来成本远超差价不建议接手。版本目录上1.0.16 常见的布局有两种原生小程序目录project.config.json 加 miniprogram/配 PHP 后台或者 uniapp 工程manifest.json 加 pages.json配 thinkphp 后台。这两种布局的配置入口不一样但有个共同原则改业务逻辑永远改源码不要改编译产物否则下次构建全丢。2.2 用户关系表与佣金流水表怎么建拓客源码的所有业务逻辑最后都要落到两张表上上下级关系表和佣金流水表。关系表决定「客户归谁」佣金表决定「钱给谁」。关系表最常见的模型是「一用户一上级」即一个用户最多只有一个推荐人绑定后长期有效很多源码还会加一个 30 天或 90 天的保护期保护期内不允许换绑。建表 SQL 大致是这样CREATE TABLE tuoke_relation ( id int(11) unsigned NOT NULL AUTO_INCREMENT, uid int(11) NOT NULL COMMENT 用户ID唯一身份, pid int(11) NOT NULL DEFAULT 0 COMMENT 上级推广员ID0 表示没有上级, deep tinyint(4) NOT NULL DEFAULT 1 COMMENT 距顶层的层级数, scene varchar(64) NOT NULL DEFAULT COMMENT 入场渠道qr/card/h5, created_at int(11) NOT NULL DEFAULT 0 COMMENT 首次绑定时间, updated_at int(11) NOT NULL DEFAULT 0 COMMENT 最近更新时间, PRIMARY KEY (id), UNIQUE KEY uk_uid (uid), KEY idx_pid (pid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT拓客上下级关系表;这里的uk_uid是核心设计它保证一个用户只有一行天然杜绝「扫码一次插一条」导致的关系重复。deep是冗余字段算佣金时可以快速判断是否超出层级上限避免每次递归查整条链。scene字段建议保留后面分析渠道投放效果时直接GROUP BY scene就能看出扫码和转发卡片哪个贡献大。佣金流水表要按「一笔订单一条记录」设计订单号必须有索引CREATE TABLE tuoke_commission ( id int(11) unsigned NOT NULL AUTO_INCREMENT, order_sn varchar(32) NOT NULL COMMENT 来源订单号对账锚点, uid int(11) NOT NULL COMMENT 获得佣金的推广员, from_uid int(11) NOT NULL COMMENT 成交客户ID, amount decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 佣金金额, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 0待结算 1可提现 2已打款 3已失效, settle_at int(11) NOT NULL DEFAULT 0 COMMENT 实际结算时间, PRIMARY KEY (id), KEY idx_uid_status (uid,status), KEY idx_order (order_sn) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT佣金流水表;佣金金额用 decimal 而不是 float是为了结算对账不出浮点误差。idx_uid_status覆盖「某个推广员有多少可提现佣金」这类高频查询idx_order是退单时按订单号反查佣金用的。status 的状态机建议保持单向流转待结算到可提现到已打款退款时走失效不要允许跳过状态否则后台审核会乱。2.3 海报二维码要用接口出别在前端拼拓客海报是转化率的关键海报上那个码必须是小程序码用户长按识别才能带参进入。很多新手把码画在前端 canvas 上这在两个问题小程序码生成需要 access_token 调官方接口前端拿不到前端画码容易糊码里的信息量和识别率都打折扣。正确做法是服务端调getwxacodeunlimit接口拿到二进制图片存服务器或 OSS再配合海报模板合成。PHP 源码包里最常见的写法$token get_access_token(); // 全局缓存过期前 200 秒刷新 $url https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token{$token}; $body json_encode([ scene uid . $uid, // 可见字符最多 32 个只放参数不放冗余 page pages/index/index, // 必须是已发布页面不带 query width 430, // 码的边长配合海报尺寸 check_path false, // true 要求页面已发布提审前记得改 env_version release, // release / trial / develop ], JSON_UNESCAPED_UNICODE); $resp http_post($url, $body); // 成功返回 image/jpeg失败返回 JSON if (strpos($resp, errcode) false) { file_put_contents(/data/posters/{$uid}.jpg, $resp); }scene 是整条链路的核心用户扫码进入小程序后前端在onLoad里拿到的options.scene是 URL 编码过的必须先decodeURIComponent再解析。page不能带问号和参数参数全部放进 scenecheck_path在联调期设 false 省事提审前要改回 true。另外 access_token 获取接口每天有 2000 次调用上限必须做全局缓存不做缓存的话用户量一大小程序码接口会被账号限流。3. 本地跑通 1.0.16先认工程类型再改三个配置3.1 先分清交付物是原生小程序还是 uniapp 工程这一步判断错了后面所有配置都会找错位置。打开交付包根目录看特征文件有project.config.json和miniprogram/目录的是原生微信小程序微信开发者工具直接导入有manifest.json和pages.json的是 uniapp 工程需要先用 HBuilderX 打开配好微信 appid 后重新编译出 dist再导入开发者工具。现在市面上的小程序源码交付PHP 后台配 uniapp 前端的比例很高uniapp 一套代码能同时出微信、支付宝和 H5对做多端拓客业务的团队划算。但注意 uniapp 工程里如果带了unpackage/dist/dev/mp-weixin这层编译产物开发者工具要导出的应该是这个 dist 目录而不是工程根目录如果之前有人在 dist 里手动改过东西build 一次就全被覆盖。所以接手 1.0.16 时我一般先确认哪些改动写在源码里避免后续全量编译把线上差异冲掉。3.2 三个必改配置appid、接口地址、合法域名本地跑通最快路径是后端起在 127.0.0.1前端用开发者工具编译开发阶段勾选「不校验合法域名」。三个配置逐一改。第一个是 appid。原生改project.config.json里的appid字段uniapp 改manifest.json里 mp-weixin 节点下的 appid。没有真实 appid 时可以先用测试号但测试号调不了微信登录和订阅消息功能验证不完整所以建议尽早用企业主体的真实 appid。第二个是接口地址。前端接口地址统一收敛在一个配置文件里原生常见utils/config.jsuniapp 常见common/config.js写法类似// utils/config.js const ENV dev; const CONFIG { dev: { baseUrl: http://127.0.0.1:8080/api, // 仅限开发者工具内调试 }, prod: { baseUrl: https://tuoke.example.com/api, // 微信要求 https 且域名已备案 } }; module.exports CONFIG[ENV];前端所有 wx.request 都从这个文件读 baseUrl。本地联调时 127.0.0.1 没问题但真机预览就访问不到手机也访问不到电脑的 localhost这是新手最常卡住的地方。要真机调试要么后端起在局域网 IP要么直接把 HTTPS 域名配上。调试接口本身直接用开发者工具 Network 面板看请求和响应比外部抓包工具省事。第三个是 request 合法域名。在微信公众平台「开发管理 → 开发设置 → 服务器域名」里添加 request 合法域名。提示开发阶段务必在开发者工具「详情 → 本地设置」勾选「不校验合法域名」否则本地接口直接报request:fail url not in domain list这是新手最常遇到的第一个报错。后端配置集中在服务端项目根目录的.env# server/.env PHP 端以 thinkphp / laravel 类框架为例 APP_DEBUGfalse DB_HOST127.0.0.1 DB_NAMEtuoke_1016 DB_USERtuoke DB_PASS你的数据库密码 WX_APPIDwx你的appid WX_SECRET你的apisecretWX_SECRET这类敏感配置不要提交进 git接手后第一时间改掉默认值并确认交付包里没有残留上家的线上数据库地址和密码。二手市场流转过好几轮的包配置文件里经常留着别人的生产库连接串这是安全隐患。3.3 数据库导入与服务端初始化的常见坑数据库脚本一般在交付包的sql/目录导入执行mysql -utuoke -p tuoke_1016 /path/to/install.sql导入后进后台管理端初始账号密码通常是 admin / admin123登录后第一件事改密码再检查后台能否正常读到默认配置。这一环节有四个高频坑。第一个是 PHP 版本兼容老包用 PHP 5.6 语法写的放到 PHP 7.4 或 8.x 环境直接语法报错装环境前先看交付文档或 composer.json 要求的版本。第二个是运行时目录权限thinkphp 类框架的runtime/必须可写否则白屏或报「目录不可写」执行chmod -R 775 runtime即可。第三个是伪静态Apache 环境一般自带 .htaccessNginx 要手动加 rewrite# /etc/nginx/sites-available/tuoke.conf location 段 location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s$1 last; } }第四个坑是时区和字符集数据库连接要显式指定 utf8mb4否则用户昵称里的 emoji 存进去直接变问号。这几个问题排查完前后端基本就能联调了。4. 拓客链路里最该调的三个参数绑定、佣金、订阅4.1 上级绑定不能只靠 scene 硬写小程序码的 scene 会带出推广员 uid前端拿到后上报给后端做绑定。看似简单实际有边界同一个用户先扫了 A 的码又扫了 B 的码系统必须决定是否换绑。绝大多数拓客源码采用「首次绑定不可覆盖」策略因为换绑会导致业绩纠纷默认把第一个推荐人钉死。少数 1.0.x 版本支持保护期换绑超过保护期才允许被新推荐人覆盖。绑定接口的幂等写法很关键直接在 SQL 层做唯一键防重INSERT INTO tuoke_relation (uid, pid, scene, created_at, updated_at) VALUES (10086, 9527, qr, unix_timestamp(), unix_timestamp()) ON DUPLICATE KEY UPDATE updated_at updated_at;uk_uid唯一键保证同一用户只插入一次第二次扫码进来不会覆盖 pid只有 updated_at 被刷新。如果业务要支持保护期换绑不能靠这条 SQL 一把梭要先查 created_at 再决定是否 UPDATE pid而且要加事务防止并发下两人同时绑定同一 uid。前端另一个隐蔽问题从分享卡片进入时options里没有 scene而是options.uid。所以绑定逻辑要同时兼容两种入口统一封装成一个bindRelation(uid, source)函数别在 onLoad 里散落两套解析代码否则以后加第三种入口比如 H5 拉起时又要改一遍。4.2 佣金比例与提现门槛的配置落点佣金是拓客系统的命门参数集中在后台「分销设置」和「提现设置」两个菜单里典型配置项参数名常见默认值改动位置对业务的影响level1_rate10%分销设置-一级比例直属客户成交时推广员的提成level2_rate5%分销设置-二级比例下级推广员成交时的间接提成max_level2分销设置-层级上限最多算到第几级直接决定成本settle_days1结算设置-结算周期T1 表示订单确认后一天进入可提现withdraw_min10.00 元提现设置-最低金额低于门槛不显示提现按钮withdraw_fee0.00 元提现设置-手续费平台侧成本转嫁佣金计算在服务端做核心是沿关系链向上递归累加的循环function settleCommission(int $orderId): void { $order Order::find($orderId); $buyer $order-buyer_id; // 成交的这个用户 $rel Relation::where(uid, $buyer)-first(); $pid $rel-pid ?? 0; $level 1; $max (int) Setting::get(max_level, 2); while ($pid 0 $level $max) { $rate (float) Setting::get(level{$level}_rate, 0); $amount round($order-pay_amount * $rate / 100, 2); if ($amount 0) { Commission::create([ order_sn $order-order_sn, uid $pid, // 当前层推广员 from_uid $buyer, amount $amount, status Setting::get(settle_days) 0 ? 0 : 1, ]); } $next Relation::where(uid, $pid)-first(); $pid $next-pid ?? 0; // 继续向上找上级 $level; } }这个循环要注意三点round到小数点后两位再入库防止累计误差max_level必须后台可调运营做活动时可以临时放开settle_days为 0 时直接置为可提现为 1 或以上时先挂待结算给退款预留空间。如果这套源码旁边还挂了小程序商城佣金表里的order_sn要和商城订单表保持同一套生成规则两边对账才不打架。4.3 分享动作和订阅消息的配合拓客的传播入口集中在分享卡片但分享本身不产生转化转化靠用户点开后能继续收到消息。前端推荐这样组织分享函数和订阅请求Page({ onShareAppMessage() { return { title: 你看这套方案适不适合合适直接联系我, path: /pages/index/index?uid this.data.uid, // 分享卡片不带 scene imageUrl: this.data.shareCover }; }, requestNotice() { wx.requestSubscribeMessage({ tmplIds: [模板消息ID_提现审核, 模板消息ID_佣金到账], success(res) { // res[模板消息ID_佣金到账] accept 时才真正订阅成功 if (res[模板消息ID_提现审核] accept) { // 用户允许后后端才可以在审核事件里调用 subscribeMessage.send } } }); } });onShareAppMessage里的 path 不能带 scene只能带 query且 title 和 imageUrl 要针对拓客场景单独设计默认页面标题的点击率比自定义标题低很多。订阅消息是「一次性」的用户每拒绝一次下次主动请求订阅的通过率都会下降所以请求时机建议放在「提现申请提交成功」这类用户有明确预期动作之后而不是一进页面就弹。5. 上线前容易卡住的三个细节备案备注、加载页、动态标题5.1 小程序备案备注信息怎么填小程序备案时「备注信息」一栏不能只写「小程序」三个字会被驳回。按实际业务写比如拓客工具可以写本小程序提供客户线索收集与推广海报生成服务用户可上传名片并分享提交意向表单后由入驻企业跟进不涉及金融、医疗、新闻等前置审批类目。把主服务描述清楚再补一句不涉及的内容通过率明显更高。5.2 修改刚进入的加载页面有时候业务要求先进活动落地页或渠道分包页。原生小程序的进入页在 app.json 的entryPagePath里指定uniapp 要在 pages.json 里把目标页面放到 pages 数组第一位并配合全屏自定义导航{ pages: [ { path: pages/loading/loading, style: { navigationStyle: custom } }, { path: pages/index/index, style: { navigationTitleText: 首页 } } ] }改完重新编译模拟器里第一屏就会变成 loading 页。页面里别放 setTimeout 硬等跳转要基于数据是否就绪来判断比如拿到用户身份和渠道参数后再wx.reLaunch到首页否则弱网环境下 loading 页会闪白。5.3 动态设置标题与带参拉起小程序拓客海报和分享卡片需要按渠道显示不同标题前端在 onLoad 里根据参数动态设置导航栏标题onLoad(options) { if (options.channel) { wx.setNavigationBarTitle({ title: options.channel 渠道推广 }); } }动态标题要放在首个导航完成后调用否则会被默认标题覆盖。如果是从自家 App 或 H5 拉起这个小程序优先在微信公众平台生成 URL Link 或 URL Scheme别在前端拼默认 scheme官方接口返回的链接才带完整的路径参数校验前端只负责对返回的链接做跳转收口。本文还有配套的精品资源点击获取
网站建设高端定制企业官网