H1-H10 优化OCR实时体验闭环

这个提交包含在:
2026-05-09 11:48:57 +08:00
父节点 549bd81e30
当前提交 c26cf9b954
共修改 34 个文件,包含 1217 行新增和 184 行删除
@@ -1,6 +1,8 @@
const {
INVOICE_UNAVAILABLE_REASONS,
classifyInvoiceConflict,
formatInvoiceOcrFailureMessage,
resolveInvoiceAvailability,
resolveUploadDedupDecision,
} = require("../../src/services/invoiceGovernance");
@@ -17,6 +19,7 @@ function buildInvoice(overrides = {}) {
file_sha256: overrides.file_sha256 ?? "sha256-a",
invoice_code: overrides.invoice_code ?? null,
invoice_number: overrides.invoice_number ?? null,
ocr_last_error: overrides.ocr_last_error ?? null,
};
}
@@ -90,4 +93,34 @@ describe("invoiceGovernance dedup", () => {
expect(decision.action).toBe("blocked");
expect(decision.reason).toBe(INVOICE_UNAVAILABLE_REASONS.duplicateOtherOwner);
});
it("formats invoice availability without leaking raw OCR error codes", () => {
expect(
resolveInvoiceAvailability(
buildInvoice({
status: "ocr_failed",
ocr_last_error: "missing_required_fields:invoiceCode,sellerName",
}),
),
).toEqual({
reason: "ocr_failed",
message: "票据识别缺少关键字段:发票代码、销售方。",
});
expect(
resolveInvoiceAvailability(
buildInvoice({
status: "ocr_failed",
ocr_last_error: "duplicate_invoice_code_number",
}),
),
).toEqual({
reason: "duplicate_invoice",
message: "已识别出相同发票,不能重复添加",
});
expect(formatInvoiceOcrFailureMessage("mock_ocr_failed")).toBe(
"票据识别失败,请重试或人工补齐关键信息。",
);
});
});