feat(client): add manual digital employee sync

This commit is contained in:
baiyanyun
2026-06-05 18:24:04 +08:00
parent b7aecad092
commit 17475bf0d7
6 changed files with 170 additions and 120 deletions

View File

@@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type { KeyboardEvent as ReactKeyboardEvent, MouseEvent as ReactMouseEvent } from 'react';
import { Clock3, Download, Eye, PlayCircle } from 'lucide-react';
import { Clock3, Download, Eye, PlayCircle, RefreshCw } from 'lucide-react';
import Avatar3D from '@/components/digital/Avatar3D';
import { basePath } from '@/lib/basePath';
import {
@@ -851,6 +851,36 @@ export default function CommandDeck({ onNavigate }: { onNavigate: (target: Digit
}
}, [isResting, selectedDate, selectedDutyIds, selectedSubmissionDutyIds]);
const flushManagementSync = useCallback(async () => {
setActionBusy('flush_management_sync');
setActionError(null);
setActionNotice(null);
try {
const bridge = window.QimingClawBridge?.digital;
if (!bridge?.flushSync) {
setActionNotice('当前环境未连接 qimingclaw 同步桥。');
return;
}
const syncStatus = await bridge.flushSync();
if (!mountedRef.current) return;
const latestProjection = await getDigitalEmployeeWorkday(selectedDate);
if (!mountedRef.current) return;
setWorkdayProjection(latestProjection);
const statusText = syncStatus.failed > 0
? `同步完成,仍有 ${syncStatus.failed} 条失败记录。`
: syncStatus.pending > 0
? `同步完成,仍有 ${syncStatus.pending} 条待同步记录。`
: '管理端同步完成。';
setActionNotice(statusText);
} catch (error) {
if (mountedRef.current) {
setActionError(error instanceof Error ? error.message : '同步管理端失败');
}
} finally {
if (mountedRef.current) setActionBusy(null);
}
}, [selectedDate]);
const cancelAllTasks = useCallback(() => {
setSelectedDutyIds(new Set());
selectionDirtyRef.current = true;
@@ -1209,6 +1239,16 @@ export default function CommandDeck({ onNavigate }: { onNavigate: (target: Digit
>
</button>
<button
type="button"
className="de-btn-secondary de-btn-sm"
disabled={projectionLoading || actionBusy === 'flush_management_sync'}
onClick={flushManagementSync}
title="立即同步数字员工本地状态到管理端"
>
<RefreshCw size={13} aria-hidden="true" />
<span>{actionBusy === 'flush_management_sync' ? '同步中...' : '同步管理端'}</span>
</button>
</div>
{(actionNotice || actionError || planDataError || workdayProjection?.demo_reason) && (