index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <template>
  2. <el-dialog
  3. v-model="dialogVisible"
  4. :close-on-click-modal="false"
  5. :title="parameter.title"
  6. :destroy-on-close="true"
  7. :width="parameter.width"
  8. :top="parameter.top"
  9. :before-close="handleClose"
  10. draggable
  11. >
  12. <ProFrom ref="proFormRef" :items-options="parameter.itemsOptions" :form-options="_options" :model="parameter.model">
  13. <template #modelAddress="{}">
  14. <FileUpload :file-size="4096" :file-type="['pt']" @update:model-value="setModelAddr" />
  15. </template>
  16. </ProFrom>
  17. <template #footer>
  18. <span class="dialog-footer">
  19. <el-button type="primary" v-if="parameter.isEdit" :loading="butLoading" @click="handleSubmit">确认</el-button>
  20. <el-button @click="handleCancel">取消</el-button>
  21. </span>
  22. </template>
  23. </el-dialog>
  24. </template>
  25. <script setup lang="ts" name="FormDialog">
  26. import { ref, ComputedRef, computed, reactive } from 'vue'
  27. import ProFrom from '@/components/ProForm/index.vue'
  28. import { ElMessage } from 'element-plus'
  29. import FileUpload from '@/components/Upload/File.vue'
  30. // import mittBus from '@/utils/mittBus'
  31. interface EmitEvent {
  32. (e: 'update'): void
  33. }
  34. const emits = defineEmits<EmitEvent>()
  35. const videoUploadRef = ref<InstanceType<typeof FileUpload> | null>(null)
  36. export interface FormParameterProps {
  37. title: string // 标题
  38. width?: number // 弹框宽度
  39. labelWidth?: number // label宽度
  40. api?: (params: any) => Promise<any> // 表单提交api
  41. isEdit?: boolean // 是否编辑
  42. top?: string // 离顶部距离
  43. formOptions?: ProForm.FormOptions // 表单配置
  44. itemsOptions: ProForm.ItemsOptions[] // 动态表单字段配置
  45. model?: Record<ProForm.FormItem['prop'], ProForm.FormItem['value']> // 表单数据对象
  46. getTableList?: () => void // 获取表格数据的Api
  47. }
  48. // dialog状态
  49. const dialogVisible = ref(false)
  50. const butLoading = ref(false)
  51. // 父组件传过来的参数
  52. const parameter = ref<FormParameterProps>({
  53. title: '',
  54. width: 500,
  55. top: '10vh',
  56. itemsOptions: [],
  57. formOptions: {},
  58. isEdit: true
  59. })
  60. const _options: ComputedRef<ProForm.FormOptions> = computed(() => {
  61. const form = {
  62. labelWidth: 120,
  63. hasFooter: false,
  64. disabled: false
  65. }
  66. return Object.assign(form, parameter.value.formOptions)
  67. })
  68. const modelAddr = ref(null)
  69. const setModelAddr = res => {
  70. //console.log("setModelAddr res:")
  71. console.log(res)
  72. modelAddr.value = res
  73. }
  74. //属性选择逻辑
  75. const mergeWithCondition = (formModel, parameterModel) => {
  76. const result = {}
  77. // 获取所有可能的属性名
  78. const allKeys = new Set([...Object.keys(formModel), ...Object.keys(parameterModel)])
  79. allKeys.forEach(key => {
  80. // 检查 formModel 中的属性值
  81. if (formModel.hasOwnProperty(key) && formModel[key] !== null && formModel[key] !== '' && formModel[key] !== undefined) {
  82. result[key] = formModel[key]
  83. } else {
  84. // 使用 parameterModel 中的属性值
  85. result[key] = parameterModel[key]
  86. }
  87. })
  88. return result
  89. }
  90. const isFloat = str => {
  91. // 正则表达式匹配浮点数
  92. const floatRegex = /^-?\d+(\.\d+)?$/
  93. // 使用正则表达式测试字符串
  94. return floatRegex.test(str)
  95. }
  96. const proFormRef = ref<InstanceType<typeof ProFrom> | null>(null)
  97. // 表单提交校验
  98. const handleSubmit = () => {
  99. const formEl = proFormRef.value?.proFormRef
  100. const formModel = proFormRef.value?.formModel
  101. formModel.modelAddress = modelAddr.value
  102. //console.log('formModel', formModel)
  103. butLoading.value = true
  104. if (!formEl) return
  105. formEl.validate(valid => {
  106. if (valid) {
  107. let data = {}
  108. if (algorithmModelId.value) {
  109. data = { ...formModel, ...parameter.value.model, algorithmId: algorithmModelId.value }
  110. } else {
  111. // data = { ...formModel, ...parameter.value.model }
  112. data = mergeWithCondition(formModel, parameter.value.model)
  113. }
  114. let excludedKeys = ['name', 'taskType', 'inputOssId', 'remarks', 'modelAddress']
  115. for (let key in data) {
  116. if (data.hasOwnProperty(key) && !excludedKeys.includes(key)) {
  117. if (!isFloat(data[key])) {
  118. ElMessage.error(key + '参数设置不合理!')
  119. butLoading.value = false
  120. return
  121. } else {
  122. let num = parseFloat(data[key])
  123. if (key == 's_v' && Number.isInteger(num) && num % 2 == 0) {
  124. ElMessage.error(key + '参数只能为奇数!')
  125. butLoading.value = false
  126. return
  127. }
  128. }
  129. }
  130. }
  131. // 使用 Object.fromEntries 从指定的键值对创建新的对象
  132. let hyperparameters = Object.fromEntries(Object.entries(data).filter(([key, _]) => !excludedKeys.includes(key)))
  133. // 将 hyperparameters 对象转换为 JSON 字符串
  134. let hyperparameterConfigurationStr = JSON.stringify(hyperparameters)
  135. // 向 data 对象中新增 hyperparameterConfiguration 属性
  136. data.hyperparameterConfiguration = hyperparameterConfigurationStr
  137. // 删除 modelAddress 属性,如果它存在
  138. if (data.hasOwnProperty('modelAddress')) {
  139. delete data.modelAddress
  140. }
  141. // console.log(data)
  142. parameter.value.api!(data).then(res => {
  143. if (res.code == 200) {
  144. proFormRef.value?.resetForm(formEl)
  145. ElMessage.success('操作成功')
  146. emits('update')
  147. setItemsOptions()
  148. parameter.value.model = {}
  149. dialogVisible.value = false
  150. parameter.value.getTableList && parameter.value.getTableList()
  151. } else {
  152. //console.log('message', res.message)
  153. }
  154. })
  155. butLoading.value = false
  156. }
  157. butLoading.value = false
  158. })
  159. }
  160. // mittBus.on('data:fileName', (fileName: string) => {
  161. // if (fileName !== undefined && fileName !== null) {
  162. // console.log(proFormRef.value?.formModel)
  163. // if(proFormRef.value?.formModel){
  164. // proFormRef.value.formModel.name = fileName.split('.')[0]
  165. // }
  166. // }
  167. // })
  168. // 取消按钮,重置表单,关闭弹框
  169. const setItemsOptions = () => {
  170. if (parameter.value.itemsOptions.length > 4) {
  171. parameter.value.itemsOptions.splice(4) //取消和确认后需要重新设置itemOptions
  172. }
  173. }
  174. const handleClose = () => {
  175. parameter.value.model = {}
  176. dialogVisible.value = false
  177. setItemsOptions()
  178. }
  179. const handleCancel = () => {
  180. //console.log(parameter.value.model)
  181. parameter.value.model = {}
  182. setItemsOptions()
  183. const formEl = proFormRef.value?.proFormRef
  184. if (!formEl) return
  185. if (parameter.value.model?.url) {
  186. ElMessage.info('请先删除已经上传的图片')
  187. return
  188. }
  189. proFormRef.value?.resetForm(formEl)
  190. butLoading.value = false
  191. dialogVisible.value = false
  192. }
  193. let algorithmModelId = ref(0)
  194. // 接收父组件参数
  195. const openDialog = (params: FormParameterProps, algoModelId = null) => {
  196. algorithmModelId.value = algoModelId
  197. parameter.value = { ...parameter.value, ...params }
  198. _options.value.disabled = !parameter.value.isEdit
  199. butLoading.value = false
  200. dialogVisible.value = true
  201. }
  202. defineExpose({
  203. openDialog
  204. })
  205. </script>
  206. <style scoped>
  207. .upload-video-box {
  208. display: flex;
  209. align-items: center;
  210. justify-content: center;
  211. width: 100%;
  212. height: 200px;
  213. margin-top: 20px;
  214. border: 1px dashed #cccccc;
  215. :deep(.upload-file-uploader) {
  216. display: flex;
  217. align-items: center;
  218. justify-content: center;
  219. width: 100%;
  220. height: 100%;
  221. font-size: 18px;
  222. text-align: center;
  223. cursor: pointer;
  224. }
  225. }
  226. </style>