实现业务附件受控入库 V1(05-28-business-attachment-governance-v1)
这个提交包含在:
@@ -23,6 +23,8 @@ import { useAuth } from "../auth/AuthContext";
|
||||
import { hasPermission } from "../auth/permissions";
|
||||
import { ListWorkspace, WorkspaceHeader } from "../components/patterns/ListWorkspace";
|
||||
import { ActionConfirmDialog } from "../components/common/ActionConfirmDialog";
|
||||
import { AttachmentGovernanceBadges } from "../components/common/AttachmentGovernanceBadges";
|
||||
import { useAttachmentDownloadReasonDialog } from "../components/common/useAttachmentDownloadReasonDialog";
|
||||
import { Button } from "../components/ui/button";
|
||||
import { Input } from "../components/ui/input";
|
||||
import { Label } from "../components/ui/label";
|
||||
@@ -301,12 +303,14 @@ export function PaymentBatchesPage() {
|
||||
},
|
||||
});
|
||||
|
||||
const { requestDownloadReason, downloadReasonDialog } = useAttachmentDownloadReasonDialog();
|
||||
|
||||
const downloadReceiptMutation = useMutation({
|
||||
mutationFn: async (attachment: PaymentBatchReceiptAttachment) => {
|
||||
mutationFn: async ({ attachment, reason }: { attachment: PaymentBatchReceiptAttachment; reason?: string }) => {
|
||||
if (!selectedBatch) {
|
||||
throw new Error("请先选择付款批次");
|
||||
}
|
||||
const response = await downloadPaymentBatchReceiptAttachment(selectedBatch.id, attachment.id);
|
||||
const response = await downloadPaymentBatchReceiptAttachment(selectedBatch.id, attachment.id, reason);
|
||||
return { response, attachment };
|
||||
},
|
||||
onSuccess: ({ response, attachment }) => {
|
||||
@@ -319,6 +323,14 @@ export function PaymentBatchesPage() {
|
||||
},
|
||||
});
|
||||
|
||||
async function handleDownloadReceipt(attachment: PaymentBatchReceiptAttachment) {
|
||||
const reason = await requestDownloadReason(attachment);
|
||||
if (reason === null) {
|
||||
return;
|
||||
}
|
||||
downloadReceiptMutation.mutate({ attachment, reason });
|
||||
}
|
||||
|
||||
const deleteReceiptMutation = useMutation({
|
||||
mutationFn: async (attachmentId: string) => {
|
||||
if (!selectedBatch) {
|
||||
@@ -340,6 +352,7 @@ export function PaymentBatchesPage() {
|
||||
|
||||
return (
|
||||
<ListWorkspace>
|
||||
{downloadReasonDialog}
|
||||
<WorkspaceHeader title="付款批次" subtitle="复核、回单和已付款标记集中处理。" />
|
||||
|
||||
{error ? <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">{error}</div> : null}
|
||||
@@ -607,6 +620,7 @@ export function PaymentBatchesPage() {
|
||||
{attachment.mimeType} · {formatFileSize(attachment.fileSize)} · {formatDisplayDateTime(attachment.createdAt)}
|
||||
{attachment.uploadedBy ? ` · ${attachment.uploadedBy.name}` : ""}
|
||||
</div>
|
||||
<AttachmentGovernanceBadges attachment={attachment} className="mt-2" />
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button
|
||||
@@ -614,7 +628,7 @@ export function PaymentBatchesPage() {
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
disabled={downloadReceiptMutation.isPending}
|
||||
onClick={() => downloadReceiptMutation.mutate(attachment)}
|
||||
onClick={() => void handleDownloadReceipt(attachment)}
|
||||
>
|
||||
下载
|
||||
</Button>
|
||||
|
||||
在新工单中引用
屏蔽一个用户