<script setup>
|
import { getCurrentInstance, ref, watch, nextTick } from 'vue';
|
import { useRouter } from "vue-router";
|
import { get, post, postForm } from '@/utils/request.js'
|
import { message, Modal } from 'ant-design-vue';
|
import { logout } from '@/config.js';
|
import { formatMessage } from '@/utils/localeUtils.js';
|
import useTableSearch from '@/utils/tableUtils.jsx';
|
const context = getCurrentInstance()?.appContext.config.globalProperties;
|
|
const open = ref(false)
|
const showWidth = ref("70%")
|
const chatContainer = ref(null);
|
const aiLoading = ref(false)
|
const messageValue = ref(null)
|
const messageList = ref([
|
{
|
'author': 'AI',
|
'message': '欢迎使用中扬AI大模型智能助手',
|
'type': 'str'
|
}
|
])
|
|
const handleOk = () => {
|
|
}
|
|
const handleCancel = () => {
|
|
}
|
|
const openModal = () => {
|
open.value = true
|
}
|
|
const handleSubmit = () => {
|
let message = messageValue.value;
|
let tmp = {
|
'author': 'Me',
|
'message': message,
|
'type': 'str'
|
}
|
|
messageList.value.push(tmp)
|
messageValue.value = ''
|
aiLoading.value = true
|
|
get("http://192.168.4.61:5000/chat?message=" + message, {}).then(resp => {
|
let result = resp.data;
|
if (result.code == 200) {
|
let aiTmp = {
|
'author': 'AI',
|
'message': result.data,
|
'img': result.img,
|
'type': result.type
|
}
|
messageList.value.push(aiTmp)
|
aiLoading.value = false
|
} else {
|
let aiTmp = {
|
'author': 'AI',
|
'message': '抱歉,我暂时不能回答这个问题',
|
'img': '',
|
'type': 'str'
|
}
|
messageList.value.push(aiTmp)
|
aiLoading.value = false
|
}
|
|
scrollToBottom()
|
}).catch(resp => {
|
let aiTmp = {
|
'author': 'AI',
|
'message': '抱歉,我暂时不能回答这个问题',
|
'img': '',
|
'type': 'str'
|
}
|
messageList.value.push(aiTmp)
|
aiLoading.value = false
|
|
scrollToBottom()
|
})
|
}
|
|
const scrollToBottom = () => {
|
if (chatContainer.value) {
|
nextTick(() => {
|
setTimeout(() => {
|
chatContainer.value.scrollTop = chatContainer.value.scrollHeight;
|
}, 100);
|
});
|
}
|
}
|
|
|
</script>
|
|
<script>
|
export default {
|
name: 'aiComponent'
|
}
|
</script>
|
|
<template>
|
<div>
|
<a-modal v-model:open="open" :width="showWidth" @ok="handleOk" @cancel="handleCancel">
|
<div class="box" ref="chatContainer">
|
<a-comment v-for="(item, index) in messageList" :key="index">
|
<template #author><a>{{ item.author }}</a></template>
|
<template #avatar>
|
<a-avatar src="/public/img/logo.png" :alt="item.author" />
|
</template>
|
<template #content>
|
<div v-if="item.type == 'str'">
|
{{ item.message }}
|
</div>
|
<div v-else-if="item.type == 'html'" v-html="item.message"></div>
|
<div v-else-if="item.type == 'img'">
|
<img :src="'data:image/png;base64,' + item.img" />
|
</div>
|
</template>
|
</a-comment>
|
|
<a-comment v-if="aiLoading">
|
<template #author><a>AI</a></template>
|
<template #content>
|
<a-spin tip="Loading...">
|
<a-alert message="AI is Loading..."></a-alert>
|
</a-spin>
|
</template>
|
</a-comment>
|
</div>
|
|
<a-comment>
|
<template #content>
|
<a-form-item>
|
<a-textarea v-model:value="messageValue" :rows="4" />
|
</a-form-item>
|
<a-form-item>
|
<a-button html-type="submit" type="primary" @click="handleSubmit">
|
发送
|
</a-button>
|
</a-form-item>
|
</template>
|
</a-comment>
|
</a-modal>
|
|
<a-float-button type="primary" :style="{
|
right: '24px',
|
}" @click="openModal">
|
<template #icon>
|
AI
|
</template>
|
</a-float-button>
|
</div>
|
</template>
|
|
<style>
|
.box {
|
height: 768px;
|
overflow-y: auto;
|
}
|
</style>
|