Junjie
2024-08-09 3e3a7e84d99f6cde98b7d00d86aa17c677c2fc7e
#AI功能
2个文件已修改
1个文件已添加
171 ■■■■■ 已修改文件
zy-asrs-admin/src/components/ai/index.vue 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-admin/src/utils/request.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-admin/src/views/IndexView.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-admin/src/components/ai/index.vue
New file
@@ -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>
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) => {
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([]);
@@ -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>