From 3e3a7e84d99f6cde98b7d00d86aa17c677c2fc7e Mon Sep 17 00:00:00 2001 From: Junjie <540245094@qq.com> Date: 星期五, 09 八月 2024 15:25:15 +0800 Subject: [PATCH] #AI功能 --- zy-asrs-admin/src/views/IndexView.vue | 8 ++ zy-asrs-admin/src/components/ai/index.vue | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ zy-asrs-admin/src/utils/request.js | 2 3 files changed, 170 insertions(+), 3 deletions(-) diff --git a/zy-asrs-admin/src/components/ai/index.vue b/zy-asrs-admin/src/components/ai/index.vue new file mode 100644 index 0000000..feffded --- /dev/null +++ b/zy-asrs-admin/src/components/ai/index.vue @@ -0,0 +1,163 @@ +<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> diff --git a/zy-asrs-admin/src/utils/request.js b/zy-asrs-admin/src/utils/request.js index 04ff032..8a10e3a 100644 --- a/zy-asrs-admin/src/utils/request.js +++ b/zy-asrs-admin/src/utils/request.js @@ -3,7 +3,7 @@ const instance = axios.create({ baseURL: '', - timeout: 30000, + timeout: 120000, }) export const get = async (url, params) => { diff --git a/zy-asrs-admin/src/views/IndexView.vue b/zy-asrs-admin/src/views/IndexView.vue index f56e558..95d73b6 100644 --- a/zy-asrs-admin/src/views/IndexView.vue +++ b/zy-asrs-admin/src/views/IndexView.vue @@ -16,6 +16,7 @@ ApartmentOutlined, } from "@ant-design/icons-vue"; import { formatMessage, loadData } from '@/utils/localeUtils.js'; +import AiView from '@/components/ai/index.vue' const globalState = inject('globalState'); const selectedKeys = ref([]); @@ -185,7 +186,7 @@ post('/api/license/getLicenseDays', {}).then((resp) => { let result = resp.data; let data = result.data; - if(result.code == 200) { + if (result.code == 200) { licenseDays.value = data; } }) @@ -215,7 +216,8 @@ <a-layout class="main"> <a-layout-sider class="main-sider" v-model:collapsed="collapsed" :trigger="null" collapsible theme="dark"> <div class="logo" /> - <a-menu v-model:openKeys="openKeys" v-model:selectedKeys="selectedKeys" @select="menuSelect" theme="dark" mode="inline"> + <a-menu v-model:openKeys="openKeys" v-model:selectedKeys="selectedKeys" @select="menuSelect" theme="dark" + mode="inline"> <div> <a-menu-item key="/" name="涓婚〉"> <HomeOutlined /> {{ formatMessage('common.home', '涓婚〉') }} @@ -320,6 +322,8 @@ </a-layout-content> </a-layout> </a-layout> + + <AiView /> </template> <style scoped></style> -- Gitblit v1.9.1