uni-app做同城交友小程序可行,但需解决LBS定位不准(须逆地理编码转adcode/city)、卡片列表卡顿(可视区懒加载+OSS缩略图)、多端登录消息不同步(WebSocket主动推送)、实名认证状态不一致(后端幂等处理+前端事件监听)等真实卡点。

直接上手做同城交友相亲小程序,uni-app 是可行的,但关键不在“能不能写”,而在“怎么绕过那些真实卡点”——比如 LBS 定位不准、匹配列表卡顿、多端登录消息不同步、实名认证失败后状态不重置。下面聚焦几个开发中真正要动手改、不能只抄文档的地方。
uni-app 获取用户位置并转成“同城”范围(不是简单调 uni.getLocation)
微信小程序里 uni.getLocation 返回的是经纬度,但“同城”不是固定半径,而是按行政区域(如“杭州市西湖区”)动态划定。直接用 5km/10km 圆形范围会漏掉隔壁区但实际通勤可达的用户。
- 必须调用腾讯地图或高德的逆地理编码 API(如
https://apis.map.qq.com/ws/geocoder/v1/),把经纬度转成adcode(行政区划码)和city - 前端缓存
city和adcode,后续所有匹配请求都带上这两个参数,后端用它们查 MySQL 的user.city或user.adcode字段,而不是算距离 - 用户没授权定位时,fallback 到
uni.getSystemInfoSync().region(iOS)或微信openLocation回退城市名,避免白屏 - 别在 onShow 里反复调定位——微信限制每 5 分钟最多触发一次,否则
getLocation:fail auth deny错误频发
滑动卡片列表性能崩了?别碰 v-for 渲染全部数据
相亲类小程序首页常是“左滑无感、右滑喜欢”的卡片流,但一次性拉 100 条用户数据 + 图片 + 距离计算,scroll-view 在低端安卓机直接卡死,iOS 微信还会白屏重启。
- 用
uni.createSelectorQuery()拿到可视区域高度,配合scroll-y的scrolltolower事件做“可视区懒加载”,首次只渲染 6 张卡 - 图片必须加
lazy-load,且 src 用 OSS 缩略图地址(如https://xxx.oss-cn-hangzhou.aliyuncs.com/avatar_200x200.jpg),原图等滑到再加载 - 距离字段(如“距你 2.3km”)不要前端算——后端接口已返回
distance字段,否则 JS 算球面距离(haversine)在低端机耗时超 80ms - 禁止在卡片组件里调
uni.getLocation或uni.getSystemInfo,这些是同步阻塞 API,会打断滚动帧率
ThinkPHP6 后端匹配接口怎么扛住并发?别只靠 MySQL 查询
用户点“刷新推荐”,后端要从几万用户里筛出年龄 25–35、同城、有照片、近 7 天活跃的 20 人——纯 SQL WHERE 扫表,QPS 上 50 就慢得像挂掉。
- 把“同城+年龄+性别+是否实名”这几个高频筛选字段建联合索引,例如
KEY idx_city_age_sex_auth (city, age_min, age_max, gender, is_realname) - 用 Redis Sorted Set 存“活跃用户池”:
ZREVRANGEBYSCORE active_users 1630425600 +inf LIMIT 0 500(时间戳代表最近活跃),每次匹配先从这个集合随机取 100 个 ID,再查 MySQL 补全资料 - 匹配结果必须加本地缓存:对同一用户(
uid)的“今日推荐”,用Cache::remember('match_'.$uid.'_20261030', 3600, function () { ... })缓存 1 小时,避免重复计算 - 如果用了 Workerman 做 WebSocket,千万别把匹配逻辑塞进
onMessage——它会阻塞整个连接池,应扔进Redis Queue异步处理
实名认证回调状态不同步?别让前端自己轮询
调腾讯云人脸核身,用户跳转后返回小程序,onLoad 里立刻查认证状态,90% 情况返回“审核中”。因为后端还没收到腾讯云的异步通知(notify_url),前端干等或轮询,体验极差。
- 后端收到腾讯云
POST /api/auth/notify后,除了更新数据库,必须主动推一条 WebSocket 消息给该用户(用Workerman的$connection->send()) - 前端监听自定义事件(如
uni.$on('auth_status_update', handler)),收到即刷新资料页,不用 setTimeout 轮询 - 若用户关闭页面再进来,首次
onShow仍需查一次状态,但此时数据库已更新,可立即显示“认证成功”或“未通过”,而非“处理中” - 注意腾讯云回调可能重试,后端要校验
sign并幂等处理(用redis.setex('auth_lock_'.$notify_id, 300, 1)防重复入库)
最麻烦的从来不是写代码,而是定位“为什么 iOS 微信里距离显示 NaN”或者“为什么红娘后台看到用户已实名,小程序里还是提示去认证”——这类问题基本都出在跨端状态没对齐,或缓存没清干净。动手前先想清楚:这个状态,到底是存在 localStorage、vuex、还是后端数据库里?三者生命周期完全不同。











