Sfoglia il codice sorgente

feat: 超参配置

28968 8 mesi fa
parent
commit
c4ef837f6c

+ 218 - 0
src/components/DataAugmentationFormDialog/index.vue

@@ -0,0 +1,218 @@
+<template>
+  <el-dialog
+    v-model="dialogVisible"
+    :close-on-click-modal="false"
+    :title="parameter.title"
+    :destroy-on-close="true"
+    :width="parameter.width"
+    :top="parameter.top"
+    :before-close="handleClose"
+    draggable
+  >
+    <ProFrom ref="proFormRef" :items-options="parameter.itemsOptions" :form-options="_options" :model="parameter.model">
+      <template #modelAddress="{}">
+        <FileUpload :file-size="4096" :file-type="['pt']" @update:model-value="setModelAddr" />
+      </template>
+    </ProFrom>
+    <template #footer>
+      <span class="dialog-footer">
+        <el-button type="primary" v-if="parameter.isEdit" :loading="butLoading" @click="handleSubmit">确认</el-button>
+        <el-button @click="handleCancel">取消</el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts" name="FormDialog">
+import { ref, ComputedRef, computed, reactive } from 'vue'
+import ProFrom from '@/components/ProForm/index.vue'
+import { ElMessage } from 'element-plus'
+import FileUpload from '@/components/Upload/File.vue'
+
+// import mittBus from '@/utils/mittBus'
+
+interface EmitEvent {
+  (e: 'update'): void
+}
+
+const emits = defineEmits<EmitEvent>()
+
+const videoUploadRef = ref<InstanceType<typeof FileUpload> | null>(null)
+
+export interface FormParameterProps {
+  title: string // 标题
+  width?: number // 弹框宽度
+  labelWidth?: number // label宽度
+  api?: (params: any) => Promise<any> // 表单提交api
+  isEdit?: boolean // 是否编辑
+  top?: string // 离顶部距离
+  formOptions?: ProForm.FormOptions // 表单配置
+  itemsOptions: ProForm.ItemsOptions[] // 动态表单字段配置
+  model?: Record<ProForm.FormItem['prop'], ProForm.FormItem['value']> // 表单数据对象
+  getTableList?: () => void // 获取表格数据的Api
+}
+
+// dialog状态
+const dialogVisible = ref(false)
+const butLoading = ref(false)
+// 父组件传过来的参数
+const parameter = ref<FormParameterProps>({
+  title: '',
+  width: 500,
+  top: '10vh',
+  itemsOptions: [],
+  formOptions: {},
+  isEdit: true
+})
+const _options: ComputedRef<ProForm.FormOptions> = computed(() => {
+  const form = {
+    labelWidth: 120,
+    hasFooter: false,
+    disabled: false
+  }
+  return Object.assign(form, parameter.value.formOptions)
+})
+
+const modelAddr = ref(null)
+const setModelAddr = res => {
+  //console.log("setModelAddr res:")
+  console.log(res)
+  modelAddr.value = res
+}
+
+const proFormRef = ref<InstanceType<typeof ProFrom> | null>(null)
+// 表单提交校验
+const handleSubmit = () => {
+  const formEl = proFormRef.value?.proFormRef
+  const formModel = proFormRef.value?.formModel
+  formModel.modelAddress = modelAddr.value
+  //console.log('formModel', formModel)
+
+  butLoading.value = true
+  if (!formEl) return
+  formEl.validate(valid => {
+    if (valid) {
+      let data = {}
+      if (algorithmModelId.value) {
+        data = { ...formModel, ...parameter.value.model, algorithmId: algorithmModelId.value }
+      } else {
+        data = { ...formModel, ...parameter.value.model }
+      }
+
+      let excludedKeys = ['name', 'taskType', 'inputOssId', 'remarks', 'modelAddress']
+      for (const key in data) {
+        if (data.hasOwnProperty(key) && !excludedKeys.includes(key)) {
+          let num = parseFloat(data[key])
+          if (isNaN(num) || !isFinite(num)) {
+            ElMessage.error('${key}参数设置不合理!')
+            return
+          } else {
+            if (key == 's_v' && Number.isInteger(num) && num % 2 == 0) {
+              ElMessage.error('${key}参数只能为奇数!')
+              return
+            }
+          }
+        }
+      }
+      // 使用 Object.fromEntries 从指定的键值对创建新的对象
+      let hyperparameters = Object.fromEntries(Object.entries(data).filter(([key, _]) => !excludedKeys.includes(key)))
+
+      // 将 hyperparameters 对象转换为 JSON 字符串
+      let hyperparameterConfigurationStr = JSON.stringify(hyperparameters)
+
+      // 向 data 对象中新增 hyperparameterConfiguration 属性
+      data.hyperparameterConfiguration = hyperparameterConfigurationStr
+      // 删除 modelAddress 属性,如果它存在
+      if (data.hasOwnProperty('modelAddress')) {
+        delete data.modelAddress
+      }
+      console.log(data)
+      parameter.value.api!(data).then(res => {
+        if (res.code == 200) {
+          proFormRef.value?.resetForm(formEl)
+          ElMessage.success('操作成功')
+          emits('update')
+          setItemsOptions()
+          parameter.value.model = {}
+          dialogVisible.value = false
+          parameter.value.getTableList && parameter.value.getTableList()
+        } else {
+          //console.log('message', res.message)
+        }
+      })
+      butLoading.value = false
+    }
+    butLoading.value = false
+  })
+}
+// mittBus.on('data:fileName', (fileName: string) => {
+//   if (fileName !== undefined && fileName !== null) {
+//     console.log(proFormRef.value?.formModel)
+//     if(proFormRef.value?.formModel){
+//       proFormRef.value.formModel.name = fileName.split('.')[0]
+//     }
+//   }
+// })
+// 取消按钮,重置表单,关闭弹框
+const setItemsOptions = () => {
+  if (parameter.value.itemsOptions.length > 4) {
+    parameter.value.itemsOptions.splice(4) //取消和确认后需要重新设置itemOptions
+  }
+}
+const handleClose = () => {
+  parameter.value.model = {}
+  dialogVisible.value = false
+  setItemsOptions()
+}
+const handleCancel = () => {
+  //console.log(parameter.value.model)
+  parameter.value.model = {}
+  setItemsOptions()
+  const formEl = proFormRef.value?.proFormRef
+  if (!formEl) return
+  if (parameter.value.model?.url) {
+    ElMessage.info('请先删除已经上传的图片')
+    return
+  }
+  proFormRef.value?.resetForm(formEl)
+  butLoading.value = false
+  dialogVisible.value = false
+}
+
+let algorithmModelId = ref(0)
+
+// 接收父组件参数
+const openDialog = (params: FormParameterProps, algoModelId = null) => {
+  algorithmModelId.value = algoModelId
+  parameter.value = { ...parameter.value, ...params }
+  _options.value.disabled = !parameter.value.isEdit
+  butLoading.value = false
+  dialogVisible.value = true
+}
+
+defineExpose({
+  openDialog
+})
+</script>
+
+<style scoped>
+.upload-video-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 200px;
+  margin-top: 20px;
+  border: 1px dashed #cccccc;
+  :deep(.upload-file-uploader) {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 100%;
+    font-size: 18px;
+    text-align: center;
+    cursor: pointer;
+  }
+}
+</style>

