update
This commit is contained in:
parent
b834b6fdd7
commit
f8149ce383
11
web/package-lock.json
generated
11
web/package-lock.json
generated
@ -15699,7 +15699,8 @@
|
|||||||
"node_modules/viewerjs": {
|
"node_modules/viewerjs": {
|
||||||
"version": "1.11.6",
|
"version": "1.11.6",
|
||||||
"resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
|
||||||
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
|
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw==",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/vm-browserify": {
|
"node_modules/vm-browserify": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
@ -19257,7 +19258,6 @@
|
|||||||
"integrity": "sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==",
|
"integrity": "sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/core": "^7.11.0",
|
|
||||||
"@babel/helper-compilation-targets": "^7.9.6",
|
"@babel/helper-compilation-targets": "^7.9.6",
|
||||||
"@babel/helper-module-imports": "^7.8.3",
|
"@babel/helper-module-imports": "^7.8.3",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||||
@ -19270,7 +19270,6 @@
|
|||||||
"@vue/babel-plugin-jsx": "^1.0.3",
|
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||||
"@vue/babel-preset-jsx": "^1.2.4",
|
"@vue/babel-preset-jsx": "^1.2.4",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||||
"core-js": "^3.6.5",
|
|
||||||
"core-js-compat": "^3.6.5",
|
"core-js-compat": "^3.6.5",
|
||||||
"semver": "^6.1.0"
|
"semver": "^6.1.0"
|
||||||
}
|
}
|
||||||
@ -29566,8 +29565,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-1.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-1.7.4.tgz",
|
||||||
"integrity": "sha512-K3PQ8utnVXXBCa5IRXRAhk/m83fNIsK77gTSXqAmPJe8eDTaSY1nifAOWPUmQDjzuCxYfa14UjGftHR9MFV70Q==",
|
"integrity": "sha512-K3PQ8utnVXXBCa5IRXRAhk/m83fNIsK77gTSXqAmPJe8eDTaSY1nifAOWPUmQDjzuCxYfa14UjGftHR9MFV70Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21"
|
||||||
"viewerjs": "^1.11.6"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
@ -29632,7 +29630,8 @@
|
|||||||
"viewerjs": {
|
"viewerjs": {
|
||||||
"version": "1.11.6",
|
"version": "1.11.6",
|
||||||
"resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
|
"resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
|
||||||
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
|
"integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw==",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"vm-browserify": {
|
"vm-browserify": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
|
|||||||
@ -422,5 +422,58 @@ export default {
|
|||||||
nodeTagStyle: {
|
nodeTagStyle: {
|
||||||
placeholder: 'Please enter the tag content',
|
placeholder: 'Please enter the tag content',
|
||||||
delete: 'Delete this tag'
|
delete: 'Delete this tag'
|
||||||
|
},
|
||||||
|
ai: {
|
||||||
|
chatTitle: 'AI dialogue',
|
||||||
|
clearRecords: 'Clear records',
|
||||||
|
connectFailedTitle: 'Client connection failure prompt',
|
||||||
|
connectFailedTip: 'Client connection failed, please check:',
|
||||||
|
connectFailedCheckTip1:
|
||||||
|
'1. Have you installed the mind mapping client? If not, please click here to install:',
|
||||||
|
connectFailedCheckTip2: '2. If the client is installed, please confirm if the client is opened.',
|
||||||
|
connectFailedCheckTip3:
|
||||||
|
'If it has already been installed and started, you can try closing and restarting it.',
|
||||||
|
connectFailedCheckTip4: 'After completing the above steps, you can click on:',
|
||||||
|
baiduNetdisk: 'Baidu Netdisk',
|
||||||
|
createMindMapTitle: 'One click generation of mind maps',
|
||||||
|
createTip:
|
||||||
|
'Please enter a theme, and AI will generate a mind map based on your theme, such as: Hangzhou weekend travel plan.',
|
||||||
|
importantTip: 'Important note: One click generation will overwrite existing data. It is recommended to export the current data first.',
|
||||||
|
wantModifyAiConfigTip: 'Do you want to modify the AI configuration? Please click on:',
|
||||||
|
modifyAIConfiguration: 'Modify AI configuration',
|
||||||
|
chatInputPlaceholder: 'Enter to send, Shift+Enter to wrap.',
|
||||||
|
send: 'Send',
|
||||||
|
stopGenerating: 'Stop generating',
|
||||||
|
generationFailed: 'Generation failed',
|
||||||
|
aiGenerationSuccess: 'AI generation completed',
|
||||||
|
stoppedGenerating: 'Stopped generating',
|
||||||
|
AIConfiguration: 'AI configuration',
|
||||||
|
VolcanoArkLargeModelConfiguration: 'Volcano Ark Large Model Configuration:',
|
||||||
|
configTip: 'At present, only the Volcano Ark model is supported, and you need to obtain the key yourself. For detailed operation steps, please refer to:',
|
||||||
|
course: 'Course',
|
||||||
|
inferenceAccessPoint: 'Inference access point',
|
||||||
|
mindMappingClientConfiguration: 'Mind mapping client configuration:',
|
||||||
|
port: 'Port',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
confirm: 'Confirm',
|
||||||
|
close: 'Close',
|
||||||
|
configSaveSuccessTip: 'Configuration saved successfully',
|
||||||
|
apiValidateTip: 'Please enter the interface',
|
||||||
|
keyValidateTip: 'Please enter the API Key',
|
||||||
|
modelValidateTip: 'Please enter the inference access point',
|
||||||
|
portValidateTip: 'Please enter the port',
|
||||||
|
methodValidateTip: 'Please select the request method',
|
||||||
|
noInputTip: 'Please enter the content',
|
||||||
|
connectSuccessful: 'Connection successful',
|
||||||
|
connectFailed: 'connection failed',
|
||||||
|
connectionDetection: 'Connection detection',
|
||||||
|
configurationMissing: 'Configuration missing',
|
||||||
|
aiCreateMsgPrefix: 'Help me write one【',
|
||||||
|
aiCreateMsgPostfix:
|
||||||
|
'】. It needs to be returned in Markdown format and can only use two syntax: Markdown title and unordered list. It can support multiple layers of nesting. Just return the content.',
|
||||||
|
aiCreatePartMsgPrefix: 'I have a theme for【',
|
||||||
|
aiCreatePartMsgCenter: '】Can you help me continue writing one of the contents of the mind map【',
|
||||||
|
aiCreatePartMsgPostfix:
|
||||||
|
'】The subordinate content of the node needs to be returned in Markdown format and can only use two syntax: Markdown title and unordered list. It can support multi-level nesting. Just return the content.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -416,6 +416,56 @@ export default {
|
|||||||
delete: '删除此标签'
|
delete: '删除此标签'
|
||||||
},
|
},
|
||||||
ai: {
|
ai: {
|
||||||
chatTitle: 'AI对话'
|
chatTitle: 'AI对话',
|
||||||
|
clearRecords: '清空记录',
|
||||||
|
connectFailedTitle: '客户端连接失败提示',
|
||||||
|
connectFailedTip: '客户端连接失败,请检查:',
|
||||||
|
connectFailedCheckTip1:
|
||||||
|
'1.是否安装了思绪思维导图客户端,如果没有请点此安装:',
|
||||||
|
connectFailedCheckTip2: '2.如果安装了客户端,请确认是否打开了客户端。',
|
||||||
|
connectFailedCheckTip3:
|
||||||
|
'3.如果已经安装并启动了,那么可以尝试关闭然后重新启动。',
|
||||||
|
connectFailedCheckTip4: '完成以上步骤后可点击:',
|
||||||
|
baiduNetdisk: '百度网盘',
|
||||||
|
createMindMapTitle: '一键生成思维导图',
|
||||||
|
createTip:
|
||||||
|
'请输入一个主题,AI会根据你的主题生成思维导图,如:杭州周末出游计划。',
|
||||||
|
importantTip: '重要提示:一键生成会覆盖现有数据,建议先导出当前数据。',
|
||||||
|
wantModifyAiConfigTip: '想要修改AI配置?请点击:',
|
||||||
|
modifyAIConfiguration: '修改AI配置',
|
||||||
|
chatInputPlaceholder: 'Enter 发送,Shift + Enter 换行。',
|
||||||
|
send: '发送',
|
||||||
|
stopGenerating: '停止生成',
|
||||||
|
generationFailed: '生成失败',
|
||||||
|
aiGenerationSuccess: 'AI生成完成',
|
||||||
|
stoppedGenerating: '已停止生成',
|
||||||
|
AIConfiguration: 'AI配置',
|
||||||
|
VolcanoArkLargeModelConfiguration: '火山方舟大模型配置:',
|
||||||
|
configTip: '目前仅支持火山方舟大模型,需要自行去获取key,详细操作步骤见:',
|
||||||
|
course: '教程',
|
||||||
|
inferenceAccessPoint: '推理接入点',
|
||||||
|
mindMappingClientConfiguration: '思绪思维导图客户端配置:',
|
||||||
|
port: '端口',
|
||||||
|
cancel: '取消',
|
||||||
|
confirm: '确认',
|
||||||
|
close: '关闭',
|
||||||
|
configSaveSuccessTip: '配置保存成功',
|
||||||
|
apiValidateTip: '请输入接口',
|
||||||
|
keyValidateTip: '请输入API Key',
|
||||||
|
modelValidateTip: '请输入推理接入点',
|
||||||
|
portValidateTip: '请输入端口',
|
||||||
|
methodValidateTip: '请选择请求方式',
|
||||||
|
noInputTip: '请输入内容',
|
||||||
|
connectSuccessful: '连接成功',
|
||||||
|
connectFailed: '连接失败',
|
||||||
|
connectionDetection: '连接检测',
|
||||||
|
configurationMissing: '配置缺失',
|
||||||
|
aiCreateMsgPrefix: '帮我写一个【',
|
||||||
|
aiCreateMsgPostfix:
|
||||||
|
'】,需要以Markdown格式返回,并且只能使用Markdown的标题和无序列表两种语法,可以支持多层嵌套。只需返回内容即可。',
|
||||||
|
aiCreatePartMsgPrefix: '我有一个主题为【',
|
||||||
|
aiCreatePartMsgCenter: '】的思维导图,帮我续写其中一个内容为【',
|
||||||
|
aiCreatePartMsgPostfix:
|
||||||
|
'】的节点的下级内容,需要以Markdown格式返回,并且只能使用Markdown的标题和无序列表两种语法,可以支持多层嵌套。只需返回内容即可。'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -413,5 +413,58 @@ export default {
|
|||||||
nodeTagStyle: {
|
nodeTagStyle: {
|
||||||
placeholder: '請輸入標籤內容',
|
placeholder: '請輸入標籤內容',
|
||||||
delete: '刪除此標籤'
|
delete: '刪除此標籤'
|
||||||
|
},
|
||||||
|
ai: {
|
||||||
|
chatTitle: 'AI對話',
|
||||||
|
clearRecords: '清空記錄',
|
||||||
|
connectFailedTitle: '客戶端連接失敗提示',
|
||||||
|
connectFailedTip: '客戶端連接失敗,請檢查:',
|
||||||
|
connectFailedCheckTip1:
|
||||||
|
'1.是否安裝了思緒思維導圖客戶端,如果沒有請點此安裝:',
|
||||||
|
connectFailedCheckTip2: '2.如果安裝了客戶端,請確認是否打開了客戶端。',
|
||||||
|
connectFailedCheckTip3:
|
||||||
|
'3.如果已經安裝並啓動了,那麽可以嘗試關閉然後重新啓動。',
|
||||||
|
connectFailedCheckTip4: '完成以上步驟後可點擊:',
|
||||||
|
baiduNetdisk: '百度網盤',
|
||||||
|
createMindMapTitle: '一鍵生成思維導圖',
|
||||||
|
createTip:
|
||||||
|
'請輸入一個主題,AI會根據你的主題生成思維導圖,如:杭州周末出遊計劃。',
|
||||||
|
importantTip: '重要提示:一鍵生成會覆蓋現有數據,建議先導出當前數據。',
|
||||||
|
wantModifyAiConfigTip: '想要修改AI配置?請點擊:',
|
||||||
|
modifyAIConfiguration: '修改AI配置',
|
||||||
|
chatInputPlaceholder: 'Enter 發送,Shift Enter 換行。',
|
||||||
|
send: '發送',
|
||||||
|
stopGenerating: '停止生成',
|
||||||
|
generationFailed: '生成失敗',
|
||||||
|
aiGenerationSuccess: 'AI生成完成',
|
||||||
|
stoppedGenerating: '已停止生成',
|
||||||
|
AIConfiguration: 'AI配置',
|
||||||
|
VolcanoArkLargeModelConfiguration: '火山方舟大模型配置:',
|
||||||
|
configTip: '目前僅支持火山方舟大模型,需要自行去獲取key,詳細操作步驟見:',
|
||||||
|
course: '教程',
|
||||||
|
inferenceAccessPoint: '推理接入點',
|
||||||
|
mindMappingClientConfiguration: '思緒思維導圖客戶端配置:',
|
||||||
|
port: '端口',
|
||||||
|
cancel: '取消',
|
||||||
|
confirm: '確認',
|
||||||
|
close: '關閉',
|
||||||
|
configSaveSuccessTip: '配置保存成功',
|
||||||
|
apiValidateTip: '請輸入接口',
|
||||||
|
keyValidateTip: '請輸入API Key',
|
||||||
|
modelValidateTip: '請輸入推理接入點',
|
||||||
|
portValidateTip: '請輸入端口',
|
||||||
|
methodValidateTip: '請選擇請求方式',
|
||||||
|
noInputTip: '請輸入內容',
|
||||||
|
connectSuccessful: '連接成功',
|
||||||
|
connectFailed: '連接失敗',
|
||||||
|
connectionDetection: '連接檢測',
|
||||||
|
configurationMissing: '配置缺失',
|
||||||
|
aiCreateMsgPrefix: '幫我寫一個【',
|
||||||
|
aiCreateMsgPostfix:
|
||||||
|
'】,需要以Markdown格式返回,並且只能使用Markdown的標題和無序列表兩種語法,可以支持多層嵌套。只需返回內容即可。',
|
||||||
|
aiCreatePartMsgPrefix: '我有一個主題爲【',
|
||||||
|
aiCreatePartMsgCenter: '】的思維導圖,幫我續寫其中一個內容爲【',
|
||||||
|
aiCreatePartMsgPostfix:
|
||||||
|
'】的節點的下級內容,需要以Markdown格式返回,並且只能使用Markdown的標題和無序列表兩種語法,可以支持多層嵌套。只需返回內容即可。'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,14 @@
|
|||||||
<Sidebar ref="sidebar" :title="$t('ai.chatTitle')">
|
<Sidebar ref="sidebar" :title="$t('ai.chatTitle')">
|
||||||
<div class="aiChatBox" :class="{ isDark: isDark }">
|
<div class="aiChatBox" :class="{ isDark: isDark }">
|
||||||
<div class="chatHeader">
|
<div class="chatHeader">
|
||||||
<el-button size="mini" @click="clear">清空记录</el-button>
|
<el-button size="mini" @click="clear">
|
||||||
|
<span class="el-icon-delete"></span>
|
||||||
|
{{ $t('ai.clearRecords') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button size="mini" @click="modifyAiConfig">
|
||||||
|
<span class="el-icon-edit"></span>
|
||||||
|
{{ $t('ai.modifyAIConfiguration') }}
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="chatResBox customScrollbar" ref="chatResBoxRef">
|
<div class="chatResBox customScrollbar" ref="chatResBoxRef">
|
||||||
<div
|
<div
|
||||||
@ -29,13 +36,22 @@
|
|||||||
<textarea
|
<textarea
|
||||||
v-model="text"
|
v-model="text"
|
||||||
class="customScrollbar"
|
class="customScrollbar"
|
||||||
placeholder="Enter 发送,Shift + Enter 换行。"
|
:placeholder="$t('ai.chatInputPlaceholder')"
|
||||||
@keydown.enter.prevent
|
@keydown="onKeydown"
|
||||||
@keyup.enter.prevent="send"
|
|
||||||
></textarea>
|
></textarea>
|
||||||
<el-button class="btn" size="mini" @click="send" :loading="isCreating"
|
<el-button class="btn" size="mini" @click="send" :loading="isCreating">
|
||||||
>发送</el-button
|
{{ $t('ai.send') }}
|
||||||
|
<span class="el-icon-position"></span>
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
class="stop"
|
||||||
|
size="mini"
|
||||||
|
type="warning"
|
||||||
|
@click="stop"
|
||||||
|
v-show="isCreating"
|
||||||
>
|
>
|
||||||
|
{{ $t('ai.stopGenerating') }}
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
@ -43,7 +59,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Sidebar from './Sidebar'
|
import Sidebar from './Sidebar'
|
||||||
import { mapState, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { createUid } from 'simple-mind-map/src/utils'
|
import { createUid } from 'simple-mind-map/src/utils'
|
||||||
import MarkdownIt from 'markdown-it'
|
import MarkdownIt from 'markdown-it'
|
||||||
|
|
||||||
@ -78,6 +94,16 @@ export default {
|
|||||||
created() {},
|
created() {},
|
||||||
beforeDestroy() {},
|
beforeDestroy() {},
|
||||||
methods: {
|
methods: {
|
||||||
|
onKeydown(e) {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
if (!e.shiftKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.send()
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
send() {
|
send() {
|
||||||
if (this.isCreating) return
|
if (this.isCreating) return
|
||||||
const text = this.text.trim()
|
const text = this.text.trim()
|
||||||
@ -85,6 +111,13 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.text = ''
|
this.text = ''
|
||||||
|
const historyUserMsgList = this.chatList
|
||||||
|
.filter(item => {
|
||||||
|
return item.type === 'user'
|
||||||
|
})
|
||||||
|
.map(item => {
|
||||||
|
return item.content
|
||||||
|
})
|
||||||
this.chatList.push({
|
this.chatList.push({
|
||||||
id: createUid(),
|
id: createUid(),
|
||||||
type: 'user',
|
type: 'user',
|
||||||
@ -96,9 +129,10 @@ export default {
|
|||||||
content: ''
|
content: ''
|
||||||
})
|
})
|
||||||
this.isCreating = true
|
this.isCreating = true
|
||||||
|
const textList = [...historyUserMsgList, text]
|
||||||
this.$bus.$emit(
|
this.$bus.$emit(
|
||||||
'ai_chat',
|
'ai_chat',
|
||||||
text,
|
textList,
|
||||||
res => {
|
res => {
|
||||||
if (!md) {
|
if (!md) {
|
||||||
md = new MarkdownIt()
|
md = new MarkdownIt()
|
||||||
@ -111,12 +145,22 @@ export default {
|
|||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.isCreating = false
|
this.isCreating = false
|
||||||
|
this.$message.error(this.$t('ai.generationFailed'))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
this.$bus.$emit('ai_chat_stop')
|
||||||
|
this.isCreating = false
|
||||||
|
},
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.chatList = []
|
this.chatList = []
|
||||||
|
},
|
||||||
|
|
||||||
|
modifyAiConfig() {
|
||||||
|
this.$bus.$emit('showAiConfigDialog')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,6 +328,13 @@ export default {
|
|||||||
right: 12px;
|
right: 12px;
|
||||||
bottom: 12px;
|
bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stop {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
top: -30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
class="aiConfigDialog"
|
class="aiConfigDialog"
|
||||||
title="AI配置"
|
:title="$t('ai.AIConfiguration')"
|
||||||
:visible.sync="aiConfigDialogVisible"
|
:visible.sync="aiConfigDialogVisible"
|
||||||
width="550px"
|
width="550px"
|
||||||
append-to-body
|
append-to-body
|
||||||
@ -13,17 +13,15 @@
|
|||||||
ref="ruleFormRef"
|
ref="ruleFormRef"
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
>
|
>
|
||||||
<p class="title">火山方舟大模型配置:</p>
|
<p class="title">{{ $t('ai.VolcanoArkLargeModelConfiguration') }}</p>
|
||||||
<p class="desc">
|
<p class="desc">
|
||||||
目前仅支持火山方舟大模型,需要自行去获取key,详细操作步骤见:<a
|
{{ $t('ai.configTip') }}<a href="">{{ $t('ai.course') }}</a
|
||||||
href=""
|
|
||||||
>教程</a
|
|
||||||
>。
|
>。
|
||||||
</p>
|
</p>
|
||||||
<el-form-item label="API Key" prop="key">
|
<el-form-item label="API Key" prop="key">
|
||||||
<el-input v-model="ruleForm.key"></el-input>
|
<el-input v-model="ruleForm.key"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="推理接入点" prop="model">
|
<el-form-item :label="$t('ai.inferenceAccessPoint')" prop="model">
|
||||||
<el-input v-model="ruleForm.model"></el-input>
|
<el-input v-model="ruleForm.model"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="接口" prop="api">
|
<!-- <el-form-item label="接口" prop="api">
|
||||||
@ -35,15 +33,17 @@
|
|||||||
<el-option key="GET" label="GET" value="GET"></el-option>
|
<el-option key="GET" label="GET" value="GET"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<p class="title">思绪思维导图客户端配置:</p>
|
<p class="title">{{ $t('ai.mindMappingClientConfiguration') }}</p>
|
||||||
<el-form-item label="端口" prop="port">
|
<el-form-item :label="$t('ai.port')" prop="port">
|
||||||
<el-input v-model="ruleForm.port"></el-input>
|
<el-input v-model="ruleForm.port"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="cancel">取消</el-button>
|
<el-button @click="cancel">{{ $t('ai.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="confirm">确认</el-button>
|
<el-button type="primary" @click="confirm">{{
|
||||||
|
$t('ai.confirm')
|
||||||
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
@ -73,13 +73,41 @@ export default {
|
|||||||
method: ''
|
method: ''
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
api: [{ required: true, message: '请输入接口', trigger: 'blur' }],
|
api: [
|
||||||
key: [{ required: true, message: '请输入API Key', trigger: 'blur' }],
|
{
|
||||||
model: [
|
required: true,
|
||||||
{ required: true, message: '请输入推理接入点', trigger: 'blur' }
|
message: this.$t('ai.apiValidateTip'),
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
port: [{ required: true, message: '请输入端口', trigger: 'blur' }],
|
key: [
|
||||||
method: [{ required: true, message: '请选择', trigger: 'blur' }]
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('ai.keyValidateTip'),
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
model: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('ai.modelValidateTip'),
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
port: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('ai.portValidateTip'),
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
method: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('ai.methodValidateTip'),
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -124,7 +152,7 @@ export default {
|
|||||||
this.setLocalConfig({
|
this.setLocalConfig({
|
||||||
...this.ruleForm
|
...this.ruleForm
|
||||||
})
|
})
|
||||||
this.$message.success('配置保存成功')
|
this.$message.success(this.$t('ai.configSaveSuccessTip'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -139,6 +167,10 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.aiConfigBox {
|
.aiConfigBox {
|
||||||
|
a {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
@ -3,37 +3,39 @@
|
|||||||
<!-- 客户端连接失败提示弹窗 -->
|
<!-- 客户端连接失败提示弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
class="clientTipDialog"
|
class="clientTipDialog"
|
||||||
title="客户端连接失败提示"
|
:title="$t('ai.connectFailedTitle')"
|
||||||
:visible.sync="clientTipDialogVisible"
|
:visible.sync="clientTipDialogVisible"
|
||||||
width="400px"
|
width="400px"
|
||||||
append-to-body
|
append-to-body
|
||||||
>
|
>
|
||||||
<div class="tipBox">
|
<div class="tipBox">
|
||||||
<p>客户端连接失败,请检查:</p>
|
<p>{{ $t('ai.connectFailedTip') }}</p>
|
||||||
<p>
|
<p>
|
||||||
1.是否安装了思绪思维导图客户端,如果没有请点此安装:<a
|
{{ $t('ai.connectFailedCheckTip1')
|
||||||
|
}}<a
|
||||||
href="https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3"
|
href="https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3"
|
||||||
>百度网盘</a
|
>{{ $t('ai.baiduNetdisk') }}</a
|
||||||
>、<a href="https://github.com/wanglin2/mind-map/releases">Github</a>
|
>、<a href="https://github.com/wanglin2/mind-map/releases">Github</a>
|
||||||
</p>
|
</p>
|
||||||
<p>2.如果安装了客户端,请确认是否打开了客户端。</p>
|
<p>{{ $t('ai.connectFailedCheckTip2') }}</p>
|
||||||
<P>3.如果已经安装并启动了,那么可以尝试关闭然后重新启动。</P>
|
<P>{{ $t('ai.connectFailedCheckTip3') }}</P>
|
||||||
<p>
|
<p>
|
||||||
完成以上步骤后可点击:<el-button size="small" @click="testConnect"
|
{{ $t('ai.connectFailedCheckTip4')
|
||||||
>连接检测</el-button
|
}}<el-button size="small" @click="testConnect">{{
|
||||||
>
|
$t('ai.connectionDetection')
|
||||||
|
}}</el-button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" @click="clientTipDialogVisible = false"
|
<el-button type="primary" @click="clientTipDialogVisible = false">{{
|
||||||
>关闭</el-button
|
$t('ai.close')
|
||||||
>
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- ai内容输入弹窗 -->
|
<!-- ai内容输入弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
class="createDialog"
|
class="createDialog"
|
||||||
title="一键生成思维导图"
|
:title="$t('ai.createMindMapTitle')"
|
||||||
:visible.sync="createDialogVisible"
|
:visible.sync="createDialogVisible"
|
||||||
width="450px"
|
width="450px"
|
||||||
append-to-body
|
append-to-body
|
||||||
@ -42,24 +44,27 @@
|
|||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:rows="5"
|
:rows="5"
|
||||||
placeholder="请输入一个主题,AI会根据你的主题生成思维导图,如:杭州周末出游计划。"
|
:placeholder="$t('ai.createTip')"
|
||||||
v-model="aiInput"
|
v-model="aiInput"
|
||||||
>
|
>
|
||||||
</el-input>
|
</el-input>
|
||||||
<div class="tip warning">
|
<div class="tip warning">
|
||||||
重要提示:一键生成会覆盖现有数据,建议先导出当前数据。
|
{{ $t('ai.importantTip') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="tip">
|
<div class="tip">
|
||||||
想要修改AI配置?请点击:<el-button
|
{{ $t('ai.wantModifyAiConfigTip')
|
||||||
size="small"
|
}}<el-button size="small" @click="showAiConfigDialog">{{
|
||||||
@click="aiConfigDialogVisible = true"
|
$t('ai.modifyAIConfiguration')
|
||||||
>修改配置</el-button
|
}}</el-button>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="closeAiCreateDialog">取消</el-button>
|
<el-button @click="closeAiCreateDialog">{{
|
||||||
<el-button type="primary" @click="doAiCreate">确认</el-button>
|
$t('ai.cancel')
|
||||||
|
}}</el-button>
|
||||||
|
<el-button type="primary" @click="doAiCreate">{{
|
||||||
|
$t('ai.confirm')
|
||||||
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- ai生成中添加一个透明层,防止期间用户进行操作 -->
|
<!-- ai生成中添加一个透明层,防止期间用户进行操作 -->
|
||||||
@ -68,9 +73,9 @@
|
|||||||
ref="aiCreatingMaskRef"
|
ref="aiCreatingMaskRef"
|
||||||
v-show="aiCreatingMaskVisible"
|
v-show="aiCreatingMaskVisible"
|
||||||
>
|
>
|
||||||
<el-button type="warning" class="btn" @click="stopCreate"
|
<el-button type="warning" class="btn" @click="stopCreate">{{
|
||||||
>停止生成</el-button
|
$t('ai.stopGenerating')
|
||||||
>
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<AiConfigDialog v-model="aiConfigDialogVisible"></AiConfigDialog>
|
<AiConfigDialog v-model="aiConfigDialogVisible"></AiConfigDialog>
|
||||||
</div>
|
</div>
|
||||||
@ -124,6 +129,8 @@ export default {
|
|||||||
this.$bus.$on('ai_create_all', this.aiCrateAll)
|
this.$bus.$on('ai_create_all', this.aiCrateAll)
|
||||||
this.$bus.$on('ai_create_part', this.aiCreatePart)
|
this.$bus.$on('ai_create_part', this.aiCreatePart)
|
||||||
this.$bus.$on('ai_chat', this.aiChat)
|
this.$bus.$on('ai_chat', this.aiChat)
|
||||||
|
this.$bus.$on('ai_chat_stop', this.aiChatStop)
|
||||||
|
this.$bus.$on('showAiConfigDialog', this.showAiConfigDialog)
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
document.body.appendChild(this.$refs.aiCreatingMaskRef)
|
document.body.appendChild(this.$refs.aiCreatingMaskRef)
|
||||||
@ -132,20 +139,27 @@ export default {
|
|||||||
this.$bus.$off('ai_create_all', this.aiCrateAll)
|
this.$bus.$off('ai_create_all', this.aiCrateAll)
|
||||||
this.$bus.$off('ai_create_part', this.aiCreatePart)
|
this.$bus.$off('ai_create_part', this.aiCreatePart)
|
||||||
this.$bus.$off('ai_chat', this.aiChat)
|
this.$bus.$off('ai_chat', this.aiChat)
|
||||||
|
this.$bus.$off('ai_chat_stop', this.aiChatStop)
|
||||||
|
this.$bus.$off('showAiConfigDialog', this.showAiConfigDialog)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 显示AI配置修改弹窗
|
||||||
|
showAiConfigDialog() {
|
||||||
|
this.aiConfigDialogVisible = true
|
||||||
|
},
|
||||||
|
|
||||||
// 客户端连接检测
|
// 客户端连接检测
|
||||||
async testConnect() {
|
async testConnect() {
|
||||||
try {
|
try {
|
||||||
await fetch(`http://localhost:${this.aiConfig.port}/ai/test`, {
|
await fetch(`http://localhost:${this.aiConfig.port}/ai/test`, {
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
})
|
})
|
||||||
this.$message.success('连接成功')
|
this.$message.success(this.$t('ai.connectSuccessful'))
|
||||||
this.clientTipDialogVisible = false
|
this.clientTipDialogVisible = false
|
||||||
this.createDialogVisible = true
|
this.createDialogVisible = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
this.$message.error('连接失败')
|
this.$message.error(this.$t('ai.connectFailed'))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -160,8 +174,8 @@ export default {
|
|||||||
this.aiConfig.port
|
this.aiConfig.port
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
this.aiConfigDialogVisible = true
|
this.showAiConfigDialog()
|
||||||
throw new Error('配置缺失')
|
throw new Error(this.$t('ai.configurationMissing'))
|
||||||
}
|
}
|
||||||
// 检查连接
|
// 检查连接
|
||||||
let isConnect = false
|
let isConnect = false
|
||||||
@ -175,7 +189,7 @@ export default {
|
|||||||
this.clientTipDialogVisible = true
|
this.clientTipDialogVisible = true
|
||||||
}
|
}
|
||||||
if (!isConnect) {
|
if (!isConnect) {
|
||||||
throw new Error('连接失败')
|
throw new Error(this.$t('ai.connectFailed'))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -199,7 +213,7 @@ export default {
|
|||||||
doAiCreate() {
|
doAiCreate() {
|
||||||
const aiInputText = this.aiInput.trim()
|
const aiInputText = this.aiInput.trim()
|
||||||
if (!aiInputText) {
|
if (!aiInputText) {
|
||||||
this.$message.warning('请输入内容')
|
this.$message.warning(this.$t('ai.noInputTip'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.closeAiCreateDialog()
|
this.closeAiCreateDialog()
|
||||||
@ -217,7 +231,9 @@ export default {
|
|||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: `帮我写一个【${aiInputText}】,需要以Markdown格式返回,并且只能使用Markdown的标题和无序列表两种语法,可以支持多层嵌套。只需返回内容即可。`
|
content: `${this.$t(
|
||||||
|
'ai.aiCreateMsgPrefix'
|
||||||
|
)}${aiInputText}${this.$t('ai.aiCreateMsgPostfix')}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -230,12 +246,12 @@ export default {
|
|||||||
content => {
|
content => {
|
||||||
this.aiCreatingContent = content
|
this.aiCreatingContent = content
|
||||||
this.resetOnAiCreatingStop()
|
this.resetOnAiCreatingStop()
|
||||||
this.$message.success('AI生成完成')
|
this.$message.success(this.$t('ai.aiGenerationSuccess'))
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.resetOnAiCreatingStop()
|
this.resetOnAiCreatingStop()
|
||||||
this.resetOnRenderEnd()
|
this.resetOnRenderEnd()
|
||||||
this.$message.error('生成失败')
|
this.$message.error(this.$t('ai.generationFailed'))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -261,7 +277,7 @@ export default {
|
|||||||
this.aiInstance.stop()
|
this.aiInstance.stop()
|
||||||
this.isAiCreating = false
|
this.isAiCreating = false
|
||||||
this.aiCreatingMaskVisible = false
|
this.aiCreatingMaskVisible = false
|
||||||
this.$message.success('已停止生成')
|
this.$message.success(this.$t('ai.stoppedGenerating'))
|
||||||
},
|
},
|
||||||
|
|
||||||
// 轮询进行渲染
|
// 轮询进行渲染
|
||||||
@ -374,11 +390,13 @@ export default {
|
|||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: `我有一个主题为【${getStrWithBrFromHtml(
|
content: `${this.$t(
|
||||||
|
'ai.aiCreatePartMsgPrefix'
|
||||||
|
)}${getStrWithBrFromHtml(
|
||||||
currentMindMapData.data.text
|
currentMindMapData.data.text
|
||||||
)}】的思维导图,帮我续写其中一个内容为【${getStrWithBrFromHtml(
|
)}${this.$t('ai.aiCreatePartMsgCenter')}${getStrWithBrFromHtml(
|
||||||
node.getData('text')
|
node.getData('text')
|
||||||
)}】的节点的下级内容,需要以Markdown格式返回,并且只能使用Markdown的标题和无序列表两种语法,可以支持多层嵌套。只需返回内容即可。`
|
)}${this.$t('ai.aiCreatePartMsgPostfix')}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -391,12 +409,12 @@ export default {
|
|||||||
content => {
|
content => {
|
||||||
this.aiCreatingContent = content
|
this.aiCreatingContent = content
|
||||||
this.resetOnAiCreatingStop()
|
this.resetOnAiCreatingStop()
|
||||||
this.$message.success('AI生成完成')
|
this.$message.success(this.$t('ai.aiGenerationSuccess'))
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.resetOnAiCreatingStop()
|
this.resetOnAiCreatingStop()
|
||||||
this.resetOnRenderEnd()
|
this.resetOnRenderEnd()
|
||||||
this.$message.error('生成失败')
|
this.$message.error(this.$t('ai.generationFailed'))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -472,7 +490,12 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// AI对话
|
// AI对话
|
||||||
async aiChat(text, progress = () => {}, end = () => {}, err = () => {}) {
|
async aiChat(
|
||||||
|
messageList = [],
|
||||||
|
progress = () => {},
|
||||||
|
end = () => {},
|
||||||
|
err = () => {}
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
await this.aiTest()
|
await this.aiTest()
|
||||||
// 发起请求
|
// 发起请求
|
||||||
@ -483,12 +506,12 @@ export default {
|
|||||||
this.aiInstance.init('huoshan', this.aiConfig)
|
this.aiInstance.init('huoshan', this.aiConfig)
|
||||||
this.aiInstance.request(
|
this.aiInstance.request(
|
||||||
{
|
{
|
||||||
messages: [
|
messages: messageList.map(msg => {
|
||||||
{
|
return {
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: text
|
content: msg
|
||||||
}
|
}
|
||||||
]
|
})
|
||||||
},
|
},
|
||||||
content => {
|
content => {
|
||||||
progress(content)
|
progress(content)
|
||||||
@ -503,6 +526,15 @@ export default {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// AI对话停止
|
||||||
|
aiChatStop() {
|
||||||
|
if (this.aiInstance) {
|
||||||
|
this.aiInstance.stop()
|
||||||
|
this.isAiCreating = false
|
||||||
|
this.aiInstance = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user