mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
update
This commit is contained in:
11
web/package-lock.json
generated
11
web/package-lock.json
generated
@@ -15699,7 +15699,8 @@
|
||||
"node_modules/viewerjs": {
|
||||
"version": "1.11.6",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
@@ -19257,7 +19258,6 @@
|
||||
"integrity": "sha512-VCNRiAt2P/bLo09rYt3DLe6xXUMlhJwrvU18Ddd/lYJgC7s8+wvhgYs+MTx4OiAXdu58drGwSBO9SPx7C6J82Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.11.0",
|
||||
"@babel/helper-compilation-targets": "^7.9.6",
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
@@ -19270,7 +19270,6 @@
|
||||
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||
"@vue/babel-preset-jsx": "^1.2.4",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js-compat": "^3.6.5",
|
||||
"semver": "^6.1.0"
|
||||
}
|
||||
@@ -29566,8 +29565,7 @@
|
||||
"resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-1.7.4.tgz",
|
||||
"integrity": "sha512-K3PQ8utnVXXBCa5IRXRAhk/m83fNIsK77gTSXqAmPJe8eDTaSY1nifAOWPUmQDjzuCxYfa14UjGftHR9MFV70Q==",
|
||||
"requires": {
|
||||
"lodash-es": "^4.17.21",
|
||||
"viewerjs": "^1.11.6"
|
||||
"lodash-es": "^4.17.21"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
@@ -29632,7 +29630,8 @@
|
||||
"viewerjs": {
|
||||
"version": "1.11.6",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
|
||||
@@ -422,5 +422,58 @@ export default {
|
||||
nodeTagStyle: {
|
||||
placeholder: 'Please enter the tag content',
|
||||
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: '删除此标签'
|
||||
},
|
||||
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: {
|
||||
placeholder: '請輸入標籤內容',
|
||||
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')">
|
||||
<div class="aiChatBox" :class="{ isDark: isDark }">
|
||||
<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 class="chatResBox customScrollbar" ref="chatResBoxRef">
|
||||
<div
|
||||
@@ -29,13 +36,22 @@
|
||||
<textarea
|
||||
v-model="text"
|
||||
class="customScrollbar"
|
||||
placeholder="Enter 发送,Shift + Enter 换行。"
|
||||
@keydown.enter.prevent
|
||||
@keyup.enter.prevent="send"
|
||||
:placeholder="$t('ai.chatInputPlaceholder')"
|
||||
@keydown="onKeydown"
|
||||
></textarea>
|
||||
<el-button class="btn" size="mini" @click="send" :loading="isCreating"
|
||||
>发送</el-button
|
||||
<el-button class="btn" size="mini" @click="send" :loading="isCreating">
|
||||
{{ $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>
|
||||
</Sidebar>
|
||||
@@ -43,7 +59,7 @@
|
||||
|
||||
<script>
|
||||
import Sidebar from './Sidebar'
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import { mapState } from 'vuex'
|
||||
import { createUid } from 'simple-mind-map/src/utils'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
|
||||
@@ -78,6 +94,16 @@ export default {
|
||||
created() {},
|
||||
beforeDestroy() {},
|
||||
methods: {
|
||||
onKeydown(e) {
|
||||
if (e.keyCode === 13) {
|
||||
if (!e.shiftKey) {
|
||||
e.preventDefault()
|
||||
this.send()
|
||||
} else {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
send() {
|
||||
if (this.isCreating) return
|
||||
const text = this.text.trim()
|
||||
@@ -85,6 +111,13 @@ export default {
|
||||
return
|
||||
}
|
||||
this.text = ''
|
||||
const historyUserMsgList = this.chatList
|
||||
.filter(item => {
|
||||
return item.type === 'user'
|
||||
})
|
||||
.map(item => {
|
||||
return item.content
|
||||
})
|
||||
this.chatList.push({
|
||||
id: createUid(),
|
||||
type: 'user',
|
||||
@@ -96,9 +129,10 @@ export default {
|
||||
content: ''
|
||||
})
|
||||
this.isCreating = true
|
||||
const textList = [...historyUserMsgList, text]
|
||||
this.$bus.$emit(
|
||||
'ai_chat',
|
||||
text,
|
||||
textList,
|
||||
res => {
|
||||
if (!md) {
|
||||
md = new MarkdownIt()
|
||||
@@ -111,12 +145,22 @@ export default {
|
||||
},
|
||||
() => {
|
||||
this.isCreating = false
|
||||
this.$message.error(this.$t('ai.generationFailed'))
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
stop() {
|
||||
this.$bus.$emit('ai_chat_stop')
|
||||
this.isCreating = false
|
||||
},
|
||||
|
||||
clear() {
|
||||
this.chatList = []
|
||||
},
|
||||
|
||||
modifyAiConfig() {
|
||||
this.$bus.$emit('showAiConfigDialog')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,6 +328,13 @@ export default {
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
}
|
||||
|
||||
.stop {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
top: -30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="aiConfigDialog"
|
||||
title="AI配置"
|
||||
:title="$t('ai.AIConfiguration')"
|
||||
:visible.sync="aiConfigDialogVisible"
|
||||
width="550px"
|
||||
append-to-body
|
||||
@@ -13,17 +13,15 @@
|
||||
ref="ruleFormRef"
|
||||
label-width="100px"
|
||||
>
|
||||
<p class="title">火山方舟大模型配置:</p>
|
||||
<p class="title">{{ $t('ai.VolcanoArkLargeModelConfiguration') }}</p>
|
||||
<p class="desc">
|
||||
目前仅支持火山方舟大模型,需要自行去获取key,详细操作步骤见:<a
|
||||
href=""
|
||||
>教程</a
|
||||
{{ $t('ai.configTip') }}<a href="">{{ $t('ai.course') }}</a
|
||||
>。
|
||||
</p>
|
||||
<el-form-item label="API Key" prop="key">
|
||||
<el-input v-model="ruleForm.key"></el-input>
|
||||
</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-form-item>
|
||||
<!-- <el-form-item label="接口" prop="api">
|
||||
@@ -35,15 +33,17 @@
|
||||
<el-option key="GET" label="GET" value="GET"></el-option>
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
<p class="title">思绪思维导图客户端配置:</p>
|
||||
<el-form-item label="端口" prop="port">
|
||||
<p class="title">{{ $t('ai.mindMappingClientConfiguration') }}</p>
|
||||
<el-form-item :label="$t('ai.port')" prop="port">
|
||||
<el-input v-model="ruleForm.port"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">确认</el-button>
|
||||
<el-button @click="cancel">{{ $t('ai.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('ai.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@@ -73,13 +73,41 @@ export default {
|
||||
method: ''
|
||||
},
|
||||
rules: {
|
||||
api: [{ required: true, message: '请输入接口', trigger: 'blur' }],
|
||||
key: [{ required: true, message: '请输入API Key', trigger: 'blur' }],
|
||||
model: [
|
||||
{ required: true, message: '请输入推理接入点', trigger: 'blur' }
|
||||
api: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('ai.apiValidateTip'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
port: [{ required: true, message: '请输入端口', trigger: 'blur' }],
|
||||
method: [{ required: true, message: '请选择', trigger: 'blur' }]
|
||||
key: [
|
||||
{
|
||||
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.ruleForm
|
||||
})
|
||||
this.$message.success('配置保存成功')
|
||||
this.$message.success(this.$t('ai.configSaveSuccessTip'))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -139,6 +167,10 @@ export default {
|
||||
}
|
||||
|
||||
.aiConfigBox {
|
||||
a {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 12px;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -3,37 +3,39 @@
|
||||
<!-- 客户端连接失败提示弹窗 -->
|
||||
<el-dialog
|
||||
class="clientTipDialog"
|
||||
title="客户端连接失败提示"
|
||||
:title="$t('ai.connectFailedTitle')"
|
||||
:visible.sync="clientTipDialogVisible"
|
||||
width="400px"
|
||||
append-to-body
|
||||
>
|
||||
<div class="tipBox">
|
||||
<p>客户端连接失败,请检查:</p>
|
||||
<p>{{ $t('ai.connectFailedTip') }}</p>
|
||||
<p>
|
||||
1.是否安装了思绪思维导图客户端,如果没有请点此安装:<a
|
||||
{{ $t('ai.connectFailedCheckTip1')
|
||||
}}<a
|
||||
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>
|
||||
</p>
|
||||
<p>2.如果安装了客户端,请确认是否打开了客户端。</p>
|
||||
<P>3.如果已经安装并启动了,那么可以尝试关闭然后重新启动。</P>
|
||||
<p>{{ $t('ai.connectFailedCheckTip2') }}</p>
|
||||
<P>{{ $t('ai.connectFailedCheckTip3') }}</P>
|
||||
<p>
|
||||
完成以上步骤后可点击:<el-button size="small" @click="testConnect"
|
||||
>连接检测</el-button
|
||||
>
|
||||
{{ $t('ai.connectFailedCheckTip4')
|
||||
}}<el-button size="small" @click="testConnect">{{
|
||||
$t('ai.connectionDetection')
|
||||
}}</el-button>
|
||||
</p>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="clientTipDialogVisible = false"
|
||||
>关闭</el-button
|
||||
>
|
||||
<el-button type="primary" @click="clientTipDialogVisible = false">{{
|
||||
$t('ai.close')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- ai内容输入弹窗 -->
|
||||
<el-dialog
|
||||
class="createDialog"
|
||||
title="一键生成思维导图"
|
||||
:title="$t('ai.createMindMapTitle')"
|
||||
:visible.sync="createDialogVisible"
|
||||
width="450px"
|
||||
append-to-body
|
||||
@@ -42,24 +44,27 @@
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
placeholder="请输入一个主题,AI会根据你的主题生成思维导图,如:杭州周末出游计划。"
|
||||
:placeholder="$t('ai.createTip')"
|
||||
v-model="aiInput"
|
||||
>
|
||||
</el-input>
|
||||
<div class="tip warning">
|
||||
重要提示:一键生成会覆盖现有数据,建议先导出当前数据。
|
||||
{{ $t('ai.importantTip') }}
|
||||
</div>
|
||||
<div class="tip">
|
||||
想要修改AI配置?请点击:<el-button
|
||||
size="small"
|
||||
@click="aiConfigDialogVisible = true"
|
||||
>修改配置</el-button
|
||||
>
|
||||
{{ $t('ai.wantModifyAiConfigTip')
|
||||
}}<el-button size="small" @click="showAiConfigDialog">{{
|
||||
$t('ai.modifyAIConfiguration')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeAiCreateDialog">取消</el-button>
|
||||
<el-button type="primary" @click="doAiCreate">确认</el-button>
|
||||
<el-button @click="closeAiCreateDialog">{{
|
||||
$t('ai.cancel')
|
||||
}}</el-button>
|
||||
<el-button type="primary" @click="doAiCreate">{{
|
||||
$t('ai.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- ai生成中添加一个透明层,防止期间用户进行操作 -->
|
||||
@@ -68,9 +73,9 @@
|
||||
ref="aiCreatingMaskRef"
|
||||
v-show="aiCreatingMaskVisible"
|
||||
>
|
||||
<el-button type="warning" class="btn" @click="stopCreate"
|
||||
>停止生成</el-button
|
||||
>
|
||||
<el-button type="warning" class="btn" @click="stopCreate">{{
|
||||
$t('ai.stopGenerating')
|
||||
}}</el-button>
|
||||
</div>
|
||||
<AiConfigDialog v-model="aiConfigDialogVisible"></AiConfigDialog>
|
||||
</div>
|
||||
@@ -124,6 +129,8 @@ export default {
|
||||
this.$bus.$on('ai_create_all', this.aiCrateAll)
|
||||
this.$bus.$on('ai_create_part', this.aiCreatePart)
|
||||
this.$bus.$on('ai_chat', this.aiChat)
|
||||
this.$bus.$on('ai_chat_stop', this.aiChatStop)
|
||||
this.$bus.$on('showAiConfigDialog', this.showAiConfigDialog)
|
||||
},
|
||||
mounted() {
|
||||
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_part', this.aiCreatePart)
|
||||
this.$bus.$off('ai_chat', this.aiChat)
|
||||
this.$bus.$off('ai_chat_stop', this.aiChatStop)
|
||||
this.$bus.$off('showAiConfigDialog', this.showAiConfigDialog)
|
||||
},
|
||||
methods: {
|
||||
// 显示AI配置修改弹窗
|
||||
showAiConfigDialog() {
|
||||
this.aiConfigDialogVisible = true
|
||||
},
|
||||
|
||||
// 客户端连接检测
|
||||
async testConnect() {
|
||||
try {
|
||||
await fetch(`http://localhost:${this.aiConfig.port}/ai/test`, {
|
||||
method: 'GET'
|
||||
})
|
||||
this.$message.success('连接成功')
|
||||
this.$message.success(this.$t('ai.connectSuccessful'))
|
||||
this.clientTipDialogVisible = false
|
||||
this.createDialogVisible = true
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error('连接失败')
|
||||
this.$message.error(this.$t('ai.connectFailed'))
|
||||
}
|
||||
},
|
||||
|
||||
@@ -160,8 +174,8 @@ export default {
|
||||
this.aiConfig.port
|
||||
)
|
||||
) {
|
||||
this.aiConfigDialogVisible = true
|
||||
throw new Error('配置缺失')
|
||||
this.showAiConfigDialog()
|
||||
throw new Error(this.$t('ai.configurationMissing'))
|
||||
}
|
||||
// 检查连接
|
||||
let isConnect = false
|
||||
@@ -175,7 +189,7 @@ export default {
|
||||
this.clientTipDialogVisible = true
|
||||
}
|
||||
if (!isConnect) {
|
||||
throw new Error('连接失败')
|
||||
throw new Error(this.$t('ai.connectFailed'))
|
||||
}
|
||||
},
|
||||
|
||||
@@ -199,7 +213,7 @@ export default {
|
||||
doAiCreate() {
|
||||
const aiInputText = this.aiInput.trim()
|
||||
if (!aiInputText) {
|
||||
this.$message.warning('请输入内容')
|
||||
this.$message.warning(this.$t('ai.noInputTip'))
|
||||
return
|
||||
}
|
||||
this.closeAiCreateDialog()
|
||||
@@ -217,7 +231,9 @@ export default {
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: `帮我写一个【${aiInputText}】,需要以Markdown格式返回,并且只能使用Markdown的标题和无序列表两种语法,可以支持多层嵌套。只需返回内容即可。`
|
||||
content: `${this.$t(
|
||||
'ai.aiCreateMsgPrefix'
|
||||
)}${aiInputText}${this.$t('ai.aiCreateMsgPostfix')}`
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -230,12 +246,12 @@ export default {
|
||||
content => {
|
||||
this.aiCreatingContent = content
|
||||
this.resetOnAiCreatingStop()
|
||||
this.$message.success('AI生成完成')
|
||||
this.$message.success(this.$t('ai.aiGenerationSuccess'))
|
||||
},
|
||||
() => {
|
||||
this.resetOnAiCreatingStop()
|
||||
this.resetOnRenderEnd()
|
||||
this.$message.error('生成失败')
|
||||
this.$message.error(this.$t('ai.generationFailed'))
|
||||
}
|
||||
)
|
||||
},
|
||||
@@ -261,7 +277,7 @@ export default {
|
||||
this.aiInstance.stop()
|
||||
this.isAiCreating = false
|
||||
this.aiCreatingMaskVisible = false
|
||||
this.$message.success('已停止生成')
|
||||
this.$message.success(this.$t('ai.stoppedGenerating'))
|
||||
},
|
||||
|
||||
// 轮询进行渲染
|
||||
@@ -374,11 +390,13 @@ export default {
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: `我有一个主题为【${getStrWithBrFromHtml(
|
||||
content: `${this.$t(
|
||||
'ai.aiCreatePartMsgPrefix'
|
||||
)}${getStrWithBrFromHtml(
|
||||
currentMindMapData.data.text
|
||||
)}】的思维导图,帮我续写其中一个内容为【${getStrWithBrFromHtml(
|
||||
)}${this.$t('ai.aiCreatePartMsgCenter')}${getStrWithBrFromHtml(
|
||||
node.getData('text')
|
||||
)}】的节点的下级内容,需要以Markdown格式返回,并且只能使用Markdown的标题和无序列表两种语法,可以支持多层嵌套。只需返回内容即可。`
|
||||
)}${this.$t('ai.aiCreatePartMsgPostfix')}`
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -391,12 +409,12 @@ export default {
|
||||
content => {
|
||||
this.aiCreatingContent = content
|
||||
this.resetOnAiCreatingStop()
|
||||
this.$message.success('AI生成完成')
|
||||
this.$message.success(this.$t('ai.aiGenerationSuccess'))
|
||||
},
|
||||
() => {
|
||||
this.resetOnAiCreatingStop()
|
||||
this.resetOnRenderEnd()
|
||||
this.$message.error('生成失败')
|
||||
this.$message.error(this.$t('ai.generationFailed'))
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
@@ -472,7 +490,12 @@ export default {
|
||||
},
|
||||
|
||||
// AI对话
|
||||
async aiChat(text, progress = () => {}, end = () => {}, err = () => {}) {
|
||||
async aiChat(
|
||||
messageList = [],
|
||||
progress = () => {},
|
||||
end = () => {},
|
||||
err = () => {}
|
||||
) {
|
||||
try {
|
||||
await this.aiTest()
|
||||
// 发起请求
|
||||
@@ -483,12 +506,12 @@ export default {
|
||||
this.aiInstance.init('huoshan', this.aiConfig)
|
||||
this.aiInstance.request(
|
||||
{
|
||||
messages: [
|
||||
{
|
||||
messages: messageList.map(msg => {
|
||||
return {
|
||||
role: 'user',
|
||||
content: text
|
||||
content: msg
|
||||
}
|
||||
]
|
||||
})
|
||||
},
|
||||
content => {
|
||||
progress(content)
|
||||
@@ -503,6 +526,15 @@ export default {
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
|
||||
// AI对话停止
|
||||
aiChatStop() {
|
||||
if (this.aiInstance) {
|
||||
this.aiInstance.stop()
|
||||
this.isAiCreating = false
|
||||
this.aiInstance = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user