From 75019157b37adbe487b9585512d88bcae480f22c Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Sat, 5 Sep 2026 18:23:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Handsontable=20?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E5=AF=B9=E9=BD=90=E4=B8=8E=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=EF=BC=8C=E5=B9=B6=E8=A1=A5=E9=BD=90=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=E8=AE=A2=E5=8D=95=E8=A1=A8=E5=A4=B4=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .eslintrc-auto-import.json | 3 + src/auto-imports.d.ts | 7 + src/components/HandsontablePro/index.vue | 321 +++++++++++++++++------ src/locale/en-US.ts | 2 + src/locale/zh-CN.ts | 2 + src/main.ts | 3 +- 6 files changed, 263 insertions(+), 75 deletions(-) diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 16425b7..c5bc311 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -16,6 +16,7 @@ "McpCapabilityGuide": true, "McpCapabilityId": true, "McpFieldHint": true, + "NanaBatchOpenOptions": true, "PriceAskContext": true, "PriceAskIntent": true, "PropType": true, @@ -228,6 +229,7 @@ "useId": true, "useIdle": true, "useImage": true, + "useInboxUnread": true, "useInfiniteScroll": true, "useIntersectionObserver": true, "useInterval": true, @@ -249,6 +251,7 @@ "useMouseInElement": true, "useMousePressed": true, "useMutationObserver": true, + "useNanaBatchPanel": true, "useNavigatorLanguage": true, "useNetwork": true, "useNow": true, diff --git a/src/auto-imports.d.ts b/src/auto-imports.d.ts index 2c08991..b57132f 100644 --- a/src/auto-imports.d.ts +++ b/src/auto-imports.d.ts @@ -208,6 +208,7 @@ declare global { const useId: typeof import('vue')['useId'] const useIdle: typeof import('@vueuse/core')['useIdle'] const useImage: typeof import('@vueuse/core')['useImage'] + const useInboxUnread: typeof import('./composables/useInboxUnread')['useInboxUnread'] const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] const useInterval: typeof import('@vueuse/core')['useInterval'] @@ -229,6 +230,7 @@ declare global { const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] + const useNanaBatchPanel: typeof import('./composables/useNanaBatchPanel')['useNanaBatchPanel'] const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] const useNetwork: typeof import('@vueuse/core')['useNetwork'] const useNow: typeof import('@vueuse/core')['useNow'] @@ -343,6 +345,9 @@ declare global { export type { WaybillSource, WaybillContext } from './composables/useAskAdvisor' import('./composables/useAskAdvisor') // @ts-ignore + export type { NanaBatchOpenOptions } from './composables/useNanaBatchPanel' + import('./composables/useNanaBatchPanel') + // @ts-ignore export type { ScanFeedbackType } from './composables/useOperationScanFeedback' import('./composables/useOperationScanFeedback') // @ts-ignore @@ -560,6 +565,7 @@ declare module 'vue' { readonly useId: UnwrapRef readonly useIdle: UnwrapRef readonly useImage: UnwrapRef + readonly useInboxUnread: UnwrapRef readonly useInfiniteScroll: UnwrapRef readonly useIntersectionObserver: UnwrapRef readonly useInterval: UnwrapRef @@ -581,6 +587,7 @@ declare module 'vue' { readonly useMouseInElement: UnwrapRef readonly useMousePressed: UnwrapRef readonly useMutationObserver: UnwrapRef + readonly useNanaBatchPanel: UnwrapRef readonly useNavigatorLanguage: UnwrapRef readonly useNetwork: UnwrapRef readonly useNow: UnwrapRef diff --git a/src/components/HandsontablePro/index.vue b/src/components/HandsontablePro/index.vue index 6786140..aed723a 100644 --- a/src/components/HandsontablePro/index.vue +++ b/src/components/HandsontablePro/index.vue @@ -23,6 +23,36 @@ appStore.theme === 'dark' ? 'ht-theme-classic-dark' : 'ht-theme-classic', ); + /** Vite 异步 CSS 分包时,等 --ht-line-height 就绪再 new Handsontable,避免主题告警 */ + function waitForHotThemeStyles(themeName: string, timeoutMs = 3000): Promise { + return new Promise((resolve) => { + const started = Date.now(); + const probe = document.createElement('div'); + probe.className = themeName; + probe.style.cssText = 'position:absolute;left:-99999px;top:0;visibility:hidden;pointer-events:none;'; + document.body.appendChild(probe); + + const finish = (ok: boolean) => { + probe.remove(); + resolve(ok); + }; + + const tick = () => { + const lineHeight = getComputedStyle(probe).getPropertyValue('--ht-line-height').trim(); + if (lineHeight) { + finish(true); + return; + } + if (Date.now() - started >= timeoutMs) { + finish(false); + return; + } + requestAnimationFrame(tick); + }; + tick(); + }); + } + // 注册所有 Handsontable 模块 registerAllModules(); @@ -749,12 +779,11 @@ } function applyLiquidFieldStyle(el: HTMLElement, focused = false) { - const dark = appStore.theme === 'dark'; - // 内联 !important 压过浏览器 UA / Handsontable 默认边框(截图里那圈硬黑框) + // 与工作台卡片同款磨砂玻璃 token(内联 !important 压过 UA / HOT 默认边框) el.style.setProperty('width', '100%', 'important'); el.style.setProperty('min-width', '0', 'important'); el.style.setProperty('max-width', '100%', 'important'); - el.style.setProperty('height', '24px', 'important'); + el.style.setProperty('height', '26px', 'important'); el.style.setProperty('padding', '0 10px', 'important'); el.style.setProperty('margin', '0', 'important'); el.style.setProperty('border-width', '1px', 'important'); @@ -762,37 +791,35 @@ el.style.setProperty( 'border-color', focused - ? 'color-mix(in srgb, var(--app-primary-color) 36%, transparent)' - : dark - ? 'var(--color-border-2)' - : 'rgba(255, 255, 255, 0.85)', + ? 'color-mix(in srgb, var(--app-primary-color) 22%, var(--app-acrylic-border-strong, rgba(255,255,255,0.92)))' + : 'var(--app-acrylic-border, rgba(255, 255, 255, 0.72))', 'important' ); - el.style.setProperty('border-radius', '999px', 'important'); + el.style.setProperty('border-radius', '12px', 'important'); el.style.setProperty('outline', 'none', 'important'); el.style.setProperty('box-sizing', 'border-box', 'important'); el.style.setProperty( 'background', - dark - ? focused - ? 'var(--color-bg-3)' - : 'var(--color-fill-2)' - : focused - ? 'linear-gradient(165deg, rgba(255,255,255,0.98) 0%, rgba(255,255,255,0.72) 55%, rgba(240,248,248,0.65) 100%)' - : 'linear-gradient(165deg, rgba(255,255,255,0.88) 0%, rgba(255,255,255,0.5) 55%, rgba(245,247,248,0.42) 100%)', + focused + ? 'var(--app-acrylic-hover-bg, rgba(255, 255, 255, 0.44))' + : 'var(--app-acrylic-bg, rgba(255, 255, 255, 0.32))', + 'important' + ); + el.style.setProperty( + 'backdrop-filter', + 'var(--app-acrylic-blur, blur(28px) saturate(160%))', + 'important' + ); + el.style.setProperty( + '-webkit-backdrop-filter', + 'var(--app-acrylic-blur, blur(28px) saturate(160%))', 'important' ); - el.style.setProperty('backdrop-filter', dark ? 'none' : 'blur(12px) saturate(1.2)', 'important'); - el.style.setProperty('-webkit-backdrop-filter', dark ? 'none' : 'blur(12px) saturate(1.2)', 'important'); el.style.setProperty( 'box-shadow', - dark - ? focused - ? '0 0 0 2px color-mix(in srgb, var(--app-primary-color) 28%, transparent)' - : 'none' - : focused - ? 'inset 0 1px 0 rgba(255,255,255,1), inset 0 -1px 0 rgba(0,121,121,0.06), 0 0 0 3px rgba(0,121,121,0.12), 0 3px 10px rgba(15,23,42,0.07)' - : 'inset 0 1px 0 rgba(255,255,255,0.98), inset 0 -1px 1px rgba(15,23,42,0.03), 0 1px 2px rgba(15,23,42,0.04), 0 2px 6px rgba(15,23,42,0.03)', + focused + ? '0 0 0 2px color-mix(in srgb, var(--app-primary-color) 16%, transparent)' + : 'none', 'important' ); el.style.setProperty( @@ -802,11 +829,12 @@ ); el.style.setProperty('font-size', '12px', 'important'); el.style.setProperty('font-weight', '500', 'important'); - el.style.setProperty('line-height', '22px', 'important'); + el.style.setProperty('line-height', '24px', 'important'); el.style.setProperty('font-family', 'inherit', 'important'); el.style.setProperty('caret-color', 'var(--app-primary-color, #054f74)', 'important'); el.style.setProperty('-webkit-appearance', 'none', 'important'); el.style.setProperty('appearance', 'none', 'important'); + el.style.setProperty('transition', 'border-color 0.2s ease, background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease', 'important'); if (el.tagName === 'BUTTON') { el.style.setProperty('cursor', 'pointer', 'important'); el.style.setProperty('text-align', 'left', 'important'); @@ -858,6 +886,15 @@ input.value = raw; input.title = '双击打开筛选 · 回车搜索'; }); + input.addEventListener('mouseenter', () => { + if (document.activeElement === input) return; + input.style.setProperty('background', 'var(--app-acrylic-hover-bg, rgba(255, 255, 255, 0.44))', 'important'); + input.style.setProperty('border-color', 'var(--app-acrylic-border-strong, rgba(255, 255, 255, 0.92))', 'important'); + }); + input.addEventListener('mouseleave', () => { + if (document.activeElement === input) return; + applyLiquidFieldStyle(input, false); + }); input.addEventListener('paste', (e: ClipboardEvent) => { e.stopPropagation(); const clipboardData = e.clipboardData; @@ -1311,7 +1348,8 @@ width: '100%', height: tableHeight, licenseKey: 'non-commercial-and-evaluation', - className: hotThemeClass.value, + // HOT 16:主题必须用 themeName(勿塞进 className),否则会报 stylesheets missing + themeName: hotThemeClass.value, language: 'zh-CN', readOnly: props.readOnly === true, // 可编辑:回车/选中后输入即可开始编辑 @@ -1806,6 +1844,8 @@ removeFilterIconFromColumns(); syncHybridHeaders(); remasureActionColumnFromDom(); + // remasure/updateSettings 后 HOT 会按原生滚动条再次缩短 clone,需再对齐一次 + scheduleCloneOverlaySync(); } }; @@ -1830,24 +1870,92 @@ holder.style.setProperty('-ms-overflow-style', 'none', 'important'); const hider = holder.querySelector(':scope > .wtHider') as HTMLElement | null; - if (hider) { - hider.style.setProperty('min-width', 'calc(100% + 1px)', 'important'); - } const spreader = holder.querySelector(':scope > .wtHider > .wtSpreader') as HTMLElement | null; + // 切勿给 wtSpreader 设 min-width:它带横向虚拟滚动 left 偏移,强行拉宽会在滚到最右出现空白并导致表头/内容错位 if (spreader) { - spreader.style.setProperty('min-width', 'calc(100% + 1px)', 'important'); + spreader.style.removeProperty('min-width'); + } + if (hider) { + hider.style.removeProperty('min-width'); + // 先去掉强制宽度再测:仅在 stretch 铺满、无真实横向溢出时补 1px,稳住自绘横条 + const needsFakeOverflow = props.stretchColumns && holder.scrollWidth <= holder.clientWidth; + if (needsFakeOverflow) { + hider.style.setProperty('min-width', 'calc(100% + 1px)', 'important'); + } } bindHorizontalScrollbar(holder); + scheduleCloneOverlaySync(holder); syncHorizontalScrollbarMetrics(holder); }; + const syncCloneOverlaysFromMaster = (holder?: HTMLElement | null) => { + const currentHolder = holder || masterHolderEl; + if (!currentHolder || !hotContainer.value) return; + const top = hotContainer.value.querySelector('.ht_clone_top .wtHolder') as HTMLElement | null; + const bottom = hotContainer.value.querySelector('.ht_clone_bottom .wtHolder') as HTMLElement | null; + const left = hotContainer.value.querySelector('.ht_clone_left .wtHolder') as HTMLElement | null; + const corner = hotContainer.value.querySelector('.ht_clone_top_left_corner .wtHolder') as HTMLElement | null; + if (top && top.scrollLeft !== currentHolder.scrollLeft) top.scrollLeft = currentHolder.scrollLeft; + if (bottom && bottom.scrollLeft !== currentHolder.scrollLeft) bottom.scrollLeft = currentHolder.scrollLeft; + if (left && left.scrollTop !== currentHolder.scrollTop) left.scrollTop = currentHolder.scrollTop; + if (corner) { + if (corner.scrollLeft !== currentHolder.scrollLeft) corner.scrollLeft = currentHolder.scrollLeft; + if (corner.scrollTop !== currentHolder.scrollTop) corner.scrollTop = currentHolder.scrollTop; + } + }; + + /** 隐藏原生纵条后 HOT 仍按滚动条宽度缩短 clone_top,导致表头比内容窄一截 */ + const syncCloneOverlayWidths = (holder?: HTMLElement | null) => { + const currentHolder = holder || masterHolderEl; + if (!currentHolder || !hotContainer.value) return; + const w = currentHolder.clientWidth; + if (w <= 0) return; + const widthPx = `${w}px`; + // 只校准顶部冻结表头;切勿拉宽 ht_clone_bottom,否则会盖住主表导致滚轮/拖动失效 + const cloneTop = hotContainer.value.querySelector('.ht_clone_top') as HTMLElement | null; + const cloneTopHolder = hotContainer.value.querySelector('.ht_clone_top .wtHolder') as HTMLElement | null; + if (cloneTop) { + cloneTop.style.setProperty('width', widthPx, 'important'); + cloneTop.style.setProperty('right', '0px', 'important'); + cloneTop.style.setProperty('z-index', '180', 'important'); + } + if (cloneTopHolder) cloneTopHolder.style.setProperty('width', widthPx, 'important'); + + // 无底部冻结行时,底 clone 应为不可点的空层 + const cloneBottom = hotContainer.value.querySelector('.ht_clone_bottom') as HTMLElement | null; + if (cloneBottom) { + cloneBottom.style.removeProperty('width'); + cloneBottom.style.setProperty('pointer-events', 'none', 'important'); + cloneBottom.style.setProperty('height', '0px', 'important'); + const bottomHolder = cloneBottom.querySelector('.wtHolder') as HTMLElement | null; + if (bottomHolder) { + bottomHolder.style.removeProperty('width'); + bottomHolder.style.setProperty('pointer-events', 'none', 'important'); + } + } + }; + + /** HOT 布局可能在 afterRender 之后才写回 clone 宽度,延迟再对齐一次 */ + const scheduleCloneOverlaySync = (holder?: HTMLElement | null) => { + syncCloneOverlayWidths(holder); + syncCloneOverlaysFromMaster(holder); + requestAnimationFrame(() => { + syncCloneOverlayWidths(holder); + syncCloneOverlaysFromMaster(holder); + }); + }; + const onMasterHolderScroll = () => { + // 滚动时 HOT 会把 clone_top 宽度改回“预留原生纵条”的窄值,需持续拉齐,否则右侧纵条会顶到表头空隙里 + syncCloneOverlaysFromMaster(); + syncCloneOverlayWidths(); if (scrollSyncRaf != null) return; scrollSyncRaf = window.requestAnimationFrame(() => { scrollSyncRaf = null; + syncCloneOverlayWidths(); syncHorizontalThumbFromScroll(); - syncVerticalThumbFromScroll(); + syncVerticalScrollbarMetrics(); }); }; @@ -1885,28 +1993,38 @@ const trackEl = verticalScrollbarTrackRef.value; if (!currentHolder || !trackEl) return; - // 纵向滚动条从“主数据区(wtHolder)顶部”开始,避免任何表头样式差异带来的重叠 - const holderHost = hotContainer.value?.querySelector('.ht_master .wtHolder') as HTMLElement | null; + // 纵条从冻结表头下沿开始,避免盖到表头;高度对齐主数据可视区剩余高度 const containerEl = containerRef.value; - let nextTop = 40; - if (holderHost && containerEl) { - const holderRect = holderHost.getBoundingClientRect(); + const cloneTop = hotContainer.value?.querySelector('.ht_clone_top') as HTMLElement | null; + const hScroll = horizontalScrollbarTrackRef.value; + let nextTop = 0; + let trackHeight = Math.max(currentHolder.clientHeight, 0); + + if (containerEl) { const containerRect = containerEl.getBoundingClientRect(); - // +1 作为边界安全余量,避免 1px 级别重叠 - nextTop = Math.max(Math.ceil(holderRect.top - containerRect.top) + 1, 0); - } else if (holderHost) { - nextTop = Math.max(Math.ceil(holderHost.offsetTop) + 1, 0); + const holderRect = currentHolder.getBoundingClientRect(); + if (cloneTop) { + const cloneRect = cloneTop.getBoundingClientRect(); + // +2:与冻结表头留出缝,避免贴边看起来像纵条顶进表头 + nextTop = Math.max(Math.ceil(cloneRect.bottom - containerRect.top) + 2, 0); + } else { + nextTop = Math.max(Math.ceil(holderRect.top - containerRect.top), 0); + } + const bottomLimit = hScroll && customScrollbar.visible + ? Math.floor(hScroll.getBoundingClientRect().top - containerRect.top) + : Math.floor(holderRect.bottom - containerRect.top); + trackHeight = Math.max(bottomLimit - nextTop, 0); } + if (customVerticalScrollbar.trackTop !== nextTop) { customVerticalScrollbar.trackTop = nextTop; } - const trackHeight = Math.max(currentHolder.clientHeight, 0); customVerticalScrollbar.trackVisibleHeight = trackHeight; const scrollHeight = Math.max(currentHolder.scrollHeight, currentHolder.clientHeight + 1); const maxScrollTop = Math.max(scrollHeight - currentHolder.clientHeight, 0); - customVerticalScrollbar.visible = maxScrollTop > 0; + customVerticalScrollbar.visible = maxScrollTop > 0 && trackHeight > 0; customVerticalScrollbar.trackHeight = trackHeight; const thumbHeight = maxScrollTop > 0 @@ -2121,18 +2239,15 @@ { deep: true } ); - // 日夜切换:同步 HOT 主题类并刷新表头液态输入样式 + // 日夜切换:走 HOT 官方 useTheme,确保 CSS 变量与内部主题状态一致 watch(hotThemeClass, (cls) => { const root = hotContainer.value; if (root) { root.classList.remove('ht-theme-classic', 'ht-theme-classic-dark'); root.classList.add(cls); } - // Handsontable 会把 className 写到表格根节点 - const hotRoot = hotInstance?.rootElement as HTMLElement | undefined; - if (hotRoot) { - hotRoot.classList.remove('ht-theme-classic', 'ht-theme-classic-dark'); - hotRoot.classList.add(cls); + if (hotInstance) { + hotInstance.useTheme(cls); } nextTick(() => { syncHybridHeaders(); @@ -2151,6 +2266,21 @@ } ); + /** 主题 CSS 就绪后再创建实例(首屏 / 数据晚到补初始化共用) */ + async function initHandsontableWhenReady(options?: { finalize?: boolean }) { + if (hotInstance) return; + const themeReady = await waitForHotThemeStyles(hotThemeClass.value); + if (!themeReady) { + console.warn('[HandsontablePro] theme CSS not ready, init anyway:', hotThemeClass.value); + } + if (hotInstance) return; + initHandsontable(); + if (options?.finalize !== false) { + finalizeInit(); + setupResizeObserver(); + } + } + // 监听数据变化 watch(() => props.data, () => { if (ignoreDataWatch) return; @@ -2158,9 +2288,8 @@ updateData(); } else { nextTick(() => { - setTimeout(() => { - initHandsontable(); - }, 200); + // 仅补创建;finalize/resize 留给 onMounted,避免重复观察 + void initHandsontableWhenReady({ finalize: false }); }); } }, { deep: true }); @@ -2245,6 +2374,10 @@ let resizeObserver: ResizeObserver | null = null; const setupResizeObserver = () => { if (!containerRef.value) return; + if (resizeObserver) { + resizeObserver.disconnect(); + resizeObserver = null; + } resizeObserver = new ResizeObserver((entries) => { const entry = entries[0]; if (!entry || !hotInstance) return; @@ -2280,12 +2413,7 @@ } nextTick(() => { - // 确保样式已加载后再初始化 - setTimeout(() => { - initHandsontable(); - finalizeInit(); - setupResizeObserver(); - }, 200); + void initHandsontableWhenReady(); }); // 添加窗口大小变化监听器 @@ -2443,6 +2571,41 @@ .ht_clone_corner { border: none !important; } + + // 隐藏原生纵条后 HOT 仍按 ~15px 缩短冻结表头;拉满宽度,避免右侧纵条从 freeze 表头旁“冒出来” + .ht_clone_top { + width: 100% !important; + right: 0 !important; + left: 0 !important; + z-index: 180 !important; // 高于自绘纵条,右上角由表头盖住 + background: var(--color-fill-2) !important; + box-sizing: border-box !important; + + .wtHolder { + width: 100% !important; + } + + // 表头底边压住纵条顶,视觉上纵条绝不进冻结区 + &::after { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 1px; + background: var(--color-border-2); + pointer-events: none; + z-index: 1; + } + } + + // 无底部冻结行时,底 clone 常被撑成整表透明层,挡住滚轮与纵条拖动 + .ht_clone_bottom { + pointer-events: none !important; + height: 0 !important; + max-height: 0 !important; + overflow: hidden !important; + } .wtHolder { border: none !important; @@ -2463,10 +2626,8 @@ scrollbar-width: none; -ms-overflow-style: none; - // 主表 wtHider:stretchH 拉满后 HOT 判定无横向滚动,刷新后横条会消失;略宽于视口以稳定显示横条 - > .wtHider { - min-width: calc(100% + 1px) !important; - } + // wtHider 的 1px 溢出由 ensureHorizontalScrollbarVisible 按需内联设置; + // 勿写死 min-width,否则宽表滚到最右会出现空白列、表头与内容错位 &::-webkit-scrollbar { width: 0 !important; @@ -2742,19 +2903,20 @@ width: 100% !important; min-width: 0 !important; max-width: 100%; - height: 24px !important; + height: 26px !important; padding: 0 10px !important; - border-radius: 999px !important; + /* 工作台卡片同款:磨砂玻璃 + 亮边 */ + border-radius: 12px !important; border-width: 1px !important; border-style: solid !important; - border-color: var(--color-border-2) !important; - background: var(--color-bg-2) !important; - backdrop-filter: none; - -webkit-backdrop-filter: none; + border-color: var(--app-acrylic-border, rgba(255, 255, 255, 0.72)) !important; + background: var(--app-acrylic-bg, rgba(255, 255, 255, 0.32)) !important; + backdrop-filter: var(--app-acrylic-blur, blur(28px) saturate(160%)); + -webkit-backdrop-filter: var(--app-acrylic-blur, blur(28px) saturate(160%)); box-shadow: none !important; font-size: 12px !important; font-weight: 500 !important; - line-height: 22px !important; + line-height: 24px !important; color: var(--color-text-2) !important; outline: none !important; box-sizing: border-box !important; @@ -2762,20 +2924,30 @@ caret-color: var(--app-primary-color, #054f74); -webkit-appearance: none !important; appearance: none !important; + transition: + border-color 0.2s ease, + background 0.2s ease, + color 0.2s ease, + box-shadow 0.2s ease; } :deep(.ht-header-hybrid-input) { &:hover { - background: var(--color-fill-2) !important; + border-color: var(--app-acrylic-border-strong, rgba(255, 255, 255, 0.92)) !important; + background: var(--app-acrylic-hover-bg, rgba(255, 255, 255, 0.44)) !important; box-shadow: none !important; } &:focus, &:focus-visible { color: var(--color-text-1) !important; - border-color: color-mix(in srgb, var(--app-primary-color) 36%, transparent) !important; - background: var(--color-bg-2) !important; - box-shadow: 0 0 0 2px color-mix(in srgb, var(--app-primary-color) 22%, transparent) !important; + border-color: color-mix( + in srgb, + var(--app-primary-color) 22%, + var(--app-acrylic-border-strong, rgba(255, 255, 255, 0.92)) + ) !important; + background: var(--app-acrylic-hover-bg, rgba(255, 255, 255, 0.44)) !important; + box-shadow: 0 0 0 2px color-mix(in srgb, var(--app-primary-color) 16%, transparent) !important; } &::placeholder { @@ -2798,6 +2970,8 @@ &:hover { color: var(--color-text-2) !important; + border-color: var(--app-acrylic-border-strong, rgba(255, 255, 255, 0.92)) !important; + background: var(--app-acrylic-hover-bg, rgba(255, 255, 255, 0.44)) !important; } } @@ -2938,7 +3112,8 @@ border-left: 0.5px solid #f0f0f0; cursor: pointer; user-select: none; - z-index: 3; + // 高于 ht_clone_bottom(130),低于冻结表头(180),避免滚到表头右上角时纵条压住表头 + z-index: 150; opacity: 0.92; } diff --git a/src/locale/en-US.ts b/src/locale/en-US.ts index 958f283..dba4a0e 100644 --- a/src/locale/en-US.ts +++ b/src/locale/en-US.ts @@ -5046,6 +5046,7 @@ export default { 'track.order.drawer.tabs.small': 'Small package', 'track.order.drawer.tabs.main': 'Main order', 'track.order.table.orderType': 'Order type', + 'track.order.table.orderNo': 'Order number', 'track.order.table.customsOrderNo': 'Customer order number', 'track.order.table.customerShortName': 'Customer short name', 'track.order.table.thirdPartyOrderNo': 'Last mile order number', @@ -5065,6 +5066,7 @@ export default { 'track.order.table.product': 'Sales product', 'track.order.table.channel': 'Service channel', 'track.order.table.apiCode': 'API service provider', + 'track.order.table.countryCode': 'Country', 'track.order.table.destCountryCode': 'Country', 'track.order.table.province': 'Province/State', 'track.order.table.city': 'City', diff --git a/src/locale/zh-CN.ts b/src/locale/zh-CN.ts index 7a6a9de..b346b6a 100644 --- a/src/locale/zh-CN.ts +++ b/src/locale/zh-CN.ts @@ -5116,6 +5116,7 @@ export default { 'track.order.drawer.tabs.package': '大包', 'track.order.drawer.tabs.main': '主单', 'track.order.table.orderType': '订单类型', + 'track.order.table.orderNo': '订单号', 'track.order.table.customsOrderNo': '客户单号', 'track.order.table.customerShortName': '客户简称', 'track.order.table.thirdPartyOrderNo': '尾程单号', @@ -5135,6 +5136,7 @@ export default { 'track.order.table.product': '销售产品', 'track.order.table.channel': '服务渠道', 'track.order.table.apiCode': 'API服务商', + 'track.order.table.countryCode': '国家', 'track.order.table.destCountryCode': '国家', 'track.order.table.province': '州省', 'track.order.table.city': '城市', diff --git a/src/main.ts b/src/main.ts index e4cc87a..fb5e954 100644 --- a/src/main.ts +++ b/src/main.ts @@ -51,8 +51,7 @@ function isH5LikePath(path: string) { normalized === '/h5' || normalized.startsWith('/h5/') || normalized.startsWith('/wechat/') || - normalized === '/track/query' || - normalized.startsWith('/track/') + normalized === '/track/query' ); }