import { useMemo, useState } from "react"; import { Link, useNavigate, useParams } from "react-router-dom"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { isApiError } from "../api/types"; import { mapApiErrorMessage } from "../api/errorMessages"; import { approveWorkflowTask, fetchWorkflowApprovers, fetchWorkflowTaskDetail, rejectWorkflowTask, returnWorkflowTask, transferWorkflowTask, } from "../api/workflow"; import { useAuth } from "../auth/AuthContext"; import { hasPermission } from "../auth/permissions"; import { PageHeader } from "../components/common/PageHeader"; import { Button } from "../components/ui/button"; import { Card } from "../components/ui/card"; import { Textarea } from "../components/ui/textarea"; export function WorkflowTaskDetailPage() { const { taskId = "" } = useParams(); const navigate = useNavigate(); const queryClient = useQueryClient(); const { permissions } = useAuth(); const [rejectComment, setRejectComment] = useState("请补充必要说明后重提"); const [returnComment, setReturnComment] = useState("请补充报销说明并修正后重新提交"); const [transferReason, setTransferReason] = useState("当前事项需转交对应审批人处理,请尽快处理。"); const [selectedApprover, setSelectedApprover] = useState(""); const [actionError, setActionError] = useState(""); const detailQuery = useQuery({ enabled: Boolean(taskId), queryKey: ["workflow", "task", taskId], queryFn: () => fetchWorkflowTaskDetail(taskId), }); const approverQuery = useQuery({ enabled: hasPermission(permissions, "expense.transfer"), queryKey: ["workflow", "approvers"], queryFn: () => fetchWorkflowApprovers({ page: 1, pageSize: 50 }), }); const allowedActions = useMemo(() => { return new Set(detailQuery.data?.allowedActions ?? []); }, [detailQuery.data?.allowedActions]); const mutation = useMutation({ mutationFn: async (action: "approve" | "reject" | "return" | "transfer") => { if (!taskId) { throw new Error("missing taskId"); } if (action === "approve") { return approveWorkflowTask(taskId); } if (action === "reject") { return rejectWorkflowTask(taskId, rejectComment.trim()); } if (action === "return") { return returnWorkflowTask(taskId, returnComment.trim()); } if (!selectedApprover) { throw new Error("请选择转审目标"); } return transferWorkflowTask(taskId, selectedApprover, transferReason.trim()); }, onSuccess: async () => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ["workflow", "tasks"] }), queryClient.invalidateQueries({ queryKey: ["workflow", "task", taskId] }), ]); setActionError(""); }, onError: (error) => { if (error instanceof Error && !isApiError(error)) { setActionError(error.message); return; } if (isApiError(error)) { setActionError( `${error.code}: ${mapApiErrorMessage(error.code, error.details, error.message)}`, ); return; } setActionError("动作执行失败,请稍后重试"); }, }); if (!taskId) { return (

缺少 taskId 参数。

); } if (detailQuery.isLoading) { return (

加载任务详情中...

); } if (detailQuery.isError || !detailQuery.data) { const message = isApiError(detailQuery.error) ? `${detailQuery.error.code}: ${mapApiErrorMessage( detailQuery.error.code, detailQuery.error.details, detailQuery.error.message, )}` : "加载失败,请返回列表重试"; return (

{message}

); } const detail = detailQuery.data; return (
返回待办列表 } />
状态:{detail.task.status}
实例:{detail.workflowInstance?.id ?? "-"}
报销单号:{detail.reimbursement?.formNumber ?? "-"}
报销金额:{detail.reimbursement?.totalAmount ?? "-"}
提交人:{detail.reimbursement?.submitter?.name ?? "-"}
报销人:{detail.reimbursement?.owner?.name ?? "-"}

审批动作

{actionError ? (

{actionError}

) : null}

驳回