checkpoint: pre-refactor state before fixing P0/P1 issues

This commit is contained in:
2026-06-11 18:40:59 +08:00
parent 2c3c2653fa
commit d55ed60907
41 changed files with 1129 additions and 1051 deletions

View File

@@ -2,49 +2,119 @@ const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
const db = cloud.database()
const _ = db.command
const $ = db.command.aggregate
const PAGE_SIZE = 10
// 按 where 条件取一页,时间倒序(关注流 / 个人主页 / 附近兜底共用)
async function listByWhere(where, skip) {
const col = db.collection('posts').where(where)
const countRes = await col.count()
const res = await col
.orderBy('createdAt', 'desc')
.skip(skip)
.limit(PAGE_SIZE)
.get()
return {
posts: res.data,
total: countRes.total,
hasMore: skip + res.data.length < countRes.total,
}
}
// 热门:热度分 = (点赞×3 + 评论×5 + 1) / (帖龄小时数 + 2)^1.5
// 类 Hacker News 的重力衰减,互动加分、随时间下沉;同分按发布时间倒序
async function listHot(skip) {
const countRes = await db.collection('posts').count()
const res = await db.collection('posts').aggregate()
.addFields({
hotScore: $.divide([
$.add([
$.multiply([$.ifNull(['$likeCount', 0]), 3]),
$.multiply([$.ifNull(['$commentCount', 0]), 5]),
1,
]),
$.pow([
$.add([
$.divide([$.subtract([new Date(), '$createdAt']), 3600000]),
2,
]),
1.5,
]),
]),
})
.sort({ hotScore: -1, createdAt: -1 })
.skip(skip)
.limit(PAGE_SIZE)
.end()
return {
posts: res.list,
total: countRes.total,
hasMore: skip + res.list.length < countRes.total,
}
}
// 附近geo.near 按距离由近到远,依赖 posts.geo 的地理位置索引;
// 索引未建或查询失败时回退为矩形围栏 + 时间倒序。
// $near 不支持 count用多取一条判断 hasMoretotal 为近似值
async function listNearby(latitude, longitude, skip) {
try {
const res = await db.collection('posts')
.where({
geo: _.geoNear({
geometry: db.Geo.Point(longitude, latitude),
maxDistance: 10000,
}),
})
.skip(skip)
.limit(PAGE_SIZE + 1)
.get()
const hasMore = res.data.length > PAGE_SIZE
const posts = hasMore ? res.data.slice(0, PAGE_SIZE) : res.data
return { posts, total: skip + posts.length + (hasMore ? 1 : 0), hasMore }
} catch (e) {
return listByWhere(
_.and([
{ 'location.latitude': _.gt(latitude - 0.1) },
{ 'location.latitude': _.lt(latitude + 0.1) },
{ 'location.longitude': _.gt(longitude - 0.15) },
{ 'location.longitude': _.lt(longitude + 0.15) },
]),
skip
)
}
}
exports.main = async (event, context) => {
const { OPENID } = cloud.getWXContext()
const { page = 0, type = 'hot', userId, latitude, longitude } = event
const skip = page * PAGE_SIZE
try {
let query = db.collection('posts')
const skip = page * PAGE_SIZE
let result
if (userId) {
// 某用户的帖子
query = query.where({ authorId: userId })
result = await listByWhere({ authorId: userId }, skip)
} else if (type === 'feed') {
// 关注的用户帖子
// 关注流:我关注的人 + 自己
const followsRes = await db.collection('follows')
.where({ followerId: OPENID })
.field({ followeeId: true })
.get()
const followeeIds = followsRes.data.map(f => f.followeeId)
followeeIds.push(OPENID)
query = query.where({ authorId: _.in(followeeIds) })
result = await listByWhere({ authorId: _.in(followeeIds) }, skip)
} else if (type === 'nearby' && latitude && longitude) {
// 附近帖子:使用地理围栏查询(简化版,用 geo_near
query = query.where(
_.and([
{ 'location.latitude': _.gt(latitude - 0.1) },
{ 'location.latitude': _.lt(latitude + 0.1) },
{ 'location.longitude': _.gt(longitude - 0.15) },
{ 'location.longitude': _.lt(longitude + 0.15) },
])
)
result = await listNearby(latitude, longitude, skip)
} else {
result = await listHot(skip)
}
// type === 'hot' 全量按热度排序
const total = await query.count()
const postsRes = await query
.orderBy('createdAt', 'desc')
.skip(skip)
.limit(PAGE_SIZE)
.get()
const { posts, total, hasMore } = result
const posts = postsRes.data
if (posts.length === 0) {
return { code: 0, data: { list: [], total, hasMore: false } }
}
// 批量获取作者信息
const authorIds = [...new Set(posts.map(p => p.authorId))]
@@ -71,11 +141,7 @@ exports.main = async (event, context) => {
return {
code: 0,
data: {
list: enriched,
total: total.total,
hasMore: skip + posts.length < total.total,
},
data: { list: enriched, total, hasMore },
}
} catch (e) {
return { code: -1, message: e.message }