refactor(admin): 用 usehooks-ts useEventListener/useTimeout 与 dayjs 替代手写监听、撤销计时与相对时间

This commit is contained in:
2026-08-08 17:21:33 +08:00
parent dab28f85e8
commit 74d5b90faa
3 changed files with 16 additions and 27 deletions

View File

@@ -3,6 +3,7 @@ import { DatePicker, Input, InputNumber, Select, Spin, Tooltip } from 'antd';
import dayjs, { type Dayjs } from 'dayjs';
import equal from 'fast-deep-equal';
import { usePermission } from '../../hooks/usePermission';
import { useTimeout } from 'usehooks-ts';
import { useEditableCellStore } from '../../store/editableCell/editableCellStore';
import { message } from '../../ui/app-message';
import './style.css';
@@ -102,16 +103,10 @@ const EditableCell = <Value,>({
);
// 保存成功后短暂显示「撤销」入口:记录保存前的序列化旧值
const [undoMeta, setUndoMeta] = useState<{ serializedPrevious: unknown } | null>(null);
const undoTimerRef = useRef<number | undefined>(undefined);
// 撤销入口 6 秒后自动消失useTimeout 在 undoMeta 置空/组件卸载时自动清理
useTimeout(() => setUndoMeta(null), undoMeta ? 6_000 : null);
const enabled = !disabled && (!permission || hasPermission(permission));
useEffect(
() => () => {
window.clearTimeout(undoTimerRef.current);
},
[],
);
const original = useMemo(
() =>
serializeEditableValue(
@@ -146,10 +141,8 @@ const EditableCell = <Value,>({
await onSave(parseValue ? parseValue(serialized) : (serialized as Value));
useEditableCellStore.getState().clearIfActive(idRef.current);
setEditing(false);
// 提供 6 秒内的撤销入口(把旧值再保存一次)
// 提供 6 秒内的撤销入口(把旧值再保存一次)useTimeout 负责到时自动清除
setUndoMeta({ serializedPrevious: previousValue });
window.clearTimeout(undoTimerRef.current);
undoTimerRef.current = window.setTimeout(() => setUndoMeta(null), 6_000);
return true;
} catch (error) {
message.error(getErrorMessage(error, '保存失败'));
@@ -210,7 +203,6 @@ const EditableCell = <Value,>({
}
useEditableCellStore.getState().setActiveCell({ id: idRef.current, save });
// 重新进入编辑时清掉上一次的撤销入口
window.clearTimeout(undoTimerRef.current);
setUndoMeta(null);
setDraft(normalizeEditableValue(formatValue ? formatValue(value) : value, editor));
setEditing(true);
@@ -218,7 +210,6 @@ const EditableCell = <Value,>({
const handleUndo = async () => {
if (!undoMeta) return;
window.clearTimeout(undoTimerRef.current);
setUndoMeta(null);
try {
await onSave(