318 lines
9.4 KiB
Vue
318 lines
9.4 KiB
Vue
<template>
|
|
<el-drawer v-model="visible" size="60%" :before-close="close">
|
|
<template #header>
|
|
<h4>{{ title }}</h4>
|
|
</template>
|
|
<div>
|
|
<h4 class="title-decoration-1 mb-16">基础信息</h4>
|
|
<el-form
|
|
ref="FormRef"
|
|
:model="form"
|
|
:rules="rules"
|
|
label-position="top"
|
|
require-asterisk-position="right"
|
|
v-loading="loading"
|
|
>
|
|
<el-form-item label="函数名称" prop="name">
|
|
<el-input
|
|
v-model="form.name"
|
|
placeholder="请输入函数名称"
|
|
maxlength="64"
|
|
show-word-limit
|
|
@blur="form.name = form.name?.trim()"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="描述">
|
|
<el-input
|
|
v-model="form.desc"
|
|
type="textarea"
|
|
placeholder="请输入函数的描述"
|
|
maxlength="128"
|
|
show-word-limit
|
|
:autosize="{ minRows: 3 }"
|
|
@blur="form.desc = form.desc?.trim()"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item prop="permission_type">
|
|
<template #label>
|
|
<span>权限</span>
|
|
</template>
|
|
|
|
<el-radio-group v-model="form.permission_type" class="card__radio">
|
|
<el-row :gutter="16">
|
|
<template v-for="(value, key) of PermissionType" :key="key">
|
|
<el-col :span="12">
|
|
<el-card
|
|
shadow="never"
|
|
class="mb-16"
|
|
:class="form.permission_type === key ? 'active' : ''"
|
|
>
|
|
<el-radio :value="key" size="large">
|
|
<p class="mb-4">{{ value }}</p>
|
|
<el-text type="info">
|
|
{{ PermissionDesc[key] }}
|
|
</el-text>
|
|
</el-radio>
|
|
</el-card>
|
|
</el-col>
|
|
</template>
|
|
</el-row>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div class="flex-between">
|
|
<h4 class="title-decoration-1 mb-16">
|
|
输入参数 <el-text type="info" class="color-secondary"> 使用函数时显示 </el-text>
|
|
</h4>
|
|
<el-button link type="primary" @click="openAddDialog()">
|
|
<el-icon class="mr-4"><Plus /></el-icon> 添加
|
|
</el-button>
|
|
</div>
|
|
|
|
<el-table :data="form.input_field_list" class="mb-16">
|
|
<el-table-column prop="name" label="参数名" />
|
|
<el-table-column label="数据类型">
|
|
<template #default="{ row }">
|
|
<el-tag type="info" class="info-tag">{{ row.type }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="必填">
|
|
<template #default="{ row }">
|
|
<div @click.stop>
|
|
<el-switch size="small" v-model="row.is_required" />
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="source" label="来源">
|
|
<template #default="{ row }">
|
|
{{ row.source === 'custom' ? '自定义' : '引用参数' }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作" align="left" width="80">
|
|
<template #default="{ row, $index }">
|
|
<span class="mr-4">
|
|
<el-tooltip effect="dark" content="修改" placement="top">
|
|
<el-button type="primary" text @click.stop="openAddDialog(row, $index)">
|
|
<el-icon><EditPen /></el-icon>
|
|
</el-button>
|
|
</el-tooltip>
|
|
</span>
|
|
<el-tooltip effect="dark" content="删除" placement="top">
|
|
<el-button type="primary" text @click="deleteField($index)">
|
|
<el-icon>
|
|
<Delete />
|
|
</el-icon>
|
|
</el-button>
|
|
</el-tooltip>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<h4 class="title-decoration-1 mb-16">
|
|
Python 代码 <el-text type="info" class="color-secondary"> 使用函数时不显示 </el-text>
|
|
</h4>
|
|
|
|
<div class="function-CodemirrorEditor mb-8" v-if="showEditor">
|
|
<CodemirrorEditor v-model="form.code" />
|
|
<div class="function-CodemirrorEditor__footer">
|
|
<el-button text type="info" @click="openCodemirrorDialog" class="magnify">
|
|
<AppIcon iconName="app-magnify" style="font-size: 16px"></AppIcon>
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
<h4 class="title-decoration-1 mb-16 mt-16">
|
|
输出参数 <el-text type="info" class="color-secondary"> 使用函数时显示 </el-text>
|
|
</h4>
|
|
<div class="flex-between border-r-4 p-8-12 mb-8 layout-bg lighter">
|
|
<span>结果 {result}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<template #footer>
|
|
<div>
|
|
<el-button :loading="loading" @click="visible = false">取消</el-button>
|
|
<el-button :loading="loading" @click="openDebug">调试</el-button>
|
|
<el-button type="primary" @click="submit(FormRef)" :loading="loading">
|
|
{{ isEdit ? '保存' : '创建' }}</el-button
|
|
>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Codemirror 弹出层 -->
|
|
<el-dialog v-model="dialogVisible" title="Python 代码" append-to-body fullscreen>
|
|
<CodemirrorEditor
|
|
v-model="cloneContent"
|
|
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"> 确认</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
<FunctionDebugDrawer ref="FunctionDebugDrawerRef" />
|
|
<FieldFormDialog ref="FieldFormDialogRef" @refresh="refreshFieldList" />
|
|
</el-drawer>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive, watch } from 'vue'
|
|
import FieldFormDialog from './FieldFormDialog.vue'
|
|
import FunctionDebugDrawer from './FunctionDebugDrawer.vue'
|
|
import type { functionLibData } from '@/api/type/function-lib'
|
|
import functionLibApi from '@/api/function-lib'
|
|
import type { FormInstance } from 'element-plus'
|
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
|
import { cloneDeep } from 'lodash'
|
|
import { PermissionType, PermissionDesc } from '@/enums/model'
|
|
const props = defineProps({
|
|
title: String
|
|
})
|
|
|
|
const emit = defineEmits(['refresh'])
|
|
const FieldFormDialogRef = ref()
|
|
const FunctionDebugDrawerRef = ref()
|
|
|
|
const FormRef = ref()
|
|
|
|
const isEdit = ref(false)
|
|
const loading = ref(false)
|
|
const visible = ref(false)
|
|
const showEditor = ref(false)
|
|
const currentIndex = ref<any>(null)
|
|
|
|
const form = ref<functionLibData>({
|
|
name: '',
|
|
desc: '',
|
|
code: '',
|
|
input_field_list: [],
|
|
permission_type: 'PRIVATE'
|
|
})
|
|
|
|
const dialogVisible = ref(false)
|
|
const cloneContent = ref<any>('')
|
|
|
|
watch(visible, (bool) => {
|
|
if (!bool) {
|
|
isEdit.value = false
|
|
showEditor.value = false
|
|
currentIndex.value = null
|
|
form.value = {
|
|
name: '',
|
|
desc: '',
|
|
code: '',
|
|
input_field_list: [],
|
|
permission_type: 'PRIVATE'
|
|
}
|
|
}
|
|
})
|
|
|
|
const rules = reactive({
|
|
name: [{ required: true, message: '请输入函数名称', trigger: 'blur' }],
|
|
permission_type: [{ required: true, message: '请选择', trigger: 'change' }]
|
|
})
|
|
|
|
function openCodemirrorDialog() {
|
|
cloneContent.value = form.value.code
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
function submitDialog() {
|
|
form.value.code = cloneContent.value
|
|
dialogVisible.value = false
|
|
}
|
|
|
|
function close() {
|
|
if (isEdit.value || !areAllValuesNonEmpty(form.value)) {
|
|
visible.value = false
|
|
} else {
|
|
MsgConfirm(`提示`, `当前的更改尚未保存,确认退出吗?`, {
|
|
confirmButtonText: '确认',
|
|
type: 'warning'
|
|
})
|
|
.then(() => {
|
|
visible.value = false
|
|
})
|
|
.catch(() => {})
|
|
}
|
|
}
|
|
|
|
function areAllValuesNonEmpty(obj: any) {
|
|
return Object.values(obj).some((value) => {
|
|
return Array.isArray(value)
|
|
? value.length !== 0
|
|
: value !== null && value !== undefined && value !== ''
|
|
})
|
|
}
|
|
|
|
function openDebug() {
|
|
FunctionDebugDrawerRef.value.open(form.value)
|
|
}
|
|
|
|
function deleteField(index: any) {
|
|
form.value.input_field_list?.splice(index, 1)
|
|
}
|
|
|
|
function openAddDialog(data?: any, index?: any) {
|
|
if (typeof index !== 'undefined') {
|
|
currentIndex.value = index
|
|
}
|
|
|
|
FieldFormDialogRef.value.open(data)
|
|
}
|
|
|
|
function refreshFieldList(data: any) {
|
|
if (currentIndex.value !== null) {
|
|
form.value.input_field_list?.splice(currentIndex.value, 1, data)
|
|
} else {
|
|
form.value.input_field_list?.push(data)
|
|
}
|
|
currentIndex.value = null
|
|
}
|
|
|
|
const submit = async (formEl: FormInstance | undefined) => {
|
|
if (!formEl) return
|
|
await formEl.validate((valid: any) => {
|
|
if (valid) {
|
|
if (isEdit.value) {
|
|
functionLibApi.putFunctionLib(form.value?.id as string, form.value, loading).then((res) => {
|
|
MsgSuccess('编辑成功')
|
|
emit('refresh', res.data)
|
|
visible.value = false
|
|
})
|
|
} else {
|
|
functionLibApi.postFunctionLib(form.value, loading).then((res) => {
|
|
MsgSuccess('创建成功')
|
|
emit('refresh')
|
|
visible.value = false
|
|
})
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
const open = (data: any) => {
|
|
if (data) {
|
|
isEdit.value = data?.id ? true : false
|
|
form.value = cloneDeep(data)
|
|
}
|
|
visible.value = true
|
|
setTimeout(() => {
|
|
showEditor.value = true
|
|
}, 100)
|
|
}
|
|
|
|
defineExpose({
|
|
open
|
|
})
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.function-CodemirrorEditor__footer {
|
|
position: absolute;
|
|
bottom: 10px;
|
|
right: 10px;
|
|
}
|
|
.function-CodemirrorEditor {
|
|
position: relative;
|
|
}
|
|
</style>
|