mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: tool
This commit is contained in:
parent
7a34ba6fe3
commit
a0291bea88
|
|
@ -14,6 +14,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"@codemirror/lang-python": "^6.2.1",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"axios": "^1.8.4",
|
||||
"element-plus": "^2.9.10",
|
||||
|
|
|
|||
|
|
@ -75,8 +75,16 @@ const getToolById: (
|
|||
wordspace_id: string,
|
||||
tool_id: String,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (wordspace_id, function_lib_id, loading) => {
|
||||
return get(`${prefix}/${wordspace_id}/tool/${function_lib_id}`, undefined, loading)
|
||||
) => Promise<Result<any>> = (wordspace_id, tool_id, loading) => {
|
||||
return get(`${prefix}/${wordspace_id}/tool/${tool_id}`, undefined, loading)
|
||||
}
|
||||
|
||||
const postPylint: (
|
||||
wordspace_id: string,
|
||||
code: string,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (wordspace_id, code, loading) => {
|
||||
return post(`${prefix}/${wordspace_id}/tool/pylint`, { code }, {}, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,5 +104,6 @@ export default {
|
|||
getToolList,
|
||||
putTool,
|
||||
getToolById,
|
||||
postTool
|
||||
postTool,
|
||||
postPylint
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<div class="codemirror-editor w-full">
|
||||
<Codemirror
|
||||
v-model="data"
|
||||
ref="cmRef"
|
||||
:extensions="extensions"
|
||||
:style="codemirrorStyle"
|
||||
:tab-size="4"
|
||||
:autofocus="true"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
|
||||
<div class="codemirror-editor__footer">
|
||||
<el-button text type="info" @click="openCodemirrorDialog" class="magnify">
|
||||
<AppIcon iconName="app-magnify" style="font-size: 16px"></AppIcon>
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- Codemirror 弹出层 -->
|
||||
<el-dialog v-model="dialogVisible" :title="title" append-to-body fullscreen>
|
||||
<Codemirror
|
||||
v-model="cloneContent"
|
||||
:extensions="extensions"
|
||||
:style="codemirrorStyle"
|
||||
:tab-size="4"
|
||||
:autofocus="true"
|
||||
style="
|
||||
height: calc(100vh - 160px) !important;
|
||||
border: 1px solid #bbbfc4;
|
||||
border-radius: 4px;
|
||||
"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer mt-24">
|
||||
<el-button type="primary" @click="submitDialog"> {{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { Codemirror } from 'vue-codemirror'
|
||||
import { python } from '@codemirror/lang-python'
|
||||
import { oneDark } from '@codemirror/theme-one-dark'
|
||||
import { linter, type Diagnostic } from '@codemirror/lint'
|
||||
import ToolApi from '@/api/tool/tool'
|
||||
|
||||
defineOptions({ name: 'CodemirrorEditor' })
|
||||
|
||||
const props = defineProps<{
|
||||
title: String
|
||||
modelValue: any
|
||||
}>()
|
||||
const emit = defineEmits(['update:modelValue', 'submitDialog'])
|
||||
const data = computed({
|
||||
set: (value) => {
|
||||
emit('update:modelValue', value)
|
||||
},
|
||||
get: () => {
|
||||
return props.modelValue
|
||||
},
|
||||
})
|
||||
|
||||
function getRangeFromLineAndColumn(state: any, line: number, column: number, end_column?: number) {
|
||||
const l = state.doc.line(line)
|
||||
const form = l.from + column
|
||||
const to_end_column = l.from + end_column
|
||||
return {
|
||||
form: form > l.to ? l.to : form,
|
||||
to: end_column && to_end_column < l.to ? to_end_column : l.to,
|
||||
}
|
||||
}
|
||||
|
||||
const regexpLinter = linter(async (view) => {
|
||||
let diagnostics: Diagnostic[] = []
|
||||
await ToolApi.postPylint('default', view.state.doc.toString()).then((ok) => {
|
||||
ok.data.forEach((element: any) => {
|
||||
const range = getRangeFromLineAndColumn(
|
||||
view.state,
|
||||
element.line,
|
||||
element.column,
|
||||
element.endColumn,
|
||||
)
|
||||
|
||||
diagnostics.push({
|
||||
from: range.form,
|
||||
to: range.to,
|
||||
severity: element.type,
|
||||
message: element.message,
|
||||
})
|
||||
})
|
||||
})
|
||||
return diagnostics
|
||||
})
|
||||
const extensions = [python(), regexpLinter, oneDark]
|
||||
const codemirrorStyle = {
|
||||
height: '210px!important',
|
||||
width: '100%',
|
||||
}
|
||||
const cmRef = ref<InstanceType<typeof Codemirror>>()
|
||||
// 弹出框相关代码
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
|
||||
const cloneContent = ref<string>('')
|
||||
|
||||
watch(dialogVisible, (bool) => {
|
||||
if (!bool) {
|
||||
emit('submitDialog', cloneContent.value)
|
||||
}
|
||||
})
|
||||
|
||||
const openCodemirrorDialog = () => {
|
||||
cloneContent.value = props.modelValue
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function submitDialog() {
|
||||
emit('submitDialog', cloneContent.value)
|
||||
dialogVisible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.codemirror-editor {
|
||||
position: relative;
|
||||
&__footer {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -11,6 +11,7 @@ import FolderTree from './folder-tree/index.vue'
|
|||
import CommonList from './common-list/index.vue'
|
||||
import BackButton from './back-button/index.vue'
|
||||
import AppTable from './app-table/index.vue'
|
||||
import CodemirrorEditor from './codemirror-editor/index.vue'
|
||||
export default {
|
||||
install(app: App) {
|
||||
app.component('LogoFull', LogoFull)
|
||||
|
|
@ -25,5 +26,6 @@ export default {
|
|||
app.component('CommonList', CommonList)
|
||||
app.component('BackButton', BackButton)
|
||||
app.component('AppTable', AppTable)
|
||||
app.component('CodemirrorEditor', CodemirrorEditor)
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,9 +45,17 @@
|
|||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<el-row v-if="datasetList.length > 0 || datasetFolderList.length > 0" :gutter="15">
|
||||
<template v-for="(item, index) in datasetFolderList" :key="index">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<el-row v-if="datasetList.length > 0" :gutter="15">
|
||||
<template v-for="(item, index) in datasetList" :key="index">
|
||||
<el-col
|
||||
v-if="item.resource_type === 'folder'"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="12"
|
||||
:lg="8"
|
||||
:xl="6"
|
||||
class="mb-16"
|
||||
>
|
||||
<CardBox
|
||||
:title="item.name"
|
||||
:description="item.desc || $t('common.noData')"
|
||||
|
|
@ -65,9 +73,7 @@
|
|||
</template>
|
||||
</CardBox>
|
||||
</el-col>
|
||||
</template>
|
||||
<template v-for="(item, index) in datasetList" :key="index">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<CardBox
|
||||
:title="item.name"
|
||||
:description="item.desc"
|
||||
|
|
@ -235,9 +241,8 @@ function getList() {
|
|||
folder_id: currentFolder.value?.id || 'root',
|
||||
}
|
||||
KnowledgeApi.getKnowledgeList('default', paginationConfig, params, loading).then((res) => {
|
||||
datasetFolderList.value = res.data?.folders
|
||||
paginationConfig.total = res.data.total
|
||||
datasetList.value = [...datasetList.value, ...res.data.knowledge.records]
|
||||
datasetList.value = [...datasetList.value, ...res.data.records]
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +257,7 @@ function getFolder() {
|
|||
|
||||
function folderClickHandel(row: any) {
|
||||
currentFolder.value = row
|
||||
datasetFolderList.value = []
|
||||
datasetList.value = []
|
||||
getList()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,9 +46,17 @@
|
|||
</template>
|
||||
|
||||
<div>
|
||||
<el-row v-if="toolFolderList.length > 0 || toolList.length > 0" :gutter="15">
|
||||
<template v-for="(item, index) in toolFolderList" :key="index">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<el-row v-if="toolList.length > 0" :gutter="15">
|
||||
<template v-for="(item, index) in toolList" :key="index">
|
||||
<el-col
|
||||
v-if="item.resource_type === 'folder'"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="12"
|
||||
:lg="8"
|
||||
:xl="6"
|
||||
class="mb-16"
|
||||
>
|
||||
<CardBox
|
||||
:title="item.name"
|
||||
:description="item.desc || $t('common.noData')"
|
||||
|
|
@ -66,10 +74,7 @@
|
|||
</template>
|
||||
</CardBox>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<template v-for="(item, index) in toolList" :key="index">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||
<CardBox :title="item.name" :description="item.desc" class="cursor">
|
||||
<template #icon>
|
||||
<el-avatar
|
||||
|
|
@ -212,7 +217,6 @@ const paginationConfig = reactive({
|
|||
|
||||
const folderList = ref<any[]>([])
|
||||
const toolList = ref<any[]>([])
|
||||
const toolFolderList = ref<any[]>([])
|
||||
const currentFolder = ref<any>({})
|
||||
|
||||
const search_type_change = () => {
|
||||
|
|
@ -247,9 +251,8 @@ function getList() {
|
|||
tool_type: 'CUSTOM',
|
||||
}
|
||||
ToolApi.getToolList('default', paginationConfig, params, loading).then((res) => {
|
||||
toolFolderList.value = res.data?.folders
|
||||
paginationConfig.total = res.data?.tools.total
|
||||
toolList.value = [...toolList.value, ...res.data?.tools.records]
|
||||
paginationConfig.total = res.data?.total
|
||||
toolList.value = [...toolList.value, ...res.data?.records]
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue