fix(client): sync digital approval decisions

This commit is contained in:
baiyanyun
2026-06-07 17:52:20 +08:00
parent b07f133ed6
commit aee8af0877
3 changed files with 126 additions and 4 deletions

View File

@@ -337,6 +337,7 @@ export function saveDigitalEmployeeUiState(
): DigitalEmployeeUiState {
const state = normalizeUiState(update.state);
writeSetting(UI_STATE_KEY, state);
recordUiApprovalDecision(update);
if (update.action) {
recordDigitalEmployeeRuntimeEvent({
kind: `digital_workday_${update.action}`,
@@ -353,6 +354,59 @@ export function saveDigitalEmployeeUiState(
return state;
}
function recordUiApprovalDecision(update: DigitalEmployeeUiStateUpdate): void {
if (update.action !== "decide_approval") return;
const metadata = objectRecord(update.metadata);
const decisionId = stringValue(metadata?.decision_id);
const decision = stringValue(metadata?.decision);
if (!decisionId || !decision) return;
const db = getDb();
if (!db) return;
const existing = db.prepare(`
SELECT id, plan_id, task_id, run_id, title, status, payload, created_at
FROM digital_approvals
WHERE id = ?
`).get(decisionId) as Record<string, unknown> | undefined;
if (!existing) return;
const now = new Date().toISOString();
const previousStatus = stringField(existing, "status") || "pending";
const storedPayload = parseStoredPayload(existing["payload"]);
const storedPayloadRecord = objectRecord(storedPayload);
const payload = storedPayloadRecord
? {
...storedPayloadRecord,
decision,
decidedAt: now,
previousStatus,
}
: {
value: storedPayload,
decision,
decidedAt: now,
previousStatus,
};
upsertApproval({
id: decisionId,
planId: stringField(existing, "plan_id"),
taskId: stringField(existing, "task_id"),
runId: stringField(existing, "run_id"),
title: stringField(existing, "title") || "待确认事项",
status: approvalDecisionStatus(decision),
payload,
now,
});
}
function approvalDecisionStatus(decision: string): string {
const normalized = decision.toLowerCase();
if (["approve", "approved", "accept", "accepted"].includes(normalized)) return "approved";
if (["reject", "rejected", "deny", "denied"].includes(normalized)) return "rejected";
if (["dismiss", "dismissed", "skip", "skipped"].includes(normalized)) return "dismissed";
return "completed";
}
export function readDigitalEmployeeRuntimeRecords(
limit = 120,
): DigitalEmployeeRuntimeRecords {