refactor: 重构消息处理和用户交互逻辑 fix(env): 更新环境变量配置 style: 调整用户卡片样式和布局 perf: 优化消息发送和接收性能 test: 添加消息排序和去重逻辑测试 chore: 清理无用代码和文件
441 lines
12 KiB
Vue
441 lines
12 KiB
Vue
<template>
|
|
<div v-for="(element, index) in list">
|
|
<div class="materia-element" :class="{ robotSend : element.sender_id != sendeInfo.userInfo.user_id }">
|
|
<!-- <el-image v-if="element.sender_id == sendeInfo.robotInfo.wx_id" class="tobot-image" :src="sendeInfo.robotInfo.head_url"></el-image>
|
|
<template v-else> -->
|
|
<el-image v-if="sendeInfo.userInfo.user_id != element.sender_id" class="tobot-image" :src="robot_avatar"></el-image>
|
|
<el-image v-if="sendeInfo.userInfo.user_id == element.sender_id" class="tobot-image" :src="sendeInfo.userInfo.user_avatar"></el-image>
|
|
<!-- <span class="tobot-image text-logo" v-else> {{ element.sender_name.charAt(0) }} </span> -->
|
|
<!-- </template> -->
|
|
<div class="materia-info">
|
|
<!-- <span class="robot-name">{{ element.sender_name }}</span> -->
|
|
<!-- <span v-if="element.sender_id != sendeInfo.userInfo.user_id" class="robot-name">{{ sendeInfo.robotInfo.name }}</span>
|
|
<span v-if="element.sender_id == sendeInfo.userInfo.user_id" class="robot-name">{{ sendeInfo.userInfo.nickname }}</span> -->
|
|
<div class="text" v-if="element.msg_type == 1">
|
|
<pre>{{ element.content.messages }}</pre>
|
|
</div>
|
|
<div class="image" v-if="element.msg_type == 2">
|
|
<el-image :src="element.content.messages" fit="cover"
|
|
:preview-src-list="[element.content.messages]" preview-teleported>
|
|
<template #placeholder>
|
|
<div class="image-slot">Loading<span class="dot">...</span></div>
|
|
</template>
|
|
</el-image>
|
|
</div>
|
|
|
|
<div class="time">{{ element.send_time }}
|
|
<el-icon v-if="element._failed" class="retry" @click.stop="emits('retry', element._id)">
|
|
<svg class="icon" aria-hidden="true"><use xlink:href="#icon-jinggao"></use></svg>
|
|
</el-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, watch } from 'vue'
|
|
import mihoutai from '@/assets/images/mihoutai.png'
|
|
import addess_img from '@/assets/images/addess.png'
|
|
import user_avatar from '@/assets/images/user_avatar.png'
|
|
import robot_avatar from '@/assets/images/robot.png'
|
|
const emits = defineEmits(["update:modelValue", "editMateria", "retry"])
|
|
const props = defineProps({
|
|
msgList: {
|
|
type: Array,
|
|
default: []
|
|
},
|
|
sendeInfo: {
|
|
type: Object,
|
|
default: {}
|
|
},
|
|
msgType: {
|
|
type: String,
|
|
default: 'user'
|
|
}
|
|
})
|
|
const keyWordsText = ref(props.keyWords)
|
|
const list = ref(props.msgList)
|
|
watch(() => props.msgList, (val) => {
|
|
console.log('ChatRecord 接收到消息列表:', val.length, '条消息')
|
|
list.value = val
|
|
})
|
|
|
|
onMounted(() => {
|
|
console.log('ChatRecord 组件挂载,初始消息数:', props.msgList.length)
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.materia-element {
|
|
overflow: hidden;
|
|
margin-bottom: 20px;
|
|
|
|
.tobot-image {
|
|
float: left;
|
|
width: 36px;
|
|
height: 36px;
|
|
margin-right: 15px;
|
|
border-radius: 4px;
|
|
}
|
|
.text-logo{
|
|
background-color: var(--el-color-primary);
|
|
color: #fff;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.materia-info {
|
|
width: 300px;
|
|
float: left;
|
|
|
|
|
|
|
|
.robot-name {
|
|
display: block;
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
margin-bottom: 6px;
|
|
|
|
.edit {
|
|
color: var(--el-color-primary);
|
|
margin-left: 6px;
|
|
transform: translateY(3px);
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.remove {
|
|
color: var(--el-color-danger);
|
|
margin-left: 6px;
|
|
transform: translateY(3px);
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
}
|
|
}
|
|
|
|
.text {
|
|
display: inline-block;
|
|
line-height: 22px;
|
|
background-color: #fff;
|
|
border-radius: 8px;
|
|
padding: 6px 12px;
|
|
font-size: 14px;
|
|
position: relative;
|
|
|
|
pre {
|
|
white-space: break-spaces;
|
|
}
|
|
|
|
&::before {
|
|
position: absolute;
|
|
width: 0;
|
|
height: 0;
|
|
border-top: 8px solid transparent;
|
|
border-bottom: 8px solid transparent;
|
|
border-right: 10px solid #fff;
|
|
content: '';
|
|
top: 10px;
|
|
left: -8px;
|
|
}
|
|
}
|
|
|
|
.image {
|
|
height: auto;
|
|
|
|
.el-image {
|
|
width: 120px;
|
|
height: auto;
|
|
border-radius: 6px;
|
|
}
|
|
}
|
|
|
|
.gif {
|
|
.el-image {
|
|
width: 120px;
|
|
height: auto;
|
|
}
|
|
}
|
|
|
|
.audio {
|
|
width: 100px;
|
|
|
|
.el-icon {
|
|
font-size: 20px;
|
|
transform: translateY(5px);
|
|
}
|
|
}
|
|
|
|
.video {
|
|
video {
|
|
width: 180px;
|
|
height: auto;
|
|
}
|
|
}
|
|
|
|
.mini {
|
|
height: 95px;
|
|
width: 220px;
|
|
background-color: #fff;
|
|
padding: 0;
|
|
|
|
.card-user {
|
|
overflow: hidden;
|
|
padding: 10px;
|
|
}
|
|
|
|
.el-image {
|
|
height: 50px;
|
|
width: 50px;
|
|
border-radius: 4px;
|
|
vertical-align: middle;
|
|
float: left;
|
|
}
|
|
|
|
.name {
|
|
font-size: 15px;
|
|
margin-left: 5px;
|
|
transform: translateY(7px);
|
|
display: inline-block;
|
|
float: left;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
p {
|
|
height: 20px;
|
|
line-height: 22px;
|
|
border-top: 1px solid var(--el-border-color);
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
padding-left: 10px;
|
|
}
|
|
}
|
|
|
|
.chengxu {
|
|
height: 103px;
|
|
|
|
.el-image {
|
|
height: 30px;
|
|
width: 30px;
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.name {
|
|
transform: translateY(0px);
|
|
color: var(--el-text-color-secondary);
|
|
font-size: 12px;
|
|
line-height: 30px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.cg-text {
|
|
display: block;
|
|
padding-left: 10px;
|
|
padding-right: 10px;
|
|
line-height: 20px;
|
|
margin-bottom: 6px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
p {
|
|
line-height: 25px;
|
|
}
|
|
}
|
|
|
|
.address {
|
|
padding: 0;
|
|
// overflow: hidden;
|
|
width: 220px;
|
|
|
|
h4 {
|
|
line-height: 28px;
|
|
font-size: 14px;
|
|
margin-bottom: 5px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
position: relative;
|
|
z-index: 0;
|
|
font-weight: normal;
|
|
padding: 0 10px;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
p {
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
line-height: 24px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
position: relative;
|
|
z-index: 0;
|
|
padding: 0 10px;
|
|
|
|
}
|
|
|
|
.el-image {
|
|
height: 86px;
|
|
width: 100%;
|
|
position: relative;
|
|
z-index: 0;
|
|
border-bottom-left-radius: 8px;
|
|
border-bottom-right-radius: 8px;
|
|
top: 5px;
|
|
}
|
|
}
|
|
|
|
.link {
|
|
width: 220px;
|
|
height: 100px;
|
|
|
|
.el-image {
|
|
height: 46px;
|
|
width: 46px;
|
|
float: right;
|
|
// transform: translateY(-17px);
|
|
margin-right: 0;
|
|
}
|
|
|
|
div {
|
|
// margin-top: 13px;
|
|
height: 50px;
|
|
|
|
h4 {
|
|
font-size: 14px;
|
|
line-height: 22px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
p {
|
|
color: var(--el-text-color-secondary);
|
|
height: 48px;
|
|
font-size: 12px;
|
|
float: left;
|
|
width: calc(100% - 55px);
|
|
line-height: normal;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: normal;
|
|
/* 防止文本换行 */
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3; //显示两行文本
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
}
|
|
}
|
|
|
|
.file {
|
|
width: 220px;
|
|
height: 75px;
|
|
|
|
.file-box {
|
|
float: left;
|
|
width: calc(100% - 50px);
|
|
|
|
}
|
|
|
|
.el-image {
|
|
width: 46px;
|
|
height: 46px;
|
|
float: right;
|
|
margin-right: 0;
|
|
transform: translateY(10px);
|
|
}
|
|
|
|
.el-icon {
|
|
float: right;
|
|
font-size: 40px;
|
|
color: var(--el-color-primary);
|
|
transform: translateY(12px);
|
|
}
|
|
|
|
label {
|
|
display: block;
|
|
line-height: 30px;
|
|
transform: translateY(2px);
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
span {
|
|
display: inline-block;
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
line-height: normal;
|
|
transform: translateY(-8px);
|
|
}
|
|
}
|
|
|
|
.interval-seconds {
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
margin-top: 10px;
|
|
}
|
|
.time{
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
margin-top: 10px;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
.robotSend {
|
|
.tobot-image {
|
|
float: right;
|
|
margin-right: 0;
|
|
margin-left: 15px;
|
|
}
|
|
|
|
.materia-info {
|
|
text-align: right;
|
|
float: right;
|
|
.robot-name{
|
|
text-align: right;
|
|
}
|
|
.text {
|
|
|
|
display: inline-block;
|
|
text-align: left;
|
|
background-color: var(--el-color-primary);
|
|
color: #fff;
|
|
&::before {
|
|
position: absolute;
|
|
width: 0;
|
|
height: 0;
|
|
border-top: 8px solid transparent;
|
|
border-bottom: 8px solid transparent;
|
|
border-left: 10px solid var(--el-color-primary);
|
|
border-right: 0;
|
|
content: '';
|
|
top: 10px;
|
|
right: -8px;
|
|
left: auto;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.image-slot {
|
|
height: 100%;
|
|
background-color: #F0F2F5;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--el-text-color-secondary);
|
|
}
|
|
</style> |