Browse Source

复制规则增加loading按钮

祁鹏飞 2 tháng trước cách đây
mục cha
commit
2c625a493e

+ 17 - 13
src/views/quoteConfig/agreement/agreementDetails.vue

@@ -270,7 +270,7 @@
         </el-form-item>
         </el-form-item>
       </el-form>
       </el-form>
       <template #footer>
       <template #footer>
-        <el-button size="small" type="primary" @click="submitCopy">确定</el-button>
+        <autoLoadingButton size="small" type="primary" :on-click="submitCopy">确定</autoLoadingButton>
       </template>
       </template>
     </el-dialog>
     </el-dialog>
   </div>
   </div>
@@ -288,6 +288,7 @@ import { Fileonload, formatFileSize, processFileName } from '@/utils/composables
 import authDrawer from "./components/agreementAuth.vue";
 import authDrawer from "./components/agreementAuth.vue";
 import ruleFeeDialog from "./components/ruleFeeDialog.vue";
 import ruleFeeDialog from "./components/ruleFeeDialog.vue";
 import ruleFeeDialogEdit from "./components/ruleFeeDialogEdit.vue";
 import ruleFeeDialogEdit from "./components/ruleFeeDialogEdit.vue";
+import autoLoadingButton from "./components/autoLoadingButton.vue";
 import { Delete, Edit, CopyDocument } from '@element-plus/icons-vue'
 import { Delete, Edit, CopyDocument } from '@element-plus/icons-vue'
 interface Agreement {
 interface Agreement {
   [key: string]: string | number; // 协议名称
   [key: string]: string | number; // 协议名称
@@ -707,18 +708,21 @@ const ruleCopy = (id: string) => {
   copyDialog1.value = true
   copyDialog1.value = true
 }
 }
 //复制规则
 //复制规则
-const submitCopy = () => {
-  api.agreementApi.rulesCopy(agreementId.value, ruleId.value).then((res: any) => {
-    if (res.code == '200') {
-      agreementRulesList();
-      copyDialog1.value = false
-      ElMessage({
-        type: 'success',
-        message: res.msg,
-        plain: true,
-      })
-    }
-  });
+const submitCopy = async () => {
+  if(!agreementId.value){
+    ElMessage.error('请选择协议')
+    return
+  }
+  const res = await api.agreementApi.rulesCopy(agreementId.value, ruleId.value)
+  if (res.code == '200') {
+    agreementRulesList();
+    copyDialog1.value = false
+    ElMessage({
+      type: 'success',
+      message: '操作成功',
+      plain: true,
+    })
+  }
 }
 }
 //添加费用
 //添加费用
 const ruleFeeVisible = ref(false);//规则费用弹窗
 const ruleFeeVisible = ref(false);//规则费用弹窗

+ 66 - 0
src/views/quoteConfig/agreement/components/autoLoadingButton.vue

@@ -0,0 +1,66 @@
+<template>
+  <el-button
+    v-bind="$attrs"
+    :loading="isLoading"
+    :disabled="isLoading || disabled"
+    @click="handleClick"
+  >
+    <slot />
+  </el-button>
+</template>
+
+<script setup>
+
+const props = defineProps({
+  // 允许外部手动控制 loading(可选)
+  loading: {
+    type: Boolean,
+    default: undefined
+  },
+  // 允许外部禁用按钮
+  disabled: {
+    type: Boolean,
+    default: false
+  },
+  // 核心:传入一个返回 Promise 的异步函数
+  onClick: {
+    type: Function,
+    default: null
+  }
+})
+
+const emit = defineEmits(['update:loading', 'success', 'error'])
+
+const internalLoading = ref(false)
+
+// 优先使用外部 loading,否则用内部状态
+const isLoading = ref(false)
+watch(() => props.loading, (val) => {
+  isLoading.value = val
+}, { immediate: true })
+
+watch(internalLoading, (val) => {
+  if (props.loading === undefined) {
+    isLoading.value = val
+  }
+  emit('update:loading', val)
+})
+
+const handleClick = async () => {
+  if (isLoading.value) return // 防重复点击
+
+  // 如果有传入 onClick,才触发异步流程
+  if (typeof props.onClick === 'function') {
+    internalLoading.value = true
+    try {
+      const result = await props.onClick()
+      emit('success', result)
+    } catch (error) {
+      emit('error', error)
+      throw error // 保留异常,方便上层继续处理
+    } finally {
+      internalLoading.value = false
+    }
+  }
+}
+</script>