feat: 支持右键菜单时间戳转换
- 在 useTimestampConverter 中添加 useContextMenuData hook - 智能识别输入是时间戳还是日期时间字符串 - 自动切换到对应模式并执行转换 - 时间戳自动识别秒/毫秒单位
This commit is contained in:
@@ -3,6 +3,7 @@ import dayjs from '@/utils/dayjs';
|
|||||||
import type { UnitType, ZoneType } from '@/config/pageTheme';
|
import type { UnitType, ZoneType } from '@/config/pageTheme';
|
||||||
import { DATE_FORMAT } from '@/config/pageTheme';
|
import { DATE_FORMAT } from '@/config/pageTheme';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useContextMenuData } from '@/utils/useContextMenuData';
|
||||||
|
|
||||||
export interface UseTimestampConverterReturn {
|
export interface UseTimestampConverterReturn {
|
||||||
// State
|
// State
|
||||||
@@ -23,6 +24,15 @@ export interface UseTimestampConverterReturn {
|
|||||||
convert: () => void;
|
convert: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断输入是否为时间戳(纯数字或长度 >= 10 的数字字符串)
|
||||||
|
*/
|
||||||
|
function isTimestampLike(input: string): boolean {
|
||||||
|
const trimmed = input.trim();
|
||||||
|
if (!/^\d+$/.test(trimmed)) return false;
|
||||||
|
return trimmed.length >= 10;
|
||||||
|
}
|
||||||
|
|
||||||
export function useTimestampConverter(): UseTimestampConverterReturn {
|
export function useTimestampConverter(): UseTimestampConverterReturn {
|
||||||
const { t } = useTranslation(['timestamp']);
|
const { t } = useTranslation(['timestamp']);
|
||||||
const [mode, setMode] = useState<'ts2dt' | 'dt2ts'>('ts2dt');
|
const [mode, setMode] = useState<'ts2dt' | 'dt2ts'>('ts2dt');
|
||||||
@@ -63,6 +73,45 @@ export function useTimestampConverter(): UseTimestampConverterReturn {
|
|||||||
}
|
}
|
||||||
}, [mode, tsInput, dtInput, unit, zone, t]);
|
}, [mode, tsInput, dtInput, unit, zone, t]);
|
||||||
|
|
||||||
|
// 处理右键菜单传递的数据
|
||||||
|
const handleContextMenuData = useCallback((payload: string) => {
|
||||||
|
const trimmed = payload.trim();
|
||||||
|
if (isTimestampLike(trimmed)) {
|
||||||
|
// 看起来是时间戳,切换到 ts2dt 模式
|
||||||
|
setMode('ts2dt');
|
||||||
|
setTsInput(trimmed);
|
||||||
|
// 如果是 13 位毫秒级时间戳,自动选择 ms 单位
|
||||||
|
const detectedUnit: UnitType = trimmed.length >= 13 ? 'ms' : 's';
|
||||||
|
setUnit(detectedUnit);
|
||||||
|
// 直接执行转换
|
||||||
|
const num = Number(trimmed);
|
||||||
|
if (!isNaN(num)) {
|
||||||
|
const d = detectedUnit === 'ms' ? dayjs(num) : dayjs.unix(num);
|
||||||
|
if (d.isValid()) {
|
||||||
|
setError('');
|
||||||
|
setResult(d.tz('Asia/Shanghai').format(DATE_FORMAT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 尝试作为日期时间解析
|
||||||
|
const d = dayjs(trimmed);
|
||||||
|
if (d.isValid()) {
|
||||||
|
setMode('dt2ts');
|
||||||
|
setDtInput(d.format(DATE_FORMAT));
|
||||||
|
// 直接执行转换
|
||||||
|
const ms = d.valueOf();
|
||||||
|
setError('');
|
||||||
|
setResult(String(ms));
|
||||||
|
} else {
|
||||||
|
// 无法识别,作为时间戳处理
|
||||||
|
setMode('ts2dt');
|
||||||
|
setTsInput(trimmed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useContextMenuData({ featureKey: 'timestamp', onData: handleContextMenuData });
|
||||||
|
|
||||||
const handleUseNow = useCallback(
|
const handleUseNow = useCallback(
|
||||||
(now: number) => {
|
(now: number) => {
|
||||||
if (mode === 'ts2dt') {
|
if (mode === 'ts2dt') {
|
||||||
|
|||||||
Reference in New Issue
Block a user