207 lines
4.3 KiB
Vue
207 lines
4.3 KiB
Vue
<template>
|
|
<el-scrollbar class="chatContent">
|
|
<div class="chat-wrapper" v-for="item in list" :key="item.id">
|
|
<div class="chat-text" :class="{right:item.userType == '0',system:item.userType == '2'}">
|
|
<img v-if="item.userType!=2" class="avatar" :src="avatar(item)" alt=""/>
|
|
<div style="max-width: max(calc(100% - 140px), 220px)">
|
|
<div class="content" v-html="markdown(item.content)"/>
|
|
<div class="attachments pointer el-icon-paperclip" v-if="item.fileName" v-text="item.fileName" @click="handleDownload(item)"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-scrollbar>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
/**
|
|
* userType: 0-用户 1-机器人 2-系统
|
|
*/
|
|
export default {
|
|
name: "chatContent",
|
|
props: {
|
|
list: {default: () => []}
|
|
},
|
|
data() {
|
|
return {
|
|
md: null
|
|
}
|
|
},
|
|
computed: {
|
|
lastMessage: v => v.list.at(-1)?.content
|
|
},
|
|
watch: {
|
|
lastMessage() {
|
|
this.$nextTick(() => this.scrollBottom())
|
|
}
|
|
},
|
|
methods: {
|
|
scrollBottom() {
|
|
const content = this.$el.querySelector(".el-scrollbar__wrap")
|
|
if (content) {
|
|
content.scrollTop = content.scrollHeight - content.clientHeight
|
|
}
|
|
},
|
|
avatar(item) {
|
|
return item.avatar || (item.userType == '0' ? 'https://cdn.sinoecare.com/i/2024/06/17/666fdb275be82.png' :
|
|
'https://cdn.sinoecare.com/i/2024/08/22/66c6dfdc3766a.png')
|
|
},
|
|
markdown(v) {
|
|
return this.md?.render(v) || v
|
|
},
|
|
handleDownload(item) {
|
|
window.open(item.sdkFileUrl)
|
|
}
|
|
},
|
|
mounted() {
|
|
const {hljs, markdownit} = window
|
|
this.md = markdownit({
|
|
highlight: function (str, lang) {
|
|
if (lang && hljs.getLanguage(lang)) {
|
|
try {
|
|
return hljs.highlight(str, {language: lang}).value;
|
|
} catch (__) {
|
|
}
|
|
}
|
|
return ''; // use external default escaping
|
|
}
|
|
})
|
|
this.scrollBottom()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.chatContent {
|
|
:deep(.el-scrollbar__wrap) {
|
|
overflow-x: hidden;
|
|
background-image: url("https://cdn.sinoecare.com/i/2024/08/22/66c6dfdd76407.png");
|
|
background-position: center center;
|
|
background-size: 153px 182px;
|
|
background-repeat: no-repeat;
|
|
|
|
.content {
|
|
pre {
|
|
background-color: #282c34;
|
|
color: #abb2bf;
|
|
font-size: 12px;
|
|
padding: 4px;
|
|
line-height: 16px;
|
|
}
|
|
|
|
code {
|
|
white-space: pre-wrap;
|
|
width: 100%;
|
|
}
|
|
}
|
|
}
|
|
|
|
.chat-text {
|
|
display: flex;
|
|
gap: 12px;
|
|
font-size: 14px;
|
|
color: #333333;
|
|
margin-bottom: 8px;
|
|
padding-right: 14px;
|
|
|
|
.content {
|
|
position: relative;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
background: #F3F5F7;
|
|
word-break: break-all;
|
|
|
|
&:before {
|
|
content: " ";
|
|
width: 0;
|
|
height: 0;
|
|
border-top: 6px solid transparent;
|
|
border-bottom: 6px solid transparent;
|
|
border-right: 6px solid #F3F5F7;
|
|
position: absolute;
|
|
left: -6px;
|
|
top: 6px;
|
|
}
|
|
}
|
|
|
|
&.right {
|
|
flex-direction: row-reverse;
|
|
|
|
.content {
|
|
background: #CCE2FF;
|
|
|
|
&:before {
|
|
left: unset;
|
|
right: -6px;
|
|
border-left: 6px solid #CCE2FF;
|
|
border-right: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
&.system {
|
|
padding-right: 0;
|
|
justify-content: center;
|
|
|
|
.content {
|
|
font-size: 12px;
|
|
background: #F0F0F0;
|
|
border-radius: 4px;
|
|
color: #888;
|
|
padding: 3px 6px;
|
|
width: fit-content;
|
|
|
|
&:before {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.attachments {
|
|
font-size: 12px;
|
|
background: #F0F0F0;
|
|
border-radius: 4px;
|
|
color: #888;
|
|
padding: 3px 6px;
|
|
width: fit-content;
|
|
margin-top: 4px;
|
|
|
|
&:hover, &:active {
|
|
color: $primaryColor;
|
|
}
|
|
&:before{
|
|
margin-right: 2px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.avatar {
|
|
width: 36px;
|
|
height: auto;
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.chat-friend {
|
|
width: 100%;
|
|
float: left;
|
|
margin-bottom: 20px;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-end;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.chat-me {
|
|
width: 100%;
|
|
float: right;
|
|
margin-bottom: 20px;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-end;
|
|
align-items: flex-end;
|
|
}
|
|
}
|
|
</style>
|