You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
8.0 KiB

5 months ago
<template>
<div class="chat-embed layout-bg">
<div class="chat-embed__header">
<div class="chat-width flex align-center" style="height: 56px;align-items: center;line-height: 56px">
<div class="mr-12 ml-24 flex">
<el-avatar
shape="square"
:size="32"
style="background: none"
>
<img src="@/assets/logo/deepseek.png" alt="" />
</el-avatar>
</div>
<h4 style="color: #1f2329;font-size: 16px; font-style: normal; font-weight: bold;margin: 0; -webkit-font-smoothing: antialiased">果知小助手</h4>
</div>
</div>
<div class="chat-embed__main">
<AiChat
ref="AiChatRef"
:record="currentRecordList"
:is_large="is_large"
:cookieSessionId = "sessionId"
class="AiChat-embed"
@scroll="handleScroll"
></AiChat>
</div>
<el-link class="chat-popover-button" :underline="false" @click.prevent.stop="showChatHistory">
<i class="ri-history-line"></i>
</el-link>
<el-link style="z-index: 100; position: absolute; top: 18px; right: 120px; font-size: 20px;" :underline="false" @click.prevent.stop="newChat" :disabled="currentRecordList.length === 0">
<el-icon><Plus /></el-icon>
</el-link>
<el-collapse-transition>
<div v-show="show" class="chat-popover w-full" style="width: 100%;" v-click-outside="clickoutside">
<div class="border-b p-16-24" style="border-bottom: 1px solid #dee0e3; padding: 16px 24px; font-size: 14px">
<span>历史记录</span>
</div>
<el-scrollbar max-height="300">
<div class="p-8" style="padding: 8px">
<common-list
:data="chatLogeData"
:mouseId="mouseId"
:defaultActive="sessionId"
@click="clickListHandle"
@mouseenter="mouseenter"
@mouseleave="mouseId = ''"
>
<template #default="{ row }">
<div class="flex-between" style="display: flex; justify-content: space-between; align-items: center;">
<auto-tooltip :content="row.sessionName">
{{ row.sessionName }}
</auto-tooltip>
<div @click.stop v-if="mouseId === row.sessionId">
<el-button style="padding: 0" link @click.stop="deleteLog(row)">
<el-icon><Delete /></el-icon>
</el-button>
</div>
</div>
</template>
<template #empty>
<div class="text-center">
<el-text type="info">暂无历史记录</el-text>
</div>
</template>
</common-list>
</div>
<div v-if="chatLogeData.length" class="gradient-divider lighter mt-8" style="font-weight: 400; margin-top: 8px">
<span>仅显示最近 20 条对话</span>
</div>
</el-scrollbar>
</div>
</el-collapse-transition>
<div class="chat-popover-mask" v-show="show"></div>
</div>
</template>
<script setup>
import { ref, onMounted, reactive, nextTick, computed } from 'vue'
import { v4 as uuidv4 } from 'uuid';
import Cookies from 'js-cookie'
import CommonList from './common-list.vue'
import AiChat from './aichat.vue'
import AutoTooltip from './auto-tooltip.vue'
import { useRoute } from 'vue-router'
import { listChatHistory, getChatList, DeleteChatSession } from "@/api/aichat/aichat";
const route = useRoute()
const { proxy } = getCurrentInstance();
const {
params: { accessToken }
} = route
const props = defineProps({
is_large: Boolean,
chatDataList: Array,
})
const AiChatRef = ref()
const chatLogeData = ref([])
const show = ref(false)
const currentRecordList = ref([])
const sessionId = ref(Cookies.get("chatSessionId")) // 当前历史记录Id 默认为'new'
const mouseId = ref('')
function mouseenter(row) {
mouseId.value = row.sessionId
}
function deleteLog(row) {
let sessionId = row.sessionId
DeleteChatSession(sessionId).then(res=>{
listChatHistory(sessionId).then(response =>{
chatLogeData.value = response.data
})
5 months ago
proxy.$modal.msgSuccess("删除成功");
5 months ago
})
}
function clickoutside() {
show.value = false
}
function showChatHistory(){
show.value = true
listChatHistory(sessionId.value).then(response =>{
chatLogeData.value = response.data
})
}
function newChat() {
currentRecordList.value = []
sessionId.value = uuidv4()
Cookies.set("chatSessionId",sessionId.value)
}
function handleScroll(event) {
if (event.scrollTop === 0 && currentRecordList.value.length>0) {
const history_height = event.dialogScrollbar.offsetHeight
event.scrollDiv.setScrollTop(event.dialogScrollbar.offsetHeight - history_height)
}
}
function clickListHandle(item){
getChatList(item.sessionId).then(res=>{
currentRecordList.value = []
let array = res.data
for (let i = 0; i < array.length; i++) {
if (array[i].type === 'answer'){
array[i].content = JSON.parse(array[i].content)
}
if (array[i].type === 'question'){
array[i].file = JSON.parse(array[i].file)
}
currentRecordList.value.push(array[i])
AiChatRef.value.setScrollBottom()
}
show.value = false
sessionId.value = item.sessionId
Cookies.set("chatSessionId",sessionId.value)
})
}
watch(() => props.chatDataList, value => currentRecordList.value = JSON.parse(JSON.stringify(value)))
5 months ago
onMounted(
()=>{
if (Cookies.get("chatSessionId")){
//调用子页面的赋值方法,给子页面赋值
getChatList(Cookies.get("chatSessionId")).then(res=>{
let array = res.data
if (array && array.length >0){
for (let i = 0; i < array.length; i++) {
if (array[i].type === 'answer'){
array[i].content = JSON.parse(array[i].content)
}
if (array[i].type === 'question'){
array[i].file = JSON.parse(array[i].file)
}
}
}
currentRecordList.value = array
}).then(()=>{
AiChatRef.value.setScrollBottom()
})
}else {
Cookies.set("chatSessionId",uuidv4())
}
}
)
5 months ago
</script>
<style lang="scss">
.chat-embed {
overflow: hidden;
height: 100%;
&__header {
background: linear-gradient(90deg, #ebf1ff 24.34%, #e5fbf8 56.18%, #f2ebfe 90.18%);;
position: absolute;
width: 100%;
left: 0;
top: 0;
z-index: 100;
height: 56px;
line-height: 56px;
box-sizing: border-box;
border-bottom: 1px solid #dee0e3;
}
&__main {
padding-top: 80px;
height: 100%;
overflow: hidden;
}
.new-chat-button {
z-index: 11;
}
// 历史对话弹出层
.chat-popover {
position: absolute;
top: 56px;
background: #ffffff;
padding-bottom: 24px;
z-index: 2009;
}
.chat-popover-button {
z-index: 100;
position: absolute;
top: 18px;
right: 85px;
font-size: 20px;
}
.chat-popover-mask {
background-color: var(--el-overlay-color-lighter);
bottom: 0;
height: 100%;
left: 0;
overflow: auto;
position: absolute;
right: 0;
top: 56px;
z-index: 2008;
}
.gradient-divider {
position: relative;
text-align: center;
color: var(--el-color-info);
::before {
content: '';
width: 17%;
height: 1px;
background: linear-gradient(90deg, rgba(222, 224, 227, 0) 0%, #dee0e3 100%);
position: absolute;
left: 16px;
top: 50%;
}
::after {
content: '';
width: 17%;
height: 1px;
background: linear-gradient(90deg, #dee0e3 0%, rgba(222, 224, 227, 0) 100%);
position: absolute;
right: 16px;
top: 50%;
}
}
.AiChat-embed {
.ai-chat__operate {
padding-top: 12px;
}
}
.chat-width {
max-width: 860px;
margin: 0 auto;
}
}
.flex {
display: flex;
}
.mr-12 {
margin-right: 12px;
}
.ml-24 {
margin-left: 24px;
}
</style>