V1-V6 收口移动视口与 PDF 发票上传
这个提交包含在:
@@ -23,12 +23,7 @@ const {
|
||||
resolveUploadDedupDecision,
|
||||
} = require("../services/invoiceGovernance");
|
||||
|
||||
const MIME_ALLOWLIST = new Set([
|
||||
"application/pdf",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
]);
|
||||
const INVOICE_UPLOAD_MIME_TYPE = "application/pdf";
|
||||
const OCR_TYPE_ALLOWLIST = new Set(["vat", "train", "flight", "taxi", "general"]);
|
||||
|
||||
const bindBodySchema = z.union([
|
||||
@@ -200,6 +195,10 @@ function parseDateOnlyString(value) {
|
||||
return new Date(`${trimmed}T00:00:00.000Z`);
|
||||
}
|
||||
|
||||
function isPdfInvoiceUpload(fileName, mimeType) {
|
||||
return mimeType === INVOICE_UPLOAD_MIME_TYPE && path.extname(fileName ?? "").toLowerCase() === ".pdf";
|
||||
}
|
||||
|
||||
async function resolveDefaultExpenseType(tx) {
|
||||
const preferred = await tx.expenseType.findFirst({
|
||||
where: {
|
||||
@@ -369,12 +368,12 @@ async function invoicePoolRoutes(fastify) {
|
||||
fileName = part.filename ?? "upload";
|
||||
fileMimeType = part.mimetype;
|
||||
|
||||
if (!MIME_ALLOWLIST.has(fileMimeType)) {
|
||||
if (!isPdfInvoiceUpload(fileName, fileMimeType)) {
|
||||
throw new AppError({
|
||||
code: "VALID_001",
|
||||
message: "参数校验失败",
|
||||
message: "请上传 PDF 发票文件",
|
||||
statusCode: 400,
|
||||
details: { file: "unsupported_mime_type" },
|
||||
details: { file: "pdf_invoice_required" },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户