const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() const _ = db.command exports.main = async (event, context) => { const { OPENID } = cloud.getWXContext() const { latitude, longitude, maxDistance = 5000, // 默认 5km,单位:米 page = 0, pageSize = 20, } = event if (!latitude || !longitude) return { code: -1, message: '缺少位置' } try { // ✅ geoNear 聚合管道:依赖 users.lastLocation 字段上的 2dsphere 地理位置索引 const { list } = await db.collection('users') .aggregate() .geoNear({ near: db.Geo.Point(longitude, latitude), // 注意:CloudBase GeoPoint 是 (lng, lat) 顺序 spherical: true, distanceField: 'dist', // 在每条记录上附加实际距离(米) maxDistance, query: { openid: _.neq(OPENID), // 排除自己 'pets.0': _.exists(true), // 至少有一只宠物 }, }) .skip(page * pageSize) .limit(pageSize) .project({ openid: false, }) .end() // 在线状态:5 分钟内活跃 const fiveMin = 5 * 60 * 1000 const now = Date.now() const result = list.map(u => ({ userId: u._id, user: u, pet: u.pets?.[0] || null, distance: Math.round(u.dist), distanceText: formatDist(u.dist), isOnline: u.lastSeen && (now - new Date(u.lastSeen).getTime()) < fiveMin, location: { latitude: u.lastLocation?.coordinates?.[1], longitude: u.lastLocation?.coordinates?.[0], }, })) return { code: 0, data: result } } catch (e) { return { code: -1, message: e.message } } } function formatDist(meters) { if (!meters && meters !== 0) return '未知' if (meters < 1000) return Math.round(meters) + 'm' return (meters / 1000).toFixed(1) + 'km' }