192 lines
4.9 KiB
TypeScript
192 lines
4.9 KiB
TypeScript
// hooks/useComment.ts
|
|
/**
|
|
* 评论相关的可复用逻辑
|
|
*/
|
|
import { ref } from 'vue'
|
|
import { courseApi } from '@/api/modules/course'
|
|
import { bookApi } from '@/api/modules/book'
|
|
import type { IComment } from '@/types/comment'
|
|
|
|
export function useComment(type: 'course' | 'book') {
|
|
const commentList = ref<IComment[]>([])
|
|
const loading = ref(false)
|
|
const hasMore = ref(true)
|
|
const currentPage = ref(0)
|
|
|
|
/**
|
|
* 加载评论列表
|
|
*/
|
|
const loadComments = async (relationId: number, userId: number, limit: number = 15) => {
|
|
if (loading.value) return
|
|
|
|
try {
|
|
loading.value = true
|
|
currentPage.value++
|
|
|
|
let res: any
|
|
if (type === 'course') {
|
|
res = await courseApi.getCourseComments(relationId, currentPage.value, limit, userId)
|
|
} else {
|
|
res = await bookApi.getBookComments(relationId, currentPage.value, limit)
|
|
}
|
|
|
|
if (res.code === 0 && res.page) {
|
|
const newComments = res.page.records.map((comment: IComment) => {
|
|
// 处理图片
|
|
if (comment.images) {
|
|
comment.imgList = comment.images.split(',')
|
|
} else {
|
|
comment.imgList = []
|
|
}
|
|
|
|
// 处理子评论
|
|
if (comment.children && comment.children.length > 0) {
|
|
comment.Bchildren = comment.children.slice(0, 5)
|
|
} else {
|
|
comment.Bchildren = []
|
|
}
|
|
|
|
return comment
|
|
})
|
|
|
|
commentList.value = [...commentList.value, ...newComments]
|
|
hasMore.value = res.page.pages > currentPage.value
|
|
}
|
|
} catch (error) {
|
|
console.error('加载评论失败:', error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 添加评论
|
|
*/
|
|
const addComment = async (
|
|
relationId: number,
|
|
userId: number,
|
|
content: string,
|
|
images: string[],
|
|
parentComment?: IComment
|
|
) => {
|
|
try {
|
|
let res: any
|
|
if (type === 'course') {
|
|
res = await courseApi.addCourseComment({
|
|
type: 0,
|
|
courseId: relationId,
|
|
chapterId: '',
|
|
pid: parentComment?.id || 0,
|
|
userId,
|
|
forUserId: parentComment?.user.id || userId,
|
|
content,
|
|
images: images.join(',')
|
|
})
|
|
} else {
|
|
res = await bookApi.insertComment(relationId, content, parentComment?.id || 0)
|
|
}
|
|
|
|
if (res.code === 0) {
|
|
const newComment = type === 'course' ? res.courseGuestbook : res.bookComment
|
|
if (newComment) {
|
|
newComment.imgList = newComment.images ? newComment.images.split(',') : []
|
|
newComment.children = []
|
|
newComment.Bchildren = []
|
|
|
|
if (parentComment) {
|
|
// 回复评论
|
|
const parentIndex = commentList.value.findIndex(c => c.id === parentComment.id)
|
|
if (parentIndex !== -1) {
|
|
commentList.value[parentIndex].children.unshift(newComment)
|
|
commentList.value[parentIndex].Bchildren.unshift(newComment)
|
|
}
|
|
} else {
|
|
// 一级评论
|
|
commentList.value.unshift(newComment)
|
|
}
|
|
}
|
|
|
|
uni.showToast({ title: '发布成功', icon: 'success' })
|
|
return true
|
|
}
|
|
return false
|
|
} catch (error) {
|
|
console.error('添加评论失败:', error)
|
|
uni.showToast({ title: '发布失败', icon: 'none' })
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 点赞/取消点赞
|
|
*/
|
|
const toggleLike = async (commentId: number, userId: number) => {
|
|
try {
|
|
// 查找评论
|
|
let targetComment: IComment | null = null
|
|
|
|
for (const comment of commentList.value) {
|
|
if (comment.id === commentId) {
|
|
targetComment = comment
|
|
break
|
|
}
|
|
|
|
for (const child of comment.children) {
|
|
if (child.id === commentId) {
|
|
targetComment = child
|
|
break
|
|
}
|
|
}
|
|
|
|
if (targetComment) break
|
|
}
|
|
|
|
if (!targetComment) return
|
|
|
|
// 调用API
|
|
if (type === 'course') {
|
|
if (targetComment.support) {
|
|
await courseApi.unlikeComment(userId, commentId)
|
|
targetComment.support = false
|
|
targetComment.supportCount--
|
|
} else {
|
|
await courseApi.likeComment(userId, commentId)
|
|
targetComment.support = true
|
|
targetComment.supportCount++
|
|
}
|
|
} else {
|
|
if (targetComment.support) {
|
|
await bookApi.unlikeComment(commentId)
|
|
targetComment.support = false
|
|
targetComment.supportCount--
|
|
} else {
|
|
await bookApi.likeComment(commentId)
|
|
targetComment.support = true
|
|
targetComment.supportCount++
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('点赞失败:', error)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 重置评论列表
|
|
*/
|
|
const resetComments = () => {
|
|
commentList.value = []
|
|
currentPage.value = 0
|
|
hasMore.value = true
|
|
}
|
|
|
|
return {
|
|
commentList,
|
|
loading,
|
|
hasMore,
|
|
loadComments,
|
|
addComment,
|
|
toggleLike,
|
|
resetComments
|
|
}
|
|
}
|