实现报销材料连续预览(07-27-yang-jun-reimbursement-readiness)
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-08-01 00:17:54 +08:00
父节点 b6485a278e
当前提交 8a9279efce
共修改 26 个文件,包含 1211 行新增和 178 行删除
+10
查看文件
@@ -28,6 +28,8 @@ export type InvoicePoolListItem = {
ocrAttempts: number;
ocrLastError: string | null;
ocrCompletedAt: string | null;
documentCategory: string | null;
documentSubtype: string | null;
invoiceCode: string | null;
invoiceNumber: string | null;
invoiceDate: string | null;
@@ -94,6 +96,8 @@ export type InvoicePoolDetail = {
ocrLastRequestedAt: string | null;
ocrLastError: string | null;
ocrCompletedAt: string | null;
documentCategory: string | null;
documentSubtype: string | null;
invoiceCode: string | null;
invoiceNumber: string | null;
invoiceDate: string | null;
@@ -136,6 +140,9 @@ export type BindableInvoiceSummary = {
invoiceNumber: string | null;
invoiceDate: string | null;
sellerName: string | null;
buyerName: string | null;
documentCategory: string | null;
documentSubtype: string | null;
totalAmount: string | null;
originalName: string | null;
createdAt: string | null;
@@ -156,6 +163,9 @@ export type InvoiceStatusItem = {
invoiceNumber: string | null;
invoiceDate: string | null;
sellerName: string | null;
buyerName: string | null;
documentCategory: string | null;
documentSubtype: string | null;
totalAmount: string | null;
originalName: string | null;
linkedReimbursementId: string | null;
+26
查看文件
@@ -173,6 +173,9 @@ export type ReimbursementDetail = {
invoiceNumber: string | null;
invoiceDate: string | null;
sellerName: string | null;
buyerName: string | null;
documentCategory: string | null;
documentSubtype: string | null;
totalAmount: string | null;
originalName: string | null;
mimeType: string | null;
@@ -544,6 +547,29 @@ export async function fetchReimbursementAttachmentPreviewUrl(
});
}
export type ReimbursementMaterialPreviewBundle = {
expiresAt: string;
pages: Array<{
url: string;
materialType: "invoice" | "attachment";
materialIndex: number;
pageNumber: number;
}>;
};
export async function fetchReimbursementMaterialPreviewBundle(
reimbursementId: string,
reason?: string,
) {
return apiRequestData<ReimbursementMaterialPreviewBundle>(
`/api/reimbursements/${reimbursementId}/materials/preview-bundle`,
{
method: "POST",
body: JSON.stringify(reason ? { reason } : {}),
},
);
}
export async function linkReimbursementProject(reimbursementId: string, projectId: string | null) {
return apiRequestData<{ projectId: string | null; project: { id: string; projectNo: string; name: string } | null }>(`/api/reimbursements/${reimbursementId}/link-project`, {