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