refactor: 模型设置支持配置参数
This commit is contained in:
parent
05c40c3ea6
commit
54695eff98
@ -22,7 +22,9 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<slot />
|
<slot />
|
||||||
<slot name="mouseEnter" v-if="$slots.mouseEnter && show" />
|
<div @mouseenter="subHoveredEnter">
|
||||||
|
<slot name="mouseEnter" v-if="$slots.mouseEnter && show" />
|
||||||
|
</div>
|
||||||
<div class="card-footer" v-if="$slots.footer">
|
<div class="card-footer" v-if="$slots.footer">
|
||||||
<slot name="footer" />
|
<slot name="footer" />
|
||||||
</div>
|
</div>
|
||||||
@ -52,12 +54,21 @@ const props = withDefaults(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
|
// card上面存在dropdown菜单
|
||||||
|
const subHovered = ref(false)
|
||||||
function cardEnter() {
|
function cardEnter() {
|
||||||
show.value = true
|
show.value = true
|
||||||
|
subHovered.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function cardLeave() {
|
function cardLeave() {
|
||||||
show.value = false
|
show.value = subHovered.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function subHoveredEnter() {
|
||||||
|
subHovered.value = true
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.card-box {
|
.card-box {
|
||||||
|
|||||||
@ -38,13 +38,20 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: any
|
||||||
|
}>()
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const ruleFormRef = ref<FormInstance>()
|
const ruleFormRef = ref<FormInstance>()
|
||||||
const input_type_list = [
|
const input_type_list = [
|
||||||
{ label: '文本框', value: 'TextInputConstructor' },
|
{ label: '文本框', value: 'TextInputConstructor' },
|
||||||
{ label: '滑块', value: 'SliderConstructor' },
|
{ label: '滑块', value: 'SliderConstructor' },
|
||||||
{label: '开关',value:'SwitchInputConstructor'}
|
{ label: '开关', value: 'SwitchInputConstructor' },
|
||||||
|
{ label: '单选框', value: 'SingleSelectConstructor' }
|
||||||
]
|
]
|
||||||
const componentFormRef = ref<any>()
|
const componentFormRef = ref<any>()
|
||||||
const form_data = ref<any>({
|
const form_data = ref<any>({
|
||||||
@ -78,12 +85,41 @@ const getData = () => {
|
|||||||
...componentFormRef.value.getData()
|
...componentFormRef.value.getData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resetFields = () => {
|
||||||
|
console.log(123)
|
||||||
|
form_data.value = {
|
||||||
|
label: '',
|
||||||
|
field: '',
|
||||||
|
tooltip: '',
|
||||||
|
required: false,
|
||||||
|
input_type: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
if (ruleFormRef.value) {
|
if (ruleFormRef.value) {
|
||||||
return ruleFormRef.value?.validate()
|
return ruleFormRef.value?.validate()
|
||||||
}
|
}
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
defineExpose({ getData, validate })
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.modelValue) {
|
||||||
|
const data = props.modelValue
|
||||||
|
// console.log(data)
|
||||||
|
form_data.value = data
|
||||||
|
// 处理option
|
||||||
|
form_data.value.input_type = data.input_type + 'Constructor'
|
||||||
|
if (data.label && data.label.input_type === 'TooltipLabel') {
|
||||||
|
form_data.value.tooltip = data.label.attrs.tooltip
|
||||||
|
form_data.value.label = data.label.label
|
||||||
|
} else {
|
||||||
|
form_data.value.label = data.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
defineExpose({ getData, resetFields, validate })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<el-form-item>
|
||||||
|
<template #label>
|
||||||
|
<div class="flex-between">
|
||||||
|
选项值
|
||||||
|
<el-button link type="primary" @click.stop="addOption()">
|
||||||
|
<el-icon class="mr-4">
|
||||||
|
<Plus />
|
||||||
|
</el-icon>
|
||||||
|
添加
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="w-full flex-between mb-8"
|
||||||
|
v-for="(option, $index) in formValue.optionList"
|
||||||
|
:key="$index"
|
||||||
|
>
|
||||||
|
<el-input v-model="formValue.optionList[$index]" placeholder="请输入选项值" />
|
||||||
|
<el-button link class="ml-8" @click.stop="delOption($index)">
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
label="默认值"
|
||||||
|
:required="formValue.required"
|
||||||
|
prop="default_value"
|
||||||
|
:rules="formValue.required ? [{ required: true, message: '默认值 为必填属性' }] : []"
|
||||||
|
>
|
||||||
|
<el-select v-model="formValue.default_value">
|
||||||
|
<el-option v-for="(option, index) in formValue.optionList" :key="index" :label="option" :value="option" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, onMounted } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: any
|
||||||
|
}>()
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const formValue = computed({
|
||||||
|
set: (item) => {
|
||||||
|
emit('update:modelValue', item)
|
||||||
|
},
|
||||||
|
get: () => {
|
||||||
|
return props.modelValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const addOption = () => {
|
||||||
|
formValue.value.optionList.push('')
|
||||||
|
}
|
||||||
|
|
||||||
|
const delOption = (index: number) => {
|
||||||
|
formValue.value.optionList.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
return {
|
||||||
|
input_type: 'SingleSelect',
|
||||||
|
attrs: {},
|
||||||
|
default_value: formValue.value.default_value,
|
||||||
|
optionList: formValue.value.optionList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ getData })
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('props.modelValue', props.modelValue)
|
||||||
|
formValue.value.optionList = props.modelValue.optionList || []
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss"></style>
|
||||||
@ -60,11 +60,11 @@ const getData = () => {
|
|||||||
}
|
}
|
||||||
defineExpose({ getData })
|
defineExpose({ getData })
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
formValue.value.min = 0
|
formValue.value.min = props.modelValue.attrs?.min || 0
|
||||||
formValue.value.max = 20
|
formValue.value.max = props.modelValue.attrs?.max || 20
|
||||||
formValue.value.step = 0.1
|
formValue.value.step = props.modelValue.attrs?.step || 0.1
|
||||||
formValue.value.precision = 1
|
formValue.value.precision = props.modelValue.attrs?.precision || 1
|
||||||
formValue.value.default_value = 1
|
formValue.value.default_value = props.modelValue.default_value || 1
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@ -33,7 +33,7 @@ const getData = () => {
|
|||||||
}
|
}
|
||||||
defineExpose({ getData })
|
defineExpose({ getData })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
formValue.value.default_value = false
|
formValue.value.default_value = formValue.value.default_value || false
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@ -50,9 +50,10 @@ const getData = () => {
|
|||||||
}
|
}
|
||||||
defineExpose({ getData })
|
defineExpose({ getData })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
formValue.value.min_length = 0
|
formValue.value.required = props.modelValue.required
|
||||||
formValue.value.max_length = 20
|
formValue.value.min_length = props.modelValue.attrs?.min_length || 0
|
||||||
formValue.value.default_value = ''
|
formValue.value.max_length = props.modelValue.attrs?.max_length || 20
|
||||||
|
formValue.value.default_value = props.modelValue.default_value || ''
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
75
ui/src/views/template/component/AddParamDrawer.vue
Normal file
75
ui/src/views/template/component/AddParamDrawer.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="drawer" :direction="direction" size="600" :destroy-on-close="true" :before-close="cancelClick">
|
||||||
|
<template #header>
|
||||||
|
<h4>{{ isEdit ? '编辑参数' : '添加参数' }}</h4>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<DynamicsFormConstructor
|
||||||
|
v-model="currentItem"
|
||||||
|
label-position="top"
|
||||||
|
require-asterisk-position="right"
|
||||||
|
ref="DynamicsFormConstructorRef"
|
||||||
|
></DynamicsFormConstructor>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<div style="flex: auto">
|
||||||
|
<el-button @click="cancelClick">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmClick()">{{ isEdit ? '保存' : '添加' }}</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import type { DrawerProps } from 'element-plus'
|
||||||
|
import { cloneDeep } from 'lodash'
|
||||||
|
import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue'
|
||||||
|
|
||||||
|
const drawer = ref(false)
|
||||||
|
const direction = ref<DrawerProps['direction']>('rtl')
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const DynamicsFormConstructorRef = ref<InstanceType<typeof DynamicsFormConstructor>>()
|
||||||
|
|
||||||
|
const currentItem = ref(null)
|
||||||
|
const currentIndex = ref(null)
|
||||||
|
|
||||||
|
const emit = defineEmits(['refresh'])
|
||||||
|
|
||||||
|
const open = (row: any, index: any) => {
|
||||||
|
// console.log(row, index)
|
||||||
|
if (row) {
|
||||||
|
currentItem.value = cloneDeep(row)
|
||||||
|
currentIndex.value = index
|
||||||
|
isEdit.value = true
|
||||||
|
}
|
||||||
|
drawer.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelClick() {
|
||||||
|
drawer.value = false
|
||||||
|
isEdit.value = false
|
||||||
|
currentItem.value = null
|
||||||
|
currentIndex.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmClick() {
|
||||||
|
const formEl = DynamicsFormConstructorRef.value
|
||||||
|
formEl?.validate().then((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
drawer.value = false
|
||||||
|
isEdit.value = false
|
||||||
|
currentItem.value = null
|
||||||
|
emit('refresh', formEl?.getData(), currentIndex.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -87,14 +87,25 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip effect="dark" content="删除" placement="top">
|
<el-dropdown trigger="click">
|
||||||
<el-button :disabled="!is_permisstion" text @click.stop="deleteModel">
|
<el-button text @click.stop>
|
||||||
<el-icon><Delete /></el-icon>
|
<el-icon><MoreFilled /></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item icon="Setting" @click.stop="openParamSetting">
|
||||||
|
模型参数设置
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item icon="Delete" :disabled="!is_permisstion" text @click.stop="deleteModel">
|
||||||
|
删除
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<EditModel ref="editModelRef" @submit="emit('change')"></EditModel>
|
<EditModel ref="editModelRef" @submit="emit('change')"></EditModel>
|
||||||
|
<ParamSettingDialog ref="paramSettingRef"/>
|
||||||
</card-box>
|
</card-box>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -106,6 +117,8 @@ import DownloadLoading from '@/components/loading/DownloadLoading.vue'
|
|||||||
import { MsgConfirm } from '@/utils/message'
|
import { MsgConfirm } from '@/utils/message'
|
||||||
import { modelType } from '@/enums/model'
|
import { modelType } from '@/enums/model'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
|
import ParamSettingDialog from './ParamSettingDialog.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
model: Model
|
model: Model
|
||||||
provider_list: Array<Provider>
|
provider_list: Array<Provider>
|
||||||
@ -193,6 +206,13 @@ const closeInterval = () => {
|
|||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const paramSettingRef = ref<InstanceType<typeof ParamSettingDialog>>()
|
||||||
|
const openParamSetting = () => {
|
||||||
|
paramSettingRef.value?.open(props.model)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initInterval()
|
initInterval()
|
||||||
})
|
})
|
||||||
|
|||||||
124
ui/src/views/template/component/ParamSettingDialog.vue
Normal file
124
ui/src/views/template/component/ParamSettingDialog.vue
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
title="模型参数设置"
|
||||||
|
v-model="dialogVisible"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
:before-close="close"
|
||||||
|
>
|
||||||
|
<el-button type="primary" @click="openAddDrawer()" class="mb-12">
|
||||||
|
添加参数
|
||||||
|
</el-button>
|
||||||
|
<el-table
|
||||||
|
:data="modelParams"
|
||||||
|
class="mb-16"
|
||||||
|
>
|
||||||
|
<el-table-column prop="label" label="参数">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span v-if="row.label && row.label.input_type === 'TooltipLabel'">{{ row.label.label }}</span>
|
||||||
|
<span v-else>{{ row.label }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="field" label="显示名称" />
|
||||||
|
<el-table-column label="组件类型">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">文本框</el-tag>
|
||||||
|
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">滑块</el-tag>
|
||||||
|
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SwitchInput'">开关</el-tag>
|
||||||
|
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SingleSelect'">单选框</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="default_value" label="默认值" />
|
||||||
|
<el-table-column label="必填">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div @click.stop>
|
||||||
|
<el-switch disabled size="small" v-model="row.required" />
|
||||||
|
</div>
|
||||||
|
</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="openAddDrawer(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="deleteParam($index)">
|
||||||
|
<el-icon>
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submit" :loading="loading"> 保存 </el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<AddParamDrawer ref="AddParamRef" @refresh="refresh" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Model } from '@/api/type/model'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import AddParamDrawer from './AddParamDrawer.vue'
|
||||||
|
import { MsgError } from '@/utils/message'
|
||||||
|
|
||||||
|
const loading = ref<boolean>(false)
|
||||||
|
const dialogVisible = ref<boolean>(false)
|
||||||
|
const modelParams = ref<any[]>([])
|
||||||
|
const AddParamRef = ref()
|
||||||
|
|
||||||
|
const open = (model: Model) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function openAddDrawer(data?: any, index?: any) {
|
||||||
|
AddParamRef.value?.open(data, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteParam(index: any) {
|
||||||
|
modelParams.value.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh(data: any, index: any) {
|
||||||
|
// console.log(data, index)
|
||||||
|
for (let i = 0; i < modelParams.value.length; i++) {
|
||||||
|
if (modelParams.value[i].field === data.field && index !== i) {
|
||||||
|
MsgError('变量已存在: ' + data.field)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index !== null) {
|
||||||
|
modelParams.value.splice(index, 1, data)
|
||||||
|
} else {
|
||||||
|
modelParams.value.push(data)
|
||||||
|
}
|
||||||
|
console.log(modelParams.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
console.log('submit')
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open, close })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user