866 lines
18 KiB
JavaScript
866 lines
18 KiB
JavaScript
const db = uniCloud.database();
|
|
const _ = db.command;
|
|
const $ = db.command.aggregate;
|
|
const {
|
|
log,
|
|
time
|
|
} = require('console');
|
|
const uniID = require('uni-id-common');
|
|
|
|
|
|
|
|
let obj = {
|
|
getDateTime() {
|
|
return new Date();
|
|
},
|
|
async getDeletedCount(commentId) {
|
|
const {
|
|
deleted
|
|
} = await db.collection('comment_like')
|
|
.where({
|
|
comment_id: commentId
|
|
})
|
|
.count();
|
|
return deleted;
|
|
},
|
|
// 高并发安全的计数方法
|
|
async incrementReadCount(query) {
|
|
const t = Date.now();
|
|
try {
|
|
await this.checkRequestFrequency(query.article_id, context.CLIENTIP);
|
|
const res = await db.collection('uni-cms-articles')
|
|
.doc(query.article_id.toString())
|
|
.update({
|
|
view_count: db.command.inc(1),
|
|
last_view_time: t
|
|
});
|
|
|
|
return {
|
|
code: 200,
|
|
data: {
|
|
view_count: res.updated ? res.data.view_count : 0
|
|
}
|
|
};
|
|
} catch (e) {
|
|
return this.handleCountError(e);
|
|
}
|
|
},
|
|
|
|
// 频率控制核心方法
|
|
async checkRequestFrequency(articleId, ip) {
|
|
const key = `req:${articleId}:${ip}`;
|
|
const now = Date.now();
|
|
|
|
const record = await db.collection('request_logs')
|
|
.where({
|
|
key
|
|
})
|
|
.orderBy('time', 'desc')
|
|
.limit(1)
|
|
.get();
|
|
|
|
if (record.data.length > 0 && (now - record.data[0].time) < 1000) {
|
|
throw new Error('REQUEST_LIMIT');
|
|
}
|
|
|
|
await db.collection('request_logs').add({
|
|
key,
|
|
time: now,
|
|
articleId,
|
|
ip
|
|
});
|
|
},
|
|
|
|
// 统一错误处理器
|
|
handleCountError(e) {
|
|
const errorConfig = {
|
|
'REQUEST_LIMIT': {
|
|
code: 429,
|
|
message: '访问过于频繁'
|
|
},
|
|
'DATABASE_BUSY': {
|
|
code: 503,
|
|
message: '系统繁忙请重试'
|
|
}
|
|
};
|
|
|
|
return errorConfig[e.message] || {
|
|
code: 500,
|
|
message: '服务内部错误'
|
|
};
|
|
},
|
|
async getUserInfoMap(userIds) {
|
|
const res = await db.collection('uni-id-users')
|
|
.where({
|
|
_id: db.command.in(userIds)
|
|
})
|
|
.field({
|
|
_id: true,
|
|
nickname: true,
|
|
avatar_file: true
|
|
|
|
})
|
|
.get();
|
|
return new Map(res.data.map(u => [u._id, u]));
|
|
},
|
|
buildCommentTree(comments) {
|
|
if (!Array.isArray(comments) || comments.length === 0) {
|
|
console.error('无效的评论数据');
|
|
return [];
|
|
}
|
|
|
|
const map = new Map();
|
|
const roots = [];
|
|
|
|
// 1. 数据预处理
|
|
comments.forEach(comment => {
|
|
// 强制校验 _id 字段
|
|
if (!comment._id) {
|
|
console.error('评论缺少 _id 字段:', comment);
|
|
return;
|
|
}
|
|
|
|
const safeId = comment._id.toString();
|
|
|
|
const parentId = comment.parent_id;
|
|
|
|
const rootId = comment.root_id;
|
|
|
|
const node = {
|
|
...comment,
|
|
id: safeId,
|
|
replies: [],
|
|
reply_count: Number(comment.reply_count) || 0,
|
|
update_time: Number(comment.update_time) || Date.now(),
|
|
create_time: new Date(comment.create_time).getTime() || Date.now()
|
|
};
|
|
|
|
map.set(node.id, node);
|
|
|
|
// 根节点判断(仅依赖 parent_id)
|
|
const isRootNode = !parentId;
|
|
if (isRootNode) {
|
|
roots.push(node);
|
|
}
|
|
|
|
console.log('节点预处理:', {
|
|
id: node.id,
|
|
parentId,
|
|
isRootNode
|
|
});
|
|
});
|
|
|
|
// 2. 构建树结构
|
|
comments.forEach(comment => {
|
|
const currentId = comment._id.toString();
|
|
const current = map.get(currentId);
|
|
const parentId = current.parent_id;
|
|
|
|
if (parentId) {
|
|
const parent = map.get(parentId);
|
|
if (parent) {
|
|
parent.replies.push(current);
|
|
parent.reply_count = parent.replies.length;
|
|
} else {
|
|
console.warn(`父节点 ${parentId} 不存在,将当前节点 ${currentId} 升级为根节点`);
|
|
roots.push(current);
|
|
}
|
|
}
|
|
});
|
|
|
|
// 3. 排序
|
|
return roots.sort((a, b) => {
|
|
return b.update_time - a.update_time;
|
|
});
|
|
},
|
|
}
|
|
|
|
module.exports = {
|
|
_before() {
|
|
this.uniID = uniID.createInstance({
|
|
context: this.getClientInfo()
|
|
});
|
|
if (!this.uniID) throw new Error('uniID 初始化失败');
|
|
},
|
|
async getReplyComment(query) {
|
|
try {
|
|
|
|
const clientInfo = this.getClientInfo();
|
|
const {
|
|
uid
|
|
} = await this.uniID.checkToken(clientInfo.uniIdToken)
|
|
let user_id = uid;
|
|
// 1. 优化数据库查询(仅获取根评论)
|
|
const commentsRes = await db.collection('comment')
|
|
.where({
|
|
root_id: query.root_id
|
|
})
|
|
.field({
|
|
_id: true,
|
|
content: true,
|
|
author_id: true,
|
|
parent_id: true,
|
|
root_id: true,
|
|
create_time: true,
|
|
update_time: true,
|
|
ip_location: true,
|
|
like_count: true,
|
|
reply_count: true
|
|
})
|
|
.orderBy('reply_count', 'desc') // 新增按时间倒序[9](@ref)
|
|
.get();
|
|
|
|
// 2. 数据预处理
|
|
const rawComments = Object.freeze(commentsRes.data);
|
|
|
|
// 3. 批量获取用户信息
|
|
const userIds = [...new Set(rawComments.map(c => c.author_id))];
|
|
const userMap = await obj.getUserInfoMap(userIds);
|
|
|
|
// 4. 批量查询点赞状态
|
|
const commentIds = rawComments.map(c => c._id);
|
|
const likeRes = await db.collection('comment_like')
|
|
.where({
|
|
comment_id: db.command.in(commentIds),
|
|
user_id: user_id
|
|
})
|
|
.get();
|
|
const likeSet = new Set(likeRes.data.map(l => l.comment_id));
|
|
|
|
// 5. 构建扁平化数据结构
|
|
|
|
const commentList = rawComments.map(comment => ({
|
|
id: comment._id,
|
|
_id: comment._id,
|
|
pl_user_id: comment.author_id,
|
|
owner: comment.author_id === user_id,
|
|
hasLike: likeSet.has(comment._id),
|
|
likeNum: comment.like_count || 0,
|
|
root_id: comment.root_id,
|
|
parent_id: comment.parent_id,
|
|
avatarUrl: userMap.get(comment.author_id)?.avatar_file || {},
|
|
nickName: userMap.get(comment.author_id)?.nickname || '已注销用户',
|
|
content: comment.content,
|
|
createTime: comment.create_time,
|
|
ip_location: comment.ip_location,
|
|
hasShowMore: false
|
|
|
|
}));
|
|
|
|
return {
|
|
code: 200,
|
|
data: {
|
|
|
|
commentList: commentList
|
|
}
|
|
};
|
|
|
|
} catch (e) {
|
|
console.error('获取评论失败:', e);
|
|
return {
|
|
code: 500,
|
|
message: '查询服务异常'
|
|
};
|
|
}
|
|
},
|
|
async replyComment(query) {
|
|
try {
|
|
const clientInfo = this.getClientInfo();
|
|
const {
|
|
uid
|
|
} = await this.uniID.checkToken(clientInfo.uniIdToken);
|
|
|
|
// 参数校验
|
|
if (!query.content) {
|
|
return {
|
|
code: 400,
|
|
message: '评论内容不能为空'
|
|
};
|
|
}
|
|
console.log(query);
|
|
let {
|
|
article_id,
|
|
content,
|
|
parent_id,
|
|
root_id
|
|
} = query;
|
|
console.log(root_id, parent_id);
|
|
// 处理父评论逻辑
|
|
if (parent_id && parent_id !== 0) {
|
|
const parentRecord = await db.collection('comment')
|
|
.doc(parent_id)
|
|
.get();
|
|
|
|
if (!parentRecord.data[0]) {
|
|
return {
|
|
code: 404,
|
|
message: '父评论不存在'
|
|
};
|
|
}
|
|
}
|
|
|
|
const parent_comment = await db.collection("comment")
|
|
.doc(parent_id)
|
|
.get();
|
|
|
|
console.log(parent_comment);
|
|
|
|
|
|
|
|
// 构建评论数据
|
|
const commentData = {
|
|
article_id,
|
|
author_id: uid,
|
|
content,
|
|
parent_id,
|
|
root_id,
|
|
parent_author_id: parent_comment.data.length > 0 ? parent_comment.data[0].author_id : 0,
|
|
parent_author_content: parent_comment.data.length > 0 ? parent_comment.data[0].content : "",
|
|
create_time: obj.getDateTime(),
|
|
update_time: obj.getDateTime(),
|
|
ip_location: {
|
|
clientIP: clientInfo.clientIP
|
|
} || {},
|
|
children:[],
|
|
like_count: 0,
|
|
reply_count: 0
|
|
};
|
|
|
|
|
|
|
|
|
|
// 插入数据库
|
|
const {
|
|
id
|
|
} = await db.collection('comment').add(commentData);
|
|
|
|
await db.collection('comment').doc(root_id)
|
|
.update({
|
|
reply_count: _.inc(1)
|
|
});
|
|
|
|
// 获取用户信息
|
|
const userMap = await obj.getUserInfoMap([uid]);
|
|
const userInfo = userMap.get(uid) || {};
|
|
|
|
// 构建返回数据
|
|
return {
|
|
code: 200,
|
|
data: {
|
|
id,
|
|
_id: id,
|
|
pl_user_id: uid,
|
|
owner: true,
|
|
hasLike: false,
|
|
likeNum: 0,
|
|
root_id: commentData.root_id,
|
|
parent_id: commentData.parent_id,
|
|
avatarUrl: userInfo.avatar_file || {
|
|
url: '',
|
|
name: '',
|
|
extname: ''
|
|
},
|
|
nickName: userInfo.nickname || '注销用户',
|
|
content: commentData.content,
|
|
createTime: commentData.create_time,
|
|
ip_location: commentData.ip_location,
|
|
replyCount: 0
|
|
}
|
|
};
|
|
|
|
} catch (e) {
|
|
console.error('添加评论失败:', e);
|
|
return {
|
|
code: 500,
|
|
message: '添加评论失败'
|
|
};
|
|
}
|
|
},
|
|
async addComment(query) {
|
|
try {
|
|
const clientInfo = this.getClientInfo();
|
|
const {
|
|
uid
|
|
} = await this.uniID.checkToken(clientInfo.uniIdToken);
|
|
|
|
// 参数校验
|
|
if (!query.content) {
|
|
return {
|
|
code: 400,
|
|
message: '评论内容不能为空'
|
|
};
|
|
}
|
|
|
|
let {
|
|
content,
|
|
parent_id = 0,
|
|
root_id = 0
|
|
} = query;
|
|
|
|
// 处理父评论逻辑
|
|
if (parent_id && parent_id !== 0) {
|
|
const parentRecord = await db.collection('comment')
|
|
.doc(parent_id)
|
|
.get();
|
|
|
|
if (!parentRecord.data[0]) {
|
|
return {
|
|
code: 404,
|
|
message: '父评论不存在'
|
|
};
|
|
}
|
|
|
|
// 继承父评论的root_id(如果父评论是根评论则使用父评论ID)
|
|
root_id = parentRecord.data[0].root_id === 0 ?
|
|
parent_id :
|
|
parentRecord.data[0].root_id;
|
|
}
|
|
|
|
// 构建评论数据
|
|
const commentData = {
|
|
article_id: query.article_id,
|
|
author_id: uid,
|
|
content,
|
|
parent_id,
|
|
root_id,
|
|
create_time: obj.getDateTime(),
|
|
update_time: obj.getDateTime(),
|
|
ip_location: {
|
|
clientIP: clientInfo.clientIP
|
|
} || {},
|
|
like_count: 0,
|
|
reply_count: 0
|
|
};
|
|
console.log(commentData);
|
|
|
|
// 插入数据库
|
|
const {
|
|
id
|
|
} = await db.collection('comment').add(commentData);
|
|
|
|
// 更新父评论的回复计数
|
|
if (parent_id !== 0) {
|
|
await db.collection('comment')
|
|
.doc(parent_id)
|
|
.update({
|
|
reply_count: db.command.inc(1)
|
|
});
|
|
}
|
|
|
|
// 获取用户信息
|
|
const userMap = await obj.getUserInfoMap([uid]);
|
|
const userInfo = userMap.get(uid) || {};
|
|
|
|
// 构建返回数据
|
|
return {
|
|
code: 200,
|
|
data: {
|
|
id,
|
|
_id: id,
|
|
pl_user_id: uid,
|
|
owner: true,
|
|
hasLike: false,
|
|
likeNum: 0,
|
|
root_id: commentData.root_id,
|
|
parent_id: commentData.parent_id,
|
|
avatarUrl: userInfo.avatar_file || {
|
|
url: '',
|
|
name: '',
|
|
extname: ''
|
|
},
|
|
children: [],
|
|
nickName: userInfo.nickname || '注销用户',
|
|
content: commentData.content,
|
|
createTime: commentData.create_time,
|
|
ip_location: commentData.ip_location,
|
|
replyCount: 0
|
|
}
|
|
};
|
|
|
|
} catch (e) {
|
|
console.error('添加评论失败:', e);
|
|
return {
|
|
code: 500,
|
|
message: '添加评论失败'
|
|
};
|
|
}
|
|
},
|
|
async deleteComment(id, root_id) {
|
|
let transaction = null;
|
|
try {
|
|
|
|
if (!id || typeof id !== 'string' || id.length !== 24) {
|
|
throw new Error('INVALID_ID: 无效的评论ID');
|
|
}
|
|
|
|
const clientInfo = this.getClientInfo();
|
|
const {
|
|
uid
|
|
} = await this.uniID.checkToken(clientInfo.uniIdToken);
|
|
if (!uid) throw new Error('PERMISSION_DENIED: 用户未登录');
|
|
|
|
|
|
const commentDoc = await db.collection('comment')
|
|
.doc(id)
|
|
.field({
|
|
author_id: 1,
|
|
article_id: 1
|
|
})
|
|
.get();
|
|
|
|
if (!commentDoc.data) {
|
|
throw new Error('NOT_FOUND: 评论不存在');
|
|
}
|
|
console.log(commentDoc.data);
|
|
|
|
|
|
if (commentDoc.data[0].author_id !== uid) {
|
|
throw new Error('PERMISSION_DENIED: 无权限删除该评论');
|
|
}
|
|
|
|
transaction = await db.startTransaction();
|
|
|
|
|
|
|
|
|
|
await transaction.collection('comment').doc(id).remove();
|
|
|
|
await transaction.collection('comment_like')
|
|
.where({
|
|
comment_id: id,
|
|
type: 'comment' // 添加类型过滤提高准确性
|
|
})
|
|
.remove();
|
|
|
|
|
|
if (!root_id === 0) {
|
|
await transaction.collection('uni-cms-articles')
|
|
.doc(root_id)
|
|
.update({
|
|
reply_count: _.inc(-1)
|
|
});
|
|
}
|
|
|
|
await transaction.commit();
|
|
|
|
|
|
await db.collection('comment_operation_logs').add({
|
|
type: 'comment_delete',
|
|
uid,
|
|
comment_id: commentDoc.id,
|
|
timestamp: obj.getDateTime()
|
|
});
|
|
|
|
console.log(1);
|
|
|
|
return {
|
|
code: 200,
|
|
message: '评论及关联数据删除成功',
|
|
data: {
|
|
deletedComment: 1,
|
|
del_id: id
|
|
}
|
|
};
|
|
|
|
} catch (e) {
|
|
// ================= 11. 事务回滚 =================
|
|
if (transaction) await transaction.rollback();
|
|
|
|
// ================= 12. 错误分类处理 =================
|
|
console.error(`[DELETE_COMMENT_ERROR] ${e.message}`, {
|
|
comment_id: id,
|
|
error: e.stack
|
|
});
|
|
|
|
const errorMap = {
|
|
'INVALID_ID': 400,
|
|
'PERMISSION_DENIED': 403,
|
|
'NOT_FOUND': 404
|
|
};
|
|
|
|
return {
|
|
code: errorMap[e.message.split(':')[0]] || 500,
|
|
message: e.message.split(':')[1]?.trim() || '系统错误',
|
|
errorType: e.message.split(':')[0] || 'UNKNOWN_ERROR'
|
|
};
|
|
}
|
|
},
|
|
|
|
// ================= 辅助方法 =================
|
|
async updateComment(id, comment) {
|
|
try {
|
|
|
|
// ==== 参数校验 ====
|
|
if (!id || typeof id !== 'string' || id.length !== 24) {
|
|
throw new Error('INVALID_ID: 评论ID格式错误');
|
|
}
|
|
if (!comment?.content?.trim() || comment.content.trim().length > 500) {
|
|
throw new Error('INVALID_CONTENT: 评论内容不能为空且不超过500字符');
|
|
}
|
|
|
|
// ==== 身份验证 ====
|
|
const clientInfo = this.getClientInfo();
|
|
const {
|
|
uid
|
|
} = await this.uniID.checkToken(clientInfo.uniIdToken);
|
|
// ==== 权限验证 ====
|
|
const commentDoc = await db.collection('comment')
|
|
.doc(id)
|
|
.field({
|
|
author_id: 1
|
|
})
|
|
.get();
|
|
|
|
if (commentDoc.data.author_id !== uid) {
|
|
throw new Error('PERMISSION_DENIED: 无权修改该评论');
|
|
}
|
|
|
|
// ==== 数据处理 ====
|
|
const sanitizedContent = comment.content.trim();
|
|
const maskedIP = clientInfo.clientIP.replace(/\.\d+$/, '.*');
|
|
|
|
// ==== 构建更新数据 ====
|
|
const updateData = {
|
|
updateTime: obj.getDateTime(),
|
|
content: sanitizedContent,
|
|
ip_location: maskedIP
|
|
};
|
|
if (comment.title) {
|
|
updateData.title = comment.title.substring(0, 50);
|
|
}
|
|
|
|
// ==== 执行更新 ====
|
|
const res = await db.collection('comment')
|
|
.doc(id)
|
|
.update(updateData);
|
|
|
|
// ==== 记录操作日志 ====
|
|
await db.collection('comment_operation_logs').add({
|
|
type: 'comment_update',
|
|
operator: uid,
|
|
target_id: id,
|
|
before_content: commentDoc.data.content,
|
|
after_content: sanitizedContent,
|
|
timestamp: obj.getDateTime()
|
|
});
|
|
|
|
return {
|
|
code: 200,
|
|
message: '评论更新成功',
|
|
data: {
|
|
updatedId: id,
|
|
newContent: sanitizedContent,
|
|
timestamp: Date.now()
|
|
}
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error(`[UPDATE_COMMENT_ERROR] ${error.message}`, {
|
|
id,
|
|
user: this.getClientInfo().uid
|
|
});
|
|
|
|
return {
|
|
code: error.code || 500,
|
|
message: error.message.split(':')[1]?.trim() || '系统错误',
|
|
errorType: error.message.split(':')[0]
|
|
};
|
|
}
|
|
},
|
|
|
|
async getComments(query) {
|
|
try {
|
|
|
|
const clientInfo = this.getClientInfo();
|
|
const {
|
|
uid
|
|
} = await this.uniID.checkToken(clientInfo.uniIdToken)
|
|
let user_id = uid;
|
|
// 1. 优化数据库查询(仅获取根评论)
|
|
console.log(query);
|
|
const commentsRes = await db.collection('comment')
|
|
.where({
|
|
root_id: 0,
|
|
article_id: query.article_id
|
|
})
|
|
.field({
|
|
_id: true,
|
|
content: true,
|
|
author_id: true,
|
|
parent_id: true,
|
|
root_id: true,
|
|
create_time: true,
|
|
update_time: true,
|
|
ip_location: true,
|
|
like_count: true,
|
|
reply_count: true
|
|
})
|
|
.orderBy('reply_count', 'desc')
|
|
.get();
|
|
|
|
// 2. 数据预处理
|
|
const rawComments = Object.freeze(commentsRes.data);
|
|
|
|
// 3. 批量获取用户信息
|
|
const userIds = [...new Set(rawComments.map(c => c.author_id))];
|
|
const userMap = await obj.getUserInfoMap(userIds);
|
|
|
|
// 4. 批量查询点赞状态
|
|
const commentIds = rawComments.map(c => c._id);
|
|
const likeRes = await db.collection('comment_like')
|
|
.where({
|
|
comment_id: db.command.in(commentIds),
|
|
user_id: user_id
|
|
})
|
|
.get();
|
|
const likeSet = new Set(likeRes.data.map(l => l.comment_id));
|
|
|
|
// 5. 构建扁平化数据结构
|
|
const commentList = rawComments.map(comment => ({
|
|
id: comment._id,
|
|
_id: comment._id,
|
|
pl_user_id: comment.author_id,
|
|
owner: comment.author_id === user_id,
|
|
hasLike: likeSet.has(comment._id),
|
|
likeNum: comment.like_count || 0,
|
|
root_id: comment.root_id,
|
|
parent_id: comment.parent_id,
|
|
avatarUrl: userMap.get(comment.author_id)?.avatar_file || {},
|
|
nickName: userMap.get(comment.author_id)?.nickname || '已注销用户',
|
|
content: comment.content,
|
|
createTime: comment.create_time,
|
|
ip_location: comment.ip_location,
|
|
|
|
replyCount: comment.reply_count || 0,
|
|
children: [],
|
|
hasShowMore: false
|
|
|
|
}));
|
|
|
|
return {
|
|
code: 200,
|
|
data: {
|
|
commentList: commentList // 直接返回无需构建树形结构[8](@ref)
|
|
}
|
|
};
|
|
|
|
} catch (e) {
|
|
console.error('获取评论失败:', e);
|
|
return {
|
|
code: 500,
|
|
message: '查询服务异常'
|
|
};
|
|
}
|
|
},
|
|
async getReadCount(query) {
|
|
try {
|
|
|
|
if (!query || !query.article_id) {
|
|
throw new Error('INVALID_PARAM');
|
|
}
|
|
|
|
const res = await db.collection('uni-cms-articles')
|
|
.doc(query.article_id.toString())
|
|
.field({
|
|
view_count: 1,
|
|
_id: 0
|
|
})
|
|
.get();
|
|
|
|
|
|
return {
|
|
code: 200,
|
|
data: {
|
|
view_count: res.data[0]?.view_count || 0
|
|
}
|
|
};
|
|
|
|
} catch (e) {
|
|
|
|
const errorMap = {
|
|
'INVALID_PARAM': {
|
|
code: 400,
|
|
message: '参数异常'
|
|
},
|
|
'DATABASE_ERROR': {
|
|
code: 503,
|
|
message: '服务暂不可用'
|
|
}
|
|
};
|
|
|
|
return errorMap[e.message] || {
|
|
code: 500,
|
|
data: {
|
|
view_count: 0
|
|
},
|
|
message: '统计服务异常'
|
|
};
|
|
}
|
|
},
|
|
|
|
async likeComment(user_id, comment_id) {
|
|
let datatime = new Date().getTime();
|
|
|
|
const transaction = await db.startTransaction();
|
|
try {
|
|
|
|
const exist = await transaction.collection('comment_like')
|
|
.where({
|
|
user_id: user_id,
|
|
comment_id: comment_id
|
|
}).count();
|
|
|
|
if (exist.total > 0) throw new Error('已点赞');
|
|
|
|
await transaction.collection('comment_like').add({
|
|
user_id: user_id,
|
|
comment_id: comment_id,
|
|
create_time: datatime
|
|
});
|
|
|
|
await transaction.collection('comment').doc(comment_id)
|
|
.update({
|
|
like_count: _.inc(1)
|
|
});
|
|
|
|
await transaction.commit();
|
|
return {
|
|
code: 200
|
|
};
|
|
} catch (e) {
|
|
await transaction.rollback();
|
|
return {
|
|
code: 500,
|
|
msg: e.message
|
|
};
|
|
}
|
|
},
|
|
|
|
async relikeComment(user_id, comment_id) {
|
|
|
|
try {
|
|
const likeRes = await db.collection('comment_like')
|
|
.where({
|
|
user_id: user_id,
|
|
comment_id: comment_id
|
|
}).remove();
|
|
|
|
if (likeRes.deleted === 0) throw new Error('未找到点赞记录');
|
|
|
|
await db.collection('comment').doc(comment_id)
|
|
.update({
|
|
like_count: _.inc(-1)
|
|
});
|
|
|
|
return {
|
|
code: 200
|
|
};
|
|
} catch (e) {
|
|
return {
|
|
code: 500,
|
|
msg: e.message
|
|
};
|
|
}
|
|
},
|
|
|
|
} |