From 8f06f2721f22bba78a8be79a18fb60083f4b64d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Tue, 31 Mar 2026 17:15:25 +0800 Subject: [PATCH] 1 --- .../static/src/js/status_bar_buttons.js | 117 ++++++++---------- .../static/src/scss/status_bar_buttons.scss | 33 +++++ 2 files changed, 87 insertions(+), 63 deletions(-) diff --git a/k_ry_mobile_form/static/src/js/status_bar_buttons.js b/k_ry_mobile_form/static/src/js/status_bar_buttons.js index 1f1cb81d8..5652016c0 100644 --- a/k_ry_mobile_form/static/src/js/status_bar_buttons.js +++ b/k_ry_mobile_form/static/src/js/status_bar_buttons.js @@ -33,6 +33,24 @@ const WORKFLOW_BUTTON_STYLES = [ ['btn-archive', '#6b7280', '#ffffff'], ]; +function forceMobileBarVisible(container) { + container.style.setProperty('display', 'block', 'important'); + container.style.setProperty('visibility', 'visible', 'important'); + container.style.setProperty('opacity', '1', 'important'); + container.style.setProperty('position', 'fixed', 'important'); + container.style.setProperty('bottom', '0', 'important'); + container.style.setProperty('left', '0', 'important'); + container.style.setProperty('right', '0', 'important'); + container.style.setProperty('z-index', '99999', 'important'); + // 强制设置容器可见背景与最小高度,避免“能点但看不见” + container.style.setProperty('background-color', '#ffffff', 'important'); + container.style.setProperty('background', '#ffffff', 'important'); + container.style.setProperty('border-top', '1px solid #d9d9d9', 'important'); + container.style.setProperty('box-shadow', '0 -2px 8px rgba(0, 0, 0, 0.12)', 'important'); + container.style.setProperty('min-height', '56px', 'important'); + container.style.setProperty('pointer-events', 'auto', 'important'); +} + function applyWorkflowButtonPaint(button) { for (const [cls, bg, fg] of WORKFLOW_BUTTON_STYLES) { if (button.classList.contains(cls)) { @@ -84,39 +102,26 @@ patch(StatusBarButtons, { useEffect(() => { const checkAndFixMobileButtons = () => { try { - // 如果是移动设备但 env.isSmall 为 false,强制显示移动端按钮 - if (isMobileDevice()) { - const mobileContainers = document.querySelectorAll('.o_statusbar_buttons_mobile_fixed'); - if (mobileContainers.length === 0) return; - - mobileContainers.forEach(container => { - try { - // 使用内联样式强制显示,优先级最高 - container.style.setProperty('display', 'block', 'important'); - container.style.setProperty('visibility', 'visible', 'important'); - container.style.setProperty('opacity', '1', 'important'); - container.style.setProperty('position', 'fixed', 'important'); - container.style.setProperty('bottom', '0', 'important'); - container.style.setProperty('left', '0', 'important'); - container.style.setProperty('right', '0', 'important'); - container.style.setProperty('z-index', '99999', 'important'); - // 强制设置背景色,防止被主题覆盖 - container.style.setProperty('background-color', '#ffffff', 'important'); - container.style.setProperty('background', '#ffffff', 'important'); - - // 同时修复容器内的按钮 - const buttons = container.querySelectorAll('button, a.btn, .btn, a[role="button"], .o_statusbar_buttons > * > button, .o_statusbar_buttons > * > a'); - buttons.forEach(button => { - try { - applyWorkflowButtonPaint(button); - // 强制设置按钮可见性 - button.style.setProperty('visibility', 'visible', 'important'); - button.style.setProperty('opacity', '1', 'important'); - button.style.setProperty('display', 'inline-block', 'important'); - button.style.setProperty('font-size', '14px', 'important'); - button.style.setProperty('font-weight', '500', 'important'); - // 防止文字被设置为透明 - button.style.setProperty('text-indent', '0', 'important'); + const mobileContainers = document.querySelectorAll('.o_statusbar_buttons_mobile_fixed'); + if (mobileContainers.length === 0) return; + + mobileContainers.forEach(container => { + try { + forceMobileBarVisible(container); + + // 同时修复容器内的按钮 + const buttons = container.querySelectorAll('button, a.btn, .btn, a[role="button"], .o_statusbar_buttons > * > button, .o_statusbar_buttons > * > a'); + buttons.forEach(button => { + try { + applyWorkflowButtonPaint(button); + // 强制设置按钮可见性 + button.style.setProperty('visibility', 'visible', 'important'); + button.style.setProperty('opacity', '1', 'important'); + button.style.setProperty('display', 'inline-block', 'important'); + button.style.setProperty('font-size', '14px', 'important'); + button.style.setProperty('font-weight', '500', 'important'); + // 防止文字被设置为透明 + button.style.setProperty('text-indent', '0', 'important'); // 检查按钮颜色 const computedStyle = getComputedStyle(button); @@ -160,24 +165,23 @@ patch(StatusBarButtons, { button.style.setProperty('color', '#ffffff', 'important'); } } - } catch (e) { - console.warn('Error fixing button in setup:', e); - } - }); - } catch (e) { - console.warn('Error fixing container in setup:', e); - } - }); - - // 隐藏桌面端按钮 - try { - const desktopButtons = document.querySelectorAll('.o_form_statusbar > .o_statusbar_buttons:not(.o_statusbar_buttons_mobile_fixed .o_statusbar_buttons)'); - desktopButtons.forEach(btn => { - btn.style.setProperty('display', 'none', 'important'); + } catch (e) { + console.warn('Error fixing button in setup:', e); + } }); } catch (e) { - console.warn('Error hiding desktop buttons in setup:', e); + console.warn('Error fixing container in setup:', e); } + }); + + // 隐藏桌面端按钮 + try { + const desktopButtons = document.querySelectorAll('.o_form_statusbar > .o_statusbar_buttons:not(.o_statusbar_buttons_mobile_fixed .o_statusbar_buttons)'); + desktopButtons.forEach(btn => { + btn.style.setProperty('display', 'none', 'important'); + }); + } catch (e) { + console.warn('Error hiding desktop buttons in setup:', e); } } catch (e) { console.warn('Error in checkAndFixMobileButtons:', e); @@ -228,21 +232,8 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') { containers.forEach(container => { try { - // 如果是移动设备,确保容器可见 - if (isMobileDevice()) { - // 使用 setProperty 的 important 标志强制设置样式 - container.style.setProperty('display', 'block', 'important'); - container.style.setProperty('visibility', 'visible', 'important'); - container.style.setProperty('opacity', '1', 'important'); - container.style.setProperty('position', 'fixed', 'important'); - container.style.setProperty('bottom', '0', 'important'); - container.style.setProperty('left', '0', 'important'); - container.style.setProperty('right', '0', 'important'); - container.style.setProperty('z-index', '99999', 'important'); - // 强制设置背景色,防止被主题覆盖 - container.style.setProperty('background-color', '#ffffff', 'important'); - container.style.setProperty('background', '#ffffff', 'important'); - } + // 无条件强制底栏可见,避免主题在特定机型上把栏绘制成透明 + forceMobileBarVisible(container); // 修复按钮的交互性和可见性 const buttons = container.querySelectorAll('button, a.btn, .btn, a[role="button"], .o_statusbar_buttons > * > button, .o_statusbar_buttons > * > a'); diff --git a/k_ry_mobile_form/static/src/scss/status_bar_buttons.scss b/k_ry_mobile_form/static/src/scss/status_bar_buttons.scss index 124548dd7..e75909976 100644 --- a/k_ry_mobile_form/static/src/scss/status_bar_buttons.scss +++ b/k_ry_mobile_form/static/src/scss/status_bar_buttons.scss @@ -85,6 +85,39 @@ } } +// 最硬兜底:避免主题将底部栏渲染为透明/不可见(iOS 上表现为“能点但看不见”) +.o_form_view .o_statusbar_buttons_mobile_fixed { + display: block !important; + visibility: visible !important; + opacity: 1 !important; + position: fixed !important; + left: 0 !important; + right: 0 !important; + bottom: 0 !important; + z-index: 99999 !important; + min-height: 56px !important; + background: #fff !important; + background-color: #fff !important; + border-top: 1px solid #d9d9d9 !important; + box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.12) !important; + pointer-events: auto !important; + + .o_statusbar_buttons, + .o_statusbar_buttons > * { + visibility: visible !important; + opacity: 1 !important; + } + + .o_statusbar_buttons button, + .o_statusbar_buttons .btn, + .o_statusbar_buttons a.btn { + visibility: visible !important; + opacity: 1 !important; + text-indent: 0 !important; + -webkit-text-fill-color: currentColor !important; + } +} + // 桌面端隐藏移动端悬浮栏 @include media-breakpoint-up(md) { .o_statusbar_buttons_mobile_fixed {