329 lines
11 KiB
Vue
329 lines
11 KiB
Vue
<script setup>
|
|
import { ref } from 'vue'
|
|
|
|
const props = defineProps({
|
|
height: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
dataList: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
userInfo: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
},
|
|
productId: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
})
|
|
|
|
const message = useMessage()
|
|
|
|
// 获取评论列表
|
|
const commentList = ref([])
|
|
async function getCommentList() {
|
|
try {
|
|
const res = await request.get(`/WorkFlowComment/comment/${props.productId}`)
|
|
for (let i = 0; i < res.data.length; i++) {
|
|
res.data[i].isShowInput = false
|
|
res.data[i].isShowSend = false
|
|
if (res.data[i].contentList.length > 0) {
|
|
for (let j = 0; j < res.data[i].contentList.length; j++) {
|
|
res.data[i].contentList[j].isShowInput = false
|
|
res.data[i].contentList[j].isShowSend = false
|
|
}
|
|
}
|
|
}
|
|
commentList.value = res.data
|
|
}
|
|
catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
getCommentList()
|
|
// const $props = defineProps(['headUrl', 'dataList', 'height'])
|
|
// const $emit = defineEmits(['sendMessage'])
|
|
// const props = defineProps
|
|
const isShowSend = ref(false)
|
|
const publicWord = ref('')
|
|
// const message = useMessage()
|
|
|
|
function handleBlur(ele) {
|
|
ele.isShowInput = false
|
|
// 默认评价
|
|
if (!ele) {
|
|
isShowSend.value = !!publicWord.value
|
|
}
|
|
else {
|
|
ele.isShowSend = !!ele.word
|
|
}
|
|
}
|
|
|
|
// 发布评论
|
|
const commentParams = ref({
|
|
content: '',
|
|
parentId: '',
|
|
userId: props.userInfo.userId,
|
|
workFlowId: props.productId,
|
|
})
|
|
//
|
|
async function sendMessage(data, ele) {
|
|
debugger
|
|
try {
|
|
if (commentParams.value.content) {
|
|
const res = await request.post('WorkFlowComment/comment', commentParams.value)
|
|
if (res.code === 200) {
|
|
message.success('评论成功!')
|
|
}
|
|
}
|
|
else {
|
|
message.error('评论不能为空!')
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.log(error)
|
|
}
|
|
// if(!publicWord.value){
|
|
// return message.info(
|
|
// '请输入评论',
|
|
// { duration: 3000 }
|
|
// )
|
|
// }
|
|
if (!data) {
|
|
// $props.dataList.push({
|
|
// headUrl: 'https://avatars.githubusercontent.com/u/19239641?s=60&v=4', // 头像
|
|
// name: '星辰流连', // 名称
|
|
// id: 6,
|
|
// des: publicWord.value, // 评论
|
|
// time: '2025/02/08 14:52:06', // 时间
|
|
// isAuthor: false, // 是否是作者
|
|
// isShowInput: false, // 是否显示回复框
|
|
// isFocus: true, // 是否点赞
|
|
// focusNum: 2, // 点赞数量
|
|
// word: '', // 评论语
|
|
// isShowSend: false, // 是否显示发送按钮
|
|
// })
|
|
|
|
publicWord.value = ''
|
|
// isShowSend.value = false
|
|
}
|
|
else {
|
|
data.push({
|
|
headUrl: 'https://avatars.githubusercontent.com/u/19239641?s=60&v=4', // 头像
|
|
name: '星辰流连', // 名称
|
|
id: 7,
|
|
des: ele.word, // 评论
|
|
time: '2025/02/08 14:52:06', // 时间
|
|
isAuthor: false, // 是否是作者
|
|
isShowInput: false, // 是否显示回复框
|
|
isFocus: true, // 是否点赞
|
|
focusNum: 2, // 点赞数量
|
|
word: '', // 评论语
|
|
isShowSend: false, // 是否显示发送按钮
|
|
})
|
|
|
|
ele.word = ''
|
|
ele.isShowInput = false
|
|
}
|
|
|
|
// 发送数据
|
|
$emit('sendMessage', data)
|
|
}
|
|
|
|
// 目前点赞都在这边,注意区分
|
|
function handleFocus(item) {
|
|
item.isFocus = !item.isFocus
|
|
}
|
|
|
|
function handleMessage(item) {
|
|
debugger
|
|
if (!item.isShowInput) {
|
|
item.word = ''
|
|
}
|
|
item.isShowInput = !item.isShowInput
|
|
}
|
|
|
|
function handleDel(ele, item) {
|
|
const index = item.findIndex(el => ele.id === el.id)
|
|
item.splice(index, 1)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="base-comment">
|
|
<!-- 头部评论框 -->
|
|
<div class="flex justify-between mb-4">
|
|
<div v-if="props.userInfo.avatar" class="w-11 h-11 rounded-full mr-4 border border-[#2d28ff] border-solid">
|
|
<img class="w-10 h-10 rounded-full p-1" alt="avatar" :src="props.userInfo.avatar">
|
|
</div>
|
|
<div class="input-wrap flex items-center leading-normal rounded-lg text-sm bg-[#f2f5f9] px-4 py-2 flex-1">
|
|
<NConfigProvider inline-theme-disabled class="w-full">
|
|
<n-input
|
|
v-model:value="commentParams.content"
|
|
type="textarea"
|
|
:autosize="{ minRows: 1 }"
|
|
placeholder="善语结善缘,恶言伤人心~"
|
|
@focus="isShowSend = true"
|
|
@blur="handleBlur"
|
|
/>
|
|
</NConfigProvider>
|
|
<div
|
|
class="mx-4 flex-shrink-0 text-sm cursor-pointer text-gray-400 hover:text-gray-900"
|
|
:class="{ 'text-gray-900': commentParams.content }"
|
|
@click="sendMessage"
|
|
>
|
|
<span v-if="isShowSend">发送sendMessage</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 评论列表 -->
|
|
<NInfiniteScroll :style="{ height: `${height}px` }" :distance="10" @load="handleLoad">
|
|
<div v-for="(item, index) in commentList" :key="index">
|
|
<!-- 主评论 -->
|
|
<div class="flex text-sm">
|
|
<div class="w-10 h-10 rounded-full mr-3 flex-shrink-0">
|
|
<img :src="item.userAvatar" class="w-full h-full rounded-full">
|
|
</div>
|
|
<div class="w-full">
|
|
<div class="mt-[10px] mb-[7px] font-medium text-gray-700">
|
|
{{ item.userName }}
|
|
</div>
|
|
<div class="leading-[1.25]">
|
|
{{ item.content }}
|
|
</div>
|
|
<div class="mt-1 flex items-center justify-between">
|
|
<span class="text-xs text-gray-400">{{ item.createTime }}</span>
|
|
<div class="text-xs text-gray-400 flex items-center cursor-pointer">
|
|
<div class="flex items-center mr-4">
|
|
<img v-if="item.focus" src="@/assets/img/heart.png" class="w-4 h-4 mr-[3px]">
|
|
<img v-else src="@/assets/img/heart.png" class="w-4 h-4 mr-[3px]" @click="handleFocus(item)">
|
|
<span class="align-middle">{{ item.likeNum }}</span>
|
|
</div>
|
|
<span class="mr-4" @click="handleMessage(item)">回复</span>
|
|
<span @click="handleDel(item, dataList)">删除</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 评论回复框 -->
|
|
<div v-if="item.isShowInput" class="input-wrap mt-[10px] flex items-center rounded-lg text-sm bg-[#f2f5f9] px-3 py-2">
|
|
<NConfigProvider inline-theme-disabled class="w-full">
|
|
<n-input
|
|
v-model:value="item.word"
|
|
type="textarea"
|
|
:autosize="{ minRows: 1 }"
|
|
:placeholder="`回复: @${item.userName}`"
|
|
@focus="item.isShowSend = true"
|
|
@blur="handleBlur(item)"
|
|
/>
|
|
</NConfigProvider>
|
|
<div
|
|
class="mx-4 flex-shrink-0 text-sm cursor-pointer text-gray-400 hover:text-gray-900"
|
|
:class="{ 'text-gray-900': item.word }"
|
|
@click="sendMessage(item.children, item)"
|
|
>
|
|
<span v-if="item.isShowSend">发送sendMessage</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 子评论 -->
|
|
<div class="pl-[52px]">
|
|
<div v-for="(ele, subIndex) in item.contentList" :key="subIndex" class="flex text-sm mt-4">
|
|
<div class="w-6 h-6 rounded-full mr-3 flex-shrink-0">
|
|
<img src="https://avatars.githubusercontent.com/u/20943608?s=60&v=4" class="w-full h-full rounded-full">
|
|
</div>
|
|
<div class="w-full">
|
|
<div class="mb-[7px] font-medium text-gray-700 flex items-center">
|
|
{{ ele.userName }}
|
|
<div v-if="ele.userAvatar" class="ml-2 px-1 py-[3px] text-xs leading-[12px] text-white rounded bg-gradient-to-r from-[#2d28ff] to-[#1a7dff]">
|
|
作者
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center">
|
|
<span>回复</span>
|
|
<span class="text-[#1880ff] mr-[6px]">@{{ ele.userName }}</span>
|
|
{{ ele.des }}
|
|
</div>
|
|
<div class="mt-1 flex items-center justify-between">
|
|
<span class="text-xs text-gray-400">{{ ele.createTime }}</span>
|
|
<div class="text-xs text-gray-400 flex items-center cursor-pointer">
|
|
<div class="flex items-center mr-4">
|
|
<img v-if="ele.isFocus" src="@/assets/img/heart.png" class="w-4 h-4 mr-[3px]" @click="handleFocus(ele, 'cancel')">
|
|
<img v-else src="@/assets/img/heart.png" class="w-4 h-4 mr-[3px]" @click="handleFocus(ele, 'add')">
|
|
<span class="align-middle">1</span>
|
|
</div>
|
|
<span class="mr-4" @click="handleMessage(ele)">回复</span>
|
|
<span @click="handleDel(ele, item.contentList)">删除</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 子评论回复框 -->
|
|
<div v-if="ele.isShowInput" class="input-wrap mt-[10px] flex items-center rounded-lg text-sm bg-[#f2f5f9] px-3 py-2">
|
|
<NConfigProvider inline-theme-disabled class="w-full">
|
|
<n-input
|
|
v-model:value="ele.word"
|
|
type="textarea"
|
|
:autosize="{ minRows: 1 }"
|
|
:placeholder="`回复: @${ele.userName}`"
|
|
@focus="ele.isShowSend = true"
|
|
@blur="handleBlur(ele)"
|
|
/>
|
|
</NConfigProvider>
|
|
<div
|
|
class="mx-4 flex-shrink-0 text-sm cursor-pointer text-gray-400 hover:text-gray-900"
|
|
:class="{ 'text-gray-900': ele.word }"
|
|
@click="sendMessage(item.children, ele)"
|
|
>
|
|
<span v-if="ele.isShowSend">发送sendMessage</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 加载更多 -->
|
|
<div class="text-sm text-gray-400 text-center py-[46px] pb-[118px]">
|
|
暂时没有更多评论
|
|
</div>
|
|
</NInfiniteScroll>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.input-wrap {
|
|
:deep(.n-input) {
|
|
--n-padding-left: 0 !important;
|
|
--n-border: 0 !important;
|
|
--n-border-hover: 0 !important;
|
|
--n-border-focus: 0 !important;
|
|
--n-box-shadow-focus: unset;
|
|
--n-padding-vertical: 0px !important;
|
|
}
|
|
&::hover {
|
|
border: 0;
|
|
}
|
|
&:active,
|
|
&:focus {
|
|
background-color: #f2f5f9;
|
|
|
|
border: 0 !important;
|
|
}
|
|
background-color: #f2f5f9;
|
|
}
|
|
.n-input--textarea {
|
|
background-color: #f2f5f9;
|
|
}
|
|
.n-input:not(.n-input--disabled).n-input--foucs {
|
|
background-color: #f2f5f9 !important;
|
|
}
|
|
.n-input--focus {
|
|
background-color: #f2f5f9 !important;
|
|
}
|
|
</style>
|