feat(lbs): 大神真实 5km 即时匹配与接单心跳
- companions 新增 latitude/longitude/last_active_at 与 idx_comp_active;切换接单中立即刷新活跃时间 - 新增 /api/companions/heartbeat(鉴权)与 /api/companions/match(真实注册+审核通过+接单中+10分钟心跳,Haversine 5km 过滤与距离排序,不返回精确坐标) - 工作台/接单大厅/雷达前台每 60s 心跳,离开停止;首页即时匹配改为服务端 LBS 匹配并展示真实距离 - 线上实测:2010 匹配排除自己,仅命中 280m 的 8 号;匿名命中 9 号 10m、8 号 280m;北京 5km 为 0;118 套件/771 用例全绿
这个提交包含在:
@@ -349,14 +349,14 @@ describe('ClientFeatures (TDD 测试套件: 用户端功能闭环)', () => {
|
||||
const content = fs.readFileSync(indexVuePath, 'utf-8');
|
||||
const apiContent = fs.readFileSync(path.join(rootDir, 'pwuniapp', 'common', 'api.js'), 'utf-8');
|
||||
|
||||
expect(content).toContain('await getCompanions()');
|
||||
expect(content).toContain('Number(e.userId) > 0');
|
||||
expect(content).toContain('Number(e.userId) !== uid');
|
||||
expect(content).toContain('matchCompanions({ ...(pos || {}), radius: 5, limit: 20 })');
|
||||
expect(content).toContain('lastMatchedId');
|
||||
expect(content).toContain('matchedMeta');
|
||||
expect(content).toContain('换一位');
|
||||
expect(content).toContain('在线大神即时匹配');
|
||||
expect(content).not.toContain('首位接单大神命中');
|
||||
expect(apiContent).toContain('userId: Number(c.userId) || 0');
|
||||
expect(apiContent).toContain('export async function matchCompanions');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户