简介:这是一套面向婚恋交友行业创业者、PHP开发者及红娘运营团队的2024年最新相亲系统源码,基于红娘金媒10.3版本,支持PC网站、微信小程序与公众号三端接入,可快速搭建覆盖多终端的婚恋平台。系统核心模块包括红娘服务、相亲活动、交友匹配与付费获取联系方式:红娘可依据用户资料与偏好提供精准配对建议,活动模块支持报名审核与通知推送,匹配模块借助大数据与智能算法推荐潜在对象,付费解锁联系方式则兼顾隐私保护与平台收益。压缩包共2008个文件,约32.03MB,以895个PHP后端文件、321个JS脚本、152个CSS样式及78个WXSS、77个WXML小程序页面文件为主,另含JSON配置、图片与字体等资源,前后端结构完整。目前已有464人学习下载,适合需要三端一体化相亲解决方案的开发者参考与二次开发。
1. 三端打通的相亲系统,到底省了哪些重复造轮子的活
去年帮一个做本地婚介的朋友看后台,他手里同时跑着三套东西:PC 站一套、微信小程序一套、公众号 H5 又一套,用户数据各存各的,红娘改一个会员资料要在三个后台里点三遍。这种场景在相亲交友这个赛道里太常见了,所以当我拿到这份「2024最新婚恋相亲系统源码」时,第一反应不是看它功能多花哨,而是看它三端是不是真的共用一套数据层。结论是:这套基于 PHP 的婚恋相亲系统,把 PC、微信小程序、公众号三端的用户体系、匹配逻辑、红娘服务和付费解锁联系方式都收在同一个后端里,前端只做展示和交互。它适合谁?适合手里有本地相亲资源、想快速搭一套能跑起来的平台、又不想从零写匹配算法和支付链路的开发者或小团队。红娘源码、相亲源码这类东西市面上不少,但三端接入做得干净的不多,这份值得拆一拆。
2. 目录结构与三端接入方式:先搞清楚文件往哪放
拿到一个 PHP 网站源码压缩包,最忌讳的就是直接丢到 web 根目录就访问。这套系统是三端共存的,目录划分直接决定了你后面配置小程序和公众号时会不会翻车。我一般会先把压缩包解开,对着目录树过一遍再动手。
2.1 从压缩包到可访问站点:目录职责划分
解压后你会看到类似这样的结构(不同版本可能略有差异,但职责划分是一致的):
# 典型的 PHP 三端项目目录结构 www/ # PC 端入口,web 根目录指向这里 index.php # PC 首页入口 static/ # 静态资源 css/ animate.css # 动画库,登录弹窗、匹配动效用它 main.css # 主样式 m.css # 移动端适配样式 p.css # PC 端样式 shop.css # 付费/商城相关样式 u.css # 用户中心样式 index.css # 首页专用样式 default.css # 默认兜底样式 js/ images/ api/ # 三端共用的接口层,小程序和公众号都打这里 user.php # 用户相关接口 match.php # 匹配相关接口 pay.php # 支付回调 admin/ # 后台管理,红娘和运营用 ... miniprogram/ # 微信小程序端源码 app.js pages/ official/ # 公众号 H5 端 ... data/ # 配置、缓存、上传文件 config.php # 数据库等核心配置这里有个关键点:api/目录是三端共用的接口层,PC 端、小程序、公众号都通过它读写同一套数据。这意味着你改一次匹配逻辑,三端同时生效,不用分别维护。random_compat.phar.pubkey.asc这类文件是 PHP 兼容库的签名文件,说明这套源码对 PHP 版本有一定兼容处理,部署时别把它删了。
提示:web 根目录一定要指向
www/,而不是项目根目录。指向错了会导致data/config.php被直接下载,数据库密码就裸奔了。
2.2 三端接入的配置差异:小程序和公众号各改哪里
三端共用后端,但接入配置各不相同。PC 端最简单,配好数据库就能跑。小程序端要填 AppID 和 AppSecret,公众号端要配服务器地址和 Token。
// data/config.php 里通常会有这样的配置段 return [ 'db' => [ 'host' => '127.0.0.1', 'port' => 3306, 'name' => 'xiangqin', // 数据库名 'user' => 'root', 'pass' => 'your_password', 'prefix' => 'xq_', // 表前缀,导入 SQL 时注意一致 ], 'wechat' => [ 'mini_appid' => '', // 小程序 AppID 'mini_secret' => '', // 小程序 AppSecret 'official_appid' => '', // 公众号 AppID 'official_secret' => '', // 公众号 AppSecret 'official_token' => '', // 公众号服务器 Token ], 'pay' => [ 'mch_id' => '', // 微信支付商户号 'mch_key' => '', // 支付密钥 ], ];参数说明:prefix是表前缀,导入 SQL 文件时如果 SQL 里写的是xq_开头,这里就必须一致,否则所有查询都会报表不存在。mini_appid和mini_secret在小程序后台「开发管理」里拿,official_token是你自己在公众号后台填的那个 Token,两边必须一模一样。支付相关的mch_id和mch_key涉及付费解锁联系方式功能,没配好之前这个模块是走不通的。
常见做法是先把 PC 端跑通,确认数据库连接正常、页面能打开,再去配小程序和公众号。因为三端共用接口层,PC 端能跑说明后端逻辑没问题,剩下就是各端的鉴权配置。
3. 红娘服务与匹配算法:数据表怎么设计,逻辑怎么跑
这套系统最值钱的部分不是前端页面,而是红娘服务和交友匹配背后的数据结构和算法逻辑。很多人拿到源码只改页面样式,结果匹配出来的结果驴唇不对马嘴,就是因为没搞懂它的匹配字段是怎么用的。
3.1 用户资料表与匹配字段:哪些字段真正参与计算
匹配算法的核心是用户资料表。这套系统里,参与匹配的字段通常包括性别、年龄、身高、学历、收入区间、所在地区、婚姻状况、兴趣爱好标签等。不是所有字段都参与计算,有些只是展示用。
| 字段名 | 类型 | 是否参与匹配 | 说明 |
|---|---|---|---|
| gender | tinyint | 是 | 1 男 2 女,硬性过滤条件 |
| age | int | 是 | 按区间计算年龄差权重 |
| height | int | 是 | 身高差超过阈值降权 |
| education | tinyint | 是 | 学历匹配度 |
| income | int | 是 | 收入区间匹配 |
| city | varchar | 是 | 同城优先,异地降权 |
| marital_status | tinyint | 是 | 未婚/离异,可配置是否硬过滤 |
| tags | varchar | 是 | 兴趣标签,交集越多分越高 |
| avatar | varchar | 否 | 仅展示 |
| intro | text | 否 | 仅展示 |
匹配逻辑一般是加权打分:先按性别做硬过滤,再对年龄、身高、学历、收入、地区、标签分别算分,最后加权求和排序。权重通常写在配置里,方便运营调整。
// api/match.php 中匹配打分的简化逻辑 function calcMatchScore($user, $target, $weights) { $score = 0; // 年龄差越小分越高,超过 10 岁直接 0 分 $ageDiff = abs($user['age'] - $target['age']); $score += max(0, (10 - $ageDiff)) * $weights['age']; // 同城加满分,不同城按省份匹配给一半 if ($user['city'] == $target['city']) { $score += 100 * $weights['city']; } elseif ($user['province'] == $target['province']) { $score += 50 * $weights['city']; } // 兴趣标签交集 $commonTags = array_intersect( explode(',', $user['tags']), explode(',', $target['tags']) ); $score += count($commonTags) * 10 * $weights['tags']; return $score; }逻辑说明:$weights是各维度权重,一般存在后台配置里,运营可以调。年龄差用10 - $ageDiff是为了让差距越小得分越高,超过 10 岁直接归零,避免推荐明显不合适的对象。标签交集用array_intersect算,交集越多分越高。这套逻辑不复杂,但字段设计合理的话,推荐结果不会太离谱。
3.2 红娘介入流程:从预约到配对建议的完整链路
红娘服务不是算法能替代的,它的价值在于人工介入。系统里的流程通常是:用户提交红娘预约 → 后台分配红娘 → 红娘查看用户资料和匹配推荐 → 红娘给出人工配对建议 → 用户收到建议并决定是否联系对方。
-- 红娘预约表的核心字段 CREATE TABLE `xq_matchmaker_order` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '预约用户ID', `matchmaker_id` int(11) DEFAULT 0 COMMENT '分配的红娘ID', `status` tinyint(1) DEFAULT 0 COMMENT '0待分配 1已分配 2已完成', `remark` varchar(500) DEFAULT '' COMMENT '用户诉求备注', `create_time` int(11) DEFAULT 0, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), KEY `matchmaker_id` (`matchmaker_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;这个表结构简单但够用。status字段驱动整个流程,后台红娘看到status=0的单子就抢单或由管理员分配,分配后改成 1,处理完改成 2。remark让用户写清楚自己的诉求,比如「希望找本地、有稳定工作、不抽烟的」,红娘据此人工筛选。
注意:红娘账号的权限要单独控制。后台一般有角色管理,红娘只能看分配给自己的用户资料,不能看全站数据,否则用户隐私就是个大问题。
4. 付费解锁联系方式:支付链路怎么接,回调怎么处理
付费获取联系方式是这类相亲系统的核心变现点,也是最容易出问题的地方。支付没接好,要么用户付了钱拿不到联系方式,要么没付钱就能拿到,前者是客诉,后者是直接损失。
4.1 微信支付下单与回调:金额、订单号、签名三个关键点
支付流程一般是:用户点击「获取联系方式」→ 后端生成订单 → 调微信支付统一下单 → 返回支付参数给前端 → 用户支付 → 微信回调后端 → 后端校验签名、更新订单状态、返回联系方式。
// api/pay.php 中统一下单的核心逻辑 function createOrder($userId, $targetId, $amount) { // 订单号用时间戳加随机数,保证唯一 $orderNo = date('YmdHis') . mt_rand(1000, 9999); // 金额单位是分,1 元要写成 100 $totalFee = intval($amount * 100); $params = [ 'appid' => $config['wechat']['official_appid'], 'mch_id' => $config['pay']['mch_id'], 'nonce_str' => md5(uniqid()), 'body' => '解锁联系方式', 'out_trade_no' => $orderNo, 'total_fee' => $totalFee, 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], 'notify_url' => 'https://yourdomain.com/api/pay_notify.php', 'trade_type' => 'JSAPI', 'openid' => getUserOpenid($userId), ]; // 签名:按字典序拼接参数,最后拼上 key,MD5 后转大写 $params['sign'] = makeSign($params, $config['pay']['mch_key']); return $params; }参数说明:out_trade_no是商户订单号,必须唯一,重复下单会报错。total_fee单位是分,这是微信支付的规定,写错了金额就全错。notify_url是回调地址,必须是公网可访问的 HTTPS 地址,本地开发环境收不到回调。trade_type用JSAPI是因为公众号内支付和小程序支付都走这个类型,区别在于openid的来源不同。
回调处理是重点:
// api/pay_notify.php 回调处理 $xml = file_get_contents('php://input'); $data = xmlToArray($xml); // 先验签,签名不对直接返回失败 if (makeSign($data, $config['pay']['mch_key']) !== $data['sign']) { echo '<xml><return_code><![CDATA[FAIL]]></return_code></xml>'; exit; } // 再查订单,防止重复处理 $order = getOrderByNo($data['out_trade_no']); if ($order['status'] == 1) { echo '<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>'; exit; } // 更新订单状态,写入解锁记录 updateOrderStatus($data['out_trade_no'], 1); grantContact($order['user_id'], $order['target_id']); echo '<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>';逻辑说明:回调必须验签,否则别人伪造一个回调就能白嫖联系方式。查订单状态是为了幂等,微信可能会重复回调,不判断的话会重复解锁。返回SUCCESS告诉微信处理成功,否则微信会持续重试。
4.2 解锁记录与隐私保护:联系方式怎么存怎么给
联系方式不能明文存在用户表里随便查,常见做法是单独建一张解锁记录表,用户付费后写入一条记录,前端请求联系方式时先查这张表有没有记录。
CREATE TABLE `xq_contact_unlock` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL COMMENT '付费用户', `target_id` int(11) NOT NULL COMMENT '被解锁用户', `order_no` varchar(32) NOT NULL, `create_time` int(11) DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `user_target` (`user_id`, `target_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;UNIQUE KEY保证同一个用户对同一个目标只解锁一次,避免重复付费。查询联系方式时先查这张表,有记录才返回,没有就提示付费。这样即使前端被人改了,后端逻辑也能兜住。
5. 部署避坑:从环境到三端联调的五个翻车点
这套系统我前后部署过几次,踩的坑基本集中在环境、编码、回调和小程序鉴权上。下面这几条是血泪经验,照着排查能省不少时间。
5.1 环境与编码:PHP 版本和字符集的两个坑
现象:页面打开一片空白,或者中文全部变成乱码。原因:PHP 版本不匹配,或者数据库字符集不是utf8mb4。这套源码里出现了random_compat.phar.pubkey.asc,说明它用了兼容库来适配不同 PHP 版本,但兼容不等于所有版本都能跑。常见做法是用 PHP 7.2 到 7.4,PHP 8 以上部分函数行为变了,容易出问题。字符集方面,用户资料里有昵称、简介、兴趣标签,必须用utf8mb4才能存 emoji,用utf8会截断。解决:先确认 PHP 版本在 7.2 到 7.4 之间,数据库和表都设成utf8mb4_general_ci,config.php里的连接字符集也改成utf8mb4。
5.2 支付回调收不到:notify_url 的三个硬性要求
现象:用户付了钱,订单状态没变,联系方式没解锁。原因:notify_url必须是公网可访问的 HTTPS 地址,本地localhost或内网 IP 微信根本回调不到。另外回调地址不能带参数,必须是纯路径。还有一种情况是服务器开了防火墙,微信的请求被拦了。解决:开发阶段用内网穿透工具把本地映射成公网 HTTPS 地址(注意这里说的是开发调试用的映射,不是网络访问工具),配到notify_url里。上线后确认回调地址能从外网直接访问,服务器安全组放行 443 端口。
5.3 小程序端登录失败:AppID 和服务器域名的绑定关系
现象:小程序端能打开页面,但登录一直失败,提示网络错误。原因:小程序的app.js里配置的接口域名没有在小程序后台「开发管理 → 服务器域名」里加白名单。微信小程序强制要求所有请求域名必须提前配置,没配的直接拦截。解决:把api/所在的域名加到 request 合法域名里,必须是 HTTPS。开发阶段可以在开发者工具里勾选「不校验合法域名」,但上线前必须配好。
5.4 公众号 Token 验证失败:两边必须一模一样
现象:公众号后台填了服务器地址和 Token,点提交提示失败。原因:公众号后台填的 Token 和config.php里的official_token不一致,或者服务器地址填错了。微信会发一个 GET 请求过来验证,后端要原样返回echostr参数。解决:确认两边 Token 完全一致,包括大小写。服务器地址填https://yourdomain.com/api/wechat.php这种形式,后端收到验证请求后直接echo $_GET['echostr']就行。
5.5 匹配结果为空:性别过滤和资料完整度的连锁反应
现象:用户反馈「一个人都匹配不到」。原因:匹配算法第一步是性别硬过滤,如果用户资料里性别没填或者填错了,直接过滤掉所有人。另外资料完整度太低也会导致打分全是 0,排序后没有有效结果。解决:后台加一个资料完整度检查,低于阈值的用户不进入匹配池,同时前端引导用户补全资料。性别字段要做必填校验,不允许为空。
6. 二次开发与验证:怎么确认这套源码真的跑通了
拿到源码跑起来只是第一步,真正要用于生产,还得验证几个关键链路是不是真的通了。我一般会按下面的顺序过一遍,确认没问题再往上加功能。
6.1 三端数据一致性验证:改一个资料,三端同步
验证三端是不是真的共用数据层,最简单的办法是:在 PC 端改一个用户的昵称,然后刷新小程序和公众号端,看昵称是不是同步变了。如果变了,说明三端读的是同一张表;如果没变,说明有端用了独立缓存或者独立数据库,后面维护会非常痛苦。
# 直接查数据库确认三端读的是同一张表 mysql -u root -p xiangqin -e "SELECT id, nickname, gender, city FROM xq_user WHERE id = 1;"如果三端显示一致,且数据库里查出来的就是改后的值,说明数据层是打通的。这一步过了,后面加功能才有意义。
6.2 付费解锁全链路验证:从下单到拿到联系方式
付费链路要完整走一遍:用户 A 点击解锁用户 B 的联系方式 → 生成订单 → 支付 → 回调 → 解锁记录写入 → 用户 A 能查到用户 B 的联系方式。每一步都要确认。
| 验证点 | 预期结果 | 检查方式 |
|---|---|---|
| 下单 | 生成唯一订单号,金额正确 | 查xq_order表 |
| 支付 | 微信返回支付成功 | 前端收到支付完成回调 |
| 回调 | 订单状态变为已支付 | 查xq_order.status |
| 解锁 | 写入解锁记录 | 查xq_contact_unlock表 |
| 查询 | 能拿到联系方式 | 前端请求接口返回手机号/微信号 |
常见问题是回调没收到但用户确实付了钱,这时候要查微信支付后台的交易记录,确认订单号对得上,然后手动补单。生产环境一定要加补单机制,不能只依赖回调。
6.3 匹配算法调参:权重怎么改,效果怎么验证
匹配算法的权重一般写在后台配置里,运营可以调。我一般会先跑一批测试数据,看推荐结果是不是合理,再微调权重。
// 后台配置里的权重示例 $weights = [ 'age' => 0.3, // 年龄权重最高 'city' => 0.25, // 同城很重要 'education' => 0.15, 'income' => 0.1, 'height' => 0.1, 'tags' => 0.1, ];调参的逻辑是:先保证硬性条件(性别、婚姻状况)过滤正确,再调软性条件的权重。如果发现推荐结果里异地太多,就把city权重调高;如果年龄差距太大,就把age权重调高。每次只调一个参数,调完跑一批测试数据看效果,不要一次改好几个,否则出了问题都不知道是哪个参数导致的。
从那以后我每次拿到这类三端源码,都强制先跑一遍数据一致性验证和付费全链路,确认底层通了再动前端。这套相亲系统的底子不错,三端共用接口层省了很多重复劳动,但支付和匹配这两块必须自己验证一遍,不能假设它默认就是对的。希望帮到你。
本文还有配套的精品资源,点击获取