refactor: 模型设置支持配置参数

This commit is contained in:
CaptainB 2024-10-12 17:17:06 +08:00 committed by shaohuzhang1
parent 05c40c3ea6
commit 54695eff98
9 changed files with 364 additions and 18 deletions

View File

@ -22,7 +22,9 @@
</slot>
</div>
<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">
<slot name="footer" />
</div>
@ -52,12 +54,21 @@ const props = withDefaults(
)
const show = ref(false)
// carddropdown
const subHovered = ref(false)
function cardEnter() {
show.value = true
subHovered.value = false
}
function cardLeave() {
show.value = false
show.value = subHovered.value;
}
function subHoveredEnter() {
subHovered.value = true
}
</script>
<style lang="scss" scoped>
.card-box {

View File

@ -38,13 +38,20 @@
</el-form>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onMounted, ref } from 'vue'
import type { FormInstance } from 'element-plus'
const props = defineProps<{
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const ruleFormRef = ref<FormInstance>()
const input_type_list = [
{ label: '文本框', value: 'TextInputConstructor' },
{ label: '滑块', value: 'SliderConstructor' },
{label: '开关',value:'SwitchInputConstructor'}
{ label: '开关', value: 'SwitchInputConstructor' },
{ label: '单选框', value: 'SingleSelectConstructor' }
]
const componentFormRef = ref<any>()
const form_data = ref<any>({
@ -78,12 +85,41 @@ const getData = () => {
...componentFormRef.value.getData()
}
}
const resetFields = () => {
console.log(123)
form_data.value = {
label: '',
field: '',
tooltip: '',
required: false,
input_type: ''
}
}
const validate = () => {
if (ruleFormRef.value) {
return ruleFormRef.value?.validate()
}
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>
<style lang="scss"></style>

View File

@ -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>

View File

@ -60,11 +60,11 @@ const getData = () => {
}
defineExpose({ getData })
onBeforeMount(() => {
formValue.value.min = 0
formValue.value.max = 20
formValue.value.step = 0.1
formValue.value.precision = 1
formValue.value.default_value = 1
formValue.value.min = props.modelValue.attrs?.min || 0
formValue.value.max = props.modelValue.attrs?.max || 20
formValue.value.step = props.modelValue.attrs?.step || 0.1
formValue.value.precision = props.modelValue.attrs?.precision || 1
formValue.value.default_value = props.modelValue.default_value || 1
})
</script>
<style lang="scss"></style>

View File

@ -33,7 +33,7 @@ const getData = () => {
}
defineExpose({ getData })
onMounted(() => {
formValue.value.default_value = false
formValue.value.default_value = formValue.value.default_value || false
})
</script>
<style lang="scss"></style>

View File

@ -50,9 +50,10 @@ const getData = () => {
}
defineExpose({ getData })
onMounted(() => {
formValue.value.min_length = 0
formValue.value.max_length = 20
formValue.value.default_value = ''
formValue.value.required = props.modelValue.required
formValue.value.min_length = props.modelValue.attrs?.min_length || 0
formValue.value.max_length = props.modelValue.attrs?.max_length || 20
formValue.value.default_value = props.modelValue.default_value || ''
})
</script>
<style lang="scss"></style>

View 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>

View File

@ -87,14 +87,25 @@
</el-icon>
</el-button>
</el-tooltip>
<el-tooltip effect="dark" content="删除" placement="top">
<el-button :disabled="!is_permisstion" text @click.stop="deleteModel">
<el-icon><Delete /></el-icon>
<el-dropdown trigger="click">
<el-button text @click.stop>
<el-icon><MoreFilled /></el-icon>
</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>
</template>
<EditModel ref="editModelRef" @submit="emit('change')"></EditModel>
<ParamSettingDialog ref="paramSettingRef"/>
</card-box>
</template>
<script setup lang="ts">
@ -106,6 +117,8 @@ import DownloadLoading from '@/components/loading/DownloadLoading.vue'
import { MsgConfirm } from '@/utils/message'
import { modelType } from '@/enums/model'
import useStore from '@/stores'
import ParamSettingDialog from './ParamSettingDialog.vue'
const props = defineProps<{
model: Model
provider_list: Array<Provider>
@ -193,6 +206,13 @@ const closeInterval = () => {
clearInterval(interval)
}
}
const paramSettingRef = ref<InstanceType<typeof ParamSettingDialog>>()
const openParamSetting = () => {
paramSettingRef.value?.open(props.model)
}
onMounted(() => {
initInterval()
})

View 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>