|
|
/**
|
|
|
* 入库「上<E3808C>?DO」样例:docx/邮件/模板/WHSU8127240-DO.pdf
|
|
|
* 用法: pnpm sample:do
|
|
|
*/
|
|
|
import { createHash } from "crypto";
|
|
|
import fs from "fs/promises";
|
|
|
import path from "path";
|
|
|
import { prisma } from "@/services/db";
|
|
|
import { ParsePipeline } from "@/services/parse/pipeline";
|
|
|
import { buildCcDoUploadFormValue } from "@/components/CcDoUploadPanel";
|
|
|
import { extractMailInstructions } from "@/services/parse/split-instructions";
|
|
|
import { sha256 } from "@/utils/hash";
|
|
|
|
|
|
const SUBJECT = "请查<E8AFB7>?DO:柜<EFBC9A>?WHSU8127240";
|
|
|
const BODY = "Dear,\n请查收附<E694B6>?DO 文件,谢谢<E8B0A2>?;
|
|
|
const MESSAGE_ID = "<sample-do-upload-whsu8127240@local.test>";
|
|
|
const DO_PDF = path.join(
|
|
|
process.cwd(),
|
|
|
"docx",
|
|
|
"邮件",
|
|
|
"模板",
|
|
|
"WHSU8127240-DO.pdf",
|
|
|
);
|
|
|
|
|
|
async function attachDo(mailId: bigint): Promise<string> {
|
|
|
const buf = await fs.readFile(DO_PDF);
|
|
|
const hash = sha256(buf);
|
|
|
const filename = "WHSU8127240-DO.pdf";
|
|
|
const dir = path.join(process.cwd(), "data", "mails", String(mailId));
|
|
|
await fs.mkdir(dir, { recursive: true });
|
|
|
const dest = path.join(dir, filename);
|
|
|
await fs.writeFile(dest, buf);
|
|
|
const rel = path.relative(process.cwd(), dest).replace(/\\/g, "/");
|
|
|
await prisma.mailAttachment.create({
|
|
|
data: {
|
|
|
mailId,
|
|
|
filename,
|
|
|
contentType: "application/pdf",
|
|
|
sha256: hash,
|
|
|
path: rel,
|
|
|
size: buf.length,
|
|
|
rejected: false,
|
|
|
},
|
|
|
});
|
|
|
return filename;
|
|
|
}
|
|
|
|
|
|
async function main() {
|
|
|
await fs.access(DO_PDF);
|
|
|
|
|
|
const rawHash = createHash("sha256")
|
|
|
.update(`do-upload-ui|${MESSAGE_ID}|${SUBJECT}|WHSU8127240-DO.pdf|v1`)
|
|
|
.digest("hex");
|
|
|
|
|
|
const existing = await prisma.mailMessage.findFirst({
|
|
|
where: { OR: [{ messageId: MESSAGE_ID }, { rawHash }] },
|
|
|
});
|
|
|
|
|
|
let mailId: bigint;
|
|
|
if (existing) {
|
|
|
await prisma.importCompensation.deleteMany({
|
|
|
where: { import: { mailId: existing.id } },
|
|
|
});
|
|
|
await prisma.containerImport.deleteMany({ where: { mailId: existing.id } });
|
|
|
await prisma.parseResult.deleteMany({ where: { mailId: existing.id } });
|
|
|
await prisma.mailAttachment.deleteMany({ where: { mailId: existing.id } });
|
|
|
await prisma.mailMessage.update({
|
|
|
where: { id: existing.id },
|
|
|
data: {
|
|
|
subject: SUBJECT.slice(0, 512),
|
|
|
fromAddr: "do-upload@local.test",
|
|
|
bodyText: BODY,
|
|
|
status: "FETCHED",
|
|
|
mailType: "UNKNOWN",
|
|
|
lastError: null,
|
|
|
rawHash,
|
|
|
receivedAt: new Date("2026-04-20T09:00:00.000Z"),
|
|
|
typeEvidence: { note: "do_upload_ui_sample" },
|
|
|
version: { increment: 1 },
|
|
|
},
|
|
|
});
|
|
|
mailId = existing.id;
|
|
|
} else {
|
|
|
const created = await prisma.mailMessage.create({
|
|
|
data: {
|
|
|
messageId: MESSAGE_ID,
|
|
|
subject: SUBJECT.slice(0, 512),
|
|
|
fromAddr: "do-upload@local.test",
|
|
|
bodyText: BODY,
|
|
|
status: "FETCHED",
|
|
|
mailType: "UNKNOWN",
|
|
|
rawHash,
|
|
|
folder: "INBOX",
|
|
|
receivedAt: new Date("2026-04-20T09:00:00.000Z"),
|
|
|
isThreadRoot: true,
|
|
|
typeEvidence: { note: "do_upload_ui_sample" },
|
|
|
},
|
|
|
});
|
|
|
mailId = created.id;
|
|
|
}
|
|
|
|
|
|
const filename = await attachDo(mailId);
|
|
|
await ParsePipeline.run(mailId);
|
|
|
|
|
|
const updated = await prisma.mailMessage.findUniqueOrThrow({
|
|
|
where: { id: mailId },
|
|
|
include: { parseResult: true, attachments: true },
|
|
|
});
|
|
|
|
|
|
const form = buildCcDoUploadFormValue({
|
|
|
subject: updated.subject,
|
|
|
body: updated.bodyText,
|
|
|
filenames: updated.attachments.map((a) => a.filename),
|
|
|
});
|
|
|
const units = extractMailInstructions({
|
|
|
subject: updated.subject,
|
|
|
body: updated.bodyText || "",
|
|
|
filenames: updated.attachments.map((a) => a.filename),
|
|
|
});
|
|
|
|
|
|
console.log(
|
|
|
JSON.stringify(
|
|
|
{
|
|
|
id: String(updated.id),
|
|
|
mail_type: updated.mailType,
|
|
|
status: updated.status,
|
|
|
attached: filename,
|
|
|
form,
|
|
|
ui_kinds: units.map((u) => u.uiKind),
|
|
|
url: `http://localhost:3100/mails/${updated.id}`,
|
|
|
},
|
|
|
null,
|
|
|
2,
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
main()
|
|
|
.catch((e) => {
|
|
|
console.error(e);
|
|
|
process.exit(1);
|
|
|
})
|
|
|
.finally(async () => {
|
|
|
await prisma.$disconnect();
|
|
|
});
|