+ 90 - 93
src/views/demo/dataAugmentation/index.vue

@@ -43,7 +43,7 @@
         </el-button>
       </template>
     </ProTable>
-    <FormDialog ref="formDialogRef" />
+    <DataAugmentationFormDialog ref="formDialogRef" />
     <ImportExcel ref="dialogRef" />
     <el-dialog v-model="dialogVisible" :title="dialogTitle" width="80%">
       <div class="image-dialog" v-if="imageIdx >= 0 && cacheImages[imageIdx]">
@@ -73,7 +73,7 @@ import { useDownload } from '@/hooks/useDownload'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import ProTable from '@/components/ProTable/index.vue'
 import ImportExcel from '@/components/ImportExcel/index.vue'
-import FormDialog from '@/components/FormDialog/index.vue'
+import DataAugmentationFormDialog from '@/components/DataAugmentationFormDialog/index.vue'
 import { ProTableInstance, ColumnProps, EnumProps } from '@/components/ProTable/interface'
 import {
   listDataAugmentationApi,
@@ -92,6 +92,7 @@ import {
 } from '@/api/modules/demo/dataAugmentation'
 import { listDataApi } from '@/api/modules/system/dictData'
 import { S } from 'vite/dist/node/types.d-aGj9QkWt'
+import { servicesVersion } from 'typescript'
 const dialogVisible = ref(false)
 const taskId = ref('')
 const imageIdx = ref(0)
@@ -283,18 +284,18 @@ const batchAdd = () => {
   dialogRef.value?.acceptParams(params)
 }
 
-const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
+const formDialogRef = ref<InstanceType<typeof DataAugmentationFormDialog> | null>(null)
 // 打开弹框的功能
 const openDialog = async (type: number, title: string, row?: any) => {
-  hyperparameter.value = ''
+  // hyperparameter.value = ''
   let res = { data: {} }
   if (row?.id) {
     res = await getDataAugmentationApi(row?.id || null)
-    hyperparameter.value = res.data?.hyperparameterConfiguration
+    // hyperparameter.value = res.data?.hyperparameterConfiguration
   }
-
+  // console.log(itemsOptions[1].compOptions?.value)
   // 重置表单
-  setItemsOptions()
+  // setItemsOptions()
   const params = {
     title,
     width: 580,
@@ -306,6 +307,7 @@ const openDialog = async (type: number, title: string, row?: any) => {
   }
   formDialogRef.value?.openDialog(params)
 }
+
 const statusEnums: EnumProps[] = [
   {
     label: '未开始',
@@ -374,25 +376,11 @@ const columns = reactive<ColumnProps<any>[]>([
   {
     prop: 'startTime',
     label: '开始时间',
-    // search: {
-    //   el: 'date-picker',
-    //   props: {
-    //     type: 'datetimerange',
-    //     valueFormat: 'YYYY-MM-DD HH:mm:ss'
-    //   }
-    // },
     width: 180
   },
   {
     prop: 'endTime',
     label: '结束时间',
-    // search: {
-    //   el: 'date-picker',
-    //   props: {
-    //     type: 'datetimerange',
-    //     valueFormat: 'YYYY-MM-DD HH:mm:ss'
-    //   }
-    // },
     width: 180
   },
   {
@@ -435,81 +423,90 @@ const columns = reactive<ColumnProps<any>[]>([
   }
 ])
 // 表单配置项
-let itemsOptions: ProForm.ItemsOptions[] = []
-const model = ref({})
-const setItemsOptions = () => {
-  itemsOptions = [
-    {
-      label: '任务名称',
-      prop: 'name',
-      rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
-      compOptions: {
-        placeholder: '请输入任务名称'
-      }
-    },
-    {
-      label: '任务类型',
-      prop: 'taskType',
-      rules: [{ required: true, message: '任务类型不能为空', trigger: 'change' }],
-      compOptions: {
-        elTagName: 'select', // 指定使用 el-select 组件
-        placeholder: '请选择任务类型',
-        enum: taskType,
-        onChange: (value: string) => {
-          hyperparameterConfiguration.forEach(obj => {
-            if (value in obj) {
-              hyperparameter.value = obj[value]
-              // console.log(obj)
-              model.value['hyperparameterConfiguration'] = obj[value]
-              // itemsOptions[3]['compOptions']['value'] = obj[value]
-              //itemsOptions[3].compOptions.onChange(obj[value])
-              // let change = itemsOptions[3]['compOptions']['onChange']
-              // change(obj[value])
-            }
-          })
-        }
-      }
-    },
-    {
-      label: '图片集压缩包',
-      prop: 'inputOssId',
-      rules: [{ required: true, message: '数据压缩包不能为空', trigger: 'change' }],
-      compOptions: {
-        elTagName: 'file-upload',
-        fileSize: 4096,
-        fileType: ['zip'],
-        placeholder: '请上传图片集压缩包'
-      }
-    },
-    {
-      label: '超参配置',
-      prop: 'hyperparameterConfiguration',
-      // rules: [{ required: true, message: '超参配置不能为空', trigger: 'blur' }],
-      rules: [{ required: false, trigger: 'blur' }],
-      compOptions: {
-        type: 'input',
-        clearable: true,
-        // placeholder: hyperparameter
-        value: hyperparameter,
-        onChange: (value: string) => {
-          hyperparameter.value = value
-        }
+let itemsOptions: ProForm.ItemsOptions[] = [
+  {
+    label: '任务名称',
+    prop: 'name',
+    rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
+    compOptions: {
+      placeholder: '请输入任务名称'
+    }
+  },
+  {
+    label: '任务类型',
+    prop: 'taskType',
+    rules: [{ required: true, message: '任务类型不能为空', trigger: 'change' }],
+    compOptions: {
+      elTagName: 'select', // 指定使用 el-select 组件
+      placeholder: '请选择任务类型',
+      enum: taskType,
+      onChange: (value: string) => {
+        model.value['taskType'] = value
+        hyperparameterConfiguration.forEach(obj => {
+          if (value in obj) {
+            // console.log(obj[value])
+            addParams(obj[value])
+            openDialog(1, '任务新增')
+          }
+        })
       }
-    },
-    {
-      label: '备注',
-      prop: 'remarks',
-      rules: [
-        {
-          required: false,
-          trigger: 'blur'
-        }
-      ],
-      compOptions: {
-        placeholder: '请输入备注'
+    }
+  },
+  {
+    label: '图片集压缩包',
+    prop: 'inputOssId',
+    rules: [{ required: true, message: '数据压缩包不能为空', trigger: 'change' }],
+    compOptions: {
+      elTagName: 'file-upload',
+      fileSize: 4096,
+      fileType: ['zip'],
+      placeholder: '请上传图片集压缩包'
+    }
+  },
+  {
+    label: '备注',
+    prop: 'remarks',
+    rules: [
+      {
+        required: false,
+        trigger: 'blur'
       }
+    ],
+    compOptions: {
+      placeholder: '请输入备注'
     }
-  ]
+  }
+]
+const model = ref({})
+const setItemsOptions = () => {
+  if (itemsOptions.length > 4) {
+    itemsOptions.splice(4) // 如果里面有新增参数,删除,重新添加
+  }
+}
+const addParams = params => {
+  setItemsOptions()
+  if (params == 'null') {
+    return
+  }
+  let validJsonString = params.replace(/'/g, '"')
+  try {
+    const obj: { [key: string]: number } = JSON.parse(validJsonString)
+    Object.keys(obj).forEach(key => {
+      // model.value[key] = obj[key]
+      itemsOptions.push({
+        label: key,
+        prop: key,
+        rules: [{ required: true, trigger: 'blur' }],
+        compOptions: {
+          type: 'input',
+          clearable: true,
+          placeholder: obj[key]
+        }
+      })
+    })
+  } catch (error) {
+    console.error('解析 JSON 字符串时出错:', error)
+  }
 }
 </script>