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

chore: 修改AI数据分析

上级 7e659cdd
......@@ -4,3 +4,8 @@ import httpRequest from '@/utils/axios'
export function qwenChat(data: any) {
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'])
const file = ref()
const onSuccess = res => {
file.value = res.data.detail
file.value = res.data
emit('success', file.value)
}
</script>
......@@ -12,13 +12,13 @@ const onSuccess = res => {
<el-upload
class="ai-upload"
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"
:data="{ purpose: 'file-extract' }"
:show-file-list="false"
:on-success="onSuccess">
<ul class="ai-upload-list" v-if="file">
<li>{{ file.filename }}</li>
<li>{{ file.file_name }}</li>
</ul>
<div class="ai-upload-box">
<img src="@/assets/images/ai_plus.png" height="40" />
......
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { ElMessage } from 'element-plus'
// import { fetchEventSource } from '@microsoft/fetch-event-source'
// 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() {
const messages = ref([])
const isLoading = ref(false)
async function post() {
async function post(data) {
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
}
})
try {
const response = await aiChat(data)
const items = response.data.items || []
items
.filter(item => item.type === 'text' || item.type === 'html')
.forEach(item => {
messages.value.push({ role: 'assistant', content: item.content, type: item.type })
})
} catch (error) {
isLoading.value = false
throw error
} finally {
isLoading.value = false
}
}
return { messages, post, isLoading }
}
......@@ -5,16 +5,16 @@ const { messages, post, isLoading } = useChat()
const chatInput = ref('')
const file = ref(null)
const onUploadSuccess = res => {
const message = { role: 'system', content: `fileid://${res.id}` }
messages.value.push(message)
file.value = res
}
async function postMessage() {
if (!chatInput.value) return
const message = { role: 'user', content: chatInput.value }
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 = ''
}
const chatRef = ref()
......@@ -43,7 +43,10 @@ watch(messages.value, () => nextTick(() => scrollToBottom()))
<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__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>
</template>
<div class="ai-message-item" v-if="isLoading">
......@@ -76,7 +79,7 @@ watch(messages.value, () => nextTick(() => scrollToBottom()))
flex: none;
}
.el-upload-dragger {
padding: 80px 0;
padding: 80px 20px;
}
}
}
......
......@@ -5,7 +5,6 @@ import { useAppConfig } from '@/composables/useAppConfig'
const appConfig = useAppConfig()
const httpRequest = axios.create({
timeout: 60000,
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论