主评论的人在数组第一层级,回复的评论都在children里面
【{
name:"张三"
idGenerator: 475403892531269
info_Conmment":"今天天气晴朗😀"
children:[
{
mainIdGenerator:475388950118469
name:"张三"
name1:"李四"
idGenerator:475403933356101
info_Conmment:"哈哈哈哈"
}
]
}】
<template>
<div
style="margin: 20px; margin-top: 40px"
v-if="route.query.isComment == 'true' || props.isComment"
>
<p style="font-size: 18px; color: #1d2129">
<el-divider
style="width: 3px; height: 18px; background: #2c68ff; margin-left: 0px"
direction="vertical"
/>{{$t('view.course.comment')}}:
</p>
<el-form :model="commentForm">
<!-- maxlength="1000"
show-word-limit -->
<el-form-item>
<el-input
v-model="commentForm.commentText"
:rows="3"
type="textarea"
maxlength="150"
@input="handleInput(commentForm.commentText)"
:placeholder="$t('view.course.add_comment')"
>
</el-input>
<div class="commentOperate">
<div class="numberLimit">
还能输入<span class="remainingCount">{{ remainingCount }}</span
>个字符
</div>
<div class="comment-operate-item">
<VueEmoji @chooseEmoji="chooseEmoji" />
<el-button class="commentBtn" type="primary" @click="userCommont"
>评论
</el-button>
</div>
</div>
</el-form-item>
</el-form>
<!-- 评论列表 -->
<div v-if="comments.length > 0">
<div
v-for="(comment, index) in comments"
:key="comment.idGenerator"
style="
margin-top: 12px;
border-bottom: 1px #f4f3f3;
display: flex;
align-items: flex-start;
"
>
<el-avatar
:size="40"
style="margin-right: 12px; margin-left: 10px"
:src="comment.avatarUrl || profile"
></el-avatar>
<div style="flex: 1">
<span style="font-size: 16px">{{ comment.name }}</span>
<p>
{{ comment.info_Conmment }}
</p>
<p style="font-size: 12px; color: #86909c; margin-top: 5px">
{{ comment.createdTime }}
<el-button
link
style="font-size: 12px; color: #86909c"
@click="
toggleLikeComment(comment.idGenerator, comment.isThumbsUp)
"
>
<!-- <svg-icon
:icon-class="getCommentIconClass(comment.idGenerator)"
:src="getCommentIconSrc(comment.idGenerator)"
class="svg-icon"
style="
margin-left: 20px;
margin-right: 3px;
transform: translateY(-1px);
"
:class="{ liked: isCommentLiked(comment.idGenerator) }"
/> -->
<svg-icon
:icon-class="getCommentzanIconClass(comment.isThumbsUp)"
:src="getCommentzanIconSrc(comment.isThumbsUp)"
class="svg-icon"
style="
margin-left: 20px;
margin-right: 3px;
transform: translateY(-1px);
"
/>
<span v-if="comment.thumbsUpCount > 0">{{
comment.thumbsUpCount
}}</span
>{{ $t('view.course.like') }}
</el-button>
<el-button
link
style="font-size: 12px; color: #86909c"
@click="toggleReply(comment.idGenerator)"
>
<el-icon style="margin-right: 3px; font-size: 16px">
<ChatLineSquare />
</el-icon>
{{ $t('view.course.reply') }}
</el-button>
<el-dropdown trigger="click">
<template #default>
<span>
<el-button link>
<el-icon
style="
margin-left: 12px;
color: #4e5969;
font-size: 12px;
transform: translateY(4px);
"
>
<MoreFilled />
</el-icon>
</el-button>
</span>
</template>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="deleteComment(comment.idGenerator)"
>删除评论</el-dropdown-item
>
<el-dropdown-item>
<el-dropdown trigger="hover" placement="right-start">
<span
>禁言<el-icon
style="transform: translateY(3px); margin-left: 20px"
>
<ArrowRight /> </el-icon
></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="banUserHour(comment.id)"
>一个小时</el-dropdown-item
>
<el-dropdown-item @click="banUserDay(comment.id)"
>一天</el-dropdown-item
>
<el-dropdown-item @click="banUserWeek(comment.id)"
>一周</el-dropdown-item
>
<el-dropdown-item @click="banUserForever(comment.id)"
>永久</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</p>
<!-- <el-input
v-if="showReplyInput[comment.id]"
v-model="replyTexts[comment.id]"
type="textarea"
placeholder="说点什么吧"
rows="4"
maxlength="150"
show-word-limit
style="margin-top: 10px"
/> -->
<el-form v-if="showReplyInput[comment.idGenerator]">
<el-form-item class="childrenForm">
<el-input
v-model="replyTexts[comment.idGenerator]"
:rows="3"
type="textarea"
maxlength="150"
@input="
handleInput(
replyTexts[comment.idGenerator],
comment.idGenerator
)
"
:placeholder="$t('view.course.add_comment')"
>
</el-input>
<div class="commentOperate">
<div class="numberLimit">
还能输入<span class="remainingCount">{{
remainCount[comment.idGenerator]
}}</span
>个字符
</div>
<div class="comment-operate-item">
<VueEmoji
@chooseEmoji="chooseEmoji"
:replyComment="replyTexts[comment.idGenerator]"
:keyId="comment.idGenerator"
/>
<el-button
class="commentBtn"
type="primary"
@click="userChildrenCommont(comment)"
>评论
</el-button>
</div>
</div>
</el-form-item>
</el-form>
<!-- 子评论列表 -->
<div
v-for="(reply, replyIndex) in comment.children"
:key="reply.id"
style="margin-top: 12px"
>
<div
style="
margin-top: 12px;
border-bottom: 1px #f4f3f3;
display: flex;
align-items: flex-start;
"
>
<el-avatar
:size="30"
:src="reply.avatarUrl || profile"
style="margin-right: 12px"
></el-avatar>
<div style="flex: 1">
<span>{{ reply.name || "0713" }}</span>
<span style="margin-left: 10px; color: #86909c">{{ $t('view.course.reply') }}</span>
<span style="margin-left: 10px; margin-right: 10px"
>{{ reply.name1 }}:{{ reply.info_Conmment }}</span
>
<p style="font-size: 12px; color: #86909c; margin-top: 5px">
{{ reply.createdTime }}
<el-button
link
style="font-size: 12px; color: #86909c"
@click="
toggleLikeComment(reply.idGenerator, reply.isThumbsUp)
"
>
<!-- <svg-icon
:icon-class="getReplyIconClass(comment.id, reply.id)"
:src="getReplyIconSrc(comment.id, reply.id)"
class="svg-icon"
style="
margin-left: 20px;
margin-right: 3px;
transform: translateY(-1px);
"
:class="{ liked: isReplyLiked(comment.id, reply.id) }"
/> -->
<svg-icon
:icon-class="getCommentzanIconClass(reply.isThumbsUp)"
:src="getCommentzanIconSrc(reply.isThumbsUp)"
class="svg-icon"
style="
margin-left: 20px;
margin-right: 3px;
transform: translateY(-1px);
"
/>
<span v-if="reply.thumbsUpCount > 0">{{
reply.thumbsUpCount
}}</span
>点赞 </el-button>
<el-button
link
style="font-size: 12px; color: #86909c"
@click="toggleReply(reply.idGenerator)"
>
<el-icon style="margin-right: 3px; font-size: 16px">
<ChatLineSquare />
</el-icon>
回复
</el-button>
<el-dropdown trigger="click">
<template #default>
<span>
<el-button link>
<el-icon
style="
margin-left: 12px;
color: #4e5969;
font-size: 12px;
transform: translateY(4px);
"
>
<MoreFilled />
</el-icon>
</el-button>
</span>
</template>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
@click="deleteComment(reply.idGenerator)"
>删除评论</el-dropdown-item
>
<el-dropdown-item>
<el-dropdown trigger="hover" placement="right-start">
<span
>禁言<el-icon
style="
transform: translateY(3px);
margin-left: 20px;
"
>
<ArrowRight /> </el-icon
></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
@click="banUserHour(comment.id)"
>一个小时</el-dropdown-item
>
<el-dropdown-item
@click="banUserDay(comment.id)"
>一天</el-dropdown-item
>
<el-dropdown-item
@click="banUserWeek(comment.id)"
>一周</el-dropdown-item
>
<el-dropdown-item
@click="banUserForever(comment.id)"
>永久</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</p>
<!-- <el-input
v-if="showReplyInput[reply.id]"
v-model="replyTexts[reply.id]"
type="textarea"
:placeholder="$t('view.course.add_comment')"
rows="3"
maxlength="150"
show-word-limit
style="margin-top: 10px"
/> -->
<el-form>
<el-form-item
class="childrenForm"
v-if="showReplyInput[reply.idGenerator]"
>
<el-input
v-model="replyTexts[reply.idGenerator]"
:rows="3"
type="textarea"
maxlength="150"
@input="
handleInput(
replyTexts[reply.idGenerator],
reply.idGenerator
)
"
:placeholder="$t('view.course.add_comment')"
>
</el-input>
<div class="commentOperate">
<div class="numberLimit">
还能输入<span class="remainingCount">{{
remainCount[reply.idGenerator]
}}</span
>个字符
</div>
<div class="comment-operate-item">
<VueEmoji
@chooseEmoji="chooseEmoji"
:replyComment="replyTexts[reply.idGenerator]"
:keyId="reply.idGenerator"
/>
<el-button
class="commentBtn"
type="primary"
@click="userChildrenCommont(reply)"
>评论
</el-button>
</div>
</div>
</el-form-item>
</el-form>
</div>
</div>
</div>
<el-divider
border-style="double"
style="height: 1px; border: 1px solid #f4f3f3"
/>
</div>
</div>
</div>
</div>
</template>
<script setup>
import VueEmoji from "@/views/activity/activityDetail/VueEmoji.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
addComments,
searchComments,
commentThumbsUp,
commentCancelThumbsUp,
deleteCommentApi,
} from "@/api/common";
import {
singleCourseCommentThumbsUp,
singleCourseCommentCancelThumbsUp,
} from "@/api/course";
import { useRoute, useRouter } from "vue-router";
const likeIcon = new URL("@/assets/images/icons/svg/like.svg", import.meta.url)
.href;
const yellowLikeIcon = new URL(
"@/assets/images/icons/svg/yellowlike.svg",
import.meta.url
).href;
import profile from "@/assets/images/profile.jpg";
import { onMounted } from "vue";
const route = useRoute();
const router = useRouter();
const isComment = ref(true);
const detailLoading = ref(false);
// 評論數據
const comments = ref([]);
//回覆評論
const replyTexts = ref({});
const showReplyInput = ref({});
const commentForm = reactive({
commentText: "",
});
const props = defineProps({
isComment: {
type: Boolean,
default: false,
},
});
onMounted(()=>{
searchCommentsFn()
})
const getCommentzanIconSrc = (isThumbsUp) => {
return isThumbsUp ? yellowLikeIcon : likeIcon;
};
const getCommentzanIconClass = (isThumbsUp) => {
return isThumbsUp ? "yellowlike" : "like";
};
const toggleReply = (commentId) => {
remainCount.value[commentId] = 150;
if (!showReplyInput.value[commentId]) {
showReplyInput.value[commentId] = false;
}
showReplyInput.value[commentId] = !showReplyInput.value[commentId];
};
// 評論點讚狀態
const commentLikes = ref({});
const toggleLikeComment = (commentId, isThumbsUp) => {
// if (!commentLikes.value[commentId]) {
// commentLikes.value[commentId] = false;
// }
// commentLikes.value[commentId] = !commentLikes.value[commentId];
// console.log(commentLikes.value[commentId], "commentLikes.value[commentId]");
if (!isThumbsUp) {
singleCourseCommentThumbsUp({
mainId: route.query.id,
commentId: commentId,
}).then((res) => {
if (res.code == 200) {
ElMessage.success("点赞成功");
searchCommentsFn();
}
});
} else {
singleCourseCommentCancelThumbsUp({
mainId: route.query.id,
commentId: commentId,
}).then((res) => {
if (res.code == 200) {
ElMessage.success("取消点赞");
searchCommentsFn();
}
});
}
};
const searchCommentsFn = () => {
comments.value = []
detailLoading.value = true;
let params = {
mainId: route.query.id,
funType: 1,
pageNum: 1,
pageSize: 10,
};
searchComments(params).then((res) => {
if (res.code == 200) {
comments.value = res.data.items;
detailLoading.value = false;
} else {
ElMessage.error(res.message);
detailLoading.value = false;
}
});
};
const remainingCount = ref(150);
const remainCount = ref({});
const handleInput = (value, id) => {
if (id) {
remainCount.value[id] = 150 - value.length;
} else {
remainingCount.value = 150 - value.length;
}
// if (remainingCount.value < 0) {
// this.message = this.message.slice(0, this.maxLength);
// event.target.scrollTop = event.target.scrollHeight;
// }
};
const chooseEmoji = (item, replyComment, keyId) => {
if (keyId) {
replyComment += item;
replyTexts.value[keyId] = replyComment;
remainCount.value[keyId]--;
} else {
commentForm.commentText += item;
remainingCount.value--;
}
};
const addCommont = (params) => {
addComments(params).then((res) => {
if (res.code == 200) {
ElMessage.success("评论成功");
showReplyInput.value[params.parentIdGenerator] = false;
replyTexts.value[params.parentIdGenerator] = "";
remainCount[params.parentIdGenerator] = 150;
commentForm.commentText = "";
remainingCount.value = 150;
searchCommentsFn();
detailLoading.value = false;
} else {
detailLoading.value = false;
ElMessage.error(res.message);
}
});
};
const userChildrenCommont = (comment) => {
detailLoading.value = true;
let params = {
info_Conmment: replyTexts.value[comment.idGenerator],
mainIdGenerator: comment.mainIdGenerator,
parentIdGenerator: comment.idGenerator,
moduleTypeEnums: 1,
};
addCommont(params);
};
const userCommont = () => {
detailLoading.value = true;
let params = {
info_Conmment: commentForm.commentText,
mainIdGenerator: route.query.id,
parentIdGenerator: 0,
moduleTypeEnums: 1,
};
addCommont(params);
};
// 刪除評論(按鈕)
const deleteComment = (idValue) => {
const data = {
id: idValue,
};
ElMessageBox.confirm(`確定刪除评论?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
deleteCommentApi(data).then((res) => {
if (res.code == 200) {
ElMessage({
type: "success",
message: "刪除评论成功",
});
searchCommentsFn();
} else {
ElMessage({
type: "error",
message: res.message,
});
}
});
})
.catch(() => {
info;
ElMessage.info("评论成功");
});
};
watch(
() => route.query,
(newValue, oldValue) => {
if (route.query.typeFlag == "courseindexEnter") {
commentForm.commentText = "";
showReplyInput.value = {};
replyTexts.value = {};
remainCount.value = {};
remainingCount.value = 150;
}
},
{ immediate: true }
);
defineExpose({ searchCommentsFn });
</script>
<style scoped lang="scss">
:deep(.el-form-item__content) {
position: relative;
// margin-left: 20px;
margin-top: 10px;
padding-bottom: 10px;
border: 1px solid #e7e7e7;
border-radius: 6px;
.el-textarea.el-input--default {
.el-textarea__inner {
box-shadow: 0 0 0 1px transparent !important;
padding: 5px 16px !important;
}
}
.commentOperate {
height: 20px;
border: 1px solid transparent;
.numberLimit {
position: absolute;
// bottom: 5px;
left: 16px;
color: #999aaa;
.remainingCount {
color: #1d2129;
padding: 0 2px;
}
}
.comment-operate-img {
width: 20px;
height: 20px;
}
.comment-operate-item {
position: absolute;
// bottom: 0px;
right: 21px;
display: flex;
align-items: center;
.comment-operate-img {
width: 20px;
height: 20px;
margin-right: 16px;
cursor: pointer;
}
.commentBtn {
padding-right: 10px;
border-radius: 16px;
width: 60px;
height: 24px;
font-size: 14px;
}
}
}
}
</style>
emoji.json
{
"data": "😀,😁,😂,😃,😄,😅,😆,😉,😊,😋,😎,😍,😘,😗,😙,😚,😇,😐,😑,😶,😏,😣,😥,😮,😯,😪,😫,😴,😌,😛,😜,😝,😒,😓,😔,😕,😲,😷,😖,😞,😟,😤,😢,😭,😦,😧,😨,😬,😰,😱,😳,😵,😡,😠,💘,❤,💓,💔,💕,💖,💗,💙,💚,💛,💜,💝,💞,💟,❣,💪,👈,👉,☝,👆,👇,✌,✋,👌,👍,👎,✊,👊,👋,👏,👐,✍,🍇,🍈,🍉,🍊,🍋,🍌,🍍,🍎,🍏,🍐,🍑,🍒,🍓,🍅,🍆,🌽,🍄,🌰,🍞,🍖,🍗,🍔,🍟,🍕,🍳,🍲,🍱,🍘,🍙,🍚,🍛,🍜,🍝,🍠,🍢,🍣,🍤,🍥,🍡,🍦,🍧,🍨,🍩,🍪,🎂,🍰,🍫,🍬,🍭,🍮,🍯,🍼,☕,🍵,🍶,🍷,🍸,🍹,🍺,🍻,🍴,🌹,🍀,🍎,💰,📱,🌙,🍁,🍂,🍃,🌷,💎,🔪,🔫,🏀,⚽,⚡,👄,👍,🔥,🙈,🙉,🙊,🐵,🐒,🐶,🐕,🐩,🐺,🐱,😺,😸,😹,😻,😼,😽,🙀,😿,😾,🐈,🐯,🐅,🐆,🐴,🐎,🐮,🐂,🐃,🐄,🐷,🐖,🐗,🐽,🐏,🐑,🐐,🐪,🐫,🐘,🐭,🐁,🐀,🐹,🐰,🐇,🐻,🐨,🐼,🐾,🐔,🐓,🐣,🐤,🐥,🐦,🐧,🐸,🐊,🐢,🐍,🐲,🐉,🐳,🐋,🐬,🐟,🐠,🐡,🐙,🐚,🐌,🐛,🐜,🐝,🐞,🦋,😈,👿,👹,👺,💀,☠,👻,👽,👾,💣"
}