From 69da74f447928298d37e5ea3f597b11a5ac76a9a Mon Sep 17 00:00:00 2001 From: luojiayi <1712054227@qq.com> Date: Tue, 15 Apr 2025 10:51:12 +0800 Subject: [PATCH] =?UTF-8?q?2025=E5=B9=B404=E6=9C=8815=E6=97=A510:51:09?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.ts | 79 ++++++++++++++++++- src/utils/index.ts | 6 +- src/utils/request.ts | 11 ++- src/views/incidentDispose/index.vue | 4 +- src/views/login.vue | 10 +-- src/views/statisticalCenter/index.vue | 4 +- .../synthesizeManage/areaManage/addFence.vue | 6 +- .../synthesizeManage/deviceManage/index.vue | 12 ++- .../synthesizeManage/mapLocation/index.vue | 5 +- .../synthesizeManage/userManage/index.vue | 2 +- .../synthesizeManage/userManage/userType.vue | 12 ++- 11 files changed, 126 insertions(+), 25 deletions(-) diff --git a/src/main.ts b/src/main.ts index 243d17e..ab39fc6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { createApp } from 'vue'; +import { createApp, Directive, DirectiveBinding } from 'vue'; import { createPinia } from 'pinia'; import * as ElementPlusIconsVue from '@element-plus/icons-vue'; import App from './App.vue'; @@ -30,4 +30,81 @@ app.directive('permiss', { }, }); +// 注册自定义指令 v-prevent-reclick +app.directive('prevent-reclick', { + beforeMount(el, binding) { + el.disabled = false; // 初始化时启用按钮 + el.addEventListener('click', (e) => { + el.disabled = true; // 点击后禁用按钮 + setTimeout(() => { + el.disabled = false; // 在指定的时间后重新启用按钮 + }, binding.value || 2000); // 使用 binding.value 来设置等待时间,默认为 2000 毫秒 + }); + }, + unmounted(el) { + // 组件卸载时移除事件监听器 + el.removeEventListener('click'); + }, +}); + +interface ReturnPromiseFn { + (...args: any[]): Promise +} +interface objectType { + fn: ReturnPromiseFn + params?: any[] +} + +const directiveBindingDirective: Directive = { + mounted(el, binding: DirectiveBinding) { + if (!binding.value) { + throw new Error('v-prevent-dup-click must pass a parameter') + } + if (typeof binding.value !== 'function' && typeof binding.value !== 'object') { + throw new Error('v-prevent-dup-click requires a function or an object with a function `fn`') + } + // 一开始是未点击状态 + el.isClicked = false + const handerClick = function (event) { + // 如果已经点击过,则阻止事件 + if (el.isClicked === 'true') { + event.preventDefault() + event.stopPropagation() + return + } + // 标记为已点击 + el.isClicked = 'true' + // 调用传入的函数 + let fn: ReturnPromiseFn + let params: any[] = [] + //如果只传函数名 + if (typeof binding.value == 'function') { + fn = binding.value + } else { + //如果传对象{fn:submit,params:[1,2,3]}或者{fn:submit} + fn = (binding.value as objectType).fn + params = (binding.value as objectType)?.params ?? [] + } + console.log(params, 'params') + try { + fn(...params).finally(() => { + el.isClicked = false + }) + } catch (error) { + throw new Error('binding.value或 binding.value.fn必须是返回Promise类型的函数') + } + } + el.hander = handerClick + el.addEventListener('click', handerClick) + }, + //销毁事件 + beforeUnmount(el) { + if (el.hander) { + el.removeEventListener('click', el.hander) + } + } +} + +app.directive('preventDupClick', directiveBindingDirective) + app.mount('#app'); diff --git a/src/utils/index.ts b/src/utils/index.ts index 01ffc61..23fdfcc 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -58,12 +58,10 @@ export const debounce = (fn: Function, time: number = 300) => { export const throttle = (fn: Function, time: number = 300) => { let flag = true return function (...argu) { - if (!flag) { - return - } + if (!flag) return flag = false + fn(...argu) let timer = setTimeout(() => { - fn(...argu) flag = true clearTimeout(timer) timer = null diff --git a/src/utils/request.ts b/src/utils/request.ts index fd84f2b..903b2bb 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -2,6 +2,11 @@ import axios, { AxiosInstance, AxiosError, AxiosResponse, InternalAxiosRequestCo import { ElMessage } from "element-plus"; import { useCommonStore } from "@/store/common"; import router from "@/router/index"; +import { debounce, throttle } from '.'; + +const showErrorNotification = throttle((message: string) => { + ElMessage.error(message) +}, 2000); // 设置防抖的等待时间,比如 2000 毫秒 const service: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_APP_URL, @@ -25,13 +30,12 @@ service.interceptors.response.use( if (headers['content-type'] === "application/vnd.ms-excel;charset=utf-8") return data if (data.code !== 200) { - ElMessage.error(data.msg) - if (data.code === 1003) { const comm = useCommonStore(); comm.clearStore() router.replace('/login'); } + showErrorNotification(data.msg, 'error'); return Promise.reject(data); } else { return data.data @@ -39,6 +43,9 @@ service.interceptors.response.use( }, (error: AxiosError) => { + let { message } = error; + const currentTime = Date.now(); + showErrorNotification(message, 'error'); return Promise.reject(); } ); diff --git a/src/views/incidentDispose/index.vue b/src/views/incidentDispose/index.vue index b0b8644..1158a9c 100644 --- a/src/views/incidentDispose/index.vue +++ b/src/views/incidentDispose/index.vue @@ -272,7 +272,9 @@ const handleResize = debounce(() => { }, 200); onMounted(() => { getData(); - map = new MapCustom({ dom: "mapcontainer", center: [116.406315, 39.908775] }); + try { + map = new MapCustom({ dom: "mapcontainer", center: [116.406315, 39.908775] }); + } catch (error) {} if (chartRef.value) { myChart = echarts.init(chartRef.value); myChart.setOption(options); diff --git a/src/views/login.vue b/src/views/login.vue index cff42a5..4ff8f7a 100644 --- a/src/views/login.vue +++ b/src/views/login.vue @@ -71,11 +71,11 @@ const submitForm = async (formEl: FormInstance | undefined) => {