9 changed files with 953 additions and 76 deletions
-
11src/api/ai/ai.js
-
9src/api/category/category.js
-
16src/utils/upload.js
-
159src/views/AIAssistant/AICataloging/Chat.vue
-
176src/views/AIAssistant/AICataloging/Chat2.vue
-
74src/views/AIAssistant/AICataloging/deepSeekChat.vue
-
4src/views/AIAssistant/AICataloging/index.vue
-
10src/views/AIAssistant/AICataloging/index2.vue
-
562src/views/AIAssistant/AICataloging/running/index.vue
@ -0,0 +1,11 @@ |
|||
import request from '@/utils/request' |
|||
import qs from 'qs' |
|||
|
|||
// AI辅助著录预生成档案
|
|||
export function FetchDoHandleEnterAnalysis(params) { |
|||
return request({ |
|||
url: 'api/ai/doHandleEnterAnalysis' + '?' + qs.stringify(params, { indices: false }), |
|||
method: 'get' |
|||
}) |
|||
} |
|||
export default { FetchDoHandleEnterAnalysis } |
@ -0,0 +1,159 @@ |
|||
<template> |
|||
<div class="chat-container"> |
|||
<div class="chat-messages"> |
|||
<div v-for="(message, index) in messages" :key="index" :class="{ 'user-message': message.sender === 'user', 'bot-message': message.sender === 'bot' }"> |
|||
{{ message.content }} |
|||
</div> |
|||
<mavon-editor |
|||
ref="typingContainer" |
|||
class="md" |
|||
:value="editorContent" |
|||
:subfield="false" |
|||
:default-open="'preview'" |
|||
:toolbars-flag="false" |
|||
:editable="false" |
|||
:scroll-style="true" |
|||
:ishljs="true" |
|||
/> |
|||
</div> |
|||
<div class="chat-input"> |
|||
<input v-model="inputMessage" placeholder="输入你的问题..." @keyup.enter="sendMessage"> |
|||
<button @click="sendMessage">发送</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
messages: [], |
|||
inputMessage: '', |
|||
currentBotMessage: '', |
|||
editorContent: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
async sendMessage() { |
|||
if (this.inputMessage.trim() === '') return |
|||
|
|||
this.messages.push({ sender: 'user', content: this.inputMessage }) |
|||
this.inputMessage = '' |
|||
this.currentBotMessage = '' |
|||
|
|||
try { |
|||
const response = await fetch('http://192.168.99.86:11434/api/generate', { |
|||
method: 'POST', |
|||
headers: { |
|||
'Content-Type': 'application/json' |
|||
}, |
|||
body: JSON.stringify({ |
|||
model: 'deepseek-r1:14b', |
|||
// model: 'qwen:7b', |
|||
prompt: this.messages[this.messages.length - 1].content, |
|||
stream: true |
|||
}) |
|||
}) |
|||
|
|||
if (!response.ok) { |
|||
throw new Error(`HTTP error! status: ${response.status}`) |
|||
} |
|||
|
|||
const reader = response.body.getReader() |
|||
const decoder = new TextDecoder('utf-8') |
|||
let done = false |
|||
|
|||
while (!done) { |
|||
const { done: isDone, value } = await reader.read() |
|||
done = isDone |
|||
if (done) break |
|||
|
|||
const chunk = decoder.decode(value) |
|||
const lines = chunk.split('\n') |
|||
|
|||
lines.forEach(line => { |
|||
if (line.trim() !== '') { |
|||
try { |
|||
const data = JSON.parse(line) |
|||
if (data.response) { |
|||
this.currentBotMessage += data.response |
|||
if (this.messages.length === 0 || this.messages[this.messages.length - 1].sender === 'user') { |
|||
this.messages.push({ sender: 'bot', content: '' }) |
|||
} |
|||
this.messages[this.messages.length - 1].content = this.currentBotMessage |
|||
} |
|||
} catch (error) { |
|||
console.error('解析JSON数据出错:', error) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
|
|||
// 更新 mavon-editor 的内容 |
|||
const lastBotMessage = this.messages.find(msg => msg.sender === 'bot') |
|||
if (lastBotMessage) { |
|||
this.editorContent = lastBotMessage.content |
|||
} |
|||
} catch (error) { |
|||
console.error('请求出错:', error) |
|||
this.messages.push({ sender: 'bot', content: '请求出错,请稍后再试。' }) |
|||
this.editorContent = '请求出错,请稍后再试。' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.chat-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 500px; |
|||
border: 1px solid #ccc; |
|||
border-radius: 5px; |
|||
padding: 10px; |
|||
} |
|||
|
|||
.chat-messages { |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.user-message { |
|||
text-align: right; |
|||
background-color: #e0f7fa; |
|||
padding: 5px; |
|||
margin: 5px; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.bot-message { |
|||
text-align: left; |
|||
background-color: #f1f8e9; |
|||
padding: 5px; |
|||
margin: 5px; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.chat-input { |
|||
display: flex; |
|||
} |
|||
|
|||
.chat-input input { |
|||
flex: 1; |
|||
padding: 5px; |
|||
border: 1px solid #ccc; |
|||
border-radius: 5px; |
|||
margin-right: 5px; |
|||
} |
|||
|
|||
.chat-input button { |
|||
padding: 5px 10px; |
|||
border: none; |
|||
background-color: #2196f3; |
|||
color: white; |
|||
border-radius: 5px; |
|||
cursor: pointer; |
|||
} |
|||
</style> |
@ -0,0 +1,176 @@ |
|||
<template> |
|||
<div class="chat-container"> |
|||
<div class="chat-messages"> |
|||
<!-- 循环渲染消息 --> |
|||
<div v-for="(message, index) in messages" :key="index"> |
|||
<!-- 用户消息 --> |
|||
<div v-if="message.sender === 'user'" class="user-message"> |
|||
{{ message.content }} |
|||
</div> |
|||
<!-- 机器人消息 --> |
|||
<mavon-editor |
|||
v-else |
|||
ref="mavonEditorRef" |
|||
class="bot-message" |
|||
:value="message.content" |
|||
:subfield="false" |
|||
:default-open="'preview'" |
|||
:toolbars-flag="false" |
|||
:editable="false" |
|||
:scroll-style="true" |
|||
:ishljs="true" |
|||
/> |
|||
</div> |
|||
</div> |
|||
<div class="chat-input"> |
|||
<input v-model="inputMessage" placeholder="输入你的问题..." @keyup.enter="sendMessage"> |
|||
<button @click="sendMessage">发送</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
messages: [], |
|||
inputMessage: '', |
|||
currentBotMessage: '' |
|||
} |
|||
}, |
|||
watch: { |
|||
messages: { |
|||
deep: true, |
|||
handler() { |
|||
this.$nextTick(() => { |
|||
const lastBotEditor = this.$refs.mavonEditorRef[this.$refs.mavonEditorRef.length - 1] |
|||
if (lastBotEditor) { |
|||
const editorContent = lastBotEditor.$el.querySelector('.editor-preview') |
|||
if (editorContent) { |
|||
editorContent.scrollTop = editorContent.scrollHeight |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
async sendMessage() { |
|||
if (this.inputMessage.trim() === '') return |
|||
|
|||
this.messages.push({ sender: 'user', content: this.inputMessage }) |
|||
this.inputMessage = '' |
|||
this.currentBotMessage = '' |
|||
|
|||
try { |
|||
const response = await fetch('http://192.168.99.86:11434/api/generate', { |
|||
method: 'POST', |
|||
headers: { |
|||
'Content-Type': 'application/json' |
|||
}, |
|||
body: JSON.stringify({ |
|||
model: 'deepseek-r1:14b', |
|||
// model: 'qwen:7b', |
|||
prompt: this.messages[this.messages.length - 1].content, |
|||
stream: true |
|||
}) |
|||
}) |
|||
|
|||
if (!response.ok) { |
|||
throw new Error(`HTTP error! status: ${response.status}`) |
|||
} |
|||
|
|||
const reader = response.body.getReader() |
|||
const decoder = new TextDecoder('utf-8') |
|||
let done = false |
|||
|
|||
while (!done) { |
|||
const { done: isDone, value } = await reader.read() |
|||
done = isDone |
|||
if (done) break |
|||
|
|||
const chunk = decoder.decode(value) |
|||
const lines = chunk.split('\n') |
|||
|
|||
lines.forEach((line) => { |
|||
if (line.trim() !== '') { |
|||
try { |
|||
const data = JSON.parse(line) |
|||
if (data.response) { |
|||
this.currentBotMessage += data.response |
|||
if ( |
|||
this.messages.length === 0 || |
|||
this.messages[this.messages.length - 1].sender === 'user' |
|||
) { |
|||
this.messages.push({ sender: 'bot', content: '' }) |
|||
} |
|||
this.messages[this.messages.length - 1].content = this.currentBotMessage |
|||
} |
|||
} catch (error) { |
|||
console.error('解析JSON数据出错:', error) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} catch (error) { |
|||
console.error('请求出错:', error) |
|||
this.messages.push({ sender: 'bot', content: '请求出错,请稍后再试。' }) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.chat-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 500px; |
|||
border: 1px solid #ccc; |
|||
border-radius: 5px; |
|||
padding: 10px; |
|||
} |
|||
|
|||
.chat-messages { |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.user-message { |
|||
text-align: right; |
|||
background-color: #e0f7fa; |
|||
padding: 5px; |
|||
margin: 5px; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.bot-message { |
|||
text-align: left; |
|||
background-color: #f1f8e9; |
|||
padding: 5px; |
|||
margin: 5px; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.chat-input { |
|||
display: flex; |
|||
} |
|||
|
|||
.chat-input input { |
|||
flex: 1; |
|||
padding: 5px; |
|||
border: 1px solid #ccc; |
|||
border-radius: 5px; |
|||
margin-right: 5px; |
|||
} |
|||
|
|||
.chat-input button { |
|||
padding: 5px 10px; |
|||
border: none; |
|||
background-color: #2196f3; |
|||
color: white; |
|||
border-radius: 5px; |
|||
cursor: pointer; |
|||
} |
|||
</style> |
@ -0,0 +1,74 @@ |
|||
<template> |
|||
<div> |
|||
<h1>DeepSeek问答</h1> |
|||
<input v-model="question" placeholder="请输入你的问题" @keyup.enter="sendQuestion"> |
|||
<button @click="sendQuestion">发送</button> |
|||
<div v-if="answer">{{ answer }}</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import axios from 'axios' |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
question: '', |
|||
answer: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
async sendQuestion() { |
|||
if (!this.question) return |
|||
|
|||
try { |
|||
// Ollama API端点,根据实际情况修改 |
|||
const apiUrl = 'http://192.168.99.86:11434/api/generate' |
|||
const response = await axios.post(apiUrl, { |
|||
model: 'deepseek-r1:14b', // 使用DeepSeek模型 |
|||
prompt: this.question |
|||
}) |
|||
console.log('response', response) |
|||
let fullAnswer = '' |
|||
const resultStr = response.data |
|||
// 假设对象之间用换行符分隔,根据实际情况调整 |
|||
const lines = resultStr.split('\n') |
|||
const resultArray = [] |
|||
lines.forEach(line => { |
|||
if (line.trim()) { |
|||
try { |
|||
const obj = JSON.parse(line) |
|||
resultArray.push(obj) |
|||
} catch (error) { |
|||
console.error('解析 JSON 时出错:', error) |
|||
} |
|||
} |
|||
}) |
|||
|
|||
resultArray.forEach(chunk => { |
|||
if (chunk.response) { |
|||
fullAnswer += chunk.response |
|||
} |
|||
}) |
|||
|
|||
this.answer = fullAnswer |
|||
} catch (error) { |
|||
console.error('请求出错:', error) |
|||
this.answer = '请求出错,请稍后再试。' |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 可以添加一些样式 */ |
|||
input { |
|||
margin-right: 10px; |
|||
padding: 5px; |
|||
} |
|||
|
|||
button { |
|||
padding: 5px 10px; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue