StudyCommentsSection.vue
8.04 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<template>
<div id="comment" class="py-4 px-4 space-y-4" :style="{ paddingBottom: bottomWrapperHeight }">
<div class="flex justify-between items-center mb-4">
<div class="text-gray-900 font-medium text-sm">评论 ({{ commentCount }})</div>
<div class="text-gray-500 cursor-pointer text-sm" @click="show_comment_popup_model = true">查看更多</div>
</div>
<div v-for="comment in commentList" :key="comment.id" class="border-b border-gray-100 last:border-b-0 py-4">
<div class="flex">
<img :src="comment.avatar || 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'"
class="w-10 h-10 rounded-full flex-shrink-0" style="margin-right: 0.5rem;" />
<div class="flex-1 ml-3">
<div class="flex justify-between items-center mb-1">
<span class="font-medium text-gray-900">{{ comment.name || '匿名用户' }}</span>
<div class="flex items-center space-x-1">
<span class="text-sm text-gray-500">{{ comment.like_count }}</span>
<van-icon :name="comment.is_like ? 'like' : 'like-o'"
:class="{ 'text-red-500': comment.is_like, 'text-gray-400': !comment.is_like }"
@click="$emit('toggleLike', comment)" class="text-lg cursor-pointer" />
</div>
</div>
<p class="text-gray-700 text-sm mb-1">{{ comment.note }}</p>
<div class="flex items-center justify-between">
<div class="text-gray-400 text-xs">{{ formatDate(comment.updated_time) }}</div>
<van-icon v-if="comment.is_my" name="ellipsis" class="text-gray-400"
@click="show_action_sheet(comment)" />
</div>
</div>
</div>
</div>
<van-popup v-model:show="show_comment_popup_model" position="bottom" round closeable safe-area-inset-bottom
style="height: 80%">
<div class="flex flex-col h-full">
<div class="flex-none px-4 py-3 border-b bg-white sticky top-0 z-10">
<div class="text-lg font-medium">全部评论 ({{ commentCount }})</div>
</div>
<div class="flex-1 overflow-y-auto">
<van-list v-model:loading="popup_loading_model" :finished="popupFinished" finished-text="没有更多评论了"
@load="$emit('popupLoad')" class="px-4 py-2 pb-16">
<div v-for="comment in popupCommentList" :key="comment.id"
class="border-b border-gray-100 last:border-b-0 py-4">
<div class="flex">
<img :src="comment.avatar || 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'"
class="w-10 h-10 rounded-full flex-shrink-0" style="margin-right: 0.5rem;" />
<div class="flex-1 ml-3">
<div class="flex justify-between items-center mb-1">
<span class="font-medium text-gray-900">{{ comment.name || '匿名用户' }}</span>
<div class="flex items-center space-x-1">
<span class="text-sm text-gray-500">{{ comment.like_count }}</span>
<van-icon :name="comment.is_like ? 'like' : 'like-o'"
:class="{ 'text-red-500': comment.is_like, 'text-gray-400': !comment.is_like }"
@click="$emit('toggleLike', comment)" class="text-lg cursor-pointer" />
</div>
</div>
<p class="text-gray-700 text-sm mb-1">{{ comment.note }}</p>
<div class="flex items-center justify-between">
<div class="text-gray-400 text-xs">{{ formatDate(comment.updated_time) }}</div>
<van-icon v-if="comment.is_my" name="ellipsis" class="text-gray-400"
@click="show_action_sheet(comment)" />
</div>
</div>
</div>
</div>
</van-list>
</div>
<div class="flex-none border-t px-4 py-2 bg-white fixed bottom-0 left-0 right-0 z-10">
<div class="flex items-center space-x-2">
<van-field v-model="popup_comment_model" rows="1" autosize type="textarea" placeholder="请输入评论"
class="flex-1 bg-gray-100 rounded-lg" />
<van-button type="primary" size="small" @click="$emit('submitPopupComment')">发送</van-button>
</div>
</div>
</div>
</van-popup>
<van-action-sheet v-model:show="show_actions" :actions="actions" cancel-text="取消" close-on-click-action
@select="on_select_action" />
</div>
</template>
<script setup>
import { computed, ref } from 'vue';
import { showConfirmDialog, showToast } from 'vant'
import { formatDate } from '@/utils/tools'
import { delGroupCommentAPI } from '@/api/course'
const props = defineProps({
commentCount: {
type: Number,
default: 0
},
commentList: {
type: Array,
default: () => []
},
showCommentPopup: {
type: Boolean,
default: false
},
popupCommentList: {
type: Array,
default: () => []
},
popupLoading: {
type: Boolean,
default: false
},
popupFinished: {
type: Boolean,
default: false
},
popupComment: {
type: String,
default: ''
},
bottomWrapperHeight: {
type: String,
default: '0px'
}
});
const emit = defineEmits([
'update:showCommentPopup',
'update:popupLoading',
'update:popupComment',
'toggleLike',
'popupLoad',
'submitPopupComment',
'commentDeleted'
]);
const show_comment_popup_model = computed({
get: () => props.showCommentPopup,
set: (val) => emit('update:showCommentPopup', val)
});
const popup_loading_model = computed({
get: () => props.popupLoading,
set: (val) => emit('update:popupLoading', val)
});
const popup_comment_model = computed({
get: () => props.popupComment,
set: (val) => emit('update:popupComment', val)
});
const show_actions = ref(false)
const current_comment = ref(null)
const actions = [
{ name: '删除', color: '#ef4444' },
]
/**
* @function show_action_sheet
* @description 打开评论操作面板(目前仅支持删除)
* @param {Object} comment - 当前选中的评论对象
* @returns {void}
*/
const show_action_sheet = (comment) => {
current_comment.value = comment
show_actions.value = true
}
/**
* @function on_select_action
* @description 处理评论操作面板选项点击
* @param {Object} action - 选中的动作项
* @returns {void}
*/
const on_select_action = (action) => {
if (action?.name === '删除') {
confirm_delete_comment()
}
}
/**
* @function confirm_delete_comment
* @description 二次确认删除评论并调用接口
* @returns {Promise<void>}
*/
const confirm_delete_comment = async () => {
const comment_id = current_comment.value?.id
if (!comment_id) return
try {
await showConfirmDialog({
title: '温馨提示',
message: '确定要删除这条评论吗?',
})
} catch (e) {
return
}
const { code } = await delGroupCommentAPI({ i: comment_id })
if (code === 1) {
showToast('评论删除成功')
emit('commentDeleted', comment_id)
}
}
</script>