fix: 全面审查修复 14 个 bug,新增 Rust 单元测试

CRITICAL:
- PathTable/MergePreview 操作后不重新渲染(加 dataVersion 版本号机制)
- moveUp/moveDown 后 selectedIndices 过时(更新到新位置)

HIGH:
- ImportDialog 显示 "true" 而非路径数量(改为 number 类型)
- F1 快捷键无效果(添加 onHelp 回调)
- useKeyboard 每次渲染重复注册事件(改用 ref 模式)
- batch delete 撤销顺序错误(拆分为独立记录)
- importPaths 存储数组引用而非副本
- StringList.all 暴露内部数组(改为返回副本)
- expand_env_vars 静默吞 API 错误(加 log::warn)
- join_path 写入前未修剪路径(加 trim 避免注册表污染)

MEDIUM:
- handleClean 总传 () => true 不验证无效路径
- HelpDialog/ImportDialog 缺 Escape 关闭
- initDarkMode 不同步 Zustand store
- 多处硬编码中文改为 i18n.t()
- Rust unsafe 块补全 SAFETY 注释

新增 Rust 测试: system.rs 4 个单元测试

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 23:14:26 +08:00
parent b1acb3690c
commit 2ceec54790
11 changed files with 173 additions and 93 deletions
+20 -10
View File
@@ -1,22 +1,32 @@
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
interface ImportDialogProps {
open: boolean;
hasSystem: boolean;
hasUser: boolean;
systemCount: number;
userCount: number;
onSelect: (target: 'system' | 'user' | 'both') => void;
onCancel: () => void;
}
export function ImportDialog({
open,
hasSystem,
hasUser,
systemCount,
userCount,
onSelect,
onCancel,
}: ImportDialogProps) {
const { t } = useTranslation();
useEffect(() => {
if (!open) return;
const handler = (e: KeyboardEvent) => {
if (e.key === 'Escape') onCancel();
};
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
}, [open, onCancel]);
if (!open) return null;
return (
@@ -32,12 +42,12 @@ export function ImportDialog({
>
<h2 className="text-lg font-semibold mb-4">{t('dialog.importTarget')}</h2>
<p className="text-sm mb-4 opacity-70">
{hasSystem && `系统变量: ${hasSystem}`}
{hasSystem && hasUser && ' | '}
{hasUser && `用户变量: ${hasUser}`}
{systemCount > 0 && `系统变量: ${systemCount}`}
{systemCount > 0 && userCount > 0 && ' | '}
{userCount > 0 && `用户变量: ${userCount}`}
</p>
<div className="flex flex-col gap-2">
{hasSystem && (
{systemCount > 0 && (
<button
className="px-4 py-2 text-sm rounded border text-left"
style={{ borderColor: 'var(--app-border)' }}
@@ -46,7 +56,7 @@ export function ImportDialog({
{t('dialog.importSystem')}
</button>
)}
{hasUser && (
{userCount > 0 && (
<button
className="px-4 py-2 text-sm rounded border text-left"
style={{ borderColor: 'var(--app-border)' }}
@@ -55,7 +65,7 @@ export function ImportDialog({
{t('dialog.importUser')}
</button>
)}
{hasSystem && hasUser && (
{systemCount > 0 && userCount > 0 && (
<button
className="px-4 py-2 text-sm rounded border text-left"
style={{ borderColor: 'var(--app-border)' }}