吸收数字员工管理端审批治理预览

This commit is contained in:
baiyanyun
2026-06-12 23:03:58 +08:00
parent bd7d7b4913
commit 8ed4e0ce3b
6 changed files with 204 additions and 2 deletions

View File

@@ -996,6 +996,7 @@ public class DigitalEmployeeSyncApplicationServiceImpl implements DigitalEmploye
private boolean matchesAdminView(String view, DigitalEmployeeAdminWorkbenchRowDto row) {
return switch (view) {
case "interventions" -> isInterventionRow(row);
case "approval_governance" -> isApprovalGovernanceRow(row);
case "artifact_lifecycle" -> isArtifactLifecycleRow(row);
case "notifications" -> isNotificationRow(row);
case "audits" -> isAuditRow(row);
@@ -1012,6 +1013,24 @@ public class DigitalEmployeeSyncApplicationServiceImpl implements DigitalEmploye
|| StringUtils.equals(row.getCategory(), "action_notification");
}
private boolean isApprovalGovernanceRow(DigitalEmployeeAdminWorkbenchRowDto row) {
String kind = firstString(row.getKind());
String category = firstString(row.getCategory());
return StringUtils.equals(category, "approval_conflict")
|| StringUtils.equals(category, "risk_approval")
|| contains(kind, "risk_approval")
|| contains(kind, "approval_action_recorded")
|| contains(kind, "approval_decision")
|| contains(kind, "approval_conflict_resolved")
|| contains(kind, "approval_conflict_resolution")
|| (StringUtils.isNotBlank(row.getApprovalId()) && (
StringUtils.equals(category, "route_intervention")
|| StringUtils.equals(category, "route_governance")
|| contains(kind, "route_decision_approval_required")
|| contains(kind, "route_decision_blocked")
));
}
private boolean isArtifactLifecycleRow(DigitalEmployeeAdminWorkbenchRowDto row) {
return StringUtils.equals(row.getEntityType(), "artifact")
|| startsWithAny(row.getKind(), "artifact_")

View File

@@ -278,6 +278,77 @@ class DigitalEmployeeSyncApplicationServiceImplTest {
assertThat(result.getRecords().get(1).getRouteDecisionId()).isEqualTo("route-1");
}
@Test
void queryAdminWorkbenchApprovalGovernanceReturnsApprovalConflictRiskAndHistoryRowsOnly() {
when(repository.queryBusinessRecords(eq(101L), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(1L), eq(20L)))
.thenReturn(page(List.of(
record("outbox-approval-conflict", "approval", "approval-1", 101L, new Date(10_000),
Map.of(
"entity_type", "approval",
"title", "远端审批冲突",
"status", "pending",
"approval_conflict_active", true,
"approval_conflict_reason", "terminal_status_mismatch",
"approval_id", "approval-1",
"plan_id", "plan-1",
"task_id", "task-1",
"priority", "high"
),
Map.of("id", "approval-1", "status", "pending")),
record("outbox-risk-approval", "event", "event-risk-1", 101L, new Date(11_000),
Map.of(
"entity_type", "event",
"category", "risk_approval",
"kind", "risk_approval_required",
"status", "blocked",
"title", "高风险动作待审批",
"approval_id", "approval-risk-1",
"plan_id", "plan-1",
"risk_level", "high"
),
Map.of("id", "event-risk-1", "kind", "risk_approval_required")),
record("outbox-route-approval", "event", "event-route-approval", 101L, new Date(12_000),
Map.of(
"entity_type", "event",
"category", "route_governance",
"kind", "route_decision_approval_required",
"status", "pending",
"title", "路由动作待审批",
"approval_id", "approval-route-1",
"route_decision_id", "route-1",
"reason", "route_decision_approval_required"
),
Map.of("id", "event-route-approval", "kind", "route_decision_approval_required")),
record("outbox-approval-history", "event", "event-approval-history", 101L, new Date(13_000),
Map.of(
"entity_type", "event",
"kind", "approval_action_recorded",
"status", "recorded",
"title", "审批动作记录",
"approval_id", "approval-1",
"message", "已转交审批"
),
Map.of("id", "event-approval-history", "kind", "approval_action_recorded")),
record("outbox-task", "task", "task-1", 101L, new Date(14_000),
Map.of("entity_type", "task", "title", "普通任务", "status", "running"),
Map.of("id", "task-1", "status", "running"))
)));
DigitalEmployeeAdminWorkbenchPageDto result = service.queryAdminWorkbench(
"approval_governance", null, null, null, null, null, null, null, null, null, null, null, 1L, 20L
);
assertThat(result.getTotal()).isEqualTo(4);
assertThat(result.getRecords()).extracting(DigitalEmployeeAdminWorkbenchRowDto::getEntityId)
.containsExactly("approval-1", "event-risk-1", "event-route-approval", "event-approval-history");
assertThat(result.getRecords().get(0).getView()).isEqualTo("approval_governance");
assertThat(result.getRecords().get(0).getApprovalId()).isEqualTo("approval-1");
assertThat(result.getRecords().get(0).getCategory()).isEqualTo("approval_conflict");
assertThat(result.getRecords().get(1).getCategory()).isEqualTo("risk_approval");
assertThat(result.getRecords().get(2).getRouteDecisionId()).isEqualTo("route-1");
assertThat(result.getRecords().get(3).getApprovalId()).isEqualTo("approval-1");
}
@Test
void queryAdminWorkbenchAuditsRedactsSensitivePayloadFields() {
when(repository.queryBusinessRecords(eq(101L), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null), eq(1L), eq(20L)))