CourseReviewsPage.vue
4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!--
* @Date: 2025-03-21 11:33:26
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-03 20:00:05
* @FilePath: /mlaj/src/views/courses/CourseReviewsPage.vue
* @Description: 文件描述
-->
<template>
<AppLayout title="全部评价">
<div class="px-4 py-3">
<!-- Overall Rating -->
<div class="flex items-center justify-between mb-4">
<div class="flex items-center">
<div class="text-2xl font-bold mr-2">{{ overallRating }}</div>
<van-rate v-model="overallRating" readonly :size="20" color="#ffd21e" void-icon="star" void-color="#eee" />
</div>
<div class="text-gray-500 text-sm">{{ commentTotal }}条评论</div>
</div>
<!-- Reviews List -->
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<div v-for="(review, index) in reviews" :key="index" class="mb-4 pb-4 border-b border-gray-100 last:border-0">
<div class="flex justify-between items-center mb-2">
<div class="flex items-center flex-1 min-w-0 mr-2">
<div class="flex-grow">
<span class="font-medium text-sm block">{{ review.name || '匿名用户' }}</span>
</div>
</div>
<van-rate v-model="review.score" readonly :size="20" color="#ffd21e" void-icon="star" void-color="#eee" />
</div>
<p class="text-gray-600 text-sm mb-2">{{ review.note }}</p>
<div class="flex justify-between items-center">
<div class="text-gray-400 text-xs">{{ formatDate(review.created_time) }}</div>
<van-icon v-if="review.is_my" name="ellipsis" class="text-gray-400" @click="showActionSheet(review)" />
</div>
</div>
</van-list>
</div>
<!-- Action Sheet -->
<van-action-sheet v-model:show="showActions" :actions="actions" cancel-text="取消" close-on-click-action
@select="onSelect" />
<!-- Review Edit Popup -->
<ReviewPopup v-model:show="showReviewPopup" title="编辑评价" :initial-score="currentReview?.score"
:initial-note="currentReview?.note" @submit="handleReviewEdit" />
</AppLayout>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import AppLayout from '@/components/layout/AppLayout.vue'
import { Rate, List, Icon, ActionSheet, showConfirmDialog, showToast } from 'vant'
import { formatDate } from '@/utils/tools'
import ReviewPopup from '@/components/courses/ReviewPopup.vue'
// 导入接口
import { getGroupCommentListAPI, editGroupCommentAPI, delGroupCommentAPI } from '@/api/course'
const route = useRoute()
const overallRating = ref(0)
const loading = ref(false)
const finished = ref(false)
const reviews = ref([])
const commentTotal = ref(0)
const limit = ref(5)
const page = ref(0)
// 动作面板相关
const showActions = ref(false)
const currentReview = ref(null)
const actions = [
{ name: '编辑', color: '#2563eb' },
{ name: '删除', color: '#ef4444' },
]
// 评论编辑相关
const showReviewPopup = ref(false)
const fetchComments = async () => {
const { code, data } = await getGroupCommentListAPI({
group_id: route.params.id,
page: page.value,
limit: limit.value
})
if (code) {
if (page.value === 0) {
reviews.value = data.comment_list
overallRating.value = data.comment_score || 0
commentTotal.value = data.comment_count || 0
} else {
reviews.value.push(...data.comment_list)
}
finished.value = data.comment_list.length < limit.value
page.value += 1
}
loading.value = false
}
const onLoad = () => {
fetchComments()
}
const showActionSheet = (review) => {
currentReview.value = review
showActions.value = true
}
const onSelect = (action) => {
if (action.name === '编辑') {
showReviewPopup.value = true
} else if (action.name === '删除') {
showConfirmDialog({
title: '温馨提示',
message: '确定要删除这条评论吗?',
}).then(() => {
handleReviewDelete()
})
}
}
const handleReviewEdit = async ({ score, note }) => {
const { code } = await editGroupCommentAPI({
i: currentReview.value.id,
score,
note
})
if (code) {
showToast('评论修改成功')
page.value = 0
await fetchComments()
}
}
const handleReviewDelete = async () => {
const { code } = await delGroupCommentAPI({
i: currentReview.value.id
})
if (code) {
showToast('评论删除成功')
page.value = 0
await fetchComments()
}
}
</script>