feat:开发分类页内容管理
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
const cloud = require('wx-server-sdk');
|
||||
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
const CONFIG_PATH = 'content/page-config.json';
|
||||
|
||||
const DIFFICULTY_LABELS = {
|
||||
1: '入门',
|
||||
2: '基础',
|
||||
3: '进阶',
|
||||
4: '挑战',
|
||||
};
|
||||
|
||||
function ageBand(min, max) {
|
||||
return `${min}-${max}岁`;
|
||||
}
|
||||
|
||||
function toDisplayItem(ws) {
|
||||
return {
|
||||
id: ws._id,
|
||||
title: ws.title || '',
|
||||
subtitle: ws.subtitle || '',
|
||||
previewImg: ws.previewImg || '',
|
||||
ageBand: ageBand(ws.ageMin || 0, ws.ageMax || 0),
|
||||
ageMin: ws.ageMin || 0,
|
||||
ageMax: ws.ageMax || 0,
|
||||
difficulty: ws.difficulty || 2,
|
||||
difficultyLabel: DIFFICULTY_LABELS[ws.difficulty] || '基础',
|
||||
path: ws.path || '',
|
||||
available: true,
|
||||
likes: ws.likes || 0,
|
||||
downloads: ws.downloads || 0,
|
||||
date: ws.updatedAt
|
||||
? new Date(ws.updatedAt).toISOString().slice(0, 10)
|
||||
: new Date().toISOString().slice(0, 10),
|
||||
};
|
||||
}
|
||||
|
||||
async function readCurrentConfig() {
|
||||
try {
|
||||
const res = await cloud.downloadFile({ fileID: CONFIG_PATH });
|
||||
return JSON.parse(res.fileContent.toString('utf-8'));
|
||||
} catch {
|
||||
return { home: null, category: null, age: null, version: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
async function buildCategoryData(db) {
|
||||
// Get all categories
|
||||
const { data: categories } = await db
|
||||
.collection('categories')
|
||||
.orderBy('sortOrder', 'asc')
|
||||
.get();
|
||||
|
||||
// Get all active worksheets
|
||||
const { data: worksheets } = await db
|
||||
.collection('worksheets')
|
||||
.where({ status: 'active' })
|
||||
.orderBy('sortOrder', 'asc')
|
||||
.orderBy('updatedAt', 'desc')
|
||||
.limit(100)
|
||||
.get();
|
||||
|
||||
// Group by category
|
||||
const grouped = {};
|
||||
for (const ws of worksheets) {
|
||||
const cat = ws.category || 'unknown';
|
||||
if (!grouped[cat]) grouped[cat] = [];
|
||||
grouped[cat].push(toDisplayItem(ws));
|
||||
}
|
||||
|
||||
const categoryData = {
|
||||
searchPlaceholder: '搜索练习纸...',
|
||||
categories: categories.map((cat) => ({
|
||||
id: cat._id,
|
||||
name: cat.name || '',
|
||||
icon: cat.icon || '',
|
||||
items: grouped[cat._id] || [],
|
||||
})),
|
||||
};
|
||||
|
||||
const stats = {};
|
||||
for (const cat of categoryData.categories) {
|
||||
stats[cat.id] = cat.items.length;
|
||||
}
|
||||
|
||||
return { categoryData, stats };
|
||||
}
|
||||
|
||||
exports.main = async (event) => {
|
||||
try {
|
||||
const db = cloud.database();
|
||||
const page = String(event.page || '').trim();
|
||||
|
||||
if (page !== 'category') {
|
||||
throw new Error('当前仅支持 page=category');
|
||||
}
|
||||
|
||||
const { categoryData, stats } = await buildCategoryData(db);
|
||||
|
||||
// Read current config, merge, bump version
|
||||
const config = await readCurrentConfig();
|
||||
config.category = categoryData;
|
||||
config.version = (config.version || 0) + 1;
|
||||
config.updatedAt = new Date().toISOString();
|
||||
|
||||
// Upload to cloud storage
|
||||
const buffer = Buffer.from(JSON.stringify(config), 'utf-8');
|
||||
await cloud.uploadFile({
|
||||
cloudPath: CONFIG_PATH,
|
||||
fileContent: buffer,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
version: config.version,
|
||||
updatedAt: config.updatedAt,
|
||||
stats,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: '生成分类页数据失败',
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "page-content-build",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "^3.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
const cloud = require('wx-server-sdk');
|
||||
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
const VALID_STATUS = new Set(['draft', 'active', 'hidden']);
|
||||
|
||||
exports.main = async (event) => {
|
||||
try {
|
||||
const db = cloud.database();
|
||||
const _ = db.command;
|
||||
const collection = db.collection('worksheets');
|
||||
|
||||
const category = String(event.category || '').trim();
|
||||
const status = String(event.status || '').trim();
|
||||
|
||||
// Build query condition
|
||||
const where = {};
|
||||
if (category) where.category = category;
|
||||
if (status && VALID_STATUS.has(status)) where.status = status;
|
||||
|
||||
// Query worksheets (cloud DB limit is 100 per call)
|
||||
const { data } = await collection
|
||||
.where(where)
|
||||
.orderBy('sortOrder', 'asc')
|
||||
.orderBy('updatedAt', 'desc')
|
||||
.limit(100)
|
||||
.get();
|
||||
|
||||
// Compute stats for the category (all statuses)
|
||||
let allData = data;
|
||||
if (status) {
|
||||
// If filtered by status, need a separate query for stats
|
||||
const statsWhere = {};
|
||||
if (category) statsWhere.category = category;
|
||||
const { data: allItems } = await collection
|
||||
.where(statsWhere)
|
||||
.limit(100)
|
||||
.get();
|
||||
allData = allItems;
|
||||
}
|
||||
|
||||
const stats = { total: 0, draft: 0, active: 0, hidden: 0 };
|
||||
for (const item of allData) {
|
||||
stats.total++;
|
||||
if (item.status === 'draft') stats.draft++;
|
||||
else if (item.status === 'active') stats.active++;
|
||||
else if (item.status === 'hidden') stats.hidden++;
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data,
|
||||
stats,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
error instanceof Error ? error.message : '查询 worksheet 失败',
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "worksheets-query",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "^3.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
const cloud = require('wx-server-sdk');
|
||||
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
const VALID_STATUS = new Set(['draft', 'active', 'hidden']);
|
||||
|
||||
exports.main = async (event) => {
|
||||
try {
|
||||
const db = cloud.database();
|
||||
const collection = db.collection('worksheets');
|
||||
|
||||
const id = String(event.id || '').trim();
|
||||
const status = String(event.status || '').trim();
|
||||
|
||||
if (!id) throw new Error('worksheet id 不能为空');
|
||||
if (!VALID_STATUS.has(status)) throw new Error('状态不合法');
|
||||
|
||||
// Check worksheet exists
|
||||
try {
|
||||
await collection.doc(id).get();
|
||||
} catch {
|
||||
throw new Error('worksheet 不存在');
|
||||
}
|
||||
|
||||
await collection.doc(id).update({
|
||||
data: {
|
||||
status,
|
||||
updatedAt: db.serverDate(),
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: { _id: id, status },
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
error instanceof Error ? error.message : '更新状态失败',
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "worksheets-update-status",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "^3.0.4"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user