重构 Wave3 详情与移动体验(05-28-frontend-ux-wave3-business-mobile)
这个提交包含在:
@@ -115,6 +115,32 @@ function isAlreadyProcessedTaskError(error: unknown) {
|
||||
return isApiError(error) && error.details?.task === "already_processed";
|
||||
}
|
||||
|
||||
function resolveWorkflowNextActionText(input: {
|
||||
taskStatus: string;
|
||||
entityType?: string | null;
|
||||
allowedActions: string[];
|
||||
}) {
|
||||
if (input.taskStatus !== "pending") {
|
||||
return "当前审批任务已结束,本页用于查看摘要、依据和处理历史。";
|
||||
}
|
||||
|
||||
const entityName = entityTitle(input.entityType ?? undefined);
|
||||
if (input.allowedActions.includes("approve")) {
|
||||
return `先核对${entityName}摘要、金额/时间和附件依据;确认无误后通过,存在缺口时退回补充。`;
|
||||
}
|
||||
if (input.allowedActions.includes("return")) {
|
||||
return `当前节点可退回,请说明需要补充的${entityName}材料或字段。`;
|
||||
}
|
||||
if (input.allowedActions.includes("reject")) {
|
||||
return `当前节点可驳回,请写清业务原因,便于申请人和后续审计理解。`;
|
||||
}
|
||||
if (input.allowedActions.includes("transfer")) {
|
||||
return "当前节点可转审,请选择更合适的审批人并说明原因。";
|
||||
}
|
||||
|
||||
return "当前账号没有可执行动作,请返回待办列表或联系管理员核对权限。";
|
||||
}
|
||||
|
||||
export function WorkflowTaskDetailPage() {
|
||||
const { taskId = "" } = useParams();
|
||||
const navigate = useNavigate();
|
||||
@@ -257,17 +283,23 @@ export function WorkflowTaskDetailPage() {
|
||||
const canTransfer = allowedActions.has("transfer");
|
||||
const allowedActionLabels = detail.allowedActions.map(workflowActionLabel).join(" / ");
|
||||
const businessStatusLabel = workflowInstanceStatusLabel(detail.workflowInstance?.currentStatus);
|
||||
const nextActionText = resolveWorkflowNextActionText({
|
||||
taskStatus: detail.task.status,
|
||||
entityType: detail.workflowInstance?.entityType,
|
||||
allowedActions: detail.allowedActions,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageScaffold>
|
||||
<EntityOverviewHero
|
||||
title={`任务详情 ${detail.task.stepName}`}
|
||||
subtitle="摘要、动作和处理历史集中办理。"
|
||||
title={`任务详情 · ${detail.task.stepName}`}
|
||||
subtitle="先核对业务摘要和证据,再处理通过、退回、驳回或转审。"
|
||||
meta={(
|
||||
<>
|
||||
<StatusBadge status={detail.task.status} />
|
||||
<span className="info-chip">业务状态:{businessStatusLabel}</span>
|
||||
<span className="info-chip">类型:{entityTitle(detail.workflowInstance?.entityType)}</span>
|
||||
</>
|
||||
)}
|
||||
actions={(
|
||||
@@ -279,8 +311,20 @@ export function WorkflowTaskDetailPage() {
|
||||
|
||||
<div className="detail-workspace-grid">
|
||||
<div className="space-y-5">
|
||||
<SectionPanel title="审批对象摘要">
|
||||
<SectionPanel title="当前状态与审批对象" description="首屏只放判断审批所需的状态、摘要和下一步。">
|
||||
<div className="space-y-4" data-testid="workflow-task-overview">
|
||||
<div className="detail-command-panel" data-testid="workflow-task-next-action">
|
||||
<div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-semibold text-zinc-500">下一步</div>
|
||||
<p className="mt-1 text-sm leading-6 text-zinc-700">{nextActionText}</p>
|
||||
</div>
|
||||
<div className="shrink-0 rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-700">
|
||||
可执行:<span className="font-semibold text-zinc-900">{allowedActionLabels || "无"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<StatStrip columns={4} className="ops-status-strip">
|
||||
<MetricCard title="当前节点" value={<span className="text-base">{detail.task.stepName}</span>} />
|
||||
<MetricCard title="业务类型" value={<span className="text-base">{entityTitle(detail.workflowInstance?.entityType)}</span>} />
|
||||
@@ -400,7 +444,7 @@ export function WorkflowTaskDetailPage() {
|
||||
</SectionPanel>
|
||||
) : null}
|
||||
|
||||
<SectionPanel title="审批动作">
|
||||
<SectionPanel title="审批动作" description="高风险动作会再次确认;驳回、退回和转审需要留下可复核说明。">
|
||||
<div className="detail-action-stack">
|
||||
{actionError ? (
|
||||
<p
|
||||
@@ -521,13 +565,16 @@ export function WorkflowTaskDetailPage() {
|
||||
</div>
|
||||
|
||||
<div className="space-y-5">
|
||||
<DetailSideMeta title="任务摘要">
|
||||
<DetailSideMeta title="任务摘要" description="保留审批留痕所需的节点、角色和时间。">
|
||||
<div>节点:{detail.task.stepName}</div>
|
||||
<div>实例状态:{workflowInstanceStatusLabel(detail.workflowInstance?.currentStatus)}</div>
|
||||
<div>当前审批角色:{detail.task.assigneeRole ?? "-"}</div>
|
||||
<div>创建时间:{formatDateTime(detail.task.createdAt)}</div>
|
||||
<div>完成时间:{formatDateTime(detail.task.completedAt)}</div>
|
||||
<div>发起时间:{formatDateTime(detail.workflowInstance?.startedAt)}</div>
|
||||
<div className="rounded-lg border border-zinc-200 bg-zinc-50 p-3 text-zinc-700">
|
||||
{nextActionText}
|
||||
</div>
|
||||
</DetailSideMeta>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
在新工单中引用
屏蔽一个用户