From 4f88a814d5e47e0bea997341359ce309356d35ae Mon Sep 17 00:00:00 2001 From: Drsakura Date: Fri, 23 Oct 2026 14:23:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(data-ui):=20=E5=AF=BC=E5=85=A5=E7=B1=BB?= =?UTF-8?q?=E5=88=AB=E6=94=B9=E4=B8=BA=E5=B8=B8=E9=A9=BB=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=EF=BC=8C=E5=8F=96=E6=B6=88=E5=8B=BE=E9=80=89=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E4=BB=8E=E5=88=97=E8=A1=A8=E6=B6=88=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前顶部类别取自服务端返回的「本次已选类别」,取消一个后列表被重算,那一项直接消失 —— 把勾选框做成了单向筛选。现在改为取包头里的全部类别(preview.file.categories)常驻显示, 勾选状态只决定预览与导入范围;取消最后一类时给明确提示,不再静默无响应。 --- frontend/src/pages/DataTransfer.jsx | 44 +++++++++++++++++---------- frontend/src/styles/data-transfer.css | 23 ++++++++++++++ 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/frontend/src/pages/DataTransfer.jsx b/frontend/src/pages/DataTransfer.jsx index 358f259..0ef6da9 100644 --- a/frontend/src/pages/DataTransfer.jsx +++ b/frontend/src/pages/DataTransfer.jsx @@ -71,6 +71,7 @@ function DataTransfer() { const [result, setResult] = useState(null) const [percent, setPercent] = useState(0) const [replanning, setReplanning] = useState(false) + const [categoryHint, setCategoryHint] = useState('') const [dragging, setDragging] = useState(false) const inputRef = useRef(null) @@ -150,6 +151,7 @@ function DataTransfer() { setPreview(null) setResult(null) setPercent(0) + setCategoryHint('') setPhase('checking') setError('') @@ -175,11 +177,16 @@ function DataTransfer() { /** 切换类别后重算预览:包已经在服务器上,不用重传 */ const toggleImport = async key => { - if (replanning) return - const next = importPicks.includes(key) - ? importPicks.filter(item => item !== key) - : [...importPicks, key] - if (!next.length) return + if (replanning || phase === 'applying') return + const on = importPicks.includes(key) + /* 全部取消等于「什么都不导」,服务端把空列表当成「全选」—— + 所以这里明确挡住,并说明原因,而不是点了没反应 */ + if (on && importPicks.length === 1) { + setCategoryHint('至少要勾一类。想放弃这次导入,点下面的「重新选择」。') + return + } + setCategoryHint('') + const next = on ? importPicks.filter(item => item !== key) : [...importPicks, key] setImportPicks(next) setReplanning(true) setError('') @@ -228,6 +235,7 @@ function DataTransfer() { setResult(null) setImportPicks([]) setPercent(0) + setCategoryHint('') setError('') if (inputRef.current) inputRef.current.value = '' } @@ -241,7 +249,10 @@ function DataTransfer() { const busy = phase === 'checking' || phase === 'applying' || replanning const plan = preview?.plan - const availableKeys = preview?.availableCategories || preview?.file?.categories || [] + /* 顶部类别必须取「包里有哪几类」,而不是「这次选了哪几类」—— + 后者会随着取消勾选而缩短,表现就是「点一下那一类就消失了」。 + preview.file.categories 来自包头,重算预览也不会变。 */ + const categoriesInFile = preview?.file?.categories || [] return (
@@ -380,24 +391,25 @@ function DataTransfer() {
导入类别 - {availableKeys.map(key => { + {categoriesInFile.map(key => { const category = categoryByKey.get(key) const on = importPicks.includes(key) return ( - + ) })} {replanning && }
+ {categoryHint &&

{categoryHint}

}
diff --git a/frontend/src/styles/data-transfer.css b/frontend/src/styles/data-transfer.css index 648297d..a352e53 100644 --- a/frontend/src/styles/data-transfer.css +++ b/frontend/src/styles/data-transfer.css @@ -202,6 +202,29 @@ margin-bottom: 12px; } +/* 导入类别是一组常驻的复选框:取消勾选只改「导不导」,不会把它从列表里拿掉 */ +.transfer-cat { + cursor: pointer; + gap: 7px; +} + +.transfer-cat-box { + width: 13px; + height: 13px; + margin: 0; + accent-color: var(--primary-light); + cursor: pointer; +} + +.transfer-cat-box:disabled { + cursor: not-allowed; +} + +.transfer-hint { + margin: -4px 0 10px; + color: var(--warning); +} + .transfer-report { max-height: 320px; }