From 7eea5a0ff27c7b1d17758e1d804da0d33e359da5 Mon Sep 17 00:00:00 2001 From: hyyy <123@qq.com> Date: Tue, 15 Jul 2025 16:25:28 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=A4=8D=E7=82=B9=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sf_demand_plan/__manifest__.py | 1 + .../static/src/js/global_button_protection.js | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 sf_demand_plan/static/src/js/global_button_protection.js diff --git a/sf_demand_plan/__manifest__.py b/sf_demand_plan/__manifest__.py index 08c981cb..0496cad2 100644 --- a/sf_demand_plan/__manifest__.py +++ b/sf_demand_plan/__manifest__.py @@ -31,6 +31,7 @@ 'sf_demand_plan/static/src/scss/style.css', 'sf_demand_plan/static/src/js/print_demand.js', 'sf_demand_plan/static/src/js/custom_button.js', + 'sf_demand_plan/static/src/js/global_button_protection.js', ] }, 'license': 'LGPL-3', diff --git a/sf_demand_plan/static/src/js/global_button_protection.js b/sf_demand_plan/static/src/js/global_button_protection.js new file mode 100644 index 00000000..530028f4 --- /dev/null +++ b/sf_demand_plan/static/src/js/global_button_protection.js @@ -0,0 +1,106 @@ +/** @odoo-module **/ + +// 全局按钮点击保护 +class ButtonClickProtection { + constructor() { + this.clickedButtons = new Set(); + this.init(); + } + + init() { + // 监听整个文档的点击事件 + console.log('init'); + document.addEventListener('click', this.handleGlobalClick.bind(this), true); + + // 监听页面变化,为新添加的按钮添加保护 + this.observePageChanges(); + } + + /** + * 处理全局点击事件 + */ + handleGlobalClick(event) { + const button = event.target.closest('button[name="button_release_plan"]'); + if (!button) return; + + // 如果按钮已经被点击过,阻止事件 + if (this.clickedButtons.has(button)) { + event.preventDefault(); + event.stopPropagation(); + return; + } + + // 标记按钮为已点击 + this.clickedButtons.add(button); + + // 立即禁用按钮 + button.disabled = true; + button.style.opacity = '0.6'; + button.style.cursor = 'not-allowed'; + + // 保存原始文本 + const originalText = button.textContent; + button.textContent = '处理中...'; + + // 5秒后重新启用按钮(如果页面没有刷新) + setTimeout(() => { + if (button && button.disabled) { + button.disabled = false; + button.style.opacity = '1'; + button.style.cursor = 'pointer'; + button.textContent = originalText; + this.clickedButtons.delete(button); + } + }, 5000); + } + + /** + * 监听页面变化 + */ + observePageChanges() { + // 使用 MutationObserver 监听DOM变化 + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.type === 'childList') { + mutation.addedNodes.forEach((node) => { + if (node.nodeType === Node.ELEMENT_NODE) { + // 检查新添加的元素中是否有下达计划按钮 + const buttons = node.querySelectorAll ? + node.querySelectorAll('button[name="button_release_plan"]') : + (node.matches && node.matches('button[name="button_release_plan"]') ? [node] : []); + + buttons.forEach(button => { + // 为新按钮添加视觉提示 + button.addEventListener('mouseenter', () => { + if (!button.disabled) { + button.title = '点击后将禁用按钮防止重复操作'; + } + }); + }); + } + }); + } + }); + }); + + // 开始观察 + observer.observe(document.body, { + childList: true, + subtree: true + }); + } +} + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', () => { + new ButtonClickProtection(); +}); + +// 如果页面已经加载完成,立即初始化 +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { + new ButtonClickProtection(); + }); +} else { + new ButtonClickProtection(); +} \ No newline at end of file