// 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([]) 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 } }