137 行
4.0 KiB
TypeScript
137 行
4.0 KiB
TypeScript
import type { InvoicePoolStatus } from "../api/invoicePool";
|
|
import { formatInvoiceOcrErrorMessage } from "./invoiceOcr";
|
|
|
|
type InvoiceDisplayLike = {
|
|
status?: string | null;
|
|
invoiceCode?: string | null;
|
|
invoiceNumber?: string | null;
|
|
invoiceDate?: string | null;
|
|
sellerName?: string | null;
|
|
originalName?: string | null;
|
|
unavailableReason?: string | null;
|
|
unavailableMessage?: string | null;
|
|
availabilityReason?: string | null;
|
|
availabilityMessage?: string | null;
|
|
archivedReason?: string | null;
|
|
reason?: string | null;
|
|
message?: string | null;
|
|
ocrLastError?: string | null;
|
|
};
|
|
|
|
const INVOICE_STATUS_LABELS: Record<InvoicePoolStatus, string> = {
|
|
pending_ocr: "识别中",
|
|
ocr_failed: "识别失败",
|
|
available: "可添加",
|
|
bound: "已添加",
|
|
archived: "已归档/已报销",
|
|
};
|
|
|
|
export function resolveInvoiceStatusLabel(status: string | null | undefined) {
|
|
return status && status in INVOICE_STATUS_LABELS
|
|
? INVOICE_STATUS_LABELS[status as InvoicePoolStatus]
|
|
: "未知状态";
|
|
}
|
|
|
|
export function formatInvoiceDisplayTitle(invoice: InvoiceDisplayLike | null | undefined) {
|
|
if (!invoice) {
|
|
return "未识别发票";
|
|
}
|
|
|
|
if (invoice.invoiceCode || invoice.invoiceNumber) {
|
|
return `${invoice.invoiceCode || "无代码"}-${invoice.invoiceNumber || "无号码"}`;
|
|
}
|
|
|
|
return invoice.sellerName || invoice.originalName || "未识别发票";
|
|
}
|
|
|
|
function looksLikeMachineMessage(message: string) {
|
|
return /^[a-z0-9_:. -]+$/i.test(message) && /[a-z]/i.test(message);
|
|
}
|
|
|
|
function resolveReasonMessage(reason: string | null | undefined) {
|
|
if (!reason) {
|
|
return "";
|
|
}
|
|
|
|
if (/duplicate/i.test(reason)) {
|
|
return "已识别出相同发票,不能重复添加。";
|
|
}
|
|
|
|
if (/used_complete|used|archived/i.test(reason)) {
|
|
return "该发票已报销或归档,不能再次添加。";
|
|
}
|
|
|
|
if (/bound|linked/i.test(reason)) {
|
|
return "该发票已添加到其他单据,不能重复添加。";
|
|
}
|
|
|
|
if (/pending/i.test(reason)) {
|
|
return "发票正在识别,完成后会自动刷新。";
|
|
}
|
|
|
|
if (/failed|missing_required_fields/i.test(reason)) {
|
|
return formatInvoiceOcrErrorMessage(reason);
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
export function resolveInvoiceUserMessage(invoice: InvoiceDisplayLike | null | undefined) {
|
|
if (!invoice) {
|
|
return "该发票暂不可添加,请稍后刷新。";
|
|
}
|
|
|
|
const explicitMessage = invoice.unavailableMessage || invoice.availabilityMessage || invoice.message || "";
|
|
if (explicitMessage && !looksLikeMachineMessage(explicitMessage)) {
|
|
return explicitMessage;
|
|
}
|
|
|
|
const reasonMessage =
|
|
resolveReasonMessage(explicitMessage) ||
|
|
resolveReasonMessage(invoice.unavailableReason) ||
|
|
resolveReasonMessage(invoice.availabilityReason) ||
|
|
resolveReasonMessage(invoice.reason) ||
|
|
resolveReasonMessage(invoice.archivedReason);
|
|
if (reasonMessage) {
|
|
return reasonMessage;
|
|
}
|
|
|
|
if (invoice.ocrLastError) {
|
|
const errorMessage = formatInvoiceOcrErrorMessage(invoice.ocrLastError);
|
|
return /重试|重新上传|人工处理/.test(errorMessage)
|
|
? errorMessage
|
|
: `${errorMessage} 可删除后重新上传。`;
|
|
}
|
|
|
|
switch (invoice.status) {
|
|
case "pending_ocr":
|
|
return "发票正在识别,完成后会自动刷新。";
|
|
case "available":
|
|
return "可添加到当前报销单。";
|
|
case "bound":
|
|
return "该发票已添加到报销单,草稿或驳回状态可移除。";
|
|
case "archived":
|
|
return "该发票已归档或已报销,不能再次添加。";
|
|
case "ocr_failed":
|
|
return "识别失败,可删除后重新上传。";
|
|
default:
|
|
return "该发票暂不可添加,请稍后刷新。";
|
|
}
|
|
}
|
|
|
|
export function resolveInvoiceNextStepText(invoice: InvoiceDisplayLike | null | undefined) {
|
|
if (!invoice?.status) {
|
|
return "";
|
|
}
|
|
|
|
if (invoice.status === "available") {
|
|
return "可添加到当前报销单。";
|
|
}
|
|
|
|
if (invoice.status === "bound") {
|
|
return "已添加到报销单,草稿或驳回状态可移除。";
|
|
}
|
|
|
|
return resolveInvoiceUserMessage(invoice);
|
|
}
|