实现报销材料连续预览(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 行删除
+9
查看文件
@@ -8,6 +8,7 @@ const { buildAttachmentContentDisposition } = require("../../utils/contentDispos
const { openReadStream, StorageNotFoundError } = require("../../services/storage");
const { toMoneyString } = require("../../utils/workflow");
const { resolveInvoiceAvailability } = require("../../services/invoiceGovernance");
const { mapInvoiceDocumentMeta } = require("../../services/invoiceDocumentMeta");
const {
mapInvoiceSummary,
normalizeInvoiceResponse,
@@ -201,11 +202,13 @@ function registerInvoicePoolReadRoutes(fastify) {
invoice_number: true,
invoice_date: true,
seller_name: true,
buyer_name: true,
total_amount: true,
original_name: true,
ocr_attempts: true,
ocr_last_error: true,
ocr_completed_at: true,
ocr_result: { select: { result_json: true } },
updated_at: true,
linked_reimbursement: {
select: {
@@ -221,6 +224,7 @@ function registerInvoicePoolReadRoutes(fastify) {
items: readableRows.map((invoice) => {
const statusReason = resolveInvoiceStatusReason(invoice);
return {
...mapInvoiceDocumentMeta(invoice),
id: invoice.id,
status: invoice.status,
reason: statusReason.reason,
@@ -231,6 +235,7 @@ function registerInvoicePoolReadRoutes(fastify) {
invoiceNumber: invoice.invoice_number ?? null,
invoiceDate: invoice.invoice_date?.toISOString?.()?.slice(0, 10) ?? null,
sellerName: invoice.seller_name ?? null,
buyerName: invoice.buyer_name ?? null,
totalAmount: toMoneyString(invoice.total_amount),
originalName: invoice.original_name ?? null,
linkedReimbursementId: invoice.linked_reimbursement_id ?? null,
@@ -319,19 +324,23 @@ function registerInvoicePoolReadRoutes(fastify) {
invoice_number: true,
invoice_date: true,
seller_name: true,
buyer_name: true,
total_amount: true,
original_name: true,
created_at: true,
ocr_result: { select: { result_json: true } },
},
});
return sendData(reply, request, {
items: items.map((item) => ({
...mapInvoiceDocumentMeta(item),
id: item.id,
invoiceCode: item.invoice_code ?? null,
invoiceNumber: item.invoice_number ?? null,
invoiceDate: item.invoice_date?.toISOString?.()?.slice(0, 10) ?? null,
sellerName: item.seller_name ?? null,
buyerName: item.buyer_name ?? null,
totalAmount: toMoneyString(item.total_amount),
originalName: item.original_name ?? null,
createdAt: item.created_at?.toISOString?.() ?? null,
@@ -1,5 +1,6 @@
const { toMoneyString } = require("../../../utils/workflow");
const { resolveInvoiceAvailability } = require("../../../services/invoiceGovernance");
const { mapInvoiceDocumentMeta } = require("../../../services/invoiceDocumentMeta");
function mapVerificationRecord(item) {
if (!item) {
@@ -30,6 +31,7 @@ function mapInvoiceSummary(item) {
const availability = resolveInvoiceAvailability(item);
return {
...mapInvoiceDocumentMeta(item),
id: item.id,
status: item.status,
availabilityReason: availability.reason,
@@ -78,6 +80,7 @@ function normalizeInvoiceResponse(invoice) {
const availability = resolveInvoiceAvailability(invoice);
return {
...mapInvoiceDocumentMeta(invoice),
id: invoice.id,
status: invoice.status,
availabilityReason: availability.reason,
@@ -49,6 +49,7 @@ function buildInvoiceSummarySelect() {
created_at: true,
updated_at: true,
verification_records: buildLatestVerificationSelect(),
ocr_result: { select: { result_json: true } },
owner_employee: {
select: { id: true, employee_no: true, name: true },
},
@@ -95,6 +96,7 @@ function buildInvoiceDetailSelect(options = {}) {
created_at: true,
updated_at: true,
verification_records: buildLatestVerificationSelect(),
ocr_result: { select: { result_json: true } },
};
if (options.includeLinkedReimbursement) {