This is an automated email from the ASF dual-hosted git repository.

songjian pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 13b1ffe  [Feature][UI Next][V1.0.0-Alpha] Add the corresponding state 
for the … (#8870)
13b1ffe is described below

commit 13b1ffe12ac2d87262a6f0f2cf2bc082b945f47e
Author: Amy0104 <[email protected]>
AuthorDate: Mon Mar 14 20:17:18 2022 +0800

    [Feature][UI Next][V1.0.0-Alpha] Add the corresponding state for the … 
(#8870)
    
    * [Feature][UI Next][V1.0.0-Alpha] Add the corresponding state for the 
saving action.
    
    * [Feature][UI Next][V1.0.0-Alpha] Add the corresponding state for the 
saving action.
---
 .../src/views/datasource/list/use-detail.ts        |  40 +++---
 .../src/views/password/use-form.ts                 |   1 +
 .../src/views/profile/index.tsx                    |   1 +
 .../src/views/profile/use-form.ts                  |   1 +
 .../src/views/profile/use-update.ts                |  36 ++---
 .../projects/list/components/project-modal.tsx     |   1 +
 .../src/views/projects/list/components/use-form.ts |  25 +++-
 .../projects/task/components/node/detail-modal.tsx |   6 +-
 .../task/definition/components/move-modal.tsx      |   1 +
 .../task/definition/components/use-move.ts         |  25 ++--
 .../src/views/projects/task/definition/index.tsx   |   1 +
 .../src/views/projects/task/definition/use-task.ts |  35 ++---
 .../definition/components/import-modal.tsx         |   1 +
 .../workflow/definition/components/start-modal.tsx |   1 +
 .../definition/components/timing-modal.tsx         |   1 +
 .../workflow/definition/components/use-form.ts     |   7 +-
 .../workflow/definition/components/use-modal.ts    | 148 ++++++++++++---------
 .../src/views/resource/file/folder/index.tsx       |   1 +
 .../src/views/resource/file/folder/use-folder.ts   |  35 ++---
 .../src/views/resource/file/folder/use-form.ts     |   1 +
 .../src/views/resource/file/rename/index.tsx       |   1 +
 .../src/views/resource/file/rename/use-form.ts     |   1 +
 .../src/views/resource/file/rename/use-rename.ts   |  31 +++--
 .../src/views/resource/file/upload/index.tsx       |   1 +
 .../src/views/resource/file/upload/use-form.ts     |   1 +
 .../src/views/resource/file/upload/use-upload.ts   |  39 +++---
 .../task-group/option/components/form-modal.tsx    |  18 ++-
 .../views/resource/task-group/option/use-form.ts   |   1 +
 .../task-group/queue/components/form-modal.tsx     |  17 ++-
 .../views/resource/task-group/queue/use-form.ts    |   1 +
 .../udf/function/components/function-modal.tsx     |   1 +
 .../resource/udf/function/components/use-form.ts   |   1 +
 .../resource/udf/function/components/use-modal.ts  |  24 ++--
 .../udf/resource/components/folder-modal.tsx       |   1 +
 .../udf/resource/components/upload-modal.tsx       |   1 +
 .../resource/udf/resource/components/use-form.ts   |   2 +
 .../resource/udf/resource/components/use-modal.ts  |  64 +++++----
 .../components/alarm-group-modal.tsx               |   1 +
 .../alarm-group-manage/components/use-modal.ts     |  24 ++--
 .../security/alarm-instance-manage/use-detail.ts   |  44 +++---
 .../components/environment-modal.tsx               |   1 +
 .../environment-manage/components/use-modal.ts     |  23 ++--
 .../components/k8s-namespace-modal.tsx             |   1 +
 .../k8s-namespace-manage/components/use-modal.ts   |  23 ++--
 .../tenant-manage/components/tenant-modal.tsx      |   1 +
 .../tenant-manage/components/use-modalData.ts      |  21 +--
 .../token-manage/components/token-modal.tsx        |   1 +
 .../security/token-manage/components/use-modal.ts  |  21 +--
 .../user-manage/components/use-user-detail.ts      |  27 ++--
 .../worker-group-manage/components/use-modal.ts    |  24 ++--
 .../components/worker-group-modal.tsx              |   1 +
 .../yarn-queue-manage/components/use-modal.ts      |  24 ++--
 .../components/yarn-queue-modal.tsx                |   1 +
 53 files changed, 507 insertions(+), 304 deletions(-)

diff --git a/dolphinscheduler-ui-next/src/views/datasource/list/use-detail.ts 
b/dolphinscheduler-ui-next/src/views/datasource/list/use-detail.ts
index d58fdd5..ab81991 100644
--- a/dolphinscheduler-ui-next/src/views/datasource/list/use-detail.ts
+++ b/dolphinscheduler-ui-next/src/views/datasource/list/use-detail.ts
@@ -56,30 +56,40 @@ export function useDetail(getFieldsValue: Function) {
   const testConnect = async () => {
     if (status.testing) return
     status.testing = true
-    const res = await connectDataSource(formatParams())
-    window.$message.success(
-      res
-        ? res.msg
-        : `${t('datasource.test_connect')} ${t('datasource.success')}`
-    )
-    status.testing = false
+    try {
+      const res = await connectDataSource(formatParams())
+      window.$message.success(
+        res
+          ? res.msg
+          : `${t('datasource.test_connect')} ${t('datasource.success')}`
+      )
+      status.testing = false
+    } catch (err) {
+      status.testing = false
+    }
   }
 
   const createOrUpdate = async (id?: number) => {
     const values = getFieldsValue()
+
     if (status.saving || !values.name) return false
     status.saving = true
 
-    if (PREV_NAME !== values.name) {
-      await verifyDataSourceName({ name: values.name })
-    }
+    try {
+      if (PREV_NAME !== values.name) {
+        await verifyDataSourceName({ name: values.name })
+      }
 
-    id
-      ? await updateDataSource(formatParams(), id)
-      : await createDataSource(formatParams())
+      id
+        ? await updateDataSource(formatParams(), id)
+        : await createDataSource(formatParams())
 
-    status.saving = false
-    return true
+      status.saving = false
+      return true
+    } catch (err) {
+      status.saving = false
+      return false
+    }
   }
 
   return { status, queryById, testConnect, createOrUpdate }
diff --git a/dolphinscheduler-ui-next/src/views/password/use-form.ts 
b/dolphinscheduler-ui-next/src/views/password/use-form.ts
index 78d8a48..e7cd6fc 100644
--- a/dolphinscheduler-ui-next/src/views/password/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/password/use-form.ts
@@ -28,6 +28,7 @@ export function useForm() {
       password: '',
       confirmPassword: ''
     },
+    saving: false,
     rules: {
       password: {
         trigger: ['input', 'blur'],
diff --git a/dolphinscheduler-ui-next/src/views/profile/index.tsx 
b/dolphinscheduler-ui-next/src/views/profile/index.tsx
index 668bc94..3312049 100644
--- a/dolphinscheduler-ui-next/src/views/profile/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/profile/index.tsx
@@ -78,6 +78,7 @@ const profile = defineComponent({
             !this.profileForm.email ||
             !utils.regex.email.test(this.profileForm.email)
           }
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git a/dolphinscheduler-ui-next/src/views/profile/use-form.ts 
b/dolphinscheduler-ui-next/src/views/profile/use-form.ts
index 84910b3..388d6a9 100644
--- a/dolphinscheduler-ui-next/src/views/profile/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/profile/use-form.ts
@@ -33,6 +33,7 @@ export function useForm() {
       email: userInfo.email,
       phone: userInfo.phone
     },
+    saving: false,
     rules: {
       username: {
         trigger: ['input', 'blur'],
diff --git a/dolphinscheduler-ui-next/src/views/profile/use-update.ts 
b/dolphinscheduler-ui-next/src/views/profile/use-update.ts
index 198bd69..28edf90 100644
--- a/dolphinscheduler-ui-next/src/views/profile/use-update.ts
+++ b/dolphinscheduler-ui-next/src/views/profile/use-update.ts
@@ -23,21 +23,27 @@ export function useUpdate(state: any) {
   const userStore = useUserStore()
   const userInfo = userStore.userInfo as UserInfoRes
 
-  const handleUpdate = () => {
-    state.profileFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        await updateUser({
-          userPassword: '',
-          id: userInfo.id,
-          userName: state.profileForm.username,
-          tenantId: userInfo.tenantId,
-          email: state.profileForm.email,
-          phone: state.profileForm.phone,
-          state: userInfo.state,
-          queue: userInfo.queue
-        })
-      }
-    })
+  const handleUpdate = async () => {
+    await state.profileFormRef.validate()
+
+    if (state.saving === true) return
+    state.saving = true
+
+    try {
+      await updateUser({
+        userPassword: '',
+        id: userInfo.id,
+        userName: state.profileForm.username,
+        tenantId: userInfo.tenantId,
+        email: state.profileForm.email,
+        phone: state.profileForm.phone,
+        state: userInfo.state,
+        queue: userInfo.queue
+      })
+      state.saving = false
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   return {
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx 
b/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
index 38b0830..f3533d5 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/projects/list/components/project-modal.tsx
@@ -101,6 +101,7 @@ const ProjectModal = defineComponent({
         onConfirm={this.confirmModal}
         onCancel={this.cancelModal}
         confirmDisabled={!this.model.projectName || !this.model.userName}
+        confirmLoading={this.saving}
       >
         <NForm rules={this.rules} ref='projectFormRef'>
           <NFormItem label={t('project.list.project_name')} path='projectName'>
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts 
b/dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts
index 29f41a8..fc0e7eb 100644
--- a/dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/list/components/use-form.ts
@@ -36,6 +36,7 @@ export function useForm(
       description: '',
       userName: (userStore.getUserInfo as UserInfoRes).userName
     },
+    saving: false,
     rules: {
       projectName: {
         required: true,
@@ -68,16 +69,28 @@ export function useForm(
     })
   }
 
-  const submitProjectModal = () => {
-    createProject(variables.model).then(() => {
+  const submitProjectModal = async () => {
+    if (variables.saving) return
+    variables.saving = true
+    try {
+      await createProject(variables.model)
+      variables.saving = false
       ctx.emit('confirmModal', props.showModalRef)
-    })
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
-  const updateProjectModal = () => {
-    updateProject(variables.model, props.row.code).then(() => {
+  const updateProjectModal = async () => {
+    if (variables.saving) return
+    variables.saving = true
+    try {
+      await updateProject(variables.model, props.row.code)
+      variables.saving = false
       ctx.emit('confirmModal', props.showModalRef)
-    })
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   return { variables, t, handleValidate }
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
index 785f8a6..d3f3c60 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/projects/task/components/node/detail-modal.tsx
@@ -65,6 +65,10 @@ const props = {
   },
   taskInstance: {
     type: Object as PropType<IWorkflowTaskInstance>
+  },
+  saving: {
+    type: Boolean,
+    default: false
   }
 }
 
@@ -168,7 +172,7 @@ const NodeDetailModal = defineComponent({
         show={props.show}
         title={`${t('project.node.current_node_settings')}`}
         onConfirm={onConfirm}
-        confirmLoading={false}
+        confirmLoading={props.saving}
         confirmDisabled={props.readonly}
         onCancel={onCancel}
         headerLinks={headerLinks}
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx
index 4e752c4..391e166 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/move-modal.tsx
@@ -83,6 +83,7 @@ const MoveModal = defineComponent({
         onCancel={cancelModal}
         onConfirm={confirmModal}
         confirmDisabled={!this.model.targetProcessDefinitionCode}
+        confirmLoading={this.saving}
       >
         <NForm
           model={this.model}
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts
 
b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts
index ac392b7..a48774d 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts
+++ 
b/dolphinscheduler-ui-next/src/views/projects/task/definition/components/use-move.ts
@@ -37,6 +37,7 @@ export function useMove() {
       targetProcessDefinitionCode: ref(''),
       generalOptions: []
     },
+    saving: false,
     rules: {
       targetProcessDefinitionCode: {
         required: true,
@@ -77,17 +78,23 @@ export function useMove() {
     })
   }
 
-  const moveTask = () => {
-    const data = {
-      targetProcessDefinitionCode: variables.model.targetProcessDefinitionCode,
-      taskCode: variables.taskCode,
-      processDefinitionCode: variables.processDefinitionCode
-    }
-
-    moveRelation(data, projectCode).then(() => {
+  const moveTask = async () => {
+    if (variables.saving) return
+    variables.saving = true
+    try {
+      const data = {
+        targetProcessDefinitionCode:
+          variables.model.targetProcessDefinitionCode,
+        taskCode: variables.taskCode,
+        processDefinitionCode: variables.processDefinitionCode
+      }
+      await moveRelation(data, projectCode)
+      variables.saving = false
       variables.model.targetProcessDefinitionCode = ''
       variables.refreshTaskDefinition = true
-    })
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   return {
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx 
b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx
index 74022da..ddb9084 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/index.tsx
@@ -196,6 +196,7 @@ const TaskDefinition = defineComponent({
           projectCode={this.projectCode}
           from={1}
           readonly={this.taskReadonly}
+          saving={this.taskSaving}
         />
       </>
     )
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts 
b/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts
index 9b8e537..ebc6e57 100644
--- a/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts
+++ b/dolphinscheduler-ui-next/src/views/projects/task/definition/use-task.ts
@@ -62,23 +62,28 @@ export function useTask(projectCode: number) {
   const onTaskSave = async (data: INodeData) => {
     if (task.taskSaving) return
     task.taskSaving = true
-    if (data.id) {
-      data.code &&
-        (await updateWithUpstream(
+    try {
+      if (data.id) {
+        data.code &&
+          (await updateWithUpstream(
+            projectCode,
+            data.code,
+            formatParams({ ...data, code: data.code }, false)
+          ))
+      } else {
+        const taskCode = await getTaskCode()
+        await saveSingle(
           projectCode,
-          data.code,
-          formatParams({ ...data, code: data.code }, false)
-        ))
-    } else {
-      const taskCode = await getTaskCode()
-      await saveSingle(
-        projectCode,
-        formatParams({ ...data, code: taskCode }, true)
-      )
-    }
+          formatParams({ ...data, code: taskCode }, true)
+        )
+      }
 
-    task.taskSaving = false
-    return true
+      task.taskSaving = false
+      return true
+    } catch (err) {
+      task.taskSaving = false
+      return false
+    }
   }
 
   const onEditTask = async (row: IRecord, readonly: boolean) => {
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/import-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/import-modal.tsx
index a1f766c..ddb084d 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/import-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/import-modal.tsx
@@ -67,6 +67,7 @@ export default defineComponent({
         title={t('project.workflow.upload')}
         onCancel={this.hideModal}
         onConfirm={this.handleImport}
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.importRules}
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/start-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/start-modal.tsx
index 488f8a4..e717577 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/start-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/start-modal.tsx
@@ -217,6 +217,7 @@ export default defineComponent({
         title={t('project.workflow.set_parameters_before_starting')}
         onCancel={this.hideModal}
         onConfirm={this.handleStart}
+        confirmLoading={this.saving}
       >
         <NForm ref='startFormRef' label-placement='left' label-width='160'>
           <NFormItem
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/timing-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/timing-modal.tsx
index ac5999c..8677c9e 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/timing-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/timing-modal.tsx
@@ -235,6 +235,7 @@ export default defineComponent({
         title={t('project.workflow.set_parameters_before_timing')}
         onCancel={this.hideModal}
         onConfirm={this.handleTiming}
+        confirmLoading={this.saving}
       >
         <NForm ref='timingFormRef' label-placement='left' label-width='160'>
           <NFormItem
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-form.ts
 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-form.ts
index 0208ae4..eacbf17 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-form.ts
+++ 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-form.ts
@@ -32,6 +32,7 @@ export const useForm = () => {
       name: '',
       file: ''
     },
+    saving: false,
     importRules: {
       file: {
         required: true,
@@ -65,7 +66,8 @@ export const useForm = () => {
       startParams: null,
       expectedParallelismNumber: '',
       dryRun: 0
-    }
+    },
+    saving: false
   })
 
   const timingState = reactive({
@@ -83,7 +85,8 @@ export const useForm = () => {
       warningGroupId: '',
       workerGroup: 'default',
       environmentCode: null
-    }
+    },
+    saving: false
   })
   return {
     importState,
diff --git 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-modal.ts
index a1e0a6b..9787a08 100644
--- 
a/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/projects/workflow/definition/components/use-modal.ts
@@ -58,81 +58,101 @@ export function useModal(
     state.importFormRef.file = ''
   }
 
-  const handleImportDefinition = () => {
-    state.importFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        const formData = new FormData()
-        formData.append('file', state.importForm.file)
-        const code = Number(router.currentRoute.value.params.projectCode)
-        await importProcessDefinition(formData, code)
-        window.$message.success(t('project.workflow.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
-        resetImportForm()
-      }
-    })
+  const handleImportDefinition = async () => {
+    await state.importFormRef.validate()
+
+    if (state.saving) return
+    state.saving = true
+    try {
+      const formData = new FormData()
+      formData.append('file', state.importForm.file)
+      const code = Number(router.currentRoute.value.params.projectCode)
+      await importProcessDefinition(formData, code)
+      window.$message.success(t('project.workflow.success'))
+      state.saving = false
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+      resetImportForm()
+    } catch (err) {
+      state.saving = false
+    }
   }
 
-  const handleStartDefinition = (code: number) => {
-    state.startFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        state.startForm.processDefinitionCode = code
-        if (state.startForm.startEndTime) {
-          const start = format(
-            new Date(state.startForm.startEndTime[0]),
-            'yyyy-MM-dd hh:mm:ss'
-          )
-          const end = format(
-            new Date(state.startForm.startEndTime[1]),
-            'yyyy-MM-dd hh:mm:ss'
-          )
-          state.startForm.scheduleTime = `${start},${end}`
-        }
+  const handleStartDefinition = async (code: number) => {
+    await state.startFormRef.validate()
+
+    if (state.saving) return
+    state.saving = true
+    try {
+      state.startForm.processDefinitionCode = code
+      if (state.startForm.startEndTime) {
+        const start = format(
+          new Date(state.startForm.startEndTime[0]),
+          'yyyy-MM-dd hh:mm:ss'
+        )
+        const end = format(
+          new Date(state.startForm.startEndTime[1]),
+          'yyyy-MM-dd hh:mm:ss'
+        )
+        state.startForm.scheduleTime = `${start},${end}`
+      }
 
-        const startParams = {} as any
-        for (const item of variables.startParamsList) {
-          if (item.value !== '') {
-            startParams[item.prop] = item.value
-          }
+      const startParams = {} as any
+      for (const item of variables.startParamsList) {
+        if (item.value !== '') {
+          startParams[item.prop] = item.value
         }
-        state.startForm.startParams = !_.isEmpty(startParams)
-          ? JSON.stringify(startParams)
-          : ''
-
-        await startProcessInstance(state.startForm, variables.projectCode)
-        window.$message.success(t('project.workflow.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
       }
-    })
+      state.startForm.startParams = !_.isEmpty(startParams)
+        ? JSON.stringify(startParams)
+        : ''
+
+      await startProcessInstance(state.startForm, variables.projectCode)
+      window.$message.success(t('project.workflow.success'))
+      state.saving = false
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+    } catch (err) {
+      state.saving = false
+    }
   }
 
-  const handleCreateTiming = (code: number) => {
-    state.timingFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        const data: any = getTimingData()
-        data.processDefinitionCode = code
+  const handleCreateTiming = async (code: number) => {
+    await state.timingFormRef.validate()
 
-        await createSchedule(data, variables.projectCode)
-        window.$message.success(t('project.workflow.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
-      }
-    })
+    if (state.saving) return
+    state.saving = true
+    try {
+      const data: any = getTimingData()
+      data.processDefinitionCode = code
+
+      await createSchedule(data, variables.projectCode)
+      window.$message.success(t('project.workflow.success'))
+      state.saving = false
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+    } catch (err) {
+      state.saving = false
+    }
   }
 
-  const handleUpdateTiming = (id: number) => {
-    state.timingFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        const data: any = getTimingData()
-        data.id = id
+  const handleUpdateTiming = async (id: number) => {
+    await state.timingFormRef.validate()
 
-        await updateSchedule(data, variables.projectCode, id)
-        window.$message.success(t('project.workflow.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
-      }
-    })
+    if (state.saving) return
+    state.saving = true
+    try {
+      const data: any = getTimingData()
+      data.id = id
+
+      await updateSchedule(data, variables.projectCode, id)
+      window.$message.success(t('project.workflow.success'))
+      state.saving = false
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   const getTimingData = () => {
diff --git a/dolphinscheduler-ui-next/src/views/resource/file/folder/index.tsx 
b/dolphinscheduler-ui-next/src/views/resource/file/folder/index.tsx
index bf00ea5..318d12b 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/folder/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/resource/file/folder/index.tsx
@@ -61,6 +61,7 @@ export default defineComponent({
         onConfirm={this.handleFolder}
         confirmClassName='btn-submit'
         cancelClassName='btn-cancel'
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.rules}
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/file/folder/use-folder.ts 
b/dolphinscheduler-ui-next/src/views/resource/file/folder/use-folder.ts
index 39d7402..d662360 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/folder/use-folder.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/file/folder/use-folder.ts
@@ -27,26 +27,31 @@ export function useFolder(state: any) {
   const router: Router = useRouter()
   const fileStore = useFileStore()
 
-  const handleCreateFolder = (
+  const handleCreateFolder = async (
     emit: IEmit,
     hideModal: () => void,
     resetForm: () => void
   ) => {
-    const pid = router.currentRoute.value.params.id || -1
-    const currentDir = fileStore.getCurrentDir || '/'
-    state.folderFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        await createDirectory({
-          ...state.folderForm,
-          ...{ pid, currentDir }
-        })
+    await state.folderFormRef.validate()
 
-        window.$message.success(t('resource.file.success'))
-        emit('updateList')
-        hideModal()
-        resetForm()
-      }
-    })
+    if (state.saving) return
+    state.saving = true
+
+    try {
+      const pid = router.currentRoute.value.params.id || -1
+      const currentDir = fileStore.getCurrentDir || '/'
+      await createDirectory({
+        ...state.folderForm,
+        ...{ pid, currentDir }
+      })
+      window.$message.success(t('resource.file.success'))
+      state.saving = false
+      emit('updateList')
+      hideModal()
+      resetForm()
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   return {
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/file/folder/use-form.ts 
b/dolphinscheduler-ui-next/src/views/resource/file/folder/use-form.ts
index 2576d9a..7e51735 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/folder/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/file/folder/use-form.ts
@@ -37,6 +37,7 @@ export function useForm() {
   const state = reactive({
     folderFormRef: ref(),
     folderForm: defaultValue(),
+    saving: false,
     rules: {
       name: {
         required: true,
diff --git a/dolphinscheduler-ui-next/src/views/resource/file/rename/index.tsx 
b/dolphinscheduler-ui-next/src/views/resource/file/rename/index.tsx
index 8e34650..5ad0147 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/rename/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/resource/file/rename/index.tsx
@@ -77,6 +77,7 @@ export default defineComponent({
         onConfirm={this.handleFile}
         confirmClassName='btn-submit'
         cancelClassName='btn-cancel'
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.rules}
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/file/rename/use-form.ts 
b/dolphinscheduler-ui-next/src/views/resource/file/rename/use-form.ts
index 4295ad3..567b23d 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/rename/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/file/rename/use-form.ts
@@ -36,6 +36,7 @@ export function useForm(name: string, description: string) {
   const state = reactive({
     renameFormRef: ref(),
     renameForm: defaultValue(name, description),
+    saving: false,
     rules: {
       name: {
         required: true,
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/file/rename/use-rename.ts 
b/dolphinscheduler-ui-next/src/views/resource/file/rename/use-rename.ts
index 9251a7d..103bbbe 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/rename/use-rename.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/file/rename/use-rename.ts
@@ -22,26 +22,31 @@ import { updateResource } from '@/service/modules/resources'
 export function useRename(state: any) {
   const { t } = useI18n()
 
-  const handleRenameFile = (
+  const handleRenameFile = async (
     emit: IEmit,
     hideModal: () => void,
     resetForm: () => void
   ) => {
-    state.renameFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        await updateResource(
-          {
-            ...state.renameForm
-          },
-          state.renameForm.id
-        )
-        window.$message.success(t('resource.file.success'))
-        emit('updateList')
-      }
+    await state.renameFormRef.validate()
 
+    if (state.saving) return
+    state.saving = true
+
+    try {
+      await updateResource(
+        {
+          ...state.renameForm
+        },
+        state.renameForm.id
+      )
+      window.$message.success(t('resource.file.success'))
+      state.saving = false
+      emit('updateList')
       hideModal()
       resetForm()
-    })
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   return {
diff --git a/dolphinscheduler-ui-next/src/views/resource/file/upload/index.tsx 
b/dolphinscheduler-ui-next/src/views/resource/file/upload/index.tsx
index 3e3443d..c63fbb6 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/upload/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/resource/file/upload/index.tsx
@@ -67,6 +67,7 @@ export default defineComponent({
         onConfirm={this.handleFile}
         confirmClassName='btn-submit'
         cancelClassName='btn-cancel'
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.rules}
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/file/upload/use-form.ts 
b/dolphinscheduler-ui-next/src/views/resource/file/upload/use-form.ts
index c29fb79..58ec7db 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/upload/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/file/upload/use-form.ts
@@ -37,6 +37,7 @@ export function useForm() {
   const state = reactive({
     uploadFormRef: ref(),
     uploadForm: defaultValue(),
+    saving: false,
     rules: {
       name: {
         required: true,
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/file/upload/use-upload.ts 
b/dolphinscheduler-ui-next/src/views/resource/file/upload/use-upload.ts
index dd67ca6..c8f3b05 100644
--- a/dolphinscheduler-ui-next/src/views/resource/file/upload/use-upload.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/file/upload/use-upload.ts
@@ -27,31 +27,36 @@ export function useUpload(state: any) {
   const router: Router = useRouter()
   const fileStore = useFileStore()
 
-  const handleUploadFile = (
+  const handleUploadFile = async (
     emit: IEmit,
     hideModal: () => void,
     resetForm: () => void
   ) => {
-    state.uploadFormRef.validate(async (valid: any) => {
+    await state.uploadFormRef.validate()
+
+    if (state.saving) return
+    state.saving = true
+    try {
       const pid = router.currentRoute.value.params.id || -1
       const currentDir = fileStore.getCurrentDir || '/'
-      if (!valid) {
-        const formData = new FormData()
-        formData.append('file', state.uploadForm.file)
-        formData.append('type', 'FILE')
-        formData.append('name', state.uploadForm.name)
-        formData.append('pid', String(pid))
-        formData.append('currentDir', currentDir)
-        formData.append('description', state.uploadForm.description)
+      const formData = new FormData()
+      formData.append('file', state.uploadForm.file)
+      formData.append('type', 'FILE')
+      formData.append('name', state.uploadForm.name)
+      formData.append('pid', String(pid))
+      formData.append('currentDir', currentDir)
+      formData.append('description', state.uploadForm.description)
 
-        await createResource(formData as any)
-        window.$message.success(t('resource.file.success'))
-        emit('updateList')
+      await createResource(formData as any)
+      window.$message.success(t('resource.file.success'))
+      state.saving = false
+      emit('updateList')
 
-        hideModal()
-        resetForm()
-      }
-    })
+      hideModal()
+      resetForm()
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   return {
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/task-group/option/components/form-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/resource/task-group/option/components/form-modal.tsx
index 3254c8b..703045c 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/task-group/option/components/form-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/resource/task-group/option/components/form-modal.tsx
@@ -67,13 +67,18 @@ const FormModal = defineComponent({
       }
     })
 
-    const onConfirm = () => {
-      ;(props.status === 1
-        ? updateTaskGroup(state.formData)
-        : createTaskGroup(state.formData)
-      ).then(() => {
+    const onConfirm = async () => {
+      if (state.saving) return
+      state.saving = true
+      try {
+        props.status === 1
+          ? await updateTaskGroup(state.formData)
+          : await createTaskGroup(state.formData)
+        state.saving = false
         emit('confirm')
-      })
+      } catch (err) {
+        state.saving = false
+      }
     }
 
     const onCancel = () => {
@@ -101,6 +106,7 @@ const FormModal = defineComponent({
           !this.formData.groupSize ||
           !this.formData.description
         }
+        confirmLoading={this.saving}
       >
         <NForm rules={this.rules} ref='formRef'>
           <NFormItem label={t('resource.task_group_option.name')} path='name'>
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/task-group/option/use-form.ts 
b/dolphinscheduler-ui-next/src/views/resource/task-group/option/use-form.ts
index 5dd7e7e..9fde7f7 100644
--- a/dolphinscheduler-ui-next/src/views/resource/task-group/option/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/task-group/option/use-form.ts
@@ -33,6 +33,7 @@ export function useForm() {
       status: 1,
       description: ''
     } as TaskGroupUpdateReq,
+    saving: false,
     rules: {
       name: {
         required: true,
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/task-group/queue/components/form-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/resource/task-group/queue/components/form-modal.tsx
index 8abf707..7fc884b 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/task-group/queue/components/form-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/resource/task-group/queue/components/form-modal.tsx
@@ -43,12 +43,18 @@ const FormModal = defineComponent({
       state.formData.priority = props.data.priority
     })
 
-    const onConfirm = () => {
-      const value = state.formData.priority + ''
-      if (value) {
-        modifyTaskGroupQueuePriority(state.formData).then(() => {
+    const onConfirm = async () => {
+      if (state.saving) return
+      state.saving = true
+      try {
+        const value = state.formData.priority + ''
+        if (value) {
+          await modifyTaskGroupQueuePriority(state.formData)
           emit('confirm')
-        })
+        }
+        state.saving = false
+      } catch (err) {
+        state.saving = false
       }
     }
 
@@ -67,6 +73,7 @@ const FormModal = defineComponent({
         show={show}
         onConfirm={onConfirm}
         onCancel={onCancel}
+        confirmLoading={this.saving}
       >
         <NForm rules={this.rules} ref='formRef'>
           <NFormItem
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/task-group/queue/use-form.ts 
b/dolphinscheduler-ui-next/src/views/resource/task-group/queue/use-form.ts
index cf67028..54d4c0a 100644
--- a/dolphinscheduler-ui-next/src/views/resource/task-group/queue/use-form.ts
+++ b/dolphinscheduler-ui-next/src/views/resource/task-group/queue/use-form.ts
@@ -29,6 +29,7 @@ export function useForm() {
       queueId: 0,
       priority: 0
     } as TaskGroupQueuePriorityUpdateReq,
+    saving: false,
     rules: {
       priority: {
         required: true,
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx
index d8f9fca..7256691 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx
@@ -126,6 +126,7 @@ export default defineComponent({
         onConfirm={this.row.id ? this.handleRename : this.handleCreate}
         confirmClassName='btn-submit'
         cancelClassName='btn-cancel'
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.rules}
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts
 
b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts
index 2850ae6..38e8f1e 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-form.ts
@@ -33,6 +33,7 @@ export const useForm = () => {
       description: '',
       resourceId: -1
     },
+    saving: false,
     rules: {
       type: {
         required: true,
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts
index 0c8ff8f..3de23cd 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/function/components/use-modal.ts
@@ -58,15 +58,21 @@ export function useModal(
     })
   }
 
-  const submitRequest = (serviceHandle: any) => {
-    state.functionFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        await serviceHandle()
-        window.$message.success(t('resource.udf.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
-      }
-    })
+  const submitRequest = async (serviceHandle: any) => {
+    await state.functionFormRef.validate()
+
+    if (state.saving) return
+    state.saving = true
+
+    try {
+      await serviceHandle()
+      window.$message.success(t('resource.udf.success'))
+      state.saving = false
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   const variables = reactive({
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx
index 909f645..e6a737d 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx
@@ -81,6 +81,7 @@ export default defineComponent({
         onConfirm={this.row.id ? this.handleRename : this.handleCreate}
         confirmClassName='btn-submit'
         cancelClassName='btn-cancel'
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.rules}
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx
index 6514c4d..1a1c21a 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx
@@ -68,6 +68,7 @@ export default defineComponent({
         onConfirm={this.handleFolder}
         confirmClassName='btn-submit'
         cancelClassName='btn-cancel'
+        confirmLoading={this.saving}
       >
         <NForm
           rules={this.rules}
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts
 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts
index 4241523..21c87fc 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-form.ts
@@ -31,6 +31,7 @@ export const useForm = () => {
       description: '',
       currentDir: '/'
     },
+    saving: false,
     rules: {
       name: {
         required: true,
@@ -53,6 +54,7 @@ export const useForm = () => {
       pid: -1,
       currentDir: '/'
     },
+    saving: false,
     rules: {
       name: {
         required: true,
diff --git 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts
index cd72101..b8cf902 100644
--- 
a/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/resource/udf/resource/components/use-modal.ts
@@ -59,15 +59,21 @@ export function useModal(
     })
   }
 
-  const submitRequest = (serviceHandle: any) => {
-    state.folderFormRef.validate(async (valid: any) => {
-      if (!valid) {
-        await serviceHandle()
-        window.$message.success(t('resource.udf.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
-      }
-    })
+  const submitRequest = async (serviceHandle: any) => {
+    await state.folderFormRef.validate()
+
+    if (state.saving) return
+    state.saving = true
+
+    try {
+      await serviceHandle()
+      window.$message.success(t('resource.udf.success'))
+      state.saving = false
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   const resetUploadForm = () => {
@@ -76,26 +82,32 @@ export function useModal(
     state.uploadForm.description = ''
   }
 
-  const handleUploadFile = () => {
-    state.uploadFormRef.validate(async (valid: any) => {
+  const handleUploadFile = async () => {
+    await state.uploadFormRef.validate()
+
+    if (state.saving) return
+    state.saving = true
+
+    try {
       const pid = router.currentRoute.value.params.id || -1
       const currentDir = pid === -1 ? '/' : fileStore.getCurrentDir || '/'
-      if (!valid) {
-        const formData = new FormData()
-        formData.append('file', state.uploadForm.file)
-        formData.append('type', 'UDF')
-        formData.append('name', state.uploadForm.name)
-        formData.append('pid', String(pid))
-        formData.append('currentDir', currentDir)
-        formData.append('description', state.uploadForm.description)
 
-        await createResource(formData as any)
-        window.$message.success(t('resource.udf.success'))
-        ctx.emit('updateList')
-        ctx.emit('update:show')
-        resetUploadForm()
-      }
-    })
+      const formData = new FormData()
+      formData.append('file', state.uploadForm.file)
+      formData.append('type', 'UDF')
+      formData.append('name', state.uploadForm.name)
+      formData.append('pid', String(pid))
+      formData.append('currentDir', currentDir)
+      formData.append('description', state.uploadForm.description)
+
+      await createResource(formData as any)
+      window.$message.success(t('resource.udf.success'))
+      ctx.emit('updateList')
+      ctx.emit('update:show')
+      resetUploadForm()
+    } catch (err) {
+      state.saving = false
+    }
   }
 
   return {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/alarm-group-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/alarm-group-modal.tsx
index dcfcb4c..abcab1a 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/alarm-group-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/alarm-group-modal.tsx
@@ -110,6 +110,7 @@ const AlarmGroupModal = defineComponent({
           confirmDisabled={
             !this.model.groupName || this.model.alertInstanceIds.length < 1
           }
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git 
a/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/use-modal.ts
index 5cbadf0..a66d24d 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/alarm-group-manage/components/use-modal.ts
@@ -41,6 +41,7 @@ export function useModal(
       description: ref(''),
       generalOptions: []
     },
+    saving: false,
     rules: {
       groupName: {
         required: true,
@@ -83,14 +84,21 @@ export function useModal(
     return state
   }
 
-  const handleValidate = (statusRef: number) => {
-    variables.alertGroupFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitAlertGroupModal() : updateAlertGroupModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.alertGroupFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0
+        ? await submitAlertGroupModal()
+        : await updateAlertGroupModal()
+
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitAlertGroupModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts
 
b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts
index 01a5e5f..8f35dc1 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/use-detail.ts
@@ -45,29 +45,35 @@ export function useDetail(getFormValues: Function) {
     const values = getFormValues()
     if (status.saving) return false
     status.saving = true
-    if (currentRecord?.instanceName !== values.instanceName) {
-      await verifyAlertInstanceName({
-        alertInstanceName: values.instanceName
-      })
-    }
 
-    currentRecord?.id
-      ? await updateAlertPluginInstance(
-          {
-            alertPluginInstanceId: values.pluginDefineId,
+    try {
+      if (currentRecord?.instanceName !== values.instanceName) {
+        await verifyAlertInstanceName({
+          alertInstanceName: values.instanceName
+        })
+      }
+
+      currentRecord?.id
+        ? await updateAlertPluginInstance(
+            {
+              alertPluginInstanceId: values.pluginDefineId,
+              instanceName: values.instanceName,
+              pluginInstanceParams: formatParams(json, values)
+            },
+            currentRecord.id
+          )
+        : await createAlertPluginInstance({
             instanceName: values.instanceName,
+            pluginDefineId: values.pluginDefineId,
             pluginInstanceParams: formatParams(json, values)
-          },
-          currentRecord.id
-        )
-      : await createAlertPluginInstance({
-          instanceName: values.instanceName,
-          pluginDefineId: values.pluginDefineId,
-          pluginInstanceParams: formatParams(json, values)
-        })
+          })
 
-    status.saving = false
-    return true
+      status.saving = false
+      return true
+    } catch (err) {
+      status.saving = false
+      return false
+    }
   }
 
   return { status, createOrUpdate }
diff --git 
a/dolphinscheduler-ui-next/src/views/security/environment-manage/components/environment-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/environment-manage/components/environment-modal.tsx
index 6cc4ccf..69d13e5 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/environment-manage/components/environment-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/environment-manage/components/environment-modal.tsx
@@ -125,6 +125,7 @@ const EnvironmentModal = defineComponent({
           }
           confirmClassName='btn-submit'
           cancelClassName='btn-cancel'
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git 
a/dolphinscheduler-ui-next/src/views/security/environment-manage/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/security/environment-manage/components/use-modal.ts
index fe23dac..f3d4d08 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/environment-manage/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/environment-manage/components/use-modal.ts
@@ -41,6 +41,7 @@ export function useModal(
       workerGroups: ref<Array<string>>([]),
       generalOptions: []
     },
+    saving: false,
     rules: {
       name: {
         required: true,
@@ -90,14 +91,20 @@ export function useModal(
     return state
   }
 
-  const handleValidate = (statusRef: number) => {
-    variables.environmentFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitEnvironmentModal() : updateEnvironmentModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.environmentFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0
+        ? await submitEnvironmentModal()
+        : await updateEnvironmentModal()
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitEnvironmentModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/k8s-namespace-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/k8s-namespace-modal.tsx
index 7c5dbe5..5e7da9b 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/k8s-namespace-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/k8s-namespace-modal.tsx
@@ -115,6 +115,7 @@ const K8sNamespaceModal = defineComponent({
           onCancel={this.cancelModal}
           onConfirm={this.confirmModal}
           confirmDisabled={!this.model.namespace || !this.model.k8s}
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git 
a/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/use-modal.ts
index 50bfebf..5910121 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/k8s-namespace-manage/components/use-modal.ts
@@ -40,6 +40,7 @@ export function useModal(
       limitsCpu: ref(''),
       limitsMemory: ref('')
     },
+    saving: false,
     rules: {
       namespace: {
         required: true,
@@ -62,14 +63,20 @@ export function useModal(
     }
   })
 
-  const handleValidate = (statusRef: number) => {
-    variables.k8sNamespaceFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitK8SNamespaceModal() : updateK8SNamespaceModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.k8sNamespaceFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0
+        ? await submitK8SNamespaceModal()
+        : await updateK8SNamespaceModal()
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitK8SNamespaceModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/tenant-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/tenant-modal.tsx
index b5646fb..eca45bb 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/tenant-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/tenant-modal.tsx
@@ -103,6 +103,7 @@ const TenantModal = defineComponent({
           onConfirm={this.confirmModal}
           confirmClassName='btn-submit'
           cancelClassName='btn-cancel'
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git 
a/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/use-modalData.ts
 
b/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/use-modalData.ts
index 05e5101..3084721 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/use-modalData.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/tenant-manage/components/use-modalData.ts
@@ -37,6 +37,7 @@ export function useModalData(
       queueId: ref<number>(-1),
       generalOptions: []
     },
+    saving: false,
     rules: {
       tenantCode: {
         required: true
@@ -64,14 +65,18 @@ export function useModalData(
     return state
   }
 
-  const handleValidate = (statusRef: number) => {
-    variables.tenantFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitTenantModal() : updateTenantModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.tenantFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0 ? await submitTenantModal() : await updateTenantModal()
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitTenantModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/token-manage/components/token-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/token-manage/components/token-modal.tsx
index 488c69e..bf99392 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/token-manage/components/token-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/token-manage/components/token-modal.tsx
@@ -141,6 +141,7 @@ const TokenModal = defineComponent({
           }
           confirmClassName='btn-submit'
           cancelClassName='btn-cancel'
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git 
a/dolphinscheduler-ui-next/src/views/security/token-manage/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/security/token-manage/components/use-modal.ts
index f2d860d..abbaa19 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/token-manage/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/token-manage/components/use-modal.ts
@@ -48,6 +48,7 @@ export function useModal(
       token: ref(''),
       generalOptions: []
     },
+    saving: false,
     rules: {
       userId: {
         required: true,
@@ -111,14 +112,18 @@ export function useModal(
     )
   }
 
-  const handleValidate = (statusRef: number) => {
-    variables.alertGroupFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitTokenModal() : updateTokenModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.alertGroupFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0 ? await submitTokenModal() : await updateTokenModal()
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitTokenModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-user-detail.ts
 
b/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-user-detail.ts
index d436716..d347eba 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-user-detail.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/user-manage/components/use-user-detail.ts
@@ -137,19 +137,24 @@ export function useUserDetail() {
     state.formData = { ...initialValues }
   }
   const onSave = async (id?: number): Promise<boolean> => {
-    await state.formRef.validate()
-    if (state.saving) return false
-    state.saving = true
-    if (PREV_NAME !== state.formData.userName) {
-      await verifyUserName({ userName: state.formData.userName })
-    }
+    try {
+      await state.formRef.validate()
+      if (state.saving) return false
+      state.saving = true
+      if (PREV_NAME !== state.formData.userName) {
+        await verifyUserName({ userName: state.formData.userName })
+      }
 
-    id
-      ? await updateUser({ id, ...state.formData })
-      : await createUser(state.formData)
+      id
+        ? await updateUser({ id, ...state.formData })
+        : await createUser(state.formData)
 
-    state.saving = false
-    return true
+      state.saving = false
+      return true
+    } catch (err) {
+      state.saving = false
+      return false
+    }
   }
   const onSetValues = (record: IRecord) => {
     state.formData = {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts
index 9330562..379571f 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/use-modal.ts
@@ -37,6 +37,7 @@ export function useModal(
       addrList: ref<Array<number>>([]),
       generalOptions: []
     },
+    saving: false,
     rules: {
       name: {
         required: true,
@@ -77,14 +78,21 @@ export function useModal(
     return state
   }
 
-  const handleValidate = (statusRef: number) => {
-    variables.workerGroupFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitWorkerGroupModal() : updateWorkerGroupModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.workerGroupFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0
+        ? await submitWorkerGroupModal()
+        : await updateWorkerGroupModal()
+
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitWorkerGroupModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx
index 62c7f05..43626d6 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/worker-group-manage/components/worker-group-modal.tsx
@@ -102,6 +102,7 @@ const WorkerGroupModal = defineComponent({
           confirmDisabled={!this.model.name || this.model.addrList.length < 1}
           confirmClassName='btn-submit'
           cancelClassName='btn-cancel'
+          confirmLoading={this.saving}
         >
           {{
             default: () => (
diff --git 
a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts
 
b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts
index 9e30a1d..f858b75 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts
+++ 
b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/use-modal.ts
@@ -32,6 +32,7 @@ export function useModal(
       queue: ref(''),
       queueName: ref('')
     },
+    saving: false,
     rules: {
       queue: {
         required: true,
@@ -54,14 +55,21 @@ export function useModal(
     }
   })
 
-  const handleValidate = (statusRef: number) => {
-    variables.yarnQueueFormRef.validate((errors: any) => {
-      if (!errors) {
-        statusRef === 0 ? submitYarnQueueModal() : updateYarnQueueModal()
-      } else {
-        return
-      }
-    })
+  const handleValidate = async (statusRef: number) => {
+    await variables.yarnQueueFormRef.validate()
+
+    if (variables.saving) return
+    variables.saving = true
+
+    try {
+      statusRef === 0
+        ? await submitYarnQueueModal()
+        : await updateYarnQueueModal()
+
+      variables.saving = false
+    } catch (err) {
+      variables.saving = false
+    }
   }
 
   const submitYarnQueueModal = () => {
diff --git 
a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx
 
b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx
index 9e5194f..2afc4bd 100644
--- 
a/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx
+++ 
b/dolphinscheduler-ui-next/src/views/security/yarn-queue-manage/components/yarn-queue-modal.tsx
@@ -95,6 +95,7 @@ const YarnQueueModal = defineComponent({
           confirmDisabled={!this.model.queueName || !this.model.queue}
           confirmClassName='btn-submit'
           cancelClassName='btn-cancel'
+          confirmLoading={this.saving}
         >
           {{
             default: () => (

Reply via email to