// 云函数 getDogDetail — 狗狗主页聚合:dog + 成就墙 + 近期记录 // 契约见 docs/03-云函数设计.md §5 const cloud = require('wx-server-sdk'); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); const db = cloud.database(); const TOTAL_ACHIEVEMENTS = 6; // 与 miniprogram/utils/achievements.js 保持一致 exports.main = async (event) => { const { OPENID } = cloud.getWXContext(); const { dogId } = event; if (!dogId) return { ok: false, code: 'INVALID', msg: '缺少 dogId' }; // 校验归属 const dogRes = await db.collection('dogs').doc(dogId).get().catch(() => null); if (!dogRes || !dogRes.data || dogRes.data._openid !== OPENID) { return { ok: false, code: 'FORBIDDEN', msg: '无权访问' }; } const unlocked = await db.collection('dog_achievements') .where({ dogId }) .orderBy('unlockedAt', 'desc') .get(); // dogIds 是数组,等值查询匹配「数组包含」语义 const recent = await db.collection('walks') .where({ _openid: OPENID, dogIds: dogId }) .orderBy('startAt', 'desc') .limit(10) .get(); return { ok: true, data: { dog: dogRes.data, achievements: { unlocked: unlocked.data, total: TOTAL_ACHIEVEMENTS }, recentWalks: recent.data, }, }; };