const db = uniCloud.database(); const _ = db.command; const uniID = require('uni-id-common'); module.exports = { _before: function () { // 通用预处理器 this.uniID = uniID.createInstance({ context: this.getClientInfo() }); }, async collectArticle(query) { const payload = await this.uniID.checkToken(this.getUniIdToken()); if (payload.errCode) throw new Error('登录状态失效,请重新登录'); const user_id = payload.uid; // 以服务端令牌为准,忽略客户端传入 const article_id = query && query.article_id; if (!article_id) { return { code: 400, msg: '缺少 article_id' }; } const transaction = await db.startTransaction(); try { // 查重只看「用户 + 文章」。曾把本次请求时间戳也放进条件, // 导致每次都查不到已有记录,可以无限重复收藏刷高计数。 const exist = await transaction.collection('cms-articles-collect') .where({ user_id: user_id, article_id: article_id }).count(); if (exist.total > 0) { await transaction.rollback(); return { code: 201, msg: '已点收藏' }; } await transaction.collection('cms-articles-collect').add({ user_id: user_id, article_id: article_id, create_time: Date.now() }); await transaction.collection('uni-cms-articles').doc(article_id) .update({ collect_count: _.inc(1) }); await transaction.commit(); return { code: 200 }; } catch (e) { await transaction.rollback(); return { code: 500, msg: e.message }; } }, async recollectArticle(query) { const payload = await this.uniID.checkToken(this.getUniIdToken()); if (payload.errCode) throw new Error('登录状态失效,请重新登录'); const user_id = payload.uid; const article_id = query && query.article_id; if (!article_id) { return { code: 400, msg: '缺少 article_id' }; } // 删除明细与减计数必须同事务,否则删成功而减失败会让计数永久偏高 const transaction = await db.startTransaction(); try { const removeRes = await transaction.collection('cms-articles-collect') .where({ user_id: user_id, article_id: article_id }).remove(); if (removeRes.deleted === 0) { await transaction.rollback(); return { code: 201, msg: '未找到收藏记录' }; } await transaction.collection('uni-cms-articles').doc(article_id) .update({ collect_count: _.inc(-1) }); await transaction.commit(); return { code: 200 }; } catch (e) { await transaction.rollback(); return { code: 500, msg: e.message }; } } }