提交 620daf75 authored 作者: 王鹏飞's avatar 王鹏飞

chore: 修改AI数据分析

上级 7e659cdd
...@@ -4,3 +4,8 @@ import httpRequest from '@/utils/axios' ...@@ -4,3 +4,8 @@ import httpRequest from '@/utils/axios'
export function qwenChat(data: any) { export function qwenChat(data: any) {
return httpRequest.post('/api/lab/v1/experiment/qwen/chat', data, { headers: { 'Content-Type': 'application/json' } }) return httpRequest.post('/api/lab/v1/experiment/qwen/chat', data, { headers: { 'Content-Type': 'application/json' } })
} }
// 聊天(流式响应)
export function aiChat(data: any) {
return httpRequest.post('/api/ai/api/chat/data-analysis/generate-chart', data, { headers: { 'Content-Type': 'application/json' } })
}
...@@ -3,7 +3,7 @@ const emit = defineEmits(['success']) ...@@ -3,7 +3,7 @@ const emit = defineEmits(['success'])
const file = ref() const file = ref()
const onSuccess = res => { const onSuccess = res => {
file.value = res.data.detail file.value = res.data
emit('success', file.value) emit('success', file.value)
} }
</script> </script>
...@@ -12,13 +12,13 @@ const onSuccess = res => { ...@@ -12,13 +12,13 @@ const onSuccess = res => {
<el-upload <el-upload
class="ai-upload" class="ai-upload"
drag drag
action="/api/lab/v1/experiment/qwen/upload-file" action="/api/ai/api/upload-file"
accept=".csv, .xls, .xlsx, text/csv, application/csv,text/comma-separated-values, application/csv, application/excel,application/vnd.msexcel, text/anytext, application/vnd. ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" accept=".csv, .xls, .xlsx, text/csv, application/csv,text/comma-separated-values, application/csv, application/excel,application/vnd.msexcel, text/anytext, application/vnd. ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
:data="{ purpose: 'file-extract' }" :data="{ purpose: 'file-extract' }"
:show-file-list="false" :show-file-list="false"
:on-success="onSuccess"> :on-success="onSuccess">
<ul class="ai-upload-list" v-if="file"> <ul class="ai-upload-list" v-if="file">
<li>{{ file.filename }}</li> <li>{{ file.file_name }}</li>
</ul> </ul>
<div class="ai-upload-box"> <div class="ai-upload-box">
<img src="@/assets/images/ai_plus.png" height="40" /> <img src="@/assets/images/ai_plus.png" height="40" />
......
import { fetchEventSource } from '@microsoft/fetch-event-source' // import { fetchEventSource } from '@microsoft/fetch-event-source'
import { ElMessage } from 'element-plus' // import { ElMessage } from 'element-plus'
// export function useChat() {
// const messages = ref([])
// const isLoading = ref(false)
// async function post() {
// isLoading.value = true
// await fetchEventSource('/api/lab/v1/experiment/qwen/chat', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ model: 'qwen-long', messages: messages.value }),
// async onopen(response) {
// if (response.ok) {
// return response
// } else {
// throw response
// }
// },
// onmessage(res) {
// console.log(res.data)
// try {
// const message = JSON.parse(res.data)
// if (message.error) {
// ElMessage.error(message.error.message)
// return
// }
// const id = message.id
// const messageIndex = messages.value.findIndex(session => session.id === id)
// let content = message?.choices[0]?.delta.content || ''
// content = content.replaceAll('\n', '<br/>')
// if (messageIndex === -1) {
// messages.value.push({ id, role: 'assistant', content })
// } else {
// messages.value[messageIndex].content = messages.value[messageIndex].content + content
// }
// isLoading.value = false
// } catch (error) {
// console.log(error)
// isLoading.value = false
// }
// },
// onerror(err) {
// isLoading.value = false
// throw err
// }
// })
// }
// return { messages, post, isLoading }
// }
import { aiChat } from '../api'
export function useChat() { export function useChat() {
const messages = ref([]) const messages = ref([])
const isLoading = ref(false) const isLoading = ref(false)
async function post(data) {
async function post() {
isLoading.value = true isLoading.value = true
await fetchEventSource('/api/lab/v1/experiment/qwen/chat', { try {
method: 'POST', const response = await aiChat(data)
headers: { 'Content-Type': 'application/json' }, const items = response.data.items || []
body: JSON.stringify({ model: 'qwen-long', messages: messages.value }), items
async onopen(response) { .filter(item => item.type === 'text' || item.type === 'html')
if (response.ok) { .forEach(item => {
return response messages.value.push({ role: 'assistant', content: item.content, type: item.type })
} else { })
throw response } catch (error) {
} isLoading.value = false
}, throw error
onmessage(res) { } finally {
console.log(res.data) isLoading.value = false
try { }
const message = JSON.parse(res.data)
if (message.error) {
ElMessage.error(message.error.message)
return
}
const id = message.id
const messageIndex = messages.value.findIndex(session => session.id === id)
let content = message?.choices[0]?.delta.content || ''
content = content.replaceAll('\n', '<br/>')
if (messageIndex === -1) {
messages.value.push({ id, role: 'assistant', content })
} else {
messages.value[messageIndex].content = messages.value[messageIndex].content + content
}
isLoading.value = false
} catch (error) {
console.log(error)
isLoading.value = false
}
},
onerror(err) {
isLoading.value = false
throw err
}
})
} }
return { messages, post, isLoading } return { messages, post, isLoading }
} }
...@@ -5,16 +5,16 @@ const { messages, post, isLoading } = useChat() ...@@ -5,16 +5,16 @@ const { messages, post, isLoading } = useChat()
const chatInput = ref('') const chatInput = ref('')
const file = ref(null)
const onUploadSuccess = res => { const onUploadSuccess = res => {
const message = { role: 'system', content: `fileid://${res.id}` } file.value = res
messages.value.push(message)
} }
async function postMessage() { async function postMessage() {
if (!chatInput.value) return if (!chatInput.value) return
const message = { role: 'user', content: chatInput.value } const message = { role: 'user', content: chatInput.value }
messages.value.push(message) messages.value.push(message)
post(message) post({ file_path: file.value?.file_path, file_name: file.value?.file_name, chart_content: chatInput.value })
chatInput.value = '' chatInput.value = ''
} }
const chatRef = ref() const chatRef = ref()
...@@ -43,7 +43,10 @@ watch(messages.value, () => nextTick(() => scrollToBottom())) ...@@ -43,7 +43,10 @@ watch(messages.value, () => nextTick(() => scrollToBottom()))
<template v-for="(item, index) in messages" :key="index"> <template v-for="(item, index) in messages" :key="index">
<div class="ai-message-item" :class="item.role" v-if="item.role !== 'system'"> <div class="ai-message-item" :class="item.role" v-if="item.role !== 'system'">
<div class="ai-message__avatar"><img :src="item.role === 'assistant' ? '/images/ai_avatar_bot.png' : '/images/ai_avatar_user.png'" /></div> <div class="ai-message__avatar"><img :src="item.role === 'assistant' ? '/images/ai_avatar_bot.png' : '/images/ai_avatar_user.png'" /></div>
<div class="ai-message__content" v-html="item.content"></div> <div class="ai-message__content">
<iframe :srcdoc="item.content" frameborder="0" v-if="item.type === 'html'" width="900" height="500"></iframe>
<div v-html="item.content" v-else></div>
</div>
</div> </div>
</template> </template>
<div class="ai-message-item" v-if="isLoading"> <div class="ai-message-item" v-if="isLoading">
...@@ -76,7 +79,7 @@ watch(messages.value, () => nextTick(() => scrollToBottom())) ...@@ -76,7 +79,7 @@ watch(messages.value, () => nextTick(() => scrollToBottom()))
flex: none; flex: none;
} }
.el-upload-dragger { .el-upload-dragger {
padding: 80px 0; padding: 80px 20px;
} }
} }
} }
......
...@@ -5,7 +5,6 @@ import { useAppConfig } from '@/composables/useAppConfig' ...@@ -5,7 +5,6 @@ import { useAppConfig } from '@/composables/useAppConfig'
const appConfig = useAppConfig() const appConfig = useAppConfig()
const httpRequest = axios.create({ const httpRequest = axios.create({
timeout: 60000,
withCredentials: true, withCredentials: true,
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/x-www-form-urlencoded'
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论