feat: add digital employee management sync endpoint

This commit is contained in:
baiyanyun
2026-06-05 17:21:48 +08:00
parent b9132c421d
commit ab1d022905
14 changed files with 308 additions and 5 deletions

View File

@@ -16,6 +16,7 @@ interface DigitalEmployeeSyncConfig {
enabled: boolean;
endpoint: string | null;
clientKey: string | null;
authToken: string | null;
batchSize: number;
}
@@ -96,7 +97,7 @@ export async function flushDigitalEmployeeSyncOutbox(): Promise<DigitalEmployeeS
if (syncing) return getDigitalEmployeeSyncStatus();
const config = resolveSyncConfig();
if (!config.enabled || !config.endpoint || !config.clientKey) {
if (!config.enabled || !config.endpoint || !config.clientKey || !config.authToken) {
lastSyncError = null;
return getDigitalEmployeeSyncStatus();
}
@@ -167,6 +168,7 @@ function resolveSyncConfig(): DigitalEmployeeSyncConfig {
enabled: !disabled,
endpoint,
clientKey: readClientKey(serverHost),
authToken: readAuthToken(serverHost),
batchSize,
};
}
@@ -190,6 +192,21 @@ function readClientKey(serverHost: string | null): string | null {
return typeof globalKey === "string" && globalKey.trim() ? globalKey : null;
}
function readAuthToken(serverHost: string | null): string | null {
const oneShotToken = readSetting("auth.token");
if (typeof oneShotToken === "string" && oneShotToken.trim()) {
return oneShotToken;
}
if (serverHost) {
const domain = serverHost.replace(/^https?:\/\//, "").replace(/\/+$/, "");
const domainToken = readSetting(`auth.tokens.${domain}`);
if (typeof domainToken === "string" && domainToken.trim()) {
return domainToken;
}
}
return null;
}
function readPendingOutbox(limit: number): OutboxRow[] {
const db = getDb();
if (!db) return [];
@@ -217,7 +234,7 @@ async function postOutbox(
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${config.clientKey}`,
Authorization: `Bearer ${config.authToken}`,
"X-Qiming-Client-Key": config.clientKey!,
},
body: JSON.stringify({

View File

@@ -455,13 +455,23 @@ window.QimingClawBridge.digital.flushSync()
当前边界:
- 后端接口尚未真正确认,因此客户端先实现可配置 endpoint 和兼容 ack 协议
- qiming-backend 已补最小接收端,先以通用同步记录表承接客户端 outbox
- worker 只消费 outbox不直接侵入 Plan / Task / Run / Event 写入链路。
- 管理端返回格式建议包含 `acked[]`,每项带 `outbox_id``entity_type``entity_id``remote_id`
- 管理端返回格式包含 `acked[]`,每项带 `outbox_id``entity_type``entity_id``remote_id`
- 当前接口沿用管理端登录态鉴权,客户端必须能读取到登录 ticket/token 才会推送;没有 token 时保持本地 outbox 等待。
后端最小落点:
```text
qiming-backend/sql/update-20260605.sql
qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-ui/.../DigitalEmployeeSyncController.java
qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/.../DigitalEmployeeSyncApplicationServiceImpl.java
qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/.../DigitalEmployeeSyncRecord.java
```
下一步:
- 在 qiming-backend 落地 `/api/digital-employee/sync/outbox`
-有 Maven 的环境验证 qiming-backend 编译与接口启动
- 数字员工页面读取 `getSyncStatus()`,展示联动状态。
- 增加 outbox 重试退避策略,避免接口长期不可用时频繁请求。