<template>
<div class="content">
<div class="message_content">
<div class="message_title" style="position: relative;">
<span>消息区</span>
<i class="el-icon-close" @click="close" style="cursor: pointer;position: absolute;top: 15px;right: 10px;font-size: 25px;"></i>
</div>
<!-- 消息区 -->
<div class="message_area" ref="chatWindow">
<div
class="message_item"
:style="{
justifyContent: item.name == '张三' ? 'flex-end' : 'flex-start',
}"
v-for="(item, index) in messageList"
:key="index"
>
<div class="avator" v-if="item.name != '张三'">
<img src="xxx/avator.png" alt="" />
</div>
<div class="">
<div class="name">{{ item.name }}</div>
<div
class="message"
:class="{
message_right: item.name == '张三',
message_left: item.name != '张三',
}"
>
<div v-html="item.content"></div>
</div>
</div>
<div class="avator" v-if="item.name == '张三'">
<img src="xxx/avator.png" alt="" />
</div>
</div>
</div>
<div class="message_input">
<el-input
type="textarea"
v-model="textarea"
autofocus
:autosize="{ minRows: 7, maxRows: 7 }"
resize="none"
@keyup.enter="keyDown($event)"
>
</el-input>
<div
style="
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
height: 60px;
"
>
<el-button @click="send">发送</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import { fetchEventSource } from '@microsoft/fetch-event-source';
import {
getToken
} from "@/utils/auth";
import axios from 'axios';
export default {
data() {
return {
textarea: "",
messageList: [
],
};
},
watch: {},
mounted() {
},
methods: {
close(){
this.$parent.closeMsg();
},
async send() {
console.log('[[[[]]]]')
if (!this.textarea) return;
this.messageList.push({
name: "张三",
content: this.textarea,
time: this.formatDate(new Date()),
});
console.log(this.messageList);
let url = 'you url'
let apikey ='your apikey'
const data = {
"inputs": {
"token":'Bearer ' + getToken(),
},
"query": this.textarea,
"response_mode": 'streaming',
"conversation_id": "",
"user": this.$store.state.user.user.userId,
};
let that= this
let fullContent =''
let eventSource =fetchEventSource(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: "text/event-stream",
Authorization: `Bearer ${apikey}`,
"Transfer-Encoding": "chunked",
},
body: JSON.stringify(data),
onopen(response) {
console.log(response, "open");
if (response.ok) {
console.log("成功建立连接");
that.messageList .push({
name: "李四",
content:'',
time: that.formatDate(new Date()),
}
);
} else {
throw new Error(JSON.stringify(response));
}
},
onmessage(ev) {
console.log('Received message:', ev.data);
if(JSON.parse(ev.data).message == 'close'){
eventSource.close()
}else{
let str = ev.data
const obj = JSON.parse(str);
const newContent = obj.answer || '';
fullContent += newContent
if (that.messageList.length > 0) {
that.messageList[that.messageList.length - 1].content = fullContent;
}
}
},
onclose() {
console.log("连接关闭");
},
onerror(error) {
console.log("关闭链接", error);
throw Error(error);
},
openWhenHidden: true,
});
this.textarea = "";
},
scrollToBottom() {
setTimeout(() => {
this.$refs.chatWindow.scrollTop = this.$refs.chatWindow.scrollHeight;
}, 0);
},
formatDate(date) {
const d = new Date(date);
let month = "" + (d.getMonth() + 1);
let day = "" + d.getDate();
let hour = "" + d.getHours();
let minute = "" + d.getMinutes();
let second = "" + d.getSeconds();
let year = d.getFullYear();
if (month.length < 2) month = "0" + month;
if (day.length < 2) day = "0" + day;
if (hour.length < 2) hour = "0" + hour;
if (minute.length < 2) minute = "0" + minute;
if (second.length < 2) second = "0" + second;
return (
[year, month, day].join("-") + " " + [hour, minute, second].join(":")
);
},
},
beforeDestroy() {
window.addEventListener("keydown", this.keyDowns);
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-textarea {
height: calc(100% - 60px);
}
::v-deep .el-textarea__inner {
height: 105px !important;
color: #fff;
min-height: 105px !important;
background-color: transparent;
border: 0;
}
::v-deep ::-webkit-scrollbar {
background-color: transparent !important;
}
.message_left {
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.message_right {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.content {
border: 2px solid #26c4d1;
border-radius: 5px;
background-color: rgba(13, 26, 42, 0.5);
box-shadow: 0 0 10px 1px #26c4d1;
margin-right: 10px;
width: 100%;
height: 600px;
overflow-y: auto;
display: flex;
.message_content {
width: 38%;
}
.message_content {
width:100%;
height: 100%;
border-radius: 5px;
box-shadow: 0 0 5px 1px #89d8f0;
background-color: rgba(66, 86, 94, 0.2);
.message_title {
height: 50px;
line-height: 50px;
color: #50d7d3;
text-align: center;
background-color: #174670;
}
.message_area {
width: 100%;
height: calc(100% - 223px);
overflow-y: auto;
.message_item {
display: flex;
justify-content: flex-end;
margin: 5px 0;
.avator {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
margin-left: 10px;
img {
display: block;
width: 100%;
height: 100%;
}
}
.name {
color: #67798e;
}
.message {
color: #71acbd;
padding: 5px;
background-color: #1f3144;
border: 1px solid #71acbd;
}
}
}
.message_input {
margin: 5px auto 0 auto;
width: 96%;
height: 165px;
border-radius: 5px;
box-shadow: 0 0 5px 1px #89d8f0;
background-color: rgba(97, 156, 180, 0.2);
}
}
}
::v-deep .el-button {
color: #fff;
border-radius: 5px;
border: 1px solid #43a0a8;
background-image: linear-gradient(to bottom, #15263b, #238298);
margin-right: 10px;
}
</style>