feat: 增加收藏、下载种子数据功能

This commit is contained in:
R524809
2026-05-11 12:38:10 +08:00
parent debecd67c6
commit 39b8e01c23
11 changed files with 521 additions and 21 deletions
@@ -35,6 +35,13 @@ function difficultyLabel(difficulty) {
return DIFFICULTY_LABELS[difficulty] || '基础';
}
function mergeSeedStats(items) {
for (const item of items) {
item.likes = (item.likes || 0) + (item.likes_seed || 0);
item.downloads = (item.downloads || 0) + (item.downloads_seed || 0);
}
}
function toRecommendedItem(ws) {
return {
worksheetId: ws._id,
@@ -118,6 +125,7 @@ exports.main = async (event) => {
const band = AGE_BANDS[ageKey];
const db = cloud.database();
const activeWorksheets = await queryActiveWorksheets(db);
mergeSeedStats(activeWorksheets);
const matchedWorksheets = activeWorksheets.filter((ws) =>
coversAgeBand(ws, band),
);
+18 -11
View File
@@ -15,6 +15,13 @@ function ageBand(min, max) {
return `${min}-${max}`;
}
function mergeSeedStats(items) {
for (const item of items) {
item.likes = (item.likes || 0) + (item.likes_seed || 0);
item.downloads = (item.downloads || 0) + (item.downloads_seed || 0);
}
}
function toHomeDisplayItem(ws) {
return {
id: ws._id,
@@ -87,21 +94,21 @@ exports.main = async () => {
return { success: true, message: '定时任务已暂停,跳过执行' };
}
// Query top 5 by downloads
const { data: topDownloads } = await db
const { data: allActive } = await db
.collection('worksheets')
.where({ status: 'active' })
.orderBy('downloads', 'desc')
.limit(5)
.limit(100)
.get();
// Query top 5 by likes
const { data: topLikes } = await db
.collection('worksheets')
.where({ status: 'active' })
.orderBy('likes', 'desc')
.limit(5)
.get();
mergeSeedStats(allActive);
const topDownloads = [...allActive]
.sort((a, b) => (b.downloads || 0) - (a.downloads || 0))
.slice(0, 5);
const topLikes = [...allActive]
.sort((a, b) => (b.likes || 0) - (a.likes || 0))
.slice(0, 5);
const featured = topDownloads.map(toHomeDisplayItem);
const hot = topLikes.map(toHomeDisplayItem);
+2 -2
View File
@@ -28,8 +28,8 @@ function toDisplayItem(ws) {
difficultyLabel: DIFFICULTY_LABELS[ws.difficulty] || '基础',
path: ws.path || '',
available: true,
likes: ws.likes || 0,
downloads: ws.downloads || 0,
likes: (ws.likes || 0) + (ws.likes_seed || 0),
downloads: (ws.downloads || 0) + (ws.downloads_seed || 0),
date: ws.updatedAt
? new Date(ws.updatedAt).toISOString().slice(0, 10)
: new Date().toISOString().slice(0, 10),
+30 -1
View File
@@ -74,11 +74,40 @@ function buildUpdateData(db, patch) {
hasField = true;
}
if (patch.likes_seed !== undefined) {
const v = toInt(patch.likes_seed, -1);
if (v < 0) return { id, ok: false, error: 'likes_seed 须为非负整数' };
data.likes_seed = v;
hasField = true;
}
if (patch.downloads_seed !== undefined) {
const v = toInt(patch.downloads_seed, -1);
if (v < 0)
return { id, ok: false, error: 'downloads_seed 须为非负整数' };
data.downloads_seed = v;
hasField = true;
}
if (patch.likes !== undefined) {
const v = toInt(patch.likes, -1);
if (v < 0) return { id, ok: false, error: 'likes 须为非负整数' };
data.likes = v;
hasField = true;
}
if (patch.downloads !== undefined) {
const v = toInt(patch.downloads, -1);
if (v < 0) return { id, ok: false, error: 'downloads 须为非负整数' };
data.downloads = v;
hasField = true;
}
if (!hasField) {
return {
id,
ok: false,
error: '未包含可更新字段(ageMin/ageMax 或 tags',
error: '未包含可更新字段(ageMin/ageMax、tags、seedstats',
};
}
+9
View File
@@ -5,6 +5,13 @@ cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
const VALID_STATUS = new Set(['draft', 'active', 'hidden']);
const STATUS_ORDER = { draft: 0, hidden: 1, active: 2 };
function mergeSeedStats(items) {
for (const item of items) {
item.likes = (item.likes || 0) + (item.likes_seed || 0);
item.downloads = (item.downloads || 0) + (item.downloads_seed || 0);
}
}
exports.main = async (event) => {
try {
const db = cloud.database();
@@ -54,6 +61,8 @@ exports.main = async (event) => {
else if (item.status === 'hidden') stats.hidden++;
}
mergeSeedStats(data);
return {
success: true,
data,