feat: 开发收藏和下载功能
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
const cloud = require('wx-server-sdk');
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
const db = cloud.database();
|
||||
const command = db.command;
|
||||
|
||||
exports.main = async (event) => {
|
||||
const wxContext = cloud.getWXContext();
|
||||
const openid = wxContext.OPENID;
|
||||
|
||||
// 获取 userId
|
||||
const { data: users } = await db
|
||||
.collection('users')
|
||||
.where({ openid })
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
if (users.length === 0) {
|
||||
return { code: -1, message: '用户未登录' };
|
||||
}
|
||||
|
||||
const userId = users[0]._id;
|
||||
const { action } = event;
|
||||
|
||||
switch (action) {
|
||||
case 'add':
|
||||
return await handleAdd(userId, event);
|
||||
case 'list':
|
||||
return await handleList(userId, event);
|
||||
default:
|
||||
return { code: -1, message: '未知操作' };
|
||||
}
|
||||
};
|
||||
|
||||
async function handleAdd(userId, event) {
|
||||
const { worksheetId } = event;
|
||||
if (!worksheetId) return { code: -1, message: 'worksheetId 不能为空' };
|
||||
|
||||
const collection = db.collection('download_logs');
|
||||
|
||||
const record = {
|
||||
userId,
|
||||
worksheetId,
|
||||
createdAt: db.serverDate(),
|
||||
};
|
||||
const { _id } = await collection.add({ data: record });
|
||||
|
||||
// worksheets.downloads +1
|
||||
try {
|
||||
await db.collection('worksheets').doc(worksheetId).update({
|
||||
data: {
|
||||
downloads: command.inc(1),
|
||||
updatedAt: db.serverDate(),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('更新 worksheets.downloads 失败', e);
|
||||
}
|
||||
|
||||
return { code: 0, data: { _id, ...record } };
|
||||
}
|
||||
|
||||
async function handleList(userId, event) {
|
||||
const { page = 1, pageSize = 20 } = event;
|
||||
const skip = (page - 1) * pageSize;
|
||||
|
||||
const collection = db.collection('download_logs');
|
||||
|
||||
const { data: logs } = await collection
|
||||
.where({ userId })
|
||||
.orderBy('createdAt', 'desc')
|
||||
.skip(skip)
|
||||
.limit(pageSize)
|
||||
.get();
|
||||
|
||||
if (logs.length === 0) {
|
||||
return { code: 0, data: [] };
|
||||
}
|
||||
|
||||
// 关联查询 worksheets 信息
|
||||
const worksheetIds = [...new Set(logs.map((l) => l.worksheetId))];
|
||||
const { data: worksheets } = await db
|
||||
.collection('worksheets')
|
||||
.where({ _id: command.in(worksheetIds) })
|
||||
.get();
|
||||
|
||||
const worksheetMap = {};
|
||||
worksheets.forEach((w) => {
|
||||
worksheetMap[w._id] = w;
|
||||
});
|
||||
|
||||
const result = logs.map((l) => ({
|
||||
...l,
|
||||
worksheet: worksheetMap[l.worksheetId] || null,
|
||||
}));
|
||||
|
||||
return { code: 0, data: result };
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "user-download-logs",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "^3.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
const cloud = require('wx-server-sdk');
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
const db = cloud.database();
|
||||
const command = db.command;
|
||||
|
||||
exports.main = async (event) => {
|
||||
const wxContext = cloud.getWXContext();
|
||||
const openid = wxContext.OPENID;
|
||||
|
||||
// 获取 userId
|
||||
const { data: users } = await db
|
||||
.collection('users')
|
||||
.where({ openid })
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
if (users.length === 0) {
|
||||
return { code: -1, message: '用户未登录' };
|
||||
}
|
||||
|
||||
const userId = users[0]._id;
|
||||
const { action } = event;
|
||||
|
||||
switch (action) {
|
||||
case 'add':
|
||||
return await handleAdd(userId, event);
|
||||
case 'remove':
|
||||
return await handleRemove(userId, event);
|
||||
case 'list':
|
||||
return await handleList(userId, event);
|
||||
case 'check':
|
||||
return await handleCheck(userId, event);
|
||||
case 'batchCheck':
|
||||
return await handleBatchCheck(userId, event);
|
||||
default:
|
||||
return { code: -1, message: '未知操作' };
|
||||
}
|
||||
};
|
||||
|
||||
async function handleAdd(userId, event) {
|
||||
const { worksheetId } = event;
|
||||
if (!worksheetId) return { code: -1, message: 'worksheetId 不能为空' };
|
||||
|
||||
const collection = db.collection('favorites');
|
||||
|
||||
// 幂等检查:已收藏则直接返回
|
||||
const { data: existing } = await collection
|
||||
.where({ userId, worksheetId })
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
if (existing.length > 0) {
|
||||
return { code: 0, data: existing[0], message: '已收藏' };
|
||||
}
|
||||
|
||||
// 写入收藏记录
|
||||
const record = {
|
||||
userId,
|
||||
worksheetId,
|
||||
createdAt: db.serverDate(),
|
||||
};
|
||||
const { _id } = await collection.add({ data: record });
|
||||
|
||||
// worksheets.likes +1
|
||||
try {
|
||||
await db
|
||||
.collection('worksheets')
|
||||
.doc(worksheetId)
|
||||
.update({
|
||||
data: {
|
||||
likes: command.inc(1),
|
||||
updatedAt: db.serverDate(),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('更新 worksheets.likes 失败', e);
|
||||
}
|
||||
|
||||
return { code: 0, data: { _id, ...record } };
|
||||
}
|
||||
|
||||
async function handleRemove(userId, event) {
|
||||
const { worksheetId } = event;
|
||||
if (!worksheetId) return { code: -1, message: 'worksheetId 不能为空' };
|
||||
|
||||
const collection = db.collection('favorites');
|
||||
|
||||
const { data: existing } = await collection
|
||||
.where({ userId, worksheetId })
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
if (existing.length === 0) {
|
||||
return { code: 0, message: '未收藏' };
|
||||
}
|
||||
|
||||
await collection.doc(existing[0]._id).remove();
|
||||
|
||||
// worksheets.likes -1
|
||||
try {
|
||||
await db
|
||||
.collection('worksheets')
|
||||
.doc(worksheetId)
|
||||
.update({
|
||||
data: {
|
||||
likes: command.inc(-1),
|
||||
updatedAt: db.serverDate(),
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('更新 worksheets.likes 失败', e);
|
||||
}
|
||||
|
||||
return { code: 0, message: '已取消收藏' };
|
||||
}
|
||||
|
||||
async function handleList(userId, event) {
|
||||
const { page = 1, pageSize = 20 } = event;
|
||||
const skip = (page - 1) * pageSize;
|
||||
|
||||
const collection = db.collection('favorites');
|
||||
|
||||
// 查询收藏记录
|
||||
const { data: favorites } = await collection
|
||||
.where({ userId })
|
||||
.orderBy('createdAt', 'desc')
|
||||
.skip(skip)
|
||||
.limit(pageSize)
|
||||
.get();
|
||||
|
||||
if (favorites.length === 0) {
|
||||
return { code: 0, data: [] };
|
||||
}
|
||||
|
||||
// 关联查询 worksheets 信息
|
||||
const worksheetIds = favorites.map((f) => f.worksheetId);
|
||||
const { data: worksheets } = await db
|
||||
.collection('worksheets')
|
||||
.where({ _id: command.in(worksheetIds) })
|
||||
.get();
|
||||
|
||||
const worksheetMap = {};
|
||||
worksheets.forEach((w) => {
|
||||
worksheetMap[w._id] = w;
|
||||
});
|
||||
|
||||
const result = favorites.map((f) => ({
|
||||
...f,
|
||||
worksheet: worksheetMap[f.worksheetId] || null,
|
||||
}));
|
||||
|
||||
return { code: 0, data: result };
|
||||
}
|
||||
|
||||
async function handleCheck(userId, event) {
|
||||
const { worksheetId } = event;
|
||||
if (!worksheetId) return { code: -1, message: 'worksheetId 不能为空' };
|
||||
|
||||
const { data } = await db
|
||||
.collection('favorites')
|
||||
.where({ userId, worksheetId })
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
return { code: 0, data: { favorited: data.length > 0 } };
|
||||
}
|
||||
|
||||
async function handleBatchCheck(userId, event) {
|
||||
const { worksheetIds } = event;
|
||||
if (
|
||||
!worksheetIds ||
|
||||
!Array.isArray(worksheetIds) ||
|
||||
worksheetIds.length === 0
|
||||
) {
|
||||
return { code: 0, data: {} };
|
||||
}
|
||||
|
||||
const { data } = await db
|
||||
.collection('favorites')
|
||||
.where({ userId, worksheetId: command.in(worksheetIds) })
|
||||
.get();
|
||||
|
||||
const favoritedMap = {};
|
||||
data.forEach((item) => {
|
||||
favoritedMap[item.worksheetId] = true;
|
||||
});
|
||||
|
||||
return { code: 0, data: favoritedMap };
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "user-favorites",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "^3.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
const cloud = require('wx-server-sdk');
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
const db = cloud.database();
|
||||
|
||||
exports.main = async (event, context) => {
|
||||
const wxContext = cloud.getWXContext();
|
||||
const openid = wxContext.OPENID;
|
||||
const unionid = wxContext.UNIONID || null;
|
||||
|
||||
const { action } = event;
|
||||
|
||||
switch (action) {
|
||||
case 'updateProfile':
|
||||
return await handleUpdateProfile(event, openid);
|
||||
default:
|
||||
return await handleSilentLogin(openid, unionid);
|
||||
}
|
||||
};
|
||||
|
||||
async function handleSilentLogin(openid, unionid) {
|
||||
const usersCollection = db.collection('users');
|
||||
|
||||
const { data } = await usersCollection.where({ openid }).limit(1).get();
|
||||
|
||||
const now = db.serverDate();
|
||||
|
||||
if (data.length > 0) {
|
||||
const user = data[0];
|
||||
const updateData = { lastActiveAt: now };
|
||||
if (unionid && !user.unionid) {
|
||||
updateData.unionid = unionid;
|
||||
}
|
||||
await usersCollection.doc(user._id).update({ data: updateData });
|
||||
|
||||
return {
|
||||
code: 0,
|
||||
data: { ...user, ...updateData, lastActiveAt: new Date() },
|
||||
};
|
||||
} else {
|
||||
const newUser = {
|
||||
openid,
|
||||
unionid,
|
||||
nickName: null,
|
||||
avatarUrl: null,
|
||||
totalDownloads: 0,
|
||||
createdAt: now,
|
||||
lastActiveAt: now,
|
||||
};
|
||||
const { _id } = await usersCollection.add({ data: newUser });
|
||||
|
||||
return {
|
||||
code: 0,
|
||||
data: {
|
||||
_id,
|
||||
...newUser,
|
||||
createdAt: new Date(),
|
||||
lastActiveAt: new Date(),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function handleUpdateProfile(event, openid) {
|
||||
const { nickName, avatarUrl } = event;
|
||||
const usersCollection = db.collection('users');
|
||||
|
||||
const { data } = await usersCollection.where({ openid }).limit(1).get();
|
||||
|
||||
if (data.length === 0) {
|
||||
return { code: -1, message: '用户不存在' };
|
||||
}
|
||||
|
||||
const updateData = {};
|
||||
if (nickName !== undefined) updateData.nickName = nickName;
|
||||
if (avatarUrl !== undefined) updateData.avatarUrl = avatarUrl;
|
||||
|
||||
await usersCollection.doc(data[0]._id).update({ data: updateData });
|
||||
|
||||
return {
|
||||
code: 0,
|
||||
data: { ...data[0], ...updateData },
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "user-login",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "^3.0.4"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user