1569 lines
73 KiB
TypeScript
1569 lines
73 KiB
TypeScript
import { XProTable } from '@/components/ProComponents';
|
||
import WorkspaceLayout from '@/components/WorkspaceLayout';
|
||
import { SUCCESS_CODE } from '@/constants/codes.constants';
|
||
import {
|
||
apiDigitalEmployeeAdminActionSubmit,
|
||
apiDigitalEmployeeAdminAuditArchive,
|
||
apiDigitalEmployeeAdminBillingEstimates,
|
||
apiDigitalEmployeeAdminDailyReportSendRecord,
|
||
apiDigitalEmployeeAdminPolicySnapshots,
|
||
apiDigitalEmployeeAdminWorkbenchList,
|
||
} from '@/services/systemManage';
|
||
import type {
|
||
DigitalEmployeeAdminWorkbenchRow,
|
||
DigitalEmployeeAdminWorkbenchView,
|
||
DigitalEmployeeBillingEstimate,
|
||
} from '@/types/interfaces/systemManage';
|
||
import type {
|
||
ActionType,
|
||
FormInstance,
|
||
ProColumns,
|
||
} from '@ant-design/pro-components';
|
||
import {
|
||
Button,
|
||
Drawer,
|
||
message,
|
||
Space,
|
||
Statistic,
|
||
Tabs,
|
||
Tag,
|
||
Typography,
|
||
} from 'antd';
|
||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||
import { history, useModel } from 'umi';
|
||
|
||
const WORKBENCH_TABS: Array<{
|
||
key: DigitalEmployeeAdminWorkbenchView;
|
||
label: string;
|
||
}> = [
|
||
{ key: 'business', label: '业务视图' },
|
||
{ key: 'interventions', label: '介入台' },
|
||
{ key: 'approval_governance', label: '审批治理' },
|
||
{ key: 'approval_policies', label: '审批策略' },
|
||
{ key: 'service_operations', label: '服务运营' },
|
||
{ key: 'artifact_lifecycle', label: '产物治理' },
|
||
{ key: 'notifications', label: '通知运营' },
|
||
{ key: 'notification_policies', label: '通知策略' },
|
||
{ key: 'audits', label: '审计诊断' },
|
||
{ key: 'daily_reports', label: '日报运营' },
|
||
{ key: 'governance_commands', label: '治理命令' },
|
||
{ key: 'route_governance', label: '路由治理' },
|
||
{ key: 'policy_conflicts', label: '策略冲突' },
|
||
{ key: 'memory_governance', label: '记忆治理' },
|
||
{ key: 'memory_policies', label: '记忆策略' },
|
||
{ key: 'skill_audits', label: '技能审计' },
|
||
{ key: 'policy_center', label: '策略中心' },
|
||
{ key: 'scheduler_operations', label: '调度运营' },
|
||
{ key: 'plan_step_dispatch', label: '步骤调度' },
|
||
{ key: 'plan_governance', label: '计划治理' },
|
||
{ key: 'plan_revisions', label: '计划版本' },
|
||
{ key: 'governance_policies', label: '治理策略' },
|
||
{ key: 'plan_revision_materialization', label: '版本物化' },
|
||
];
|
||
|
||
const ENTITY_TYPE_OPTIONS = {
|
||
plan: { text: 'Plan' },
|
||
task: { text: 'Task' },
|
||
run: { text: 'Run' },
|
||
event: { text: 'Event' },
|
||
artifact: { text: 'Artifact' },
|
||
approval: { text: 'Approval' },
|
||
policy_snapshot: { text: 'Policy Snapshot' },
|
||
};
|
||
|
||
const POLICY_KIND_OPTIONS = {
|
||
dispatch: { text: '派发策略' },
|
||
risk_approval: { text: '风险审批策略' },
|
||
route_decision: { text: '入口路由策略' },
|
||
};
|
||
|
||
const STATUS_TONE: Record<string, string> = {
|
||
active: 'processing',
|
||
allowed: 'success',
|
||
approved: 'success',
|
||
blocked: 'error',
|
||
completed: 'success',
|
||
deleted: 'default',
|
||
failed: 'error',
|
||
pending: 'warning',
|
||
rejected: 'error',
|
||
running: 'processing',
|
||
synced: 'success',
|
||
warn: 'warning',
|
||
};
|
||
|
||
function compactText(value?: string, maxLength = 96): string {
|
||
const text = (value || '').replace(/\s+/g, ' ').trim();
|
||
if (!text) return '--';
|
||
return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text;
|
||
}
|
||
|
||
function jsonText(value?: Record<string, unknown>): string {
|
||
if (!value) return '{}';
|
||
return JSON.stringify(value, null, 2);
|
||
}
|
||
|
||
function tone(value?: string): string {
|
||
return value ? STATUS_TONE[value.toLowerCase()] || 'default' : 'default';
|
||
}
|
||
|
||
function renderSummary(record: DigitalEmployeeAdminWorkbenchRow) {
|
||
const title = compactText(record.title || record.entity_id, 72);
|
||
const summary = compactText(record.summary || record.kind || record.category);
|
||
const meta = [
|
||
record.step_id && `Step ${record.step_id}`,
|
||
record.lease_state && `Lease ${record.lease_state}`,
|
||
record.dispatch_status && `Dispatch ${record.dispatch_status}`,
|
||
record.dispatch_policy_key && `Policy ${record.dispatch_policy_key}`,
|
||
record.plan_id && `Plan ${record.plan_id}`,
|
||
record.task_id && `Task ${record.task_id}`,
|
||
record.run_id && `Run ${record.run_id}`,
|
||
record.approval_id && `Approval ${record.approval_id}`,
|
||
record.approval_policy_id && `ApprovalPolicy ${record.approval_policy_id}`,
|
||
record.governance_policy_id && `GovernancePolicy ${record.governance_policy_id}`,
|
||
record.revision_fact_id && `RevisionFact ${record.revision_fact_id}`,
|
||
record.conflict_policy_id && `ConflictPolicy ${record.conflict_policy_id}`,
|
||
record.decision_guard_status && `DecisionGuard ${record.decision_guard_status}`,
|
||
record.service_id && `Service ${record.service_id}`,
|
||
record.service_lease_id && `Lease ${record.service_lease_id}`,
|
||
record.restart_record_id && `Restart ${record.restart_record_id}`,
|
||
record.recovery_policy_id && `Recovery ${record.recovery_policy_id}`,
|
||
record.auto_recovery_status && `AutoRecovery ${record.auto_recovery_status}`,
|
||
record.artifact_id && `Artifact ${record.artifact_id}`,
|
||
record.artifact_graph_id && `ArtifactGraph ${record.artifact_graph_id}`,
|
||
record.artifact_group_id && `ArtifactGroup ${record.artifact_group_id}`,
|
||
record.group_key && `Group ${record.group_key}`,
|
||
record.artifact_count != null && `Artifacts ${record.artifact_count}`,
|
||
record.version_count != null && `Versions ${record.version_count}`,
|
||
record.cleanup_request_id && `Cleanup ${record.cleanup_request_id}`,
|
||
record.route_decision_id && `Route ${record.route_decision_id}`,
|
||
record.policy_kind && `Policy ${record.policy_kind}`,
|
||
record.policy_edit_request_id && `PolicyEdit ${record.policy_edit_request_id}`,
|
||
record.policy_edit_status && `PolicyEditStatus ${record.policy_edit_status}`,
|
||
record.merge_request_id && `PolicyMerge ${record.merge_request_id}`,
|
||
record.merge_recommendation && `MergeAdvice ${record.merge_recommendation}`,
|
||
record.intervention_conflict_status && `Route ${record.intervention_conflict_status}`,
|
||
record.subscription_policy_id && `Subscription ${record.subscription_policy_id}`,
|
||
record.collaboration_thread_id && `Thread ${record.collaboration_thread_id}`,
|
||
record.daily_report_fact_id && `ReportFact ${record.daily_report_fact_id}`,
|
||
record.send_request_id && `SendRequest ${record.send_request_id}`,
|
||
record.memory_id && `Memory ${record.memory_id}`,
|
||
record.merge_candidate_count != null && `Merge ${record.merge_candidate_count}`,
|
||
record.governance_status && `Governance ${record.governance_status}`,
|
||
record.memory_policy_id && `MemoryPolicy ${record.memory_policy_id}`,
|
||
record.memory_policy_status && `MemoryPolicyStatus ${record.memory_policy_status}`,
|
||
record.merge_policy_id && `MergePolicy ${record.merge_policy_id}`,
|
||
record.skill_id && `Skill ${record.skill_id}`,
|
||
record.skill_version && `Version ${record.skill_version}`,
|
||
record.install_status && `Install ${record.install_status}`,
|
||
record.permission_scope && `Scope ${record.permission_scope}`,
|
||
record.policy_source && `PolicySource ${record.policy_source}`,
|
||
record.tool_name && `Tool ${record.tool_name}`,
|
||
record.audit_archive_id && `Archive ${record.audit_archive_id}`,
|
||
record.archive_status && `ArchiveStatus ${record.archive_status}`,
|
||
record.billing_estimate_id && `Billing ${record.billing_estimate_id}`,
|
||
record.billing_source && `BillingSource ${record.billing_source}`,
|
||
record.schedule_id && `Schedule ${record.schedule_id}`,
|
||
record.job_id && `Job ${record.job_id}`,
|
||
record.revision_id && `Revision ${record.revision_id}`,
|
||
].filter((item): item is string => Boolean(item));
|
||
|
||
return (
|
||
<div style={{ minWidth: 0 }}>
|
||
<Space size={6} wrap>
|
||
<Typography.Text strong ellipsis style={{ maxWidth: 260 }}>
|
||
{title}
|
||
</Typography.Text>
|
||
{record.status && <Tag color={tone(record.status)}>{record.status}</Tag>}
|
||
{record.materialized && <Tag color="green">materialized</Tag>}
|
||
</Space>
|
||
<Typography.Text
|
||
type="secondary"
|
||
ellipsis
|
||
style={{ display: 'block', maxWidth: 360, fontSize: 12 }}
|
||
>
|
||
{summary}
|
||
</Typography.Text>
|
||
{meta.length > 0 && (
|
||
<Space size={[4, 4]} wrap style={{ marginTop: 4 }}>
|
||
{meta.slice(0, 4).map((item) => (
|
||
<Tag key={item} color="default" style={{ marginInlineEnd: 0 }}>
|
||
{item}
|
||
</Tag>
|
||
))}
|
||
</Space>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function actionTarget(record: DigitalEmployeeAdminWorkbenchRow, view: DigitalEmployeeAdminWorkbenchView) {
|
||
if (view === 'approval_governance') {
|
||
if (record.category === 'approval_conflict' && record.approval_id) {
|
||
return { entityType: 'approval', entityId: record.approval_id };
|
||
}
|
||
if (record.route_decision_id) {
|
||
return { entityType: 'route_decision', entityId: record.route_decision_id };
|
||
}
|
||
return { entityType: 'event', entityId: record.entity_id };
|
||
}
|
||
if (view === 'approval_policies') {
|
||
return {
|
||
entityType: 'policy_snapshot',
|
||
entityId:
|
||
record.approval_policy_id ||
|
||
record.conflict_policy_id ||
|
||
record.policy_key ||
|
||
record.entity_id,
|
||
};
|
||
}
|
||
if (view === 'interventions' && record.approval_id) {
|
||
return { entityType: 'approval', entityId: record.approval_id };
|
||
}
|
||
if ((view === 'interventions' || view === 'route_governance') && record.route_decision_id) {
|
||
return { entityType: 'route_decision', entityId: record.route_decision_id };
|
||
}
|
||
if (view === 'notifications' && record.notification_id) {
|
||
return { entityType: 'notification', entityId: record.notification_id };
|
||
}
|
||
if (view === 'notification_policies') {
|
||
return {
|
||
entityType: 'notification_policy',
|
||
entityId:
|
||
record.notification_policy_id ||
|
||
record.subscription_policy_id ||
|
||
record.entity_id,
|
||
};
|
||
}
|
||
if (view === 'service_operations') {
|
||
return { entityType: 'event', entityId: record.entity_id };
|
||
}
|
||
if (view === 'artifact_lifecycle' && record.artifact_id) {
|
||
return { entityType: 'artifact', entityId: record.artifact_id };
|
||
}
|
||
if (view === 'daily_reports' && record.report_id) {
|
||
return { entityType: 'daily_report', entityId: record.report_id };
|
||
}
|
||
if (view === 'audits') {
|
||
if (record.diagnostic_id || record.issue_code || record.repair_action) {
|
||
return { entityType: 'diagnostic', entityId: record.diagnostic_id || record.entity_id };
|
||
}
|
||
return { entityType: 'audit', entityId: record.entity_id };
|
||
}
|
||
if (view === 'governance_commands') {
|
||
return { entityType: 'event', entityId: record.entity_id };
|
||
}
|
||
if (view === 'policy_conflicts') {
|
||
return {
|
||
entityType: 'policy_snapshot',
|
||
entityId: record.policy_key || record.policy_kind,
|
||
};
|
||
}
|
||
if (view === 'memory_governance') {
|
||
return { entityType: 'memory', entityId: record.memory_id || record.entity_id };
|
||
}
|
||
if (view === 'memory_policies') {
|
||
return { entityType: 'memory_policy', entityId: record.memory_policy_id || record.merge_policy_id || record.entity_id };
|
||
}
|
||
if (view === 'skill_audits') {
|
||
return { entityType: 'skill', entityId: record.skill_id || record.tool_name || record.entity_id };
|
||
}
|
||
if (view === 'policy_center') {
|
||
return { entityType: 'policy_snapshot', entityId: record.policy_key || record.policy_kind || record.entity_id };
|
||
}
|
||
if (view === 'scheduler_operations') {
|
||
return { entityType: 'scheduler', entityId: record.job_id || record.schedule_id || record.entity_id };
|
||
}
|
||
if (view === 'plan_step_dispatch') {
|
||
return { entityType: 'plan_step', entityId: record.step_id || record.entity_id };
|
||
}
|
||
if (view === 'plan_governance') {
|
||
return { entityType: 'plan', entityId: record.plan_id || record.entity_id };
|
||
}
|
||
if (view === 'plan_revisions') {
|
||
return { entityType: 'revision', entityId: record.revision_id || record.entity_id };
|
||
}
|
||
if (view === 'governance_policies') {
|
||
return { entityType: 'governance_policy', entityId: record.governance_policy_id || record.policy_key || record.entity_id };
|
||
}
|
||
if (view === 'plan_revision_materialization') {
|
||
return { entityType: 'revision', entityId: record.revision_fact_id || record.revision_id || record.entity_id };
|
||
}
|
||
return { entityType: record.entity_type, entityId: record.entity_id };
|
||
}
|
||
|
||
function allowedActions(record: DigitalEmployeeAdminWorkbenchRow, view: DigitalEmployeeAdminWorkbenchView) {
|
||
if (view === 'approval_governance') {
|
||
if (record.category === 'approval_conflict' && record.approval_id) {
|
||
return [
|
||
{ action: 'keep_local', label: '保留本地' },
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
];
|
||
}
|
||
if (record.route_decision_id) {
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'retry_policy_check', label: '重试策略检查' },
|
||
];
|
||
}
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'approval_policies') {
|
||
return [
|
||
{ action: 'pull_policy', label: '批量拉取策略' },
|
||
{ action: 'request_policy_edit', label: '请求策略编辑' },
|
||
{ action: 'request_policy_merge_review', label: '请求合并复核' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'interventions' && record.approval_id) {
|
||
return [
|
||
{ action: 'keep_local', label: '保留本地' },
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
];
|
||
}
|
||
if ((view === 'interventions' || view === 'route_governance') && record.route_decision_id) {
|
||
return [
|
||
{ action: 'request_policy_edit', label: '请求策略编辑' },
|
||
{ action: 'request_policy_merge_review', label: '请求合并复核' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'retry_policy_check', label: '重试策略检查' },
|
||
];
|
||
}
|
||
if (view === 'notifications' && record.notification_id) {
|
||
return [
|
||
{ action: 'mark_read', label: '标记已读' },
|
||
{ action: 'record_send_request', label: '记录发送请求' },
|
||
{ action: 'record_send_result', label: '记录发送结果' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'notification_policies') {
|
||
return [
|
||
{ action: 'pull_policy', label: '拉取通知策略' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'service_operations') {
|
||
return [
|
||
{ action: 'record_start_request', label: '记录启动请求' },
|
||
{ action: 'record_stop_request', label: '记录停止请求' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'artifact_lifecycle' && record.artifact_id) {
|
||
return [
|
||
{ action: 'mark_keep', label: '标记保留' },
|
||
{ action: 'mark_expire', label: '标记到期' },
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
{ action: 'record_cleanup_request', label: '记录批量清理申请' },
|
||
];
|
||
}
|
||
if (view === 'daily_reports' && record.report_id) {
|
||
return [
|
||
{ action: 'mark_delivered', label: '记录已送达' },
|
||
{ action: 'mark_confirmed', label: '确认回执' },
|
||
{ action: 'request_approval', label: '请求审批' },
|
||
{ action: 'record_send_request', label: '记录发送请求' },
|
||
{ action: 'record_send_result', label: '记录发送结果' },
|
||
{ action: 'record_approval_decision', label: '记录审批裁决' },
|
||
];
|
||
}
|
||
if (view === 'audits') {
|
||
const actions = [
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'request_repair_approval', label: '请求修复审批' },
|
||
];
|
||
if (record.diagnostic_id || record.issue_code || record.repair_action) {
|
||
return [
|
||
...actions,
|
||
{ action: 'retry_check', label: '重试诊断' },
|
||
{ action: 'record_repair_intent', label: '记录修复意图' },
|
||
];
|
||
}
|
||
return actions;
|
||
}
|
||
if (view === 'governance_commands') {
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'memory_governance') {
|
||
return [
|
||
{ action: 'archive_memory', label: '批量归档' },
|
||
{ action: 'restore_memory', label: '批量恢复' },
|
||
{ action: 'request_memory_merge_review', label: '请求记忆合并复核' },
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
];
|
||
}
|
||
if (view === 'memory_policies') {
|
||
return [
|
||
{ action: 'pull_policy', label: '拉取记忆策略' },
|
||
{ action: 'request_memory_policy_pull', label: '请求远端记忆策略拉取' },
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'skill_audits') {
|
||
return [
|
||
{ action: 'record_install_request', label: '记录安装请求' },
|
||
{ action: 'record_upgrade_request', label: '记录升级请求' },
|
||
{ action: 'request_permission_review', label: '请求权限复核' },
|
||
{ action: 'mark_reviewed', label: '标记复核' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'policy_center') {
|
||
return [
|
||
{ action: 'pull_policy', label: '批量拉取策略' },
|
||
{ action: 'request_policy_edit', label: '请求策略编辑' },
|
||
{ action: 'request_policy_merge_review', label: '请求合并复核' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'scheduler_operations') {
|
||
return [
|
||
{ action: 'retry_scheduler_check', label: '立即检查调度' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'plan_step_dispatch') {
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'retry_policy_check', label: '重试策略检查' },
|
||
];
|
||
}
|
||
if (view === 'plan_governance') {
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'request_revision_review', label: '请求版本复核' },
|
||
{ action: 'record_escalation', label: '记录升级' },
|
||
];
|
||
}
|
||
if (view === 'plan_revisions') {
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'request_revision_review', label: '请求版本复核' },
|
||
];
|
||
}
|
||
if (view === 'governance_policies') {
|
||
return [
|
||
{ action: 'pull_policy', label: '批量拉取策略' },
|
||
{ action: 'request_policy_edit', label: '请求策略编辑' },
|
||
{ action: 'request_policy_merge_review', label: '请求合并复核' },
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
];
|
||
}
|
||
if (view === 'plan_revision_materialization') {
|
||
return [
|
||
{ action: 'mark_reviewed', label: '标记已看' },
|
||
{ action: 'dismiss', label: '忽略' },
|
||
{ action: 'request_revision_review', label: '请求版本复核' },
|
||
];
|
||
}
|
||
return [];
|
||
}
|
||
|
||
const DigitalEmployeeOps: React.FC = () => {
|
||
const { hasPermission } = useModel('menuModel');
|
||
const actionRef = useRef<ActionType>();
|
||
const formRef = useRef<FormInstance>();
|
||
const [activeView, setActiveView] =
|
||
useState<DigitalEmployeeAdminWorkbenchView>('business');
|
||
const [detailRecord, setDetailRecord] =
|
||
useState<DigitalEmployeeAdminWorkbenchRow | null>(null);
|
||
const [billingEstimate, setBillingEstimate] =
|
||
useState<DigitalEmployeeBillingEstimate | null>(null);
|
||
const [billingLoading, setBillingLoading] = useState(false);
|
||
const businessViewJson = useMemo(
|
||
() => jsonText(detailRecord?.business_view),
|
||
[detailRecord],
|
||
);
|
||
const payloadJson = useMemo(
|
||
() => jsonText(detailRecord?.payload),
|
||
[detailRecord],
|
||
);
|
||
const [submittingAction, setSubmittingAction] = useState<string | null>(null);
|
||
|
||
const loadBillingEstimate = async () => {
|
||
setBillingLoading(true);
|
||
try {
|
||
const response = await apiDigitalEmployeeAdminBillingEstimates({});
|
||
if (response.code === SUCCESS_CODE) {
|
||
setBillingEstimate(response.data || null);
|
||
} else {
|
||
message.error(response.message || '查询成本估算失败');
|
||
}
|
||
} finally {
|
||
setBillingLoading(false);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
if (activeView === 'audits') {
|
||
loadBillingEstimate();
|
||
}
|
||
}, [activeView]);
|
||
|
||
const submitAdminAction = async (
|
||
record: DigitalEmployeeAdminWorkbenchRow,
|
||
action: string,
|
||
) => {
|
||
const target = actionTarget(record, activeView);
|
||
if (!target.entityType || !target.entityId) {
|
||
message.warning('当前记录缺少可操作实体');
|
||
return;
|
||
}
|
||
const submitKey = `${record.sync_record_id}:${action}`;
|
||
setSubmittingAction(submitKey);
|
||
try {
|
||
const response = await apiDigitalEmployeeAdminActionSubmit({
|
||
syncRecordId: record.sync_record_id,
|
||
deviceId: record.device_id,
|
||
entityType: target.entityType,
|
||
entityId: target.entityId,
|
||
action,
|
||
requestPayload: {
|
||
source_view: activeView,
|
||
sync_record_id: record.sync_record_id,
|
||
},
|
||
});
|
||
if (response.code === SUCCESS_CODE && response.data?.ok !== false) {
|
||
message.success('已记录,等待客户端拉取');
|
||
} else {
|
||
message.error(response.message || response.data?.reason_codes?.join(', ') || '动作记录失败');
|
||
}
|
||
} finally {
|
||
setSubmittingAction(null);
|
||
}
|
||
};
|
||
|
||
const submitDailyReportSendRecord = async (
|
||
record: DigitalEmployeeAdminWorkbenchRow,
|
||
) => {
|
||
setSubmittingAction(`${record.sync_record_id}:send-record`);
|
||
try {
|
||
const response = await apiDigitalEmployeeAdminDailyReportSendRecord({
|
||
syncRecordId: record.sync_record_id,
|
||
deviceId: record.device_id,
|
||
entityType: 'daily_report',
|
||
entityId: record.report_id || record.entity_id,
|
||
status: 'sent',
|
||
endpoint: 'admin_record',
|
||
reason: 'operator_recorded_delivery',
|
||
requestPayload: {
|
||
source_view: activeView,
|
||
sync_record_id: record.sync_record_id,
|
||
},
|
||
});
|
||
if (response.code === SUCCESS_CODE && response.data?.ok !== false) {
|
||
message.success('发送结果已记录');
|
||
} else {
|
||
message.error(
|
||
response.message ||
|
||
response.data?.reason_codes?.join(', ') ||
|
||
'记录发送结果失败',
|
||
);
|
||
}
|
||
} finally {
|
||
setSubmittingAction(null);
|
||
}
|
||
};
|
||
|
||
const submitAuditArchive = async (record: DigitalEmployeeAdminWorkbenchRow) => {
|
||
setSubmittingAction(`${record.sync_record_id}:audit-archive`);
|
||
try {
|
||
const response = await apiDigitalEmployeeAdminAuditArchive({
|
||
syncRecordId: record.sync_record_id,
|
||
deviceId: record.device_id,
|
||
entityType: 'audit',
|
||
entityId: record.entity_id,
|
||
status: 'archived',
|
||
archiveLocation: 'admin://audit-archive',
|
||
archiveSummary: {
|
||
category: record.category,
|
||
level: record.level,
|
||
status: record.status,
|
||
summary: record.summary,
|
||
},
|
||
reason: 'operator_marked_archive',
|
||
requestPayload: {
|
||
source_view: activeView,
|
||
sync_record_id: record.sync_record_id,
|
||
},
|
||
});
|
||
if (response.code === SUCCESS_CODE && response.data?.ok !== false) {
|
||
message.success('审计归档已记录');
|
||
} else {
|
||
message.error(
|
||
response.message ||
|
||
response.data?.reason_codes?.join(', ') ||
|
||
'标记归档失败',
|
||
);
|
||
}
|
||
} finally {
|
||
setSubmittingAction(null);
|
||
}
|
||
};
|
||
|
||
const columns: ProColumns<DigitalEmployeeAdminWorkbenchRow>[] = useMemo(
|
||
() => [
|
||
{
|
||
title: '客户端 Key',
|
||
dataIndex: 'client_key',
|
||
hideInTable: true,
|
||
fieldProps: { placeholder: '输入完整客户端 Key', allowClear: true },
|
||
},
|
||
{
|
||
title: '设备 ID',
|
||
dataIndex: 'device_id',
|
||
width: 150,
|
||
ellipsis: true,
|
||
fieldProps: { placeholder: '输入设备 ID', allowClear: true },
|
||
renderText: (value) => value || '--',
|
||
},
|
||
{
|
||
title: '实体类型',
|
||
dataIndex: 'entity_type',
|
||
width: 120,
|
||
valueType: 'select',
|
||
valueEnum: ENTITY_TYPE_OPTIONS,
|
||
fieldProps: { placeholder: '选择实体类型', allowClear: true },
|
||
render: (_, record) => <Tag>{record.entity_type || '--'}</Tag>,
|
||
},
|
||
{
|
||
title: '实体 ID',
|
||
dataIndex: 'entity_id',
|
||
width: 180,
|
||
ellipsis: true,
|
||
fieldProps: { placeholder: '输入实体 ID', allowClear: true },
|
||
},
|
||
{
|
||
title: '状态',
|
||
dataIndex: 'status',
|
||
width: 110,
|
||
fieldProps: { placeholder: '输入状态', allowClear: true },
|
||
render: (_, record) => (
|
||
<Tag color={tone(record.status)}>{record.status || '--'}</Tag>
|
||
),
|
||
},
|
||
{
|
||
title: '类型/分类',
|
||
dataIndex: 'kind',
|
||
width: 190,
|
||
ellipsis: true,
|
||
fieldProps: { placeholder: '输入 kind', allowClear: true },
|
||
render: (_, record) => (
|
||
<Space size={4} wrap>
|
||
{record.kind && <Tag color="blue">{record.kind}</Tag>}
|
||
{record.category && <Tag>{record.category}</Tag>}
|
||
</Space>
|
||
),
|
||
},
|
||
{
|
||
title: '分类',
|
||
dataIndex: 'category',
|
||
hideInTable: true,
|
||
fieldProps: { placeholder: '输入 category', allowClear: true },
|
||
},
|
||
{
|
||
title: '策略类型',
|
||
dataIndex: 'policy_kind',
|
||
width: 140,
|
||
valueType: 'select',
|
||
valueEnum: POLICY_KIND_OPTIONS,
|
||
fieldProps: { placeholder: '选择策略类型', allowClear: true },
|
||
render: (_, record) => record.policy_kind ? <Tag color="purple">{record.policy_kind}</Tag> : '--',
|
||
},
|
||
{
|
||
title: '冲突字段',
|
||
dataIndex: 'conflict_keys',
|
||
width: 220,
|
||
hideInSearch: true,
|
||
render: (_, record) => (
|
||
<Space size={[4, 4]} wrap>
|
||
{(record.conflict_keys || []).slice(0, 3).map((item) => (
|
||
<Tag key={item} color="orange" style={{ marginInlineEnd: 0 }}>
|
||
{item}
|
||
</Tag>
|
||
))}
|
||
{(!record.conflict_keys || record.conflict_keys.length === 0) && '--'}
|
||
</Space>
|
||
),
|
||
},
|
||
{
|
||
title: '等级',
|
||
dataIndex: 'level',
|
||
width: 90,
|
||
fieldProps: { placeholder: '等级', allowClear: true },
|
||
renderText: (value) => value || '--',
|
||
},
|
||
{
|
||
title: '优先级',
|
||
dataIndex: 'priority',
|
||
width: 90,
|
||
fieldProps: { placeholder: '优先级', allowClear: true },
|
||
renderText: (value) => value || '--',
|
||
},
|
||
{
|
||
title: '业务摘要',
|
||
dataIndex: 'summary',
|
||
width: 400,
|
||
hideInSearch: true,
|
||
render: (_, record) => renderSummary(record),
|
||
},
|
||
{
|
||
title: '更新时间',
|
||
dataIndex: 'updated_range',
|
||
valueType: 'dateTimeRange',
|
||
hideInTable: true,
|
||
},
|
||
{
|
||
title: '发生时间',
|
||
dataIndex: 'occurred_at',
|
||
width: 170,
|
||
hideInSearch: true,
|
||
renderText: (value) => value || '--',
|
||
},
|
||
{
|
||
title: '同步时间',
|
||
dataIndex: 'synced_at',
|
||
width: 170,
|
||
hideInSearch: true,
|
||
valueType: 'dateTime',
|
||
},
|
||
{
|
||
title: '详情',
|
||
valueType: 'option',
|
||
fixed: 'right',
|
||
width: 120,
|
||
render: (_, record) => (
|
||
<Space size={4}>
|
||
<Button type="link" onClick={() => setDetailRecord(record)}>
|
||
查看
|
||
</Button>
|
||
{record.sync_record_url && (
|
||
<Button
|
||
type="link"
|
||
onClick={() => history.push(record.sync_record_url || '')}
|
||
>
|
||
同步记录
|
||
</Button>
|
||
)}
|
||
</Space>
|
||
),
|
||
},
|
||
],
|
||
[],
|
||
);
|
||
|
||
const request = async (params: Record<string, any>) => {
|
||
const updatedRange = params.updated_range || [];
|
||
if (activeView === 'policy_conflicts') {
|
||
const response = await apiDigitalEmployeeAdminPolicySnapshots({
|
||
pageNo: params.current || 1,
|
||
pageSize: params.pageSize || 15,
|
||
clientKey: params.client_key,
|
||
deviceId: params.device_id,
|
||
status: params.status,
|
||
policyKind: params.policy_kind || params.kind,
|
||
updatedFrom: updatedRange[0],
|
||
updatedTo: updatedRange[1],
|
||
});
|
||
|
||
if (response.code !== SUCCESS_CODE) {
|
||
message.error(response.message || '查询数字员工策略冲突失败');
|
||
}
|
||
|
||
return {
|
||
data: (response.data?.records || []).map((record, index) => ({
|
||
view: 'policy_conflicts',
|
||
sync_record_id: index + 1,
|
||
sync_record_url: record.sync_record_url,
|
||
entity_type: 'policy_snapshot',
|
||
entity_id: record.policy_key || record.policy_kind || `policy-${index}`,
|
||
title: record.summary || record.policy_kind,
|
||
status: record.status,
|
||
kind: record.policy_kind,
|
||
category: 'policy_snapshot',
|
||
summary: record.conflict_keys?.length
|
||
? `冲突字段:${record.conflict_keys.join(', ')}`
|
||
: record.summary,
|
||
policy_kind: record.policy_kind,
|
||
policy_key: record.policy_key,
|
||
conflict_keys: record.conflict_keys,
|
||
recommended_resolution: record.recommended_resolution,
|
||
route_decision_count: record.route_decision_count,
|
||
blocked_count: record.blocked_count,
|
||
approval_required_count: record.approval_required_count,
|
||
missing_context_count: record.missing_context_count,
|
||
not_mapped_count: record.not_mapped_count,
|
||
intervention_conflict_status: record.intervention_conflict_status,
|
||
approval_policy_id: record.approval_policy_id,
|
||
conflict_policy_id: record.conflict_policy_id,
|
||
decision_guard_status: record.decision_guard_status,
|
||
batch_accept_remote_disabled: record.batch_accept_remote_disabled,
|
||
auto_decision_disabled: record.auto_decision_disabled,
|
||
policy_reason: record.policy_reason,
|
||
dispatch_policy_key: record.dispatch_policy_key,
|
||
max_per_sweep: record.max_per_sweep,
|
||
auto_dispatch_ready_steps: record.auto_dispatch_ready_steps,
|
||
catch_up_on_startup: record.catch_up_on_startup,
|
||
max_run_history: record.max_run_history,
|
||
latest_synced_at: record.latest_synced_at,
|
||
synced_at: record.latest_synced_at,
|
||
client_key_masked: record.client_key_masked,
|
||
device_id: record.device_id,
|
||
business_view: record.business_view,
|
||
payload: record.business_view,
|
||
})),
|
||
total: response.data?.total || 0,
|
||
success: response.code === SUCCESS_CODE,
|
||
};
|
||
}
|
||
|
||
const response = await apiDigitalEmployeeAdminWorkbenchList({
|
||
view: activeView,
|
||
pageNo: params.current || 1,
|
||
pageSize: params.pageSize || 15,
|
||
clientKey: params.client_key,
|
||
deviceId: params.device_id,
|
||
entityType: params.entity_type,
|
||
entityId: params.entity_id,
|
||
status: params.status,
|
||
kind: params.kind,
|
||
category: params.category,
|
||
level: params.level,
|
||
priority: params.priority,
|
||
updatedFrom: updatedRange[0],
|
||
updatedTo: updatedRange[1],
|
||
});
|
||
|
||
if (response.code !== SUCCESS_CODE) {
|
||
message.error(response.message || '查询数字员工运营台失败');
|
||
}
|
||
|
||
return {
|
||
data: response.data?.records || [],
|
||
total: response.data?.total || 0,
|
||
success: response.code === SUCCESS_CODE,
|
||
};
|
||
};
|
||
|
||
return (
|
||
<WorkspaceLayout title="数字员工运营台" hideScroll>
|
||
<Tabs
|
||
activeKey={activeView}
|
||
items={WORKBENCH_TABS}
|
||
onChange={(key) => {
|
||
setActiveView(key as DigitalEmployeeAdminWorkbenchView);
|
||
formRef.current?.resetFields();
|
||
actionRef.current?.setPageInfo?.({ current: 1, pageSize: 15 });
|
||
actionRef.current?.reload();
|
||
}}
|
||
/>
|
||
{activeView === 'audits' && (
|
||
<div style={{ marginBottom: 12 }}>
|
||
<Space size={16} wrap>
|
||
<Statistic
|
||
title="估算 Token"
|
||
value={billingEstimate?.total_tokens || 0}
|
||
loading={billingLoading}
|
||
/>
|
||
<Statistic
|
||
title="估算成本 USD"
|
||
value={String(billingEstimate?.estimated_cost_usd ?? 0)}
|
||
loading={billingLoading}
|
||
/>
|
||
<Statistic
|
||
title="估算来源"
|
||
value={billingEstimate?.request_count || 0}
|
||
suffix="条"
|
||
loading={billingLoading}
|
||
/>
|
||
<Button loading={billingLoading} onClick={loadBillingEstimate}>
|
||
刷新成本估算
|
||
</Button>
|
||
</Space>
|
||
{billingEstimate?.estimated && (
|
||
<Typography.Text
|
||
type="secondary"
|
||
style={{ display: 'block', marginTop: 4 }}
|
||
>
|
||
成本为估算来源,不代表真实扣费账单。
|
||
</Typography.Text>
|
||
)}
|
||
</div>
|
||
)}
|
||
<XProTable<DigitalEmployeeAdminWorkbenchRow>
|
||
key={activeView}
|
||
actionRef={actionRef}
|
||
formRef={formRef}
|
||
rowKey={(record) =>
|
||
`${activeView}:${record.sync_record_id || record.entity_id}`
|
||
}
|
||
columns={columns}
|
||
request={request}
|
||
showQueryButtons={hasPermission(
|
||
'content_digital_employee_ops_query_list',
|
||
)}
|
||
/>
|
||
<Drawer
|
||
width={760}
|
||
title="运营详情"
|
||
open={Boolean(detailRecord)}
|
||
onClose={() => setDetailRecord(null)}
|
||
>
|
||
{detailRecord && (
|
||
<>
|
||
<div style={{ marginBottom: 16 }}>{renderSummary(detailRecord)}</div>
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>客户端:</Typography.Text>
|
||
{detailRecord.client_key_masked || '--'} /{' '}
|
||
{detailRecord.device_id || '--'}
|
||
</Typography.Paragraph>
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>实体:</Typography.Text>
|
||
{detailRecord.entity_type || '--'} / {detailRecord.entity_id || '--'}
|
||
</Typography.Paragraph>
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>关联:</Typography.Text>
|
||
{[
|
||
detailRecord.plan_id && `Plan ${detailRecord.plan_id}`,
|
||
detailRecord.task_id && `Task ${detailRecord.task_id}`,
|
||
detailRecord.run_id && `Run ${detailRecord.run_id}`,
|
||
detailRecord.step_id && `Step ${detailRecord.step_id}`,
|
||
detailRecord.approval_id && `Approval ${detailRecord.approval_id}`,
|
||
detailRecord.service_id && `Service ${detailRecord.service_id}`,
|
||
detailRecord.service_lease_id &&
|
||
`ServiceLease ${detailRecord.service_lease_id}`,
|
||
detailRecord.restart_record_id &&
|
||
`RestartRecord ${detailRecord.restart_record_id}`,
|
||
detailRecord.recovery_policy_id &&
|
||
`RecoveryPolicy ${detailRecord.recovery_policy_id}`,
|
||
detailRecord.artifact_id && `Artifact ${detailRecord.artifact_id}`,
|
||
detailRecord.artifact_group_id &&
|
||
`ArtifactGroup ${detailRecord.artifact_group_id}`,
|
||
detailRecord.latest_artifact_id &&
|
||
`LatestArtifact ${detailRecord.latest_artifact_id}`,
|
||
detailRecord.cleanup_request_id &&
|
||
`CleanupRequest ${detailRecord.cleanup_request_id}`,
|
||
detailRecord.artifact_graph_id &&
|
||
`ArtifactGraph ${detailRecord.artifact_graph_id}`,
|
||
detailRecord.notification_id &&
|
||
`Notification ${detailRecord.notification_id}`,
|
||
detailRecord.collaboration_thread_id &&
|
||
`Thread ${detailRecord.collaboration_thread_id}`,
|
||
detailRecord.subscription_policy_id &&
|
||
`Subscription ${detailRecord.subscription_policy_id}`,
|
||
detailRecord.notification_policy_id &&
|
||
`NotificationPolicy ${detailRecord.notification_policy_id}`,
|
||
detailRecord.report_id && `Report ${detailRecord.report_id}`,
|
||
detailRecord.daily_report_fact_id &&
|
||
`ReportFact ${detailRecord.daily_report_fact_id}`,
|
||
detailRecord.send_record_id &&
|
||
`SendRecord ${detailRecord.send_record_id}`,
|
||
detailRecord.send_request_id &&
|
||
`SendRequest ${detailRecord.send_request_id}`,
|
||
detailRecord.daily_report_approval_id &&
|
||
`ReportApproval ${detailRecord.daily_report_approval_id}`,
|
||
detailRecord.route_decision_id &&
|
||
`Route ${detailRecord.route_decision_id}`,
|
||
detailRecord.policy_kind && `Policy ${detailRecord.policy_kind}`,
|
||
detailRecord.memory_id && `Memory ${detailRecord.memory_id}`,
|
||
detailRecord.memory_key && `MemoryKey ${detailRecord.memory_key}`,
|
||
detailRecord.latest_memory_id &&
|
||
`LatestMemory ${detailRecord.latest_memory_id}`,
|
||
detailRecord.skill_id && `Skill ${detailRecord.skill_id}`,
|
||
detailRecord.skill_version && `Version ${detailRecord.skill_version}`,
|
||
detailRecord.policy_source && `PolicySource ${detailRecord.policy_source}`,
|
||
detailRecord.policy_edit_request_id && `PolicyEdit ${detailRecord.policy_edit_request_id}`,
|
||
detailRecord.merge_request_id && `PolicyMerge ${detailRecord.merge_request_id}`,
|
||
detailRecord.tool_name && `Tool ${detailRecord.tool_name}`,
|
||
detailRecord.server_id && `Server ${detailRecord.server_id}`,
|
||
detailRecord.schedule_id && `Schedule ${detailRecord.schedule_id}`,
|
||
detailRecord.job_id && `Job ${detailRecord.job_id}`,
|
||
detailRecord.revision_id && `Revision ${detailRecord.revision_id}`,
|
||
]
|
||
.filter(Boolean)
|
||
.join(' / ') || '--'}
|
||
</Typography.Paragraph>
|
||
{(detailRecord.advanced_query_supported != null ||
|
||
detailRecord.aggregation_scope ||
|
||
detailRecord.materialized_source) && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>业务查询:</Typography.Text>
|
||
{detailRecord.advanced_query_supported != null &&
|
||
`高级查询 ${detailRecord.advanced_query_supported ? '支持' : '受限'}`}
|
||
{detailRecord.aggregation_scope && ` · 聚合范围 ${detailRecord.aggregation_scope}`}
|
||
{detailRecord.materialized_source && ` · 物化来源 ${detailRecord.materialized_source}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 复杂组合检索以现有业务视图和物化来源解释,不新增高风险执行入口。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'policy_conflicts' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>策略冲突:</Typography.Text>
|
||
{detailRecord.conflict_keys?.length
|
||
? detailRecord.conflict_keys.join(' / ')
|
||
: '暂无冲突字段'}
|
||
{detailRecord.intervention_conflict_status &&
|
||
` · 跨设备路由干预冲突 ${detailRecord.intervention_conflict_status}`}
|
||
{(detailRecord.approval_policy_id || detailRecord.conflict_policy_id || detailRecord.decision_guard_status) &&
|
||
` · 跨设备审批策略冲突`}
|
||
{(detailRecord.policy_kind === 'dispatch' ||
|
||
detailRecord.dispatch_policy_key ||
|
||
detailRecord.max_per_sweep != null ||
|
||
detailRecord.auto_dispatch_ready_steps != null) &&
|
||
` · 跨设备派发策略冲突`}
|
||
{(detailRecord.policy_kind === 'scheduler' ||
|
||
detailRecord.catch_up_on_startup != null ||
|
||
detailRecord.max_run_history != null) &&
|
||
` · 跨设备调度策略冲突`}
|
||
{detailRecord.approval_policy_id && ` · 审批策略 ${detailRecord.approval_policy_id}`}
|
||
{detailRecord.conflict_policy_id && ` · 冲突策略 ${detailRecord.conflict_policy_id}`}
|
||
{detailRecord.decision_guard_status && ` · 裁决保护 ${detailRecord.decision_guard_status}`}
|
||
{detailRecord.policy_reason && ` · 策略原因 ${detailRecord.policy_reason}`}
|
||
{detailRecord.dispatch_policy_key && ` · 派发策略 ${detailRecord.dispatch_policy_key}`}
|
||
{detailRecord.max_per_sweep != null && ` · max_per_sweep ${detailRecord.max_per_sweep}`}
|
||
{detailRecord.auto_dispatch_ready_steps != null &&
|
||
` · auto_dispatch_ready_steps ${detailRecord.auto_dispatch_ready_steps ? '开启' : '关闭'}`}
|
||
{detailRecord.catch_up_on_startup != null &&
|
||
` · catch_up_on_startup ${detailRecord.catch_up_on_startup ? '开启' : '关闭'}`}
|
||
{detailRecord.max_run_history != null && ` · max_run_history ${detailRecord.max_run_history}`}
|
||
{detailRecord.batch_accept_remote_disabled && ' · 批量采纳远端禁用'}
|
||
{detailRecord.auto_decision_disabled && ' · 自动裁决禁用'}
|
||
{detailRecord.route_decision_count != null &&
|
||
` · 路由 ${detailRecord.route_decision_count} 条`}
|
||
{detailRecord.blocked_count != null &&
|
||
` · 阻断 ${detailRecord.blocked_count}`}
|
||
{detailRecord.approval_required_count != null &&
|
||
` · 待审批 ${detailRecord.approval_required_count}`}
|
||
{detailRecord.missing_context_count != null &&
|
||
` · 缺上下文 ${detailRecord.missing_context_count}`}
|
||
{detailRecord.not_mapped_count != null &&
|
||
` · 未映射 ${detailRecord.not_mapped_count}`}
|
||
{detailRecord.recommended_resolution && (
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 建议:{detailRecord.recommended_resolution}
|
||
</Typography.Text>
|
||
)}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 不恢复执行、不绕过审批、不远程改策略。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'approval_governance' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>审批治理:</Typography.Text>
|
||
{detailRecord.approval_id
|
||
? `审批 ${detailRecord.approval_id}`
|
||
: '审批相关事件'}
|
||
{detailRecord.category && ` · ${detailRecord.category}`}
|
||
{detailRecord.priority && ` · 优先级 ${detailRecord.priority}`}
|
||
{detailRecord.approval_policy_id && ` · 审批策略 ${detailRecord.approval_policy_id}`}
|
||
{detailRecord.conflict_policy_id && ` · 冲突策略 ${detailRecord.conflict_policy_id}`}
|
||
{detailRecord.decision_guard_status && ` · 裁决保护 ${detailRecord.decision_guard_status}`}
|
||
{detailRecord.policy_reason && ` · 策略原因 ${detailRecord.policy_reason}`}
|
||
{detailRecord.batch_accept_remote_disabled && ' · 批量采纳远端禁用'}
|
||
{detailRecord.auto_decision_disabled && ' · 自动裁决禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示裁决策略和保护状态,批量/高风险裁决不开放,动作等待客户端拉取执行。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'approval_policies' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>审批策略:</Typography.Text>
|
||
{detailRecord.approval_policy_id && `审批策略 ${detailRecord.approval_policy_id}`}
|
||
{detailRecord.conflict_policy_id && ` · 冲突策略 ${detailRecord.conflict_policy_id}`}
|
||
{detailRecord.decision_guard_status && ` · 裁决保护 ${detailRecord.decision_guard_status}`}
|
||
{detailRecord.policy_source && ` · 来源 ${detailRecord.policy_source}`}
|
||
{detailRecord.policy_status && ` · 状态 ${detailRecord.policy_status}`}
|
||
{detailRecord.policy_reason && ` · 策略原因 ${detailRecord.policy_reason}`}
|
||
{detailRecord.approval_policy_edit_disabled && ' · 审批策略编辑禁用'}
|
||
{detailRecord.batch_accept_remote_disabled && ' · 批量采纳远端禁用'}
|
||
{detailRecord.auto_decision_disabled && ' · 自动裁决禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 审批策略编辑/裁决安全壳只记录请求,不远程编辑策略、不自动裁决、不批量采纳远端。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'service_operations' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>服务运营:</Typography.Text>
|
||
{detailRecord.service_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.category && ` · ${detailRecord.category}`}
|
||
{detailRecord.level && ` · ${detailRecord.level}`}
|
||
{detailRecord.lease_holder && ` · lease holder ${detailRecord.lease_holder}`}
|
||
{detailRecord.lease_expires_at && ` · lease 到期 ${detailRecord.lease_expires_at}`}
|
||
{detailRecord.restart_count != null && ` · 重启 ${detailRecord.restart_count} 次`}
|
||
{detailRecord.last_restart_at && ` · 最近重启 ${detailRecord.last_restart_at}`}
|
||
{detailRecord.recovery_policy_id && ` · 恢复策略 ${detailRecord.recovery_policy_id}`}
|
||
{detailRecord.auto_recovery_status && ` · 自动恢复 ${detailRecord.auto_recovery_status}`}
|
||
{detailRecord.recovery_action_request_id && ` · 恢复请求 ${detailRecord.recovery_action_request_id}`}
|
||
{detailRecord.start_request_id && ` · 启动请求 ${detailRecord.start_request_id}`}
|
||
{detailRecord.stop_request_id && ` · 停止请求 ${detailRecord.stop_request_id}`}
|
||
{detailRecord.lease_takeover_request_id && ` · lease 接管请求 ${detailRecord.lease_takeover_request_id}`}
|
||
{detailRecord.auto_recovery_request_id && ` · 自动恢复请求 ${detailRecord.auto_recovery_request_id}`}
|
||
{detailRecord.service_start_disabled && ' · 启动禁用'}
|
||
{detailRecord.service_stop_disabled && ' · 停止禁用'}
|
||
{detailRecord.start_service_disabled && ' · 服务启动禁用'}
|
||
{detailRecord.stop_service_disabled && ' · 服务停止禁用'}
|
||
{detailRecord.lease_takeover_disabled && ' · lease 接管禁用'}
|
||
{detailRecord.auto_recovery_disabled && ' · 自动恢复执行禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只记录启动/停止请求、复核/忽略意图和恢复请求状态,不开放 start/stop、不接管 lease、不自动恢复服务。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'artifact_lifecycle' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>产物协作:</Typography.Text>
|
||
{detailRecord.artifact_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.cleanup_eligible_count != null &&
|
||
` · 可清理 ${detailRecord.cleanup_eligible_count} 项`}
|
||
{detailRecord.artifact_count != null &&
|
||
` · 产物 ${detailRecord.artifact_count} 项`}
|
||
{detailRecord.device_count != null &&
|
||
` · 设备 ${detailRecord.device_count} 台`}
|
||
{detailRecord.version_count != null &&
|
||
` · 版本 ${detailRecord.version_count} 个`}
|
||
{detailRecord.latest_artifact_id &&
|
||
` · 最新产物 ${detailRecord.latest_artifact_id}`}
|
||
{detailRecord.artifact_graph_id && ` · 图谱 ${detailRecord.artifact_graph_id}`}
|
||
{detailRecord.group_key && ` · 分组 ${detailRecord.group_key}`}
|
||
{detailRecord.related_artifact_ids?.length
|
||
? ` · 关联产物 ${detailRecord.related_artifact_ids.join('/')}`
|
||
: ''}
|
||
{detailRecord.version_key && ` · 聚合键 ${detailRecord.version_key}`}
|
||
{detailRecord.retention_conflict_status &&
|
||
` · 保留冲突 ${detailRecord.retention_conflict_status}`}
|
||
{detailRecord.cleanup_conflict_status &&
|
||
` · 清理冲突 ${detailRecord.cleanup_conflict_status}`}
|
||
{detailRecord.batch_cleanup_disabled && ' · 批量真实清理禁用'}
|
||
{detailRecord.remote_delete_disabled && ' · 远端删除禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示跨设备/跨版本聚合、跨设备/跨版本图谱摘要、保留冲突和清理冲突,只允许记录批量清理申请和保留策略意图,不执行批量删除或远端删除。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'notifications' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>通知协作:</Typography.Text>
|
||
{detailRecord.notification_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.subscription_policy_id &&
|
||
` · 订阅策略 ${detailRecord.subscription_policy_id}`}
|
||
{detailRecord.collaboration_thread_id &&
|
||
` · 协作线程 ${detailRecord.collaboration_thread_id}`}
|
||
{detailRecord.subscription_conflict_status &&
|
||
` · 订阅冲突 ${detailRecord.subscription_conflict_status}`}
|
||
{detailRecord.channel && ` · ${detailRecord.channel}`}
|
||
{detailRecord.delivery_status && ` · ${detailRecord.delivery_status}`}
|
||
{detailRecord.delivery_attempt_id &&
|
||
` · 投递尝试 ${detailRecord.delivery_attempt_id}`}
|
||
{detailRecord.send_request_id &&
|
||
` · 发送请求 ${detailRecord.send_request_id}`}
|
||
{detailRecord.conflict_status && ` · ${detailRecord.conflict_status}`}
|
||
{detailRecord.real_push_disabled && ' · 真实推送禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示协作线程、订阅冲突、投递尝试和发送请求,只记录已读/忽略/发送记录意图,不触发真实推送。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'notification_policies' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>通知策略:</Typography.Text>
|
||
{detailRecord.notification_policy_id ||
|
||
detailRecord.subscription_policy_id ||
|
||
detailRecord.entity_id ||
|
||
'--'}
|
||
{detailRecord.subscription_policy_id &&
|
||
` · 订阅策略 ${detailRecord.subscription_policy_id}`}
|
||
{detailRecord.subscription_status &&
|
||
` · 订阅状态 ${detailRecord.subscription_status}`}
|
||
{detailRecord.desktop_enabled != null &&
|
||
` · 桌面通知 ${detailRecord.desktop_enabled ? '开启' : '关闭'}`}
|
||
{detailRecord.minimum_level && ` · 最低等级 ${detailRecord.minimum_level}`}
|
||
{detailRecord.channel && ` · 渠道 ${detailRecord.channel}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示复杂订阅策略和桌面通知阈值,只记录拉取/复核/忽略意图,不远程编辑策略、不触发真实推送。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'daily_reports' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>日报协作:</Typography.Text>
|
||
{detailRecord.report_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.daily_report_fact_id &&
|
||
` · 事实 ${detailRecord.daily_report_fact_id}`}
|
||
{detailRecord.daily_report_physical_fact_status &&
|
||
` · 物理事实 ${detailRecord.daily_report_physical_fact_status}`}
|
||
{detailRecord.send_record_id &&
|
||
` · 发送记录 ${detailRecord.send_record_id}`}
|
||
{detailRecord.send_channel && ` · 渠道 ${detailRecord.send_channel}`}
|
||
{detailRecord.send_request_status &&
|
||
` · 发送请求状态 ${detailRecord.send_request_status}`}
|
||
{detailRecord.approval_decision_status &&
|
||
` · 审批状态 ${detailRecord.approval_decision_status}`}
|
||
{detailRecord.external_send_disabled && ' · 外部发送禁用'}
|
||
{detailRecord.third_party_channel_disabled && ' · 第三方发送禁用'}
|
||
{detailRecord.daily_report_approval_id &&
|
||
` · 审批裁决 ${detailRecord.daily_report_approval_id}`}
|
||
{detailRecord.daily_report_approval_action &&
|
||
` · 裁决动作 ${detailRecord.daily_report_approval_action}`}
|
||
{detailRecord.daily_report_approval_actor &&
|
||
` · 裁决人 ${detailRecord.daily_report_approval_actor}`}
|
||
{detailRecord.daily_report_approval_reason &&
|
||
` · 裁决原因 ${detailRecord.daily_report_approval_reason}`}
|
||
{detailRecord.daily_report_approval_recorded_at &&
|
||
` · 裁决记录 ${detailRecord.daily_report_approval_recorded_at}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示发送记录、审批状态、审批裁决、物理事实状态和事实来源,只记录发送请求/发送结果/审批/回执/裁决意图,不触发真实外部发送或第三方发送。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'audits' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>审计归档/账单/诊断修复:</Typography.Text>
|
||
{detailRecord.diagnostic_id || detailRecord.audit_archive_id || detailRecord.billing_estimate_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.diagnostic_kind && ` · 诊断类型 ${detailRecord.diagnostic_kind}`}
|
||
{detailRecord.issue_code && ` · 问题码 ${detailRecord.issue_code}`}
|
||
{detailRecord.recommended_action && ` · 建议动作 ${detailRecord.recommended_action}`}
|
||
{detailRecord.repair_action && ` · 修复动作 ${detailRecord.repair_action}`}
|
||
{detailRecord.repair_status && ` · 修复状态 ${detailRecord.repair_status}`}
|
||
{detailRecord.repair_reason && ` · 修复原因 ${detailRecord.repair_reason}`}
|
||
{detailRecord.safe_repair_disabled && ' · 安全修复禁用'}
|
||
{detailRecord.billing_actual_disabled && ' · 真实账单禁用'}
|
||
{detailRecord.sandbox_archive_file_disabled && ' · 独立 sandbox 文件归档禁用'}
|
||
{detailRecord.auto_repair_execution_disabled && ' · 自动修复执行禁用'}
|
||
{detailRecord.repair_approval_required && ' · 高风险修复需要审批'}
|
||
{detailRecord.archive_status && ` · 归档状态 ${detailRecord.archive_status}`}
|
||
{detailRecord.archive_location && ` · 归档位置 ${detailRecord.archive_location}`}
|
||
{detailRecord.billing_source && ` · 估算来源 ${detailRecord.billing_source}`}
|
||
{detailRecord.estimated != null && ` · ${detailRecord.estimated ? '估算费用' : '真实费用'}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只展示脱敏归档摘要、账单估算来源和诊断修复建议,只记录修复意图和修复审批请求,不执行 shell、不修改系统配置、不自动修复,不触发真实扣费,不保存 prompt、raw command、authorization 或 token。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'governance_commands' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>治理命令:</Typography.Text>
|
||
{detailRecord.kind || detailRecord.category || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只记录复核/忽略意图,不开放 ACP 硬中断或高风险执行。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'route_governance' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>路由治理:</Typography.Text>
|
||
{detailRecord.route_decision_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.category && ` · ${detailRecord.category}`}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
{detailRecord.route_policy_edit_disabled && ' · 路由策略编辑禁用'}
|
||
{detailRecord.route_recovery_disabled && ' · 恢复安全壳启用'}
|
||
{detailRecord.high_risk_execution_disabled && ' · 高风险恢复执行不开放'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 路由策略编辑/恢复安全壳只记录策略编辑请求、合并复核和复查意图,高风险恢复执行不开放。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'memory_governance' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>记忆治理:</Typography.Text>
|
||
{detailRecord.memory_key || detailRecord.memory_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
{detailRecord.governance_status && ` · 治理状态 ${detailRecord.governance_status}`}
|
||
{detailRecord.merge_candidate_count != null &&
|
||
` · 合并候选 ${detailRecord.merge_candidate_count}`}
|
||
{detailRecord.duplicate_memory_ids?.length
|
||
? ` · 重复记忆 ${detailRecord.duplicate_memory_ids.join('/')}`
|
||
: ''}
|
||
{detailRecord.last_governance_action &&
|
||
` · 最近治理 ${detailRecord.last_governance_action}`}
|
||
{detailRecord.last_reviewed_at && ` · 复核 ${detailRecord.last_reviewed_at}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示重复候选、重复记忆和治理状态,批量归档/批量恢复只记录低风险意图,不自动合并记忆。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'memory_policies' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>记忆策略:</Typography.Text>
|
||
{detailRecord.memory_policy_id || detailRecord.merge_policy_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
{detailRecord.memory_policy_status && ` · 策略状态 ${detailRecord.memory_policy_status}`}
|
||
{detailRecord.memory_policy_id && ` · 记忆策略 ${detailRecord.memory_policy_id}`}
|
||
{detailRecord.merge_policy_id && ` · 合并策略 ${detailRecord.merge_policy_id}`}
|
||
{detailRecord.memory_merge_request_id && ` · 合并请求 ${detailRecord.memory_merge_request_id}`}
|
||
{detailRecord.remote_memory_policy_request_id && ` · 远端策略请求 ${detailRecord.remote_memory_policy_request_id}`}
|
||
{detailRecord.remote_memory_policy_disabled && ' · 远端记忆策略禁用'}
|
||
{detailRecord.merge_action_disabled && ' · 自动合并禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只展示远端记忆策略、合并请求和自动合并禁用状态,只记录拉取、复核和忽略意图,不触发真实下发,不触发自动合并。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'skill_audits' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>技能审计:</Typography.Text>
|
||
{detailRecord.skill_id || detailRecord.tool_name || detailRecord.category || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
{detailRecord.skill_version && ` · 版本 ${detailRecord.skill_version}`}
|
||
{detailRecord.skill_install_request_id && ` · 安装请求 ${detailRecord.skill_install_request_id}`}
|
||
{detailRecord.skill_upgrade_request_id && ` · 升级请求 ${detailRecord.skill_upgrade_request_id}`}
|
||
{detailRecord.permission_edit_request_id && ` · 权限编辑请求 ${detailRecord.permission_edit_request_id}`}
|
||
{detailRecord.install_status && ` · 安装状态 ${detailRecord.install_status}`}
|
||
{detailRecord.permission_scope && ` · 权限范围 ${detailRecord.permission_scope}`}
|
||
{detailRecord.permission_policy_id && ` · 权限策略 ${detailRecord.permission_policy_id}`}
|
||
{detailRecord.policy_source && ` · 策略来源 ${detailRecord.policy_source}`}
|
||
{detailRecord.policy_status && ` · 策略状态 ${detailRecord.policy_status}`}
|
||
{detailRecord.install_action_disabled && ' · 安装禁用'}
|
||
{detailRecord.upgrade_action_disabled && ' · 升级禁用'}
|
||
{detailRecord.permission_edit_disabled && ' · 权限编辑禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 展示版本、安装/升级请求、权限编辑请求、安装状态、权限范围和策略来源,只消费调用审计和安全摘要,不安装技能、不升级技能、不变更权限范围。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'policy_center' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>策略中心:</Typography.Text>
|
||
{detailRecord.policy_kind || detailRecord.policy_key || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
{detailRecord.policy_edit_request_id && ` · 远程策略编辑请求 ${detailRecord.policy_edit_request_id}`}
|
||
{detailRecord.policy_edit_status && ` · 编辑状态 ${detailRecord.policy_edit_status}`}
|
||
{detailRecord.policy_edit_reason && ` · 编辑原因 ${detailRecord.policy_edit_reason}`}
|
||
{detailRecord.merge_request_id && ` · 合并请求 ${detailRecord.merge_request_id}`}
|
||
{detailRecord.merge_recommendation && ` · 合并建议 ${detailRecord.merge_recommendation}`}
|
||
{detailRecord.remote_policy_edit_disabled && ' · 远程策略编辑禁用'}
|
||
{detailRecord.auto_merge_disabled && ' · 自动合并禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 策略编辑/合并安全壳只记录请求,不开放远程策略编辑,真实远程策略强编辑不开放,不自动合并策略。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'scheduler_operations' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>调度运营:</Typography.Text>
|
||
{detailRecord.job_id || detailRecord.schedule_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 支持立即检查调度和复核标记,不开放 start/stop 或高风险立即运行。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'plan_step_dispatch' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>步骤调度:</Typography.Text>
|
||
{detailRecord.step_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.dependency_status && ` · 依赖 ${detailRecord.dependency_status}`}
|
||
{detailRecord.lease_state && ` · 租约 ${detailRecord.lease_state}`}
|
||
{detailRecord.dispatch_status && ` · 派发 ${detailRecord.dispatch_status}`}
|
||
{detailRecord.dispatch_policy_key && ` · 策略 ${detailRecord.dispatch_policy_key}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 不远程派发、不抢占租约、不释放租约,只记录复核、忽略和策略复查意图。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'plan_governance' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>计划治理:</Typography.Text>
|
||
{detailRecord.plan_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只记录治理意图、版本复核和升级摘要,不开放 hard interrupt 或高风险执行。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'plan_revisions' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>计划版本:</Typography.Text>
|
||
{detailRecord.revision_id || detailRecord.plan_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.status && ` · ${detailRecord.status}`}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只用于版本复核,不自动激活计划、不取消运行或任务。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'governance_policies' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>治理策略:</Typography.Text>
|
||
{detailRecord.governance_policy_id || detailRecord.policy_key || detailRecord.entity_id || '--'}
|
||
{detailRecord.policy_guard_status && ` · 策略保护 ${detailRecord.policy_guard_status}`}
|
||
{detailRecord.policy_source && ` · 来源 ${detailRecord.policy_source}`}
|
||
{detailRecord.policy_status && ` · 状态 ${detailRecord.policy_status}`}
|
||
{detailRecord.policy_reason && ` · 原因 ${detailRecord.policy_reason}`}
|
||
{detailRecord.hard_interrupt_disabled && ' · ACP 硬中断禁用'}
|
||
{detailRecord.high_risk_execution_disabled && ' · 高风险执行禁用'}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 治理执行安全壳只记录策略拉取、编辑请求、合并复核和复核意图,不开放 ACP 硬中断、不激活计划、不取消运行或任务。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{activeView === 'plan_revision_materialization' && (
|
||
<Typography.Paragraph>
|
||
<Typography.Text strong>版本物化:</Typography.Text>
|
||
{detailRecord.revision_fact_id || detailRecord.revision_id || detailRecord.entity_id || '--'}
|
||
{detailRecord.revision_status && ` · 版本状态 ${detailRecord.revision_status}`}
|
||
{detailRecord.revision_materialized != null &&
|
||
` · 版本事实来源 ${detailRecord.revision_materialized ? 'materialized' : 'fallback'}`}
|
||
{detailRecord.base_revision_id && ` · 基线 ${detailRecord.base_revision_id}`}
|
||
{detailRecord.changed_fields?.length
|
||
? ` · 变更字段 ${detailRecord.changed_fields.join('/')}`
|
||
: ''}
|
||
<Typography.Text type="secondary">
|
||
{' '}
|
||
· 只展示计划版本物化状态并记录复核意图,不自动激活计划、不取消运行或任务。
|
||
</Typography.Text>
|
||
</Typography.Paragraph>
|
||
)}
|
||
{allowedActions(detailRecord, activeView).length > 0 && (
|
||
<div style={{ marginBottom: 16 }}>
|
||
<Typography.Title level={5}>低风险动作</Typography.Title>
|
||
<Space size={[8, 8]} wrap>
|
||
{allowedActions(detailRecord, activeView).map((item) => {
|
||
const submitKey = `${detailRecord.sync_record_id}:${item.action}`;
|
||
return (
|
||
<Button
|
||
key={item.action}
|
||
loading={submittingAction === submitKey}
|
||
onClick={() => submitAdminAction(detailRecord, item.action)}
|
||
>
|
||
{item.label}
|
||
</Button>
|
||
);
|
||
})}
|
||
</Space>
|
||
<Typography.Text type="secondary" style={{ display: 'block', marginTop: 8 }}>
|
||
动作只会记录意图并等待客户端拉取执行。
|
||
</Typography.Text>
|
||
</div>
|
||
)}
|
||
{activeView === 'daily_reports' && detailRecord.report_id && (
|
||
<div style={{ marginBottom: 16 }}>
|
||
<Typography.Title level={5}>日报发送</Typography.Title>
|
||
<Button
|
||
loading={
|
||
submittingAction ===
|
||
`${detailRecord.sync_record_id}:send-record`
|
||
}
|
||
onClick={() => submitDailyReportSendRecord(detailRecord)}
|
||
>
|
||
记录发送结果
|
||
</Button>
|
||
<Typography.Text
|
||
type="secondary"
|
||
style={{ display: 'block', marginTop: 8 }}
|
||
>
|
||
仅记录发送请求或结果,不触发第三方真实发送。
|
||
</Typography.Text>
|
||
</div>
|
||
)}
|
||
{activeView === 'audits' && (
|
||
<div style={{ marginBottom: 16 }}>
|
||
<Typography.Title level={5}>审计归档</Typography.Title>
|
||
<Button
|
||
loading={
|
||
submittingAction ===
|
||
`${detailRecord.sync_record_id}:audit-archive`
|
||
}
|
||
onClick={() => submitAuditArchive(detailRecord)}
|
||
>
|
||
标记归档
|
||
</Button>
|
||
<Typography.Text
|
||
type="secondary"
|
||
style={{ display: 'block', marginTop: 8 }}
|
||
>
|
||
只保存脱敏摘要和归档位置,不保存 prompt、raw command、authorization 或 token。
|
||
</Typography.Text>
|
||
</div>
|
||
)}
|
||
<Typography.Title level={5}>Business View</Typography.Title>
|
||
<Typography.Paragraph copyable={{ text: businessViewJson }}>
|
||
<pre
|
||
style={{
|
||
maxHeight: 260,
|
||
overflow: 'auto',
|
||
margin: 0,
|
||
padding: 16,
|
||
background: '#f6f8fa',
|
||
border: '1px solid #e5e7eb',
|
||
borderRadius: 6,
|
||
whiteSpace: 'pre-wrap',
|
||
wordBreak: 'break-word',
|
||
}}
|
||
>
|
||
{businessViewJson}
|
||
</pre>
|
||
</Typography.Paragraph>
|
||
<Typography.Title level={5}>Payload</Typography.Title>
|
||
<Typography.Paragraph copyable={{ text: payloadJson }}>
|
||
<pre
|
||
style={{
|
||
maxHeight: 260,
|
||
overflow: 'auto',
|
||
margin: 0,
|
||
padding: 16,
|
||
background: '#f6f8fa',
|
||
border: '1px solid #e5e7eb',
|
||
borderRadius: 6,
|
||
whiteSpace: 'pre-wrap',
|
||
wordBreak: 'break-word',
|
||
}}
|
||
>
|
||
{payloadJson}
|
||
</pre>
|
||
</Typography.Paragraph>
|
||
</>
|
||
)}
|
||
</Drawer>
|
||
</WorkspaceLayout>
|
||
);
|
||
};
|
||
|
||
export default DigitalEmployeeOps;
|