<template>
|
<div class="flex h-full">
|
<div class="flex flex-col h-full flex-auto relative">
|
<!-- 消息列表区域 -->
|
<div v-resize="updateChatWidth" ref="chatListDom" class="relative h-full flex flex-col items-center overflow-y-auto flex-auto">
|
<span
|
class="more-loading absolute text-blue-400 left-[50%] translate-x-[-50%] cursor-pointer w-10"
|
v-loading="moreIsLoading"
|
/>
|
|
<div class="h-full relative" v-loading="loading" :style="{ width: chatWidth }">
|
<slot name="message-list" />
|
</div>
|
</div>
|
|
<!-- 回到底部按钮 -->
|
<div class="absolute right-28 bottom-56" v-if="!isBottom">
|
<div
|
class="flex items-center justify-center size-[38px] cursor-pointer hover:text-[#0284ff] border rounded-full hover:bg-[#f6f7f9] shadow bg-white"
|
@click="scrollToBottom"
|
>
|
<i class="ywifont ywicon-xiangxiajiantou !text-[20px]" />
|
</div>
|
</div>
|
|
<!-- 输入区域 -->
|
<div class="w-full px-6 pb-6 bg-[rgb(247,248,250)] flex justify-center z-[1] flex-0" v-if="!isSharePage">
|
<slot name="input-area" />
|
</div>
|
</div>
|
|
<div class="w-[30%] flex-0 flex flex-col" v-if="fileContentIsShow">
|
<div class="bg-[#f9fbff] flex items-center justify-between p-4 border-b">
|
<div class="text-lg font-medium">{{ fileContent.title }}</div>
|
<div class="cursor-pointer hover:text-[#0284ff]" @click="fileContentIsShow = false">
|
<i class="ywifont ywicon-guanbi text-[20px]" />
|
</div>
|
</div>
|
<span class="bg-[#edf2fb] flex-1 overflow-y-auto p-4 break-words whitespace-pre-wrap">
|
{{ fileContent.content }}
|
</span>
|
</div>
|
|
<slot name="drawer" />
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { onActivated, onDeactivated, ref } from 'vue';
|
import { useChatWidth } from '../hooks/useChatWidth';
|
import { useScroll } from '../hooks/useScroll';
|
import emitter from '/@/utils/mitt';
|
|
const props = defineProps<{
|
loading?: boolean;
|
moreIsLoading?: boolean;
|
isSharePage?: boolean;
|
}>();
|
|
const chatListDom = ref<HTMLDivElement>();
|
|
const { scrollToBottom, isBottom } = useScroll({
|
chatListDom,
|
});
|
|
const fileContentIsShow = ref(false);
|
|
const fileContent = ref({
|
title: '',
|
content: '',
|
});
|
|
const setFileContent = (data: { title: string; content: string }) => {
|
fileContentIsShow.value = true;
|
fileContent.value = data;
|
};
|
|
onActivated(() => {
|
emitter.on('setFileContent', setFileContent);
|
});
|
|
onDeactivated(() => {
|
emitter.off('setFileContent', setFileContent);
|
});
|
|
const { updateChatWidth, chatWidth } = useChatWidth();
|
|
defineExpose({
|
chatListDom,
|
scrollToBottom,
|
chatWidth,
|
});
|
</script>
|
|
<style scoped>
|
.more-loading :deep(.el-loading-spinner) {
|
--loading-size: 35px;
|
margin-top: 0;
|
.circular {
|
width: var(--loading-size);
|
height: var(--loading-size);
|
}
|
}
|
</style>
|