163 lines
4.5 KiB
TypeScript
163 lines
4.5 KiB
TypeScript
import type {
|
|
JsonObject,
|
|
JsonValue,
|
|
WorkflowListItemDto,
|
|
WorkflowStatusResponseDto,
|
|
} from "@/lib/types/backend";
|
|
import {
|
|
getOrderStatusMeta,
|
|
getStepStatusMeta,
|
|
getWorkflowStepMeta,
|
|
} from "@/lib/types/status";
|
|
import {
|
|
businessEmptyState,
|
|
READY_STATE,
|
|
type WorkflowDetailVM,
|
|
type WorkflowLookupItemVM,
|
|
type WorkflowStepVM,
|
|
} from "@/lib/types/view-models";
|
|
|
|
type WorkflowAssetUriField =
|
|
| "asset_uri"
|
|
| "candidate_uri"
|
|
| "preview_uri"
|
|
| "result_uri"
|
|
| "source_uri";
|
|
|
|
const WORKFLOW_ASSET_URI_FIELDS = new Set<WorkflowAssetUriField>([
|
|
"asset_uri",
|
|
"candidate_uri",
|
|
"preview_uri",
|
|
"result_uri",
|
|
"source_uri",
|
|
]);
|
|
|
|
function collectKnownAssetUris(
|
|
value: JsonValue | undefined,
|
|
results: string[] = [],
|
|
): string[] {
|
|
if (!value || typeof value !== "object") {
|
|
return results;
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
for (const item of value) {
|
|
collectKnownAssetUris(item, results);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
for (const [key, nestedValue] of Object.entries(value)) {
|
|
if (
|
|
WORKFLOW_ASSET_URI_FIELDS.has(key as WorkflowAssetUriField) &&
|
|
typeof nestedValue === "string" &&
|
|
nestedValue.startsWith("mock://")
|
|
) {
|
|
results.push(nestedValue);
|
|
continue;
|
|
}
|
|
|
|
collectKnownAssetUris(nestedValue, results);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
function uniqueMockUris(...payloads: Array<JsonObject | null>): string[] {
|
|
return [...new Set(payloads.flatMap((payload) => collectKnownAssetUris(payload)))];
|
|
}
|
|
|
|
function adaptWorkflowStep(
|
|
currentStep: WorkflowStatusResponseDto["current_step"],
|
|
step: WorkflowStatusResponseDto["steps"][number],
|
|
): WorkflowStepVM {
|
|
const stepMeta = getWorkflowStepMeta(step.step_name);
|
|
const mockAssetUris = uniqueMockUris(step.input_json, step.output_json);
|
|
|
|
return {
|
|
id: step.id,
|
|
workflowRunId: step.workflow_run_id,
|
|
name: step.step_name,
|
|
label: stepMeta.label,
|
|
status: step.step_status,
|
|
statusMeta: getStepStatusMeta(step.step_status),
|
|
input: step.input_json,
|
|
output: step.output_json,
|
|
errorMessage: step.error_message,
|
|
startedAt: step.started_at,
|
|
endedAt: step.ended_at,
|
|
containsMockAssets: mockAssetUris.length > 0,
|
|
mockAssetUris,
|
|
isCurrent: currentStep === step.step_name,
|
|
isFailed: step.step_status === "failed",
|
|
};
|
|
}
|
|
|
|
export function adaptWorkflowLookupItem(
|
|
workflow: Pick<
|
|
WorkflowStatusResponseDto | WorkflowListItemDto,
|
|
| "order_id"
|
|
| "workflow_id"
|
|
| "workflow_type"
|
|
| "workflow_status"
|
|
| "current_step"
|
|
| "failure_count"
|
|
| "review_task_status"
|
|
| "revision_count"
|
|
| "pending_manual_confirm"
|
|
| "updated_at"
|
|
>,
|
|
): WorkflowLookupItemVM {
|
|
return {
|
|
orderId: workflow.order_id,
|
|
workflowId: workflow.workflow_id,
|
|
workflowType: workflow.workflow_type,
|
|
status: workflow.workflow_status,
|
|
statusMeta: getOrderStatusMeta(workflow.workflow_status),
|
|
currentStep: workflow.current_step,
|
|
currentStepLabel: getWorkflowStepMeta(workflow.current_step).label,
|
|
failureCount: workflow.failure_count,
|
|
reviewTaskStatus: workflow.review_task_status,
|
|
revisionCount: workflow.revision_count,
|
|
pendingManualConfirm: workflow.pending_manual_confirm,
|
|
updatedAt: workflow.updated_at,
|
|
};
|
|
}
|
|
|
|
export function adaptWorkflowDetail(
|
|
workflow: WorkflowStatusResponseDto,
|
|
): WorkflowDetailVM {
|
|
const steps = workflow.steps.map((step) =>
|
|
adaptWorkflowStep(workflow.current_step, step),
|
|
);
|
|
|
|
return {
|
|
orderId: workflow.order_id,
|
|
workflowId: workflow.workflow_id,
|
|
workflowType: workflow.workflow_type,
|
|
status: workflow.workflow_status,
|
|
statusMeta: getOrderStatusMeta(workflow.workflow_status),
|
|
currentStep: workflow.current_step,
|
|
currentStepLabel: getWorkflowStepMeta(workflow.current_step).label,
|
|
currentRevisionAssetId: workflow.current_revision_asset_id,
|
|
currentRevisionVersion: workflow.current_revision_version,
|
|
latestRevisionAssetId: workflow.latest_revision_asset_id,
|
|
latestRevisionVersion: workflow.latest_revision_version,
|
|
revisionCount: workflow.revision_count,
|
|
reviewTaskStatus: workflow.review_task_status,
|
|
pendingManualConfirm: workflow.pending_manual_confirm,
|
|
createdAt: workflow.created_at,
|
|
updatedAt: workflow.updated_at,
|
|
steps,
|
|
stepTimelineState: steps.length
|
|
? READY_STATE
|
|
: businessEmptyState(
|
|
"暂无流程记录",
|
|
"当前工作流还没有可展示的步骤执行记录。",
|
|
),
|
|
failureCount: steps.filter((step) => step.isFailed).length,
|
|
hasMockAssets: steps.some((step) => step.containsMockAssets),
|
|
};
|
|
}
|