Files
taimed-international-app/hooks/useComment.ts

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
}
}