[feat]:[FL-108][系统日志页面:实现关键词防抖搜索,对齐用户管理页面交互]

实现系统日志页面的防抖搜索功能,提升交互体验与用户管理页面保持一致

改动内容:
- 添加 actionDebounceTimeoutRef 和 userIdDebounceTimeoutRef 用于防抖管理
- 新增 handleActionChange 和 handleUserIdChange 处理器,实现500ms防抖逻辑
- 输入框变化时自动重置 offset、cardViewPage 和 allLoadedLogs
- 添加 useEffect 清理函数,组件卸载时清理 timeout
- 更新表格和卡片视图的 Input onChange 使用新的防抖处理器
- 保留"查询"和"重置筛选"按钮作为快捷操作

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
chengkai3
2026-06-19 17:14:39 +08:00
parent 7772ac163c
commit cb87f3832b
+47 -24
View File
@@ -52,9 +52,52 @@ export default function AdminSyslogPage() {
const [allLoadedLogs, setAllLoadedLogs] = useState<AuditLogItem[]>([]);
const [isLoadingMore, setIsLoadingMore] = useState(false);
const pageCardRef = useRef<HTMLDivElement | null>(null);
const actionDebounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const userIdDebounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const canRead = hasPermission("menu.read") || hasPermission("menu.manage");
const handleActionChange = (value: string) => {
setDraftFilters((prev) => ({ ...prev, action: value }));
if (actionDebounceTimeoutRef.current) {
clearTimeout(actionDebounceTimeoutRef.current);
}
actionDebounceTimeoutRef.current = setTimeout(() => {
setFilters((prev) => ({ ...prev, action: value.trim() }));
setOffset(0);
setCardViewPage(1);
setAllLoadedLogs([]);
}, 500);
};
const handleUserIdChange = (value: string) => {
setDraftFilters((prev) => ({ ...prev, user_id: value }));
if (userIdDebounceTimeoutRef.current) {
clearTimeout(userIdDebounceTimeoutRef.current);
}
userIdDebounceTimeoutRef.current = setTimeout(() => {
setFilters((prev) => ({ ...prev, user_id: value.trim() }));
setOffset(0);
setCardViewPage(1);
setAllLoadedLogs([]);
}, 500);
};
useEffect(() => {
return () => {
if (actionDebounceTimeoutRef.current) {
clearTimeout(actionDebounceTimeoutRef.current);
}
if (userIdDebounceTimeoutRef.current) {
clearTimeout(userIdDebounceTimeoutRef.current);
}
};
}, []);
const logsPath = useMemo(() => {
const params = new URLSearchParams();
params.set("limit", String(PAGE_SIZE));
@@ -345,12 +388,7 @@ export default function AdminSyslogPage() {
allowClear
placeholder="按动作筛选(如 auth.login"
value={draftFilters.action}
onChange={(event) =>
setDraftFilters((prev) => ({
...prev,
action: event.target.value,
}))
}
onChange={(event) => handleActionChange(event.target.value)}
/>
</Form.Item>
<Form.Item label="用户ID">
@@ -358,12 +396,7 @@ export default function AdminSyslogPage() {
allowClear
placeholder="按用户ID筛选(如 openclaw"
value={draftFilters.user_id}
onChange={(event) =>
setDraftFilters((prev) => ({
...prev,
user_id: event.target.value,
}))
}
onChange={(event) => handleUserIdChange(event.target.value)}
/>
</Form.Item>
<Form.Item>
@@ -399,12 +432,7 @@ export default function AdminSyslogPage() {
allowClear
placeholder="按动作筛选(如 auth.login"
value={draftFilters.action}
onChange={(event) =>
setDraftFilters((prev) => ({
...prev,
action: event.target.value,
}))
}
onChange={(event) => handleActionChange(event.target.value)}
/>
</Form.Item>
<Form.Item label="用户ID" className="min-w-[280px]">
@@ -412,12 +440,7 @@ export default function AdminSyslogPage() {
allowClear
placeholder="按用户ID筛选(如 openclaw"
value={draftFilters.user_id}
onChange={(event) =>
setDraftFilters((prev) => ({
...prev,
user_id: event.target.value,
}))
}
onChange={(event) => handleUserIdChange(event.target.value)}
/>
</Form.Item>
<Form.Item>