feat: tool
This commit is contained in:
parent
7a34ba6fe3
commit
a0291bea88
@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-json": "^6.0.1",
|
"@codemirror/lang-json": "^6.0.1",
|
||||||
|
"@codemirror/lang-python": "^6.2.1",
|
||||||
"@codemirror/theme-one-dark": "^6.1.2",
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.8.4",
|
||||||
"element-plus": "^2.9.10",
|
"element-plus": "^2.9.10",
|
||||||
|
|||||||
@ -75,8 +75,16 @@ const getToolById: (
|
|||||||
wordspace_id: string,
|
wordspace_id: string,
|
||||||
tool_id: String,
|
tool_id: String,
|
||||||
loading?: Ref<boolean>,
|
loading?: Ref<boolean>,
|
||||||
) => Promise<Result<any>> = (wordspace_id, function_lib_id, loading) => {
|
) => Promise<Result<any>> = (wordspace_id, tool_id, loading) => {
|
||||||
return get(`${prefix}/${wordspace_id}/tool/${function_lib_id}`, undefined, 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,
|
getToolList,
|
||||||
putTool,
|
putTool,
|
||||||
getToolById,
|
getToolById,
|
||||||
postTool
|
postTool,
|
||||||
|
postPylint
|
||||||
}
|
}
|
||||||
|
|||||||
133
ui/src/components/codemirror-editor/index.vue
Normal file
133
ui/src/components/codemirror-editor/index.vue
Normal file
@ -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 CommonList from './common-list/index.vue'
|
||||||
import BackButton from './back-button/index.vue'
|
import BackButton from './back-button/index.vue'
|
||||||
import AppTable from './app-table/index.vue'
|
import AppTable from './app-table/index.vue'
|
||||||
|
import CodemirrorEditor from './codemirror-editor/index.vue'
|
||||||
export default {
|
export default {
|
||||||
install(app: App) {
|
install(app: App) {
|
||||||
app.component('LogoFull', LogoFull)
|
app.component('LogoFull', LogoFull)
|
||||||
@ -25,5 +26,6 @@ export default {
|
|||||||
app.component('CommonList', CommonList)
|
app.component('CommonList', CommonList)
|
||||||
app.component('BackButton', BackButton)
|
app.component('BackButton', BackButton)
|
||||||
app.component('AppTable', AppTable)
|
app.component('AppTable', AppTable)
|
||||||
|
app.component('CodemirrorEditor', CodemirrorEditor)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,9 +45,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div>
|
<div>
|
||||||
<el-row v-if="datasetList.length > 0 || datasetFolderList.length > 0" :gutter="15">
|
<el-row v-if="datasetList.length > 0" :gutter="15">
|
||||||
<template v-for="(item, index) in datasetFolderList" :key="index">
|
<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-if="item.resource_type === 'folder'"
|
||||||
|
:xs="24"
|
||||||
|
:sm="12"
|
||||||
|
:md="12"
|
||||||
|
:lg="8"
|
||||||
|
:xl="6"
|
||||||
|
class="mb-16"
|
||||||
|
>
|
||||||
<CardBox
|
<CardBox
|
||||||
:title="item.name"
|
:title="item.name"
|
||||||
:description="item.desc || $t('common.noData')"
|
:description="item.desc || $t('common.noData')"
|
||||||
@ -65,9 +73,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||||
<template v-for="(item, index) in datasetList" :key="index">
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
|
||||||
<CardBox
|
<CardBox
|
||||||
:title="item.name"
|
:title="item.name"
|
||||||
:description="item.desc"
|
:description="item.desc"
|
||||||
@ -235,9 +241,8 @@ function getList() {
|
|||||||
folder_id: currentFolder.value?.id || 'root',
|
folder_id: currentFolder.value?.id || 'root',
|
||||||
}
|
}
|
||||||
KnowledgeApi.getKnowledgeList('default', paginationConfig, params, loading).then((res) => {
|
KnowledgeApi.getKnowledgeList('default', paginationConfig, params, loading).then((res) => {
|
||||||
datasetFolderList.value = res.data?.folders
|
|
||||||
paginationConfig.total = res.data.total
|
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) {
|
function folderClickHandel(row: any) {
|
||||||
currentFolder.value = row
|
currentFolder.value = row
|
||||||
datasetFolderList.value = []
|
datasetList.value = []
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,9 +46,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<el-row v-if="toolFolderList.length > 0 || toolList.length > 0" :gutter="15">
|
<el-row v-if="toolList.length > 0" :gutter="15">
|
||||||
<template v-for="(item, index) in toolFolderList" :key="index">
|
<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-if="item.resource_type === 'folder'"
|
||||||
|
:xs="24"
|
||||||
|
:sm="12"
|
||||||
|
:md="12"
|
||||||
|
:lg="8"
|
||||||
|
:xl="6"
|
||||||
|
class="mb-16"
|
||||||
|
>
|
||||||
<CardBox
|
<CardBox
|
||||||
:title="item.name"
|
:title="item.name"
|
||||||
:description="item.desc || $t('common.noData')"
|
:description="item.desc || $t('common.noData')"
|
||||||
@ -66,10 +74,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
<el-col v-else :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
||||||
|
|
||||||
<template v-for="(item, index) in toolList" :key="index">
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
|
|
||||||
<CardBox :title="item.name" :description="item.desc" class="cursor">
|
<CardBox :title="item.name" :description="item.desc" class="cursor">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-avatar
|
<el-avatar
|
||||||
@ -212,7 +217,6 @@ const paginationConfig = reactive({
|
|||||||
|
|
||||||
const folderList = ref<any[]>([])
|
const folderList = ref<any[]>([])
|
||||||
const toolList = ref<any[]>([])
|
const toolList = ref<any[]>([])
|
||||||
const toolFolderList = ref<any[]>([])
|
|
||||||
const currentFolder = ref<any>({})
|
const currentFolder = ref<any>({})
|
||||||
|
|
||||||
const search_type_change = () => {
|
const search_type_change = () => {
|
||||||
@ -247,9 +251,8 @@ function getList() {
|
|||||||
tool_type: 'CUSTOM',
|
tool_type: 'CUSTOM',
|
||||||
}
|
}
|
||||||
ToolApi.getToolList('default', paginationConfig, params, loading).then((res) => {
|
ToolApi.getToolList('default', paginationConfig, params, loading).then((res) => {
|
||||||
toolFolderList.value = res.data?.folders
|
paginationConfig.total = res.data?.total
|
||||||
paginationConfig.total = res.data?.tools.total
|
toolList.value = [...toolList.value, ...res.data?.records]
|
||||||
toolList.value = [...toolList.value, ...res.data?.tools.records]
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user