fix(product-archive): 固定列不再透字,操作列改图标按钮

问题:产品全量档案的「序号」「操作」是两个 position: sticky 固定列。
主题样式把半透明的 --sc-hover(rgba(17,19,21,0.035))用 !important 打到了
这两个固定列上,覆盖了组件自带的不透明底色;横向滚动时压在固定列下方的
单元格文字就会透出来,污染序号列与操作列。

修复:
- .archive-td-index / .archive-td-actions 从半透明 hover 规则中摘出,
  改为「不透明底色 var(--sc-surface) + linear-gradient(var(--sc-hover)) 叠加色层」,
  视觉与原来一致,但底色恒不透明(浅色与深色主题均适用)
- 操作列「查看 / 更多」文字按钮改为图标按钮(Eye / MoreHorizontal),
  补 title 与 aria-label,菜单项加图标并改用 --sc-* 主题变量配色
- 操作列宽度由 138px 收窄到 96px(colgroup / th / td 同步)

验证:3001 真机 puppeteer 复验 9/9 通过——hover 与横向滚动后两个固定列
背景均为不透明 rgb;操作列仅 2 个图标、无文字、宽度 96px;「更多」菜单与
「商品修改日志」入口正常,图标「查看」仍能打开条码档案详情。
type-check EXIT=0。jest 的 3 个失败用例均与本改动无关(主体文件属其他线程
未提交改动,或与 HEAD 逐字节一致属既有失败)。
This commit is contained in:
WuYongJie 2026-09-16 13:52:12 +08:00
parent 2a7d2b04a2
commit 9c9a6a9a08
4 changed files with 45 additions and 24 deletions

View File

@ -1,7 +1,7 @@
'use client'
import { useEffect, useRef, useState } from 'react'
import { ChevronDown } from 'lucide-react'
import { Eye, History, MoreHorizontal } from 'lucide-react'
import type { SupplyChainProductArchiveRow } from '@/lib/supply-chain-product-archive'
export function ProductArchiveActions({
@ -29,36 +29,42 @@ export function ProductArchiveActions({
<div className="archive-row-actions" ref={rootRef}>
<button
type="button"
className="archive-row-action-link"
className="archive-row-action-icon"
title="查看"
aria-label="查看"
onClick={(event) => {
event.stopPropagation()
onView(row)
}}
>
查看
<Eye size={16} strokeWidth={1.8} />
</button>
<button
type="button"
className="archive-row-action-link archive-row-more-trigger"
className="archive-row-action-icon"
title="更多"
aria-label="更多"
aria-haspopup="menu"
aria-expanded={open}
onClick={(event) => {
event.stopPropagation()
setOpen((current) => !current)
}}
>
更多
<ChevronDown size={13} strokeWidth={1.8} />
<MoreHorizontal size={16} strokeWidth={1.8} />
</button>
{open && (
<div className="archive-row-more-menu">
<div className="archive-row-more-menu" role="menu">
<button
type="button"
role="menuitem"
onClick={(event) => {
event.stopPropagation()
setOpen(false)
onChangeLog(row.barcode)
}}
>
<History size={14} strokeWidth={1.8} />
商品修改日志
</button>
</div>
@ -68,46 +74,55 @@ export function ProductArchiveActions({
position: relative;
display: inline-flex;
align-items: center;
gap: 8px;
gap: 4px;
white-space: nowrap;
}
.archive-row-action-link {
.archive-row-action-icon {
display: inline-flex;
width: 26px;
height: 26px;
align-items: center;
gap: 2px;
justify-content: center;
padding: 0;
border: 0;
border-radius: 6px;
background: transparent;
color: #2563eb;
font-size: 12px;
color: var(--sc-muted);
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.archive-row-action-icon:hover { background: var(--sc-hover); color: var(--sc-ink); }
.archive-row-action-icon[aria-expanded='true'] {
background: var(--sc-surface-strong);
color: var(--sc-ink);
}
.archive-row-action-link:hover { color: #1d4ed8; text-decoration: underline; }
.archive-row-more-menu {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 40;
min-width: 148px;
min-width: 152px;
padding: 5px;
border: 1px solid #e4e4e7;
border: 1px solid var(--sc-border);
border-radius: 6px;
background: #fff;
background: var(--sc-surface);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}
.archive-row-more-menu button {
display: block;
display: flex;
width: 100%;
align-items: center;
gap: 8px;
padding: 8px 9px;
border: 0;
border-radius: 4px;
background: transparent;
color: #3f3f46;
color: var(--sc-ink);
font-size: 12px;
text-align: left;
cursor: pointer;
}
.archive-row-more-menu button:hover { background: #f4f4f5; color: #18181b; }
.archive-row-more-menu button:hover { background: var(--sc-hover); }
`}</style>
</div>
)

View File

@ -188,7 +188,7 @@ export const ProductArchiveTableBody = memo(function ProductArchiveTableBody({
position: sticky;
right: 0;
z-index: 3;
min-width: 138px;
min-width: 96px;
padding: 8px 10px;
overflow: visible;
border: 0;

View File

@ -57,15 +57,21 @@ export function ProductArchiveThemeStyles() {
.archive-product-image {
border-color: var(--sc-border) !important;
}
tbody tr:hover .archive-td-index,
tbody tr:hover .archive-td-field,
tbody tr:hover .archive-td-actions,
.archive-page-btn:hover:not(:disabled),
.archive-toolbar-action:hover,
.archive-toolbar-clear-filter:hover,
.archive-reload:hover {
background: var(--sc-hover) !important;
}
/* 固定列(序号 / 操作)必须始终保留不透明底色:
hover 只能在其上叠加一层半透明色,否则横向滚动时压在固定列下方的
单元格文字会透出来,污染序号列和操作列 */
tbody tr:hover .archive-td-index,
tbody tr:hover .archive-td-actions {
background-color: var(--sc-surface) !important;
background-image: linear-gradient(var(--sc-hover), var(--sc-hover)) !important;
}
`}</style>
)
}

View File

@ -205,7 +205,7 @@ export function ProductArchiveView({ canDownload = false }: { canDownload?: bool
/>
)),
)}
<col style={{ width: 138 }} />
<col style={{ width: 96 }} />
</colgroup>
<thead className="archive-table-head">
{/* 一级表头:分组 */}
@ -473,7 +473,7 @@ export function ProductArchiveView({ canDownload = false }: { canDownload?: bool
}
:global(.archive-th-actions) {
position: sticky; right: 0; z-index: 4;
width: 138px; min-width: 138px; height: 76px; padding: 0 8px;
width: 96px; min-width: 96px; height: 76px; padding: 0 8px;
border: 0; border-bottom: 1px solid #e4e4e7; background: #f4f4f5;
box-shadow: -5px 0 10px rgba(24, 24, 27, 0.06);
color: #27272a; font-size: 13px; font-weight: 600; text-align: center;