148 lines
4.5 KiB
JavaScript
148 lines
4.5 KiB
JavaScript
const cloud = require('wx-server-sdk');
|
|
|
|
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
|
|
|
const VALID_STATUS = new Set(['draft', 'active', 'hidden']);
|
|
const VALID_DIFFICULTY = new Set([1, 2, 3, 4]);
|
|
|
|
function toInt(value, fallback = 0) {
|
|
const number = Number(value);
|
|
if (!Number.isFinite(number)) return fallback;
|
|
return Math.round(number);
|
|
}
|
|
|
|
function toStringArray(value) {
|
|
if (!Array.isArray(value)) return [];
|
|
return value.map((item) => String(item || '').trim()).filter(Boolean);
|
|
}
|
|
|
|
async function ensureCategoryExists(db, category) {
|
|
try {
|
|
await db.collection('categories').doc(category).get();
|
|
return true;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function validatePayload(event, db) {
|
|
const id = String(event.id || '').trim();
|
|
const title = String(event.title || '').trim();
|
|
const subtitle = String(event.subtitle || '').trim();
|
|
const category = String(event.category || '').trim();
|
|
const subcategory = String(event.subcategory || '').trim();
|
|
const path = String(event.path || '').trim();
|
|
const previewImg = String(event.previewImg || '').trim();
|
|
const ageMin = toInt(event.ageMin, 0);
|
|
const ageMax = toInt(event.ageMax, 0);
|
|
const grade = toInt(event.grade, 0);
|
|
const difficulty = toInt(event.difficulty, 0);
|
|
const tags = toStringArray(event.tags);
|
|
const isNew = !!event.isNew;
|
|
const isHot = !!event.isHot;
|
|
const sortOrder = toInt(event.sortOrder, 0);
|
|
const downloads = toInt(event.downloads, 0);
|
|
const likes = toInt(event.likes, 0);
|
|
const status = String(event.status || 'draft').trim();
|
|
|
|
if (!id) throw new Error('题型 id 不能为空');
|
|
if (!title) throw new Error('标题不能为空');
|
|
if (!subtitle) throw new Error('副标题不能为空');
|
|
if (!category) throw new Error('分类不能为空');
|
|
if (!path) throw new Error('页面路径不能为空');
|
|
if (!previewImg) throw new Error('预览图不能为空');
|
|
if (ageMin < 0 || ageMax < ageMin) throw new Error('年龄范围不合法');
|
|
if (!VALID_DIFFICULTY.has(difficulty)) throw new Error('难度不合法');
|
|
if (!VALID_STATUS.has(status)) throw new Error('状态不合法');
|
|
if (!(await ensureCategoryExists(db, category))) {
|
|
throw new Error('分类不合法,categories 集合中不存在该分类');
|
|
}
|
|
|
|
return {
|
|
id,
|
|
title,
|
|
subtitle,
|
|
category,
|
|
subcategory,
|
|
path,
|
|
previewImg,
|
|
ageMin,
|
|
ageMax,
|
|
grade,
|
|
difficulty,
|
|
tags,
|
|
isNew,
|
|
isHot,
|
|
sortOrder,
|
|
downloads,
|
|
likes,
|
|
status,
|
|
};
|
|
}
|
|
|
|
exports.main = async (event) => {
|
|
try {
|
|
const db = cloud.database();
|
|
const payload = await validatePayload(event, db);
|
|
const collection = db.collection('worksheets');
|
|
|
|
const record = {
|
|
title: payload.title,
|
|
subtitle: payload.subtitle,
|
|
category: payload.category,
|
|
subcategory: payload.subcategory,
|
|
path: payload.path,
|
|
ageMin: payload.ageMin,
|
|
ageMax: payload.ageMax,
|
|
grade: payload.grade,
|
|
difficulty: payload.difficulty,
|
|
previewImg: payload.previewImg,
|
|
tags: payload.tags,
|
|
isNew: payload.isNew,
|
|
isHot: payload.isHot,
|
|
sortOrder: payload.sortOrder,
|
|
downloads: payload.downloads,
|
|
likes: payload.likes,
|
|
status: payload.status,
|
|
updatedAt: db.serverDate(),
|
|
};
|
|
|
|
try {
|
|
const { data } = await collection.doc(payload.id).get();
|
|
|
|
await collection.doc(payload.id).update({
|
|
data: record,
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
_id: payload.id,
|
|
createdAt: data.createdAt,
|
|
...record,
|
|
},
|
|
};
|
|
} catch (error) {
|
|
await collection.doc(payload.id).set({
|
|
data: {
|
|
...record,
|
|
createdAt: db.serverDate(),
|
|
},
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
_id: payload.id,
|
|
...record,
|
|
},
|
|
};
|
|
}
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
message: error instanceof Error ? error.message : '发布题型失败',
|
|
};
|
|
}
|
|
};
|