Files
PetCommunity/cloudfunctions/getNearbyPets/index.js
chenwu 24891d9004 chore: 补全工程配置,部署云函数,建立数据库索引
- 新增 .gitignore(排除 node_modules、私有配置、编译产物)
- 新增 cloudbaserc.json,绑定云环境 cloud1-d4g697lte499543d8
- project.config.json:补 miniprogramRoot、开启 useCompilerPlugins typescript,修复预览报 app.json 找不到的问题
- tsconfig.json:移除无效 typeRoots,解除 TypeScript 编译阻断
- miniprogram/app.json:移除 glass-easel(需基础库 3.x,兼容性差)
- miniprogram/utils/constants.ts:填入真实云环境 ID
- cloudfunctions/updateLocation:位置字段改用 GeoPoint 以支持地理索引
- cloudfunctions/getNearbyPets:改用 geoNear 聚合管道,支持真实距离排序

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-06 00:37:33 +08:00

67 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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'
